summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore41
-rw-r--r--.htaccess.dist36
-rw-r--r--COPYING339
-rw-r--r--README10
-rw-r--r--_cs/DokuWiki/DokuWikiCodingStandard.php78
-rw-r--r--_cs/DokuWiki/Sniffs/Functions/OpeningFunctionBraceSniff.php81
-rw-r--r--_cs/DokuWiki/Sniffs/PHP/DiscouragedFunctionsSniff.php56
-rw-r--r--_cs/DokuWiki/Sniffs/WhiteSpace/ScopeIndentSniff.php319
-rw-r--r--_cs/README18
-rw-r--r--_test/README84
-rw-r--r--_test/cases/inc/DifferenceEngine.test.php31
-rw-r--r--_test/cases/inc/IXR_Library_IXR_Message.test.php139
-rw-r--r--_test/cases/inc/IXR_Library_date.test.php34
-rw-r--r--_test/cases/inc/auth_aclcheck.test.php231
-rw-r--r--_test/cases/inc/auth_admincheck.test.php132
-rw-r--r--_test/cases/inc/auth_nameencode.test.php50
-rw-r--r--_test/cases/inc/auth_password.test.php68
-rw-r--r--_test/cases/inc/common_clientip.test.php155
-rw-r--r--_test/cases/inc/common_obfuscate.test.php28
-rw-r--r--_test/cases/inc/common_pagetemplate.test.php19
-rw-r--r--_test/cases/inc/form_form.test.php105
-rw-r--r--_test/cases/inc/html_hilight.test.php104
-rw-r--r--_test/cases/inc/indexer_idx_indexlengths.test.php60
-rw-r--r--_test/cases/inc/init_fullpath.test.php89
-rw-r--r--_test/cases/inc/init_getbaseurl.test.php305
-rw-r--r--_test/cases/inc/mail_isvalid.test.php83
-rw-r--r--_test/cases/inc/mail_quoted_printable_encode.php44
-rw-r--r--_test/cases/inc/mail_send.php49
-rw-r--r--_test/cases/inc/pageutils_clean_id.test.php157
-rw-r--r--_test/cases/inc/pageutils_getid.test.php106
-rw-r--r--_test/cases/inc/pageutils_resolve_id.test.php45
-rw-r--r--_test/cases/inc/pageutils_resolve_pageid.test.php85
-rw-r--r--_test/cases/inc/parser/lexer.group.php21
-rw-r--r--_test/cases/inc/parser/lexer.test.php625
-rw-r--r--_test/cases/inc/parser/parser.group.php34
-rw-r--r--_test/cases/inc/parser/parser.inc.php53
-rw-r--r--_test/cases/inc/parser/parser_eol.test.php100
-rw-r--r--_test/cases/inc/parser/parser_footnote.test.php392
-rw-r--r--_test/cases/inc/parser/parser_formatting.test.php434
-rw-r--r--_test/cases/inc/parser/parser_headers.test.php286
-rw-r--r--_test/cases/inc/parser/parser_i18n.test.php166
-rw-r--r--_test/cases/inc/parser/parser_links.test.php683
-rw-r--r--_test/cases/inc/parser/parser_lists.test.php397
-rw-r--r--_test/cases/inc/parser/parser_preformatted.test.php235
-rw-r--r--_test/cases/inc/parser/parser_quote.test.php98
-rw-r--r--_test/cases/inc/parser/parser_quotes.test.php273
-rw-r--r--_test/cases/inc/parser/parser_replacements.test.php384
-rw-r--r--_test/cases/inc/parser/parser_table.test.php576
-rw-r--r--_test/cases/inc/parser/parser_unformatted.test.php42
-rw-r--r--_test/cases/inc/parser/xhtml_htmlphp.test.php203
-rw-r--r--_test/cases/inc/parser/xhtml_links.test.php239
-rw-r--r--_test/cases/inc/parserutils_set_metadata_during_rendering.test.php93
-rw-r--r--_test/cases/inc/safefn.test.php48
-rw-r--r--_test/cases/inc/search/data/ns1/ns3/page3.txt0
-rw-r--r--_test/cases/inc/search/data/ns1/page1.txt0
-rw-r--r--_test/cases/inc/search/data/ns1/page2.txt0
-rw-r--r--_test/cases/inc/search/data/ns2/nopage.ext0
-rw-r--r--_test/cases/inc/search/data/ns2/page1.txt0
-rw-r--r--_test/cases/inc/search/search.test.php102
-rw-r--r--_test/cases/inc/utf8_correctidx.test.php78
-rw-r--r--_test/cases/inc/utf8_html.test.php72
-rw-r--r--_test/cases/inc/utf8_kanaromaji.txt22893
-rw-r--r--_test/cases/inc/utf8_romanize.test.php36
-rw-r--r--_test/cases/inc/utf8_stripspecials.test.php28
-rw-r--r--_test/cases/inc/utf8_substr.test.php43
-rw-r--r--_test/cases/inc/utf8_unicode.test.php60
-rw-r--r--_test/cases/inc/utf8_utf16be.test.php28
-rw-r--r--_test/cases/lib/exe/css_css_compress.test.php68
-rw-r--r--_test/cases/lib/exe/css_css_loadfile.test.php57
-rw-r--r--_test/cases/lib/exe/js_js_compress.test.php129
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes1-in.js5
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes1-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes2-in.js5
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes2-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes1-in.js5
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes1-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes2-in.js5
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes2-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentMultiline-in.js11
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentMultiline-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentSingleLine-in.js7
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-CommentSingleLine-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-IfThenElseBraces-in.js7
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-IfThenElseBraces-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-IfThenElseNoBraces-in.js7
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-IfThenElseNoBraces-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-RegexpBackslash-in.js3
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-RegexpBackslash-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-RegexpSimple-in.js3
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-RegexpSimple-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-RegexpSimpleWhitespace-in.js5
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-RegexpSimpleWhitespace-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-RegexpString-in.js3
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-RegexpString-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StatementDoWhile-in.js2
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StatementDoWhile-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StatementForIn-in.js2
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StatementForIn-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StatementNew-in.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StatementNew-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StatementSwitchCase-in.js4
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StatementSwitchCase-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StringDoubleQuotes-in.js3
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StringDoubleQuotes-out.js1
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StringSingleQuotes-in.js8
-rw-r--r--_test/cases/lib/exe/js_js_compress/test-StringSingleQuotes-out.js1
-rw-r--r--_test/debug.note4
-rw-r--r--_test/index.php228
-rw-r--r--_test/jslint.js89
-rw-r--r--_test/lib/cli_reporter.php114
-rw-r--r--_test/lib/mock_functions.php519
-rw-r--r--_test/lib/rss_writer_class.php369
-rw-r--r--_test/lib/testmanager.php579
-rw-r--r--_test/lib/unittest.php5
-rw-r--r--_test/lib/web.inc.php47
-rw-r--r--_test/lib/xml_writer_class.php292
-rwxr-xr-x_test/remotetests.php163
-rw-r--r--_test/rss2html.xsl110
-rwxr-xr-x_test/runtests.php187
-rw-r--r--_test/tests.css27
-rw-r--r--_test/tests.ini12
-rwxr-xr-x_test/webtest-stripper.sh41
-rw-r--r--bin/.htaccess2
-rwxr-xr-xbin/dwpage.php378
-rwxr-xr-xbin/indexer.php158
-rwxr-xr-xbin/render.php67
-rw-r--r--bin/striplangs.php148
-rwxr-xr-xbin/wantedpages.php134
-rw-r--r--conf/.htaccess4
-rw-r--r--conf/acl.auth.php.dist21
-rw-r--r--conf/acronyms.conf145
-rw-r--r--conf/dokuwiki.php167
-rw-r--r--conf/entities.conf22
-rw-r--r--conf/interwiki.conf131
-rw-r--r--conf/license.php36
-rw-r--r--conf/local.php.dist16
-rw-r--r--conf/mediameta.php91
-rw-r--r--conf/mime.conf64
-rw-r--r--conf/mysql.conf.php.example253
-rw-r--r--conf/plugins.required.php11
-rw-r--r--conf/scheme.conf11
-rw-r--r--conf/smileys.conf28
-rw-r--r--conf/users.auth.php.dist10
-rw-r--r--conf/wordblock.conf32
-rw-r--r--data/.htaccess3
-rw-r--r--data/_dummy0
-rw-r--r--data/attic/_dummy0
-rw-r--r--data/cache/_dummy0
-rw-r--r--data/deleted.files257
-rw-r--r--data/index/_dummy0
-rw-r--r--data/locks/_dummy0
-rw-r--r--data/media/wiki/dokuwiki-128.pngbin0 -> 33615 bytes
-rw-r--r--data/media_attic/_dummy0
-rw-r--r--data/media_meta/_dummy0
-rw-r--r--data/meta/_dummy0
-rw-r--r--data/pages/wiki/dokuwiki.txt64
-rw-r--r--data/pages/wiki/syntax.txt486
-rw-r--r--data/security.pngbin0 -> 7917 bytes
-rw-r--r--data/security.xcfbin0 -> 12093 bytes
-rw-r--r--data/tmp/_dummy0
-rw-r--r--doku.php93
-rw-r--r--feed.php457
-rw-r--r--inc/.htaccess4
-rw-r--r--inc/DifferenceEngine.php1163
-rw-r--r--inc/EmailAddressValidator.php191
-rw-r--r--inc/FeedParser.php76
-rw-r--r--inc/HTTPClient.php686
-rw-r--r--inc/IXR_Library.php816
-rw-r--r--inc/JSON.php661
-rw-r--r--inc/JpegMeta.php3008
-rw-r--r--inc/PassHash.class.php433
-rw-r--r--inc/SafeFN.class.php157
-rw-r--r--inc/SimplePie.php15299
-rw-r--r--inc/Sitemapper.php203
-rw-r--r--inc/TarLib.class.php795
-rw-r--r--inc/ZipLib.class.php504
-rw-r--r--inc/actions.php762
-rw-r--r--inc/adLDAP.php2422
-rw-r--r--inc/auth.php1026
-rw-r--r--inc/auth/ad.class.php351
-rw-r--r--inc/auth/basic.class.php403
-rw-r--r--inc/auth/ldap.class.php463
-rw-r--r--inc/auth/mysql.class.php939
-rw-r--r--inc/auth/pgsql.class.php410
-rw-r--r--inc/auth/plain.class.php328
-rw-r--r--inc/blowfish.php514
-rw-r--r--inc/cache.php270
-rw-r--r--inc/changelog.php539
-rw-r--r--inc/cliopts.php504
-rw-r--r--inc/common.php1573
-rw-r--r--inc/config_cascade.php78
-rw-r--r--inc/confutils.php334
-rw-r--r--inc/events.php197
-rw-r--r--inc/feedcreator.class.php1580
-rw-r--r--inc/form.php950
-rw-r--r--inc/fulltext.php753
-rw-r--r--inc/geshi.php4656
-rw-r--r--inc/geshi/4cs.php139
-rw-r--r--inc/geshi/abap.php1409
-rw-r--r--inc/geshi/actionscript-french.php957
-rw-r--r--inc/geshi/actionscript.php197
-rw-r--r--inc/geshi/actionscript3.php473
-rw-r--r--inc/geshi/ada.php135
-rw-r--r--inc/geshi/apache.php480
-rw-r--r--inc/geshi/applescript.php157
-rw-r--r--inc/geshi/apt_sources.php144
-rw-r--r--inc/geshi/asm.php225
-rw-r--r--inc/geshi/asp.php164
-rw-r--r--inc/geshi/autoconf.php512
-rw-r--r--inc/geshi/autohotkey.php373
-rw-r--r--inc/geshi/autoit.php1175
-rw-r--r--inc/geshi/avisynth.php194
-rw-r--r--inc/geshi/awk.php158
-rw-r--r--inc/geshi/bash.php327
-rw-r--r--inc/geshi/basic4gl.php341
-rw-r--r--inc/geshi/bf.php114
-rw-r--r--inc/geshi/bibtex.php183
-rw-r--r--inc/geshi/blitzbasic.php185
-rw-r--r--inc/geshi/bnf.php119
-rw-r--r--inc/geshi/boo.php217
-rw-r--r--inc/geshi/c.php202
-rw-r--r--inc/geshi/c_mac.php227
-rw-r--r--inc/geshi/caddcl.php126
-rw-r--r--inc/geshi/cadlisp.php186
-rw-r--r--inc/geshi/cfdg.php124
-rw-r--r--inc/geshi/cfm.php299
-rw-r--r--inc/geshi/chaiscript.php140
-rw-r--r--inc/geshi/cil.php196
-rw-r--r--inc/geshi/clojure.php134
-rw-r--r--inc/geshi/cmake.php181
-rw-r--r--inc/geshi/cobol.php244
-rw-r--r--inc/geshi/cpp-qt.php564
-rw-r--r--inc/geshi/cpp.php240
-rw-r--r--inc/geshi/csharp.php253
-rw-r--r--inc/geshi/css.php212
-rw-r--r--inc/geshi/cuesheet.php138
-rw-r--r--inc/geshi/d.php272
-rw-r--r--inc/geshi/dcs.php182
-rw-r--r--inc/geshi/delphi.php289
-rw-r--r--inc/geshi/diff.php196
-rw-r--r--inc/geshi/div.php126
-rw-r--r--inc/geshi/dos.php202
-rw-r--r--inc/geshi/dot.php164
-rw-r--r--inc/geshi/ecmascript.php210
-rw-r--r--inc/geshi/eiffel.php395
-rw-r--r--inc/geshi/email.php210
-rw-r--r--inc/geshi/erlang.php441
-rw-r--r--inc/geshi/fo.php327
-rw-r--r--inc/geshi/fortran.php160
-rw-r--r--inc/geshi/freebasic.php141
-rw-r--r--inc/geshi/fsharp.php211
-rw-r--r--inc/geshi/gambas.php214
-rw-r--r--inc/geshi/gdb.php175
-rw-r--r--inc/geshi/genero.php463
-rw-r--r--inc/geshi/genie.php157
-rw-r--r--inc/geshi/gettext.php97
-rw-r--r--inc/geshi/glsl.php205
-rw-r--r--inc/geshi/gml.php506
-rw-r--r--inc/geshi/gnuplot.php296
-rw-r--r--inc/geshi/groovy.php1011
-rw-r--r--inc/geshi/gwbasic.php153
-rw-r--r--inc/geshi/haskell.php202
-rw-r--r--inc/geshi/hicest.php108
-rw-r--r--inc/geshi/hq9plus.php104
-rw-r--r--inc/geshi/html4strict.php203
-rw-r--r--inc/geshi/icon.php212
-rw-r--r--inc/geshi/idl.php123
-rw-r--r--inc/geshi/ini.php128
-rw-r--r--inc/geshi/inno.php212
-rw-r--r--inc/geshi/intercal.php122
-rw-r--r--inc/geshi/io.php138
-rw-r--r--inc/geshi/j.php227
-rw-r--r--inc/geshi/java.php983
-rw-r--r--inc/geshi/java5.php1037
-rw-r--r--inc/geshi/javascript.php150
-rw-r--r--inc/geshi/jquery.php238
-rw-r--r--inc/geshi/kixtart.php329
-rw-r--r--inc/geshi/klonec.php282
-rw-r--r--inc/geshi/klonecpp.php310
-rw-r--r--inc/geshi/latex.php223
-rw-r--r--inc/geshi/lisp.php144
-rw-r--r--inc/geshi/locobasic.php130
-rw-r--r--inc/geshi/logtalk.php330
-rw-r--r--inc/geshi/lolcode.php152
-rw-r--r--inc/geshi/lotusformulas.php318
-rw-r--r--inc/geshi/lotusscript.php191
-rw-r--r--inc/geshi/lscript.php387
-rw-r--r--inc/geshi/lsl2.php898
-rw-r--r--inc/geshi/lua.php137
-rw-r--r--inc/geshi/m68k.php143
-rw-r--r--inc/geshi/magiksf.php193
-rw-r--r--inc/geshi/make.php151
-rw-r--r--inc/geshi/mapbasic.php908
-rw-r--r--inc/geshi/matlab.php227
-rw-r--r--inc/geshi/mirc.php171
-rw-r--r--inc/geshi/mmix.php173
-rw-r--r--inc/geshi/modula2.php136
-rw-r--r--inc/geshi/modula3.php135
-rw-r--r--inc/geshi/mpasm.php164
-rw-r--r--inc/geshi/mxml.php145
-rw-r--r--inc/geshi/mysql.php475
-rw-r--r--inc/geshi/newlisp.php191
-rw-r--r--inc/geshi/nsis.php351
-rw-r--r--inc/geshi/oberon2.php135
-rw-r--r--inc/geshi/objc.php358
-rw-r--r--inc/geshi/ocaml-brief.php112
-rw-r--r--inc/geshi/ocaml.php187
-rw-r--r--inc/geshi/oobas.php135
-rw-r--r--inc/geshi/oracle11.php614
-rw-r--r--inc/geshi/oracle8.php496
-rw-r--r--inc/geshi/oxygene.php152
-rw-r--r--inc/geshi/oz.php144
-rw-r--r--inc/geshi/pascal.php152
-rw-r--r--inc/geshi/pcre.php188
-rw-r--r--inc/geshi/per.php302
-rw-r--r--inc/geshi/perl.php213
-rw-r--r--inc/geshi/perl6.php197
-rw-r--r--inc/geshi/pf.php178
-rw-r--r--inc/geshi/php-brief.php222
-rw-r--r--inc/geshi/php.php1114
-rw-r--r--inc/geshi/pic16.php141
-rw-r--r--inc/geshi/pike.php103
-rw-r--r--inc/geshi/pixelbender.php176
-rw-r--r--inc/geshi/plsql.php256
-rw-r--r--inc/geshi/postgresql.php288
-rw-r--r--inc/geshi/povray.php199
-rw-r--r--inc/geshi/powerbuilder.php418
-rw-r--r--inc/geshi/powershell.php277
-rw-r--r--inc/geshi/progress.php485
-rw-r--r--inc/geshi/prolog.php143
-rw-r--r--inc/geshi/properties.php127
-rw-r--r--inc/geshi/providex.php299
-rw-r--r--inc/geshi/purebasic.php303
-rw-r--r--inc/geshi/python.php237
-rw-r--r--inc/geshi/q.php149
-rw-r--r--inc/geshi/qbasic.php158
-rw-r--r--inc/geshi/rails.php406
-rw-r--r--inc/geshi/rebol.php196
-rw-r--r--inc/geshi/reg.php233
-rw-r--r--inc/geshi/robots.php100
-rw-r--r--inc/geshi/rpmspec.php133
-rw-r--r--inc/geshi/rsplus.php483
-rw-r--r--inc/geshi/ruby.php231
-rw-r--r--inc/geshi/sas.php290
-rw-r--r--inc/geshi/scala.php122
-rw-r--r--inc/geshi/scheme.php170
-rw-r--r--inc/geshi/scilab.php295
-rw-r--r--inc/geshi/sdlbasic.php165
-rw-r--r--inc/geshi/smalltalk.php154
-rw-r--r--inc/geshi/smarty.php192
-rw-r--r--inc/geshi/sql.php140
-rw-r--r--inc/geshi/systemverilog.php317
-rw-r--r--inc/geshi/tcl.php194
-rw-r--r--inc/geshi/teraterm.php317
-rw-r--r--inc/geshi/text.php84
-rw-r--r--inc/geshi/thinbasic.php868
-rw-r--r--inc/geshi/tsql.php375
-rw-r--r--inc/geshi/typoscript.php300
-rw-r--r--inc/geshi/unicon.php210
-rw-r--r--inc/geshi/vala.php151
-rw-r--r--inc/geshi/vb.php157
-rw-r--r--inc/geshi/vbnet.php201
-rw-r--r--inc/geshi/verilog.php173
-rw-r--r--inc/geshi/vhdl.php144
-rw-r--r--inc/geshi/vim.php420
-rw-r--r--inc/geshi/visualfoxpro.php456
-rw-r--r--inc/geshi/visualprolog.php129
-rw-r--r--inc/geshi/whitespace.php121
-rw-r--r--inc/geshi/whois.php181
-rw-r--r--inc/geshi/winbatch.php369
-rw-r--r--inc/geshi/xbasic.php144
-rw-r--r--inc/geshi/xml.php157
-rw-r--r--inc/geshi/xorg_conf.php124
-rw-r--r--inc/geshi/xpp.php436
-rw-r--r--inc/geshi/z80.php144
-rw-r--r--inc/html.php1869
-rw-r--r--inc/httputils.php251
-rw-r--r--inc/indexer.php1395
-rw-r--r--inc/infoutils.php423
-rw-r--r--inc/init.php561
-rw-r--r--inc/io.php610
-rw-r--r--inc/lang/.htaccess4
-rw-r--r--inc/lang/af/lang.php73
-rw-r--r--inc/lang/ar/admin.txt3
-rw-r--r--inc/lang/ar/adminplugins.txt1
-rw-r--r--inc/lang/ar/backlinks.txt3
-rw-r--r--inc/lang/ar/conflict.txt5
-rw-r--r--inc/lang/ar/denied.txt3
-rw-r--r--inc/lang/ar/diff.txt3
-rw-r--r--inc/lang/ar/draft.txt5
-rw-r--r--inc/lang/ar/edit.txt1
-rw-r--r--inc/lang/ar/editrev.txt2
-rw-r--r--inc/lang/ar/index.txt3
-rw-r--r--inc/lang/ar/install.html12
-rw-r--r--inc/lang/ar/lang.php277
-rw-r--r--inc/lang/ar/locked.txt3
-rw-r--r--inc/lang/ar/login.txt3
-rw-r--r--inc/lang/ar/mailtext.txt17
-rw-r--r--inc/lang/ar/newpage.txt3
-rw-r--r--inc/lang/ar/norev.txt3
-rw-r--r--inc/lang/ar/password.txt10
-rw-r--r--inc/lang/ar/preview.txt3
-rw-r--r--inc/lang/ar/pwconfirm.txt8
-rw-r--r--inc/lang/ar/read.txt1
-rw-r--r--inc/lang/ar/recent.txt3
-rw-r--r--inc/lang/ar/register.txt3
-rw-r--r--inc/lang/ar/registermail.txt14
-rw-r--r--inc/lang/ar/resendpwd.txt3
-rw-r--r--inc/lang/ar/revisions.txt2
-rw-r--r--inc/lang/ar/searchpage.txt5
-rw-r--r--inc/lang/ar/showrev.txt2
-rw-r--r--inc/lang/ar/stopwords.txt29
-rw-r--r--inc/lang/ar/subscr_digest.txt20
-rw-r--r--inc/lang/ar/subscr_form.txt3
-rw-r--r--inc/lang/ar/subscr_list.txt17
-rw-r--r--inc/lang/ar/subscr_single.txt23
-rw-r--r--inc/lang/ar/updateprofile.txt3
-rw-r--r--inc/lang/ar/uploadmail.txt14
-rw-r--r--inc/lang/az/admin.txt4
-rw-r--r--inc/lang/az/adminplugins.txt1
-rw-r--r--inc/lang/az/backlinks.txt4
-rw-r--r--inc/lang/az/conflict.txt5
-rw-r--r--inc/lang/az/denied.txt3
-rw-r--r--inc/lang/az/diff.txt4
-rw-r--r--inc/lang/az/draft.txt5
-rw-r--r--inc/lang/az/edit.txt1
-rw-r--r--inc/lang/az/editrev.txt2
-rw-r--r--inc/lang/az/index.txt4
-rw-r--r--inc/lang/az/install.html7
-rw-r--r--inc/lang/az/lang.php227
-rw-r--r--inc/lang/az/locked.txt3
-rw-r--r--inc/lang/az/login.txt4
-rw-r--r--inc/lang/az/mailtext.txt18
-rw-r--r--inc/lang/az/newpage.txt3
-rw-r--r--inc/lang/az/norev.txt4
-rw-r--r--inc/lang/az/password.txt11
-rw-r--r--inc/lang/az/preview.txt4
-rw-r--r--inc/lang/az/pwconfirm.txt14
-rw-r--r--inc/lang/az/read.txt2
-rw-r--r--inc/lang/az/recent.txt5
-rw-r--r--inc/lang/az/register.txt3
-rw-r--r--inc/lang/az/registermail.txt15
-rw-r--r--inc/lang/az/resendpwd.txt3
-rw-r--r--inc/lang/az/revisions.txt3
-rw-r--r--inc/lang/az/searchpage.txt5
-rw-r--r--inc/lang/az/showrev.txt2
-rw-r--r--inc/lang/az/stopwords.txt64
-rw-r--r--inc/lang/az/updateprofile.txt5
-rw-r--r--inc/lang/az/uploadmail.txt15
-rw-r--r--inc/lang/az/wordblock.txt3
-rw-r--r--inc/lang/bg/admin.txt3
-rw-r--r--inc/lang/bg/adminplugins.txt1
-rw-r--r--inc/lang/bg/backlinks.txt3
-rw-r--r--inc/lang/bg/conflict.txt6
-rw-r--r--inc/lang/bg/denied.txt4
-rw-r--r--inc/lang/bg/diff.txt3
-rw-r--r--inc/lang/bg/draft.txt6
-rw-r--r--inc/lang/bg/edit.txt2
-rw-r--r--inc/lang/bg/editrev.txt2
-rw-r--r--inc/lang/bg/index.txt4
-rw-r--r--inc/lang/bg/install.html15
-rw-r--r--inc/lang/bg/lang.php311
-rw-r--r--inc/lang/bg/locked.txt3
-rw-r--r--inc/lang/bg/login.txt3
-rw-r--r--inc/lang/bg/mailtext.txt16
-rw-r--r--inc/lang/bg/newpage.txt4
-rw-r--r--inc/lang/bg/norev.txt4
-rw-r--r--inc/lang/bg/password.txt9
-rw-r--r--inc/lang/bg/preview.txt3
-rw-r--r--inc/lang/bg/pwconfirm.txt13
-rw-r--r--inc/lang/bg/read.txt2
-rw-r--r--inc/lang/bg/recent.txt4
-rw-r--r--inc/lang/bg/register.txt4
-rw-r--r--inc/lang/bg/registermail.txt13
-rw-r--r--inc/lang/bg/resendpwd.txt3
-rw-r--r--inc/lang/bg/revisions.txt4
-rw-r--r--inc/lang/bg/searchpage.txt5
-rw-r--r--inc/lang/bg/showrev.txt2
-rw-r--r--inc/lang/bg/stopwords.txt29
-rw-r--r--inc/lang/bg/subscr_digest.txt18
-rw-r--r--inc/lang/bg/subscr_form.txt3
-rw-r--r--inc/lang/bg/subscr_list.txt15
-rw-r--r--inc/lang/bg/subscr_single.txt22
-rw-r--r--inc/lang/bg/updateprofile.txt3
-rw-r--r--inc/lang/bg/uploadmail.txt13
-rw-r--r--inc/lang/ca-valencia/admin.txt4
-rw-r--r--inc/lang/ca-valencia/adminplugins.txt1
-rw-r--r--inc/lang/ca-valencia/backlinks.txt3
-rw-r--r--inc/lang/ca-valencia/conflict.txt6
-rw-r--r--inc/lang/ca-valencia/denied.txt4
-rw-r--r--inc/lang/ca-valencia/diff.txt4
-rw-r--r--inc/lang/ca-valencia/draft.txt6
-rw-r--r--inc/lang/ca-valencia/edit.txt2
-rw-r--r--inc/lang/ca-valencia/editrev.txt2
-rw-r--r--inc/lang/ca-valencia/index.txt4
-rw-r--r--inc/lang/ca-valencia/install.html11
-rw-r--r--inc/lang/ca-valencia/lang.php231
-rw-r--r--inc/lang/ca-valencia/locked.txt3
-rw-r--r--inc/lang/ca-valencia/login.txt4
-rw-r--r--inc/lang/ca-valencia/mailtext.txt17
-rw-r--r--inc/lang/ca-valencia/newpage.txt3
-rw-r--r--inc/lang/ca-valencia/norev.txt3
-rw-r--r--inc/lang/ca-valencia/password.txt10
-rw-r--r--inc/lang/ca-valencia/preview.txt4
-rw-r--r--inc/lang/ca-valencia/pwconfirm.txt15
-rw-r--r--inc/lang/ca-valencia/read.txt2
-rw-r--r--inc/lang/ca-valencia/recent.txt5
-rw-r--r--inc/lang/ca-valencia/register.txt5
-rw-r--r--inc/lang/ca-valencia/registermail.txt14
-rw-r--r--inc/lang/ca-valencia/resendpwd.txt4
-rw-r--r--inc/lang/ca-valencia/revisions.txt4
-rw-r--r--inc/lang/ca-valencia/searchpage.txt5
-rw-r--r--inc/lang/ca-valencia/showrev.txt2
-rw-r--r--inc/lang/ca-valencia/stopwords.txt76
-rw-r--r--inc/lang/ca-valencia/updateprofile.txt5
-rw-r--r--inc/lang/ca-valencia/uploadmail.txt14
-rw-r--r--inc/lang/ca/admin.txt4
-rw-r--r--inc/lang/ca/adminplugins.txt1
-rw-r--r--inc/lang/ca/backlinks.txt4
-rw-r--r--inc/lang/ca/conflict.txt6
-rw-r--r--inc/lang/ca/denied.txt4
-rw-r--r--inc/lang/ca/diff.txt4
-rw-r--r--inc/lang/ca/draft.txt5
-rw-r--r--inc/lang/ca/edit.txt2
-rw-r--r--inc/lang/ca/editrev.txt2
-rw-r--r--inc/lang/ca/index.txt4
-rw-r--r--inc/lang/ca/install.html8
-rw-r--r--inc/lang/ca/lang.php227
-rw-r--r--inc/lang/ca/locked.txt3
-rw-r--r--inc/lang/ca/login.txt4
-rw-r--r--inc/lang/ca/mailtext.txt16
-rw-r--r--inc/lang/ca/newpage.txt3
-rw-r--r--inc/lang/ca/norev.txt5
-rw-r--r--inc/lang/ca/password.txt10
-rw-r--r--inc/lang/ca/preview.txt4
-rw-r--r--inc/lang/ca/pwconfirm.txt15
-rw-r--r--inc/lang/ca/read.txt2
-rw-r--r--inc/lang/ca/recent.txt5
-rw-r--r--inc/lang/ca/register.txt4
-rw-r--r--inc/lang/ca/registermail.txt14
-rw-r--r--inc/lang/ca/resendpwd.txt3
-rw-r--r--inc/lang/ca/revisions.txt4
-rw-r--r--inc/lang/ca/searchpage.txt5
-rw-r--r--inc/lang/ca/showrev.txt2
-rw-r--r--inc/lang/ca/stopwords.txt106
-rw-r--r--inc/lang/ca/updateprofile.txt3
-rw-r--r--inc/lang/ca/uploadmail.txt14
-rw-r--r--inc/lang/cs/admin.txt3
-rw-r--r--inc/lang/cs/adminplugins.txt1
-rw-r--r--inc/lang/cs/backlinks.txt3
-rw-r--r--inc/lang/cs/conflict.txt5
-rw-r--r--inc/lang/cs/denied.txt3
-rw-r--r--inc/lang/cs/diff.txt4
-rw-r--r--inc/lang/cs/draft.txt5
-rw-r--r--inc/lang/cs/edit.txt1
-rw-r--r--inc/lang/cs/editrev.txt2
-rw-r--r--inc/lang/cs/index.txt3
-rw-r--r--inc/lang/cs/install.html23
-rw-r--r--inc/lang/cs/lang.php317
-rw-r--r--inc/lang/cs/locked.txt3
-rw-r--r--inc/lang/cs/login.txt3
-rw-r--r--inc/lang/cs/mailtext.txt17
-rw-r--r--inc/lang/cs/newpage.txt3
-rw-r--r--inc/lang/cs/norev.txt3
-rw-r--r--inc/lang/cs/password.txt11
-rw-r--r--inc/lang/cs/preview.txt3
-rw-r--r--inc/lang/cs/pwconfirm.txt13
-rw-r--r--inc/lang/cs/read.txt1
-rw-r--r--inc/lang/cs/recent.txt3
-rw-r--r--inc/lang/cs/register.txt3
-rw-r--r--inc/lang/cs/registermail.txt14
-rw-r--r--inc/lang/cs/resendpwd.txt3
-rw-r--r--inc/lang/cs/revisions.txt3
-rw-r--r--inc/lang/cs/searchpage.txt5
-rw-r--r--inc/lang/cs/showrev.txt3
-rw-r--r--inc/lang/cs/stopwords.txt944
-rw-r--r--inc/lang/cs/subscr_digest.txt22
-rw-r--r--inc/lang/cs/subscr_form.txt3
-rw-r--r--inc/lang/cs/subscr_list.txt19
-rw-r--r--inc/lang/cs/subscr_single.txt25
-rw-r--r--inc/lang/cs/updateprofile.txt5
-rw-r--r--inc/lang/cs/uploadmail.txt14
-rw-r--r--inc/lang/da/admin.txt4
-rw-r--r--inc/lang/da/adminplugins.txt1
-rw-r--r--inc/lang/da/backlinks.txt4
-rw-r--r--inc/lang/da/conflict.txt5
-rw-r--r--inc/lang/da/denied.txt3
-rw-r--r--inc/lang/da/diff.txt4
-rw-r--r--inc/lang/da/draft.txt6
-rw-r--r--inc/lang/da/edit.txt2
-rw-r--r--inc/lang/da/editrev.txt2
-rw-r--r--inc/lang/da/index.txt3
-rw-r--r--inc/lang/da/install.html24
-rw-r--r--inc/lang/da/lang.php273
-rw-r--r--inc/lang/da/locked.txt3
-rw-r--r--inc/lang/da/login.txt3
-rw-r--r--inc/lang/da/mailtext.txt17
-rw-r--r--inc/lang/da/newpage.txt3
-rw-r--r--inc/lang/da/norev.txt4
-rw-r--r--inc/lang/da/password.txt11
-rw-r--r--inc/lang/da/preview.txt4
-rw-r--r--inc/lang/da/pwconfirm.txt14
-rw-r--r--inc/lang/da/read.txt2
-rw-r--r--inc/lang/da/recent.txt5
-rw-r--r--inc/lang/da/register.txt4
-rw-r--r--inc/lang/da/registermail.txt14
-rw-r--r--inc/lang/da/resendpwd.txt3
-rw-r--r--inc/lang/da/revisions.txt3
-rw-r--r--inc/lang/da/searchpage.txt5
-rw-r--r--inc/lang/da/showrev.txt2
-rw-r--r--inc/lang/da/stopwords.txt87
-rw-r--r--inc/lang/da/subscr_form.txt3
-rw-r--r--inc/lang/da/subscr_single.txt23
-rw-r--r--inc/lang/da/updateprofile.txt3
-rw-r--r--inc/lang/da/uploadmail.txt14
-rw-r--r--inc/lang/de-informal/admin.txt4
-rw-r--r--inc/lang/de-informal/adminplugins.txt1
-rw-r--r--inc/lang/de-informal/backlinks.txt5
-rw-r--r--inc/lang/de-informal/conflict.txt6
-rw-r--r--inc/lang/de-informal/denied.txt4
-rw-r--r--inc/lang/de-informal/diff.txt5
-rw-r--r--inc/lang/de-informal/draft.txt6
-rw-r--r--inc/lang/de-informal/edit.txt4
-rw-r--r--inc/lang/de-informal/editrev.txt2
-rw-r--r--inc/lang/de-informal/index.txt4
-rw-r--r--inc/lang/de-informal/install.html27
-rw-r--r--inc/lang/de-informal/lang.php323
-rw-r--r--inc/lang/de-informal/locked.txt4
-rw-r--r--inc/lang/de-informal/login.txt4
-rw-r--r--inc/lang/de-informal/mailtext.txt18
-rw-r--r--inc/lang/de-informal/newpage.txt5
-rw-r--r--inc/lang/de-informal/norev.txt4
-rw-r--r--inc/lang/de-informal/password.txt11
-rw-r--r--inc/lang/de-informal/preview.txt5
-rw-r--r--inc/lang/de-informal/pwconfirm.txt17
-rw-r--r--inc/lang/de-informal/read.txt2
-rw-r--r--inc/lang/de-informal/recent.txt5
-rw-r--r--inc/lang/de-informal/register.txt4
-rw-r--r--inc/lang/de-informal/registermail.txt14
-rw-r--r--inc/lang/de-informal/resendpwd.txt3
-rw-r--r--inc/lang/de-informal/revisions.txt4
-rw-r--r--inc/lang/de-informal/searchpage.txt7
-rw-r--r--inc/lang/de-informal/showrev.txt2
-rw-r--r--inc/lang/de-informal/stopwords.txt125
-rw-r--r--inc/lang/de-informal/subscr_digest.txt21
-rw-r--r--inc/lang/de-informal/subscr_form.txt3
-rw-r--r--inc/lang/de-informal/subscr_list.txt17
-rw-r--r--inc/lang/de-informal/subscr_single.txt24
-rw-r--r--inc/lang/de-informal/updateprofile.txt5
-rw-r--r--inc/lang/de-informal/uploadmail.txt16
-rw-r--r--inc/lang/de/admin.txt4
-rw-r--r--inc/lang/de/adminplugins.txt1
-rw-r--r--inc/lang/de/backlinks.txt5
-rw-r--r--inc/lang/de/conflict.txt6
-rw-r--r--inc/lang/de/denied.txt4
-rw-r--r--inc/lang/de/diff.txt5
-rw-r--r--inc/lang/de/draft.txt6
-rw-r--r--inc/lang/de/edit.txt4
-rw-r--r--inc/lang/de/editrev.txt2
-rw-r--r--inc/lang/de/index.txt4
-rw-r--r--inc/lang/de/install.html27
-rw-r--r--inc/lang/de/lang.php330
-rw-r--r--inc/lang/de/locked.txt4
-rw-r--r--inc/lang/de/login.txt4
-rw-r--r--inc/lang/de/mailtext.txt17
-rw-r--r--inc/lang/de/newpage.txt5
-rw-r--r--inc/lang/de/norev.txt4
-rw-r--r--inc/lang/de/password.txt10
-rw-r--r--inc/lang/de/preview.txt5
-rw-r--r--inc/lang/de/pwconfirm.txt16
-rw-r--r--inc/lang/de/read.txt2
-rw-r--r--inc/lang/de/recent.txt5
-rw-r--r--inc/lang/de/register.txt4
-rw-r--r--inc/lang/de/registermail.txt14
-rw-r--r--inc/lang/de/resendpwd.txt3
-rw-r--r--inc/lang/de/revisions.txt4
-rw-r--r--inc/lang/de/searchpage.txt7
-rw-r--r--inc/lang/de/showrev.txt2
-rw-r--r--inc/lang/de/stopwords.txt125
-rw-r--r--inc/lang/de/subscr_digest.txt21
-rw-r--r--inc/lang/de/subscr_form.txt3
-rw-r--r--inc/lang/de/subscr_list.txt18
-rw-r--r--inc/lang/de/subscr_single.txt24
-rw-r--r--inc/lang/de/updateprofile.txt5
-rw-r--r--inc/lang/de/uploadmail.txt15
-rw-r--r--inc/lang/el/admin.txt3
-rw-r--r--inc/lang/el/adminplugins.txt1
-rw-r--r--inc/lang/el/backlinks.txt3
-rw-r--r--inc/lang/el/conflict.txt8
-rw-r--r--inc/lang/el/denied.txt5
-rw-r--r--inc/lang/el/diff.txt3
-rw-r--r--inc/lang/el/draft.txt9
-rw-r--r--inc/lang/el/edit.txt3
-rw-r--r--inc/lang/el/editrev.txt2
-rw-r--r--inc/lang/el/index.txt3
-rw-r--r--inc/lang/el/install.html26
-rw-r--r--inc/lang/el/lang.php311
-rw-r--r--inc/lang/el/locked.txt5
-rw-r--r--inc/lang/el/login.txt5
-rw-r--r--inc/lang/el/mailtext.txt17
-rw-r--r--inc/lang/el/newpage.txt4
-rw-r--r--inc/lang/el/norev.txt5
-rw-r--r--inc/lang/el/password.txt10
-rw-r--r--inc/lang/el/preview.txt5
-rw-r--r--inc/lang/el/pwconfirm.txt14
-rw-r--r--inc/lang/el/read.txt2
-rw-r--r--inc/lang/el/recent.txt3
-rw-r--r--inc/lang/el/register.txt5
-rw-r--r--inc/lang/el/registermail.txt14
-rw-r--r--inc/lang/el/resendpwd.txt6
-rw-r--r--inc/lang/el/revisions.txt8
-rw-r--r--inc/lang/el/searchpage.txt4
-rw-r--r--inc/lang/el/showrev.txt2
-rw-r--r--inc/lang/el/stopwords.txt103
-rw-r--r--inc/lang/el/subscr_digest.txt20
-rw-r--r--inc/lang/el/subscr_form.txt3
-rw-r--r--inc/lang/el/subscr_list.txt20
-rw-r--r--inc/lang/el/subscr_single.txt22
-rw-r--r--inc/lang/el/updateprofile.txt4
-rw-r--r--inc/lang/el/uploadmail.txt15
-rw-r--r--inc/lang/en/admin.txt4
-rw-r--r--inc/lang/en/adminplugins.txt2
-rw-r--r--inc/lang/en/backlinks.txt4
-rw-r--r--inc/lang/en/conflict.txt6
-rw-r--r--inc/lang/en/denied.txt4
-rw-r--r--inc/lang/en/diff.txt4
-rw-r--r--inc/lang/en/draft.txt6
-rw-r--r--inc/lang/en/edit.txt2
-rw-r--r--inc/lang/en/editrev.txt2
-rw-r--r--inc/lang/en/index.txt4
-rw-r--r--inc/lang/en/install.html24
-rw-r--r--inc/lang/en/lang.php349
-rw-r--r--inc/lang/en/locked.txt3
-rw-r--r--inc/lang/en/login.txt4
-rw-r--r--inc/lang/en/mailtext.txt17
-rw-r--r--inc/lang/en/newpage.txt4
-rw-r--r--inc/lang/en/norev.txt4
-rw-r--r--inc/lang/en/password.txt10
-rw-r--r--inc/lang/en/preview.txt4
-rw-r--r--inc/lang/en/pwconfirm.txt15
-rw-r--r--inc/lang/en/read.txt2
-rw-r--r--inc/lang/en/recent.txt5
-rw-r--r--inc/lang/en/register.txt4
-rw-r--r--inc/lang/en/registermail.txt14
-rw-r--r--inc/lang/en/resendpwd.txt4
-rw-r--r--inc/lang/en/revisions.txt4
-rw-r--r--inc/lang/en/searchpage.txt5
-rw-r--r--inc/lang/en/showrev.txt2
-rw-r--r--inc/lang/en/stopwords.txt39
-rw-r--r--inc/lang/en/subscr_digest.txt20
-rw-r--r--inc/lang/en/subscr_form.txt3
-rw-r--r--inc/lang/en/subscr_list.txt17
-rw-r--r--inc/lang/en/subscr_single.txt23
-rw-r--r--inc/lang/en/updateprofile.txt5
-rw-r--r--inc/lang/en/uploadmail.txt15
-rw-r--r--inc/lang/eo/admin.txt3
-rw-r--r--inc/lang/eo/adminplugins.txt1
-rw-r--r--inc/lang/eo/backlinks.txt3
-rw-r--r--inc/lang/eo/conflict.txt5
-rw-r--r--inc/lang/eo/denied.txt4
-rw-r--r--inc/lang/eo/diff.txt4
-rw-r--r--inc/lang/eo/draft.txt5
-rw-r--r--inc/lang/eo/edit.txt1
-rw-r--r--inc/lang/eo/editrev.txt2
-rw-r--r--inc/lang/eo/index.txt3
-rw-r--r--inc/lang/eo/install.html9
-rw-r--r--inc/lang/eo/lang.php316
-rw-r--r--inc/lang/eo/locked.txt3
-rw-r--r--inc/lang/eo/login.txt3
-rw-r--r--inc/lang/eo/mailtext.txt16
-rw-r--r--inc/lang/eo/newpage.txt4
-rw-r--r--inc/lang/eo/norev.txt3
-rw-r--r--inc/lang/eo/password.txt10
-rw-r--r--inc/lang/eo/preview.txt3
-rw-r--r--inc/lang/eo/pwconfirm.txt14
-rw-r--r--inc/lang/eo/read.txt2
-rw-r--r--inc/lang/eo/recent.txt3
-rw-r--r--inc/lang/eo/register.txt4
-rw-r--r--inc/lang/eo/registermail.txt14
-rw-r--r--inc/lang/eo/resendpwd.txt3
-rw-r--r--inc/lang/eo/revisions.txt3
-rw-r--r--inc/lang/eo/searchpage.txt5
-rw-r--r--inc/lang/eo/showrev.txt2
-rw-r--r--inc/lang/eo/stopwords.txt20
-rw-r--r--inc/lang/eo/subscr_digest.txt20
-rw-r--r--inc/lang/eo/subscr_form.txt3
-rw-r--r--inc/lang/eo/subscr_list.txt17
-rw-r--r--inc/lang/eo/subscr_single.txt23
-rw-r--r--inc/lang/eo/updateprofile.txt3
-rw-r--r--inc/lang/eo/uploadmail.txt14
-rw-r--r--inc/lang/es/admin.txt3
-rw-r--r--inc/lang/es/adminplugins.txt1
-rw-r--r--inc/lang/es/backlinks.txt4
-rw-r--r--inc/lang/es/conflict.txt5
-rw-r--r--inc/lang/es/denied.txt3
-rw-r--r--inc/lang/es/diff.txt4
-rw-r--r--inc/lang/es/draft.txt6
-rw-r--r--inc/lang/es/edit.txt2
-rw-r--r--inc/lang/es/editrev.txt2
-rw-r--r--inc/lang/es/index.txt4
-rw-r--r--inc/lang/es/install.html14
-rw-r--r--inc/lang/es/lang.php332
-rw-r--r--inc/lang/es/locked.txt3
-rw-r--r--inc/lang/es/login.txt3
-rw-r--r--inc/lang/es/mailtext.txt17
-rw-r--r--inc/lang/es/newpage.txt3
-rw-r--r--inc/lang/es/norev.txt4
-rw-r--r--inc/lang/es/password.txt9
-rw-r--r--inc/lang/es/preview.txt4
-rw-r--r--inc/lang/es/pwconfirm.txt16
-rw-r--r--inc/lang/es/read.txt1
-rw-r--r--inc/lang/es/recent.txt5
-rw-r--r--inc/lang/es/register.txt3
-rw-r--r--inc/lang/es/registermail.txt14
-rw-r--r--inc/lang/es/resendpwd.txt3
-rw-r--r--inc/lang/es/revisions.txt4
-rw-r--r--inc/lang/es/searchpage.txt5
-rw-r--r--inc/lang/es/showrev.txt2
-rw-r--r--inc/lang/es/stopwords.txt171
-rw-r--r--inc/lang/es/subscr_digest.txt20
-rw-r--r--inc/lang/es/subscr_form.txt3
-rw-r--r--inc/lang/es/subscr_list.txt17
-rw-r--r--inc/lang/es/subscr_single.txt23
-rw-r--r--inc/lang/es/updateprofile.txt3
-rw-r--r--inc/lang/es/uploadmail.txt14
-rw-r--r--inc/lang/et/admin.txt4
-rw-r--r--inc/lang/et/backlinks.txt4
-rw-r--r--inc/lang/et/conflict.txt6
-rw-r--r--inc/lang/et/denied.txt3
-rw-r--r--inc/lang/et/diff.txt4
-rw-r--r--inc/lang/et/draft.txt6
-rw-r--r--inc/lang/et/edit.txt2
-rw-r--r--inc/lang/et/editrev.txt3
-rw-r--r--inc/lang/et/index.txt3
-rw-r--r--inc/lang/et/lang.php234
-rw-r--r--inc/lang/et/locked.txt3
-rw-r--r--inc/lang/et/login.txt3
-rw-r--r--inc/lang/et/mailtext.txt16
-rw-r--r--inc/lang/et/newpage.txt3
-rw-r--r--inc/lang/et/norev.txt4
-rw-r--r--inc/lang/et/password.txt9
-rw-r--r--inc/lang/et/preview.txt3
-rw-r--r--inc/lang/et/pwconfirm.txt12
-rw-r--r--inc/lang/et/read.txt2
-rw-r--r--inc/lang/et/recent.txt5
-rw-r--r--inc/lang/et/register.txt4
-rw-r--r--inc/lang/et/registermail.txt14
-rw-r--r--inc/lang/et/resendpwd.txt4
-rw-r--r--inc/lang/et/revisions.txt4
-rw-r--r--inc/lang/et/searchpage.txt5
-rw-r--r--inc/lang/et/showrev.txt2
-rw-r--r--inc/lang/et/stopwords.txt15
-rw-r--r--inc/lang/et/updateprofile.txt5
-rw-r--r--inc/lang/eu/admin.txt3
-rw-r--r--inc/lang/eu/adminplugins.txt1
-rw-r--r--inc/lang/eu/backlinks.txt3
-rw-r--r--inc/lang/eu/conflict.txt5
-rw-r--r--inc/lang/eu/denied.txt3
-rw-r--r--inc/lang/eu/diff.txt4
-rw-r--r--inc/lang/eu/draft.txt5
-rw-r--r--inc/lang/eu/edit.txt1
-rw-r--r--inc/lang/eu/editrev.txt2
-rw-r--r--inc/lang/eu/index.txt4
-rw-r--r--inc/lang/eu/install.html9
-rw-r--r--inc/lang/eu/lang.php267
-rw-r--r--inc/lang/eu/locked.txt3
-rw-r--r--inc/lang/eu/login.txt4
-rw-r--r--inc/lang/eu/mailtext.txt17
-rw-r--r--inc/lang/eu/newpage.txt3
-rw-r--r--inc/lang/eu/norev.txt3
-rw-r--r--inc/lang/eu/password.txt10
-rw-r--r--inc/lang/eu/preview.txt3
-rw-r--r--inc/lang/eu/pwconfirm.txt12
-rw-r--r--inc/lang/eu/read.txt1
-rw-r--r--inc/lang/eu/recent.txt3
-rw-r--r--inc/lang/eu/register.txt3
-rw-r--r--inc/lang/eu/registermail.txt13
-rw-r--r--inc/lang/eu/resendpwd.txt3
-rw-r--r--inc/lang/eu/revisions.txt3
-rw-r--r--inc/lang/eu/searchpage.txt5
-rw-r--r--inc/lang/eu/showrev.txt2
-rw-r--r--inc/lang/eu/stopwords.txt26
-rw-r--r--inc/lang/eu/subscr_digest.txt20
-rw-r--r--inc/lang/eu/subscr_form.txt3
-rw-r--r--inc/lang/eu/subscr_list.txt17
-rw-r--r--inc/lang/eu/subscr_single.txt23
-rw-r--r--inc/lang/eu/updateprofile.txt3
-rw-r--r--inc/lang/eu/uploadmail.txt13
-rw-r--r--inc/lang/fa/admin.txt3
-rw-r--r--inc/lang/fa/adminplugins.txt1
-rw-r--r--inc/lang/fa/backlinks.txt3
-rw-r--r--inc/lang/fa/conflict.txt5
-rw-r--r--inc/lang/fa/denied.txt3
-rw-r--r--inc/lang/fa/diff.txt3
-rw-r--r--inc/lang/fa/draft.txt5
-rw-r--r--inc/lang/fa/edit.txt1
-rw-r--r--inc/lang/fa/editrev.txt1
-rw-r--r--inc/lang/fa/index.txt3
-rw-r--r--inc/lang/fa/install.html12
-rw-r--r--inc/lang/fa/lang.php274
-rw-r--r--inc/lang/fa/locked.txt3
-rw-r--r--inc/lang/fa/login.txt3
-rw-r--r--inc/lang/fa/mailtext.txt17
-rw-r--r--inc/lang/fa/newpage.txt3
-rw-r--r--inc/lang/fa/norev.txt3
-rw-r--r--inc/lang/fa/password.txt10
-rw-r--r--inc/lang/fa/preview.txt3
-rw-r--r--inc/lang/fa/pwconfirm.txt13
-rw-r--r--inc/lang/fa/read.txt1
-rw-r--r--inc/lang/fa/recent.txt3
-rw-r--r--inc/lang/fa/register.txt3
-rw-r--r--inc/lang/fa/registermail.txt14
-rw-r--r--inc/lang/fa/resendpwd.txt3
-rw-r--r--inc/lang/fa/revisions.txt3
-rw-r--r--inc/lang/fa/searchpage.txt5
-rw-r--r--inc/lang/fa/showrev.txt1
-rw-r--r--inc/lang/fa/stopwords.txt445
-rw-r--r--inc/lang/fa/subscr_digest.txt16
-rw-r--r--inc/lang/fa/subscr_form.txt3
-rw-r--r--inc/lang/fa/subscr_list.txt16
-rw-r--r--inc/lang/fa/subscr_single.txt19
-rw-r--r--inc/lang/fa/updateprofile.txt3
-rw-r--r--inc/lang/fa/uploadmail.txt14
-rw-r--r--inc/lang/fi/admin.txt3
-rw-r--r--inc/lang/fi/adminplugins.txt1
-rw-r--r--inc/lang/fi/backlinks.txt4
-rw-r--r--inc/lang/fi/conflict.txt5
-rw-r--r--inc/lang/fi/denied.txt3
-rw-r--r--inc/lang/fi/diff.txt3
-rw-r--r--inc/lang/fi/draft.txt5
-rw-r--r--inc/lang/fi/edit.txt1
-rw-r--r--inc/lang/fi/editrev.txt2
-rw-r--r--inc/lang/fi/index.txt3
-rw-r--r--inc/lang/fi/install.html21
-rw-r--r--inc/lang/fi/lang.php314
-rw-r--r--inc/lang/fi/locked.txt3
-rw-r--r--inc/lang/fi/login.txt3
-rw-r--r--inc/lang/fi/mailtext.txt17
-rw-r--r--inc/lang/fi/newpage.txt3
-rw-r--r--inc/lang/fi/norev.txt3
-rw-r--r--inc/lang/fi/password.txt10
-rw-r--r--inc/lang/fi/preview.txt3
-rw-r--r--inc/lang/fi/pwconfirm.txt13
-rw-r--r--inc/lang/fi/read.txt1
-rw-r--r--inc/lang/fi/recent.txt4
-rw-r--r--inc/lang/fi/register.txt3
-rw-r--r--inc/lang/fi/registermail.txt14
-rw-r--r--inc/lang/fi/resendpwd.txt3
-rw-r--r--inc/lang/fi/revisions.txt3
-rw-r--r--inc/lang/fi/searchpage.txt5
-rw-r--r--inc/lang/fi/showrev.txt2
-rw-r--r--inc/lang/fi/stopwords.txt11
-rw-r--r--inc/lang/fi/subscr_digest.txt20
-rw-r--r--inc/lang/fi/subscr_form.txt3
-rw-r--r--inc/lang/fi/subscr_list.txt18
-rw-r--r--inc/lang/fi/subscr_single.txt23
-rw-r--r--inc/lang/fi/updateprofile.txt3
-rw-r--r--inc/lang/fi/uploadmail.txt14
-rw-r--r--inc/lang/fo/admin.txt4
-rw-r--r--inc/lang/fo/backlinks.txt4
-rw-r--r--inc/lang/fo/conflict.txt5
-rw-r--r--inc/lang/fo/denied.txt3
-rw-r--r--inc/lang/fo/diff.txt4
-rw-r--r--inc/lang/fo/edit.txt2
-rw-r--r--inc/lang/fo/editrev.txt2
-rw-r--r--inc/lang/fo/index.txt3
-rw-r--r--inc/lang/fo/lang.php174
-rw-r--r--inc/lang/fo/locked.txt3
-rw-r--r--inc/lang/fo/login.txt3
-rw-r--r--inc/lang/fo/mailtext.txt17
-rw-r--r--inc/lang/fo/newpage.txt3
-rw-r--r--inc/lang/fo/norev.txt4
-rw-r--r--inc/lang/fo/password.txt10
-rw-r--r--inc/lang/fo/preview.txt4
-rw-r--r--inc/lang/fo/read.txt2
-rw-r--r--inc/lang/fo/recent.txt5
-rw-r--r--inc/lang/fo/register.txt4
-rw-r--r--inc/lang/fo/resendpwd.txt3
-rw-r--r--inc/lang/fo/revisions.txt3
-rw-r--r--inc/lang/fo/searchpage.txt5
-rw-r--r--inc/lang/fo/showrev.txt2
-rw-r--r--inc/lang/fo/stopwords.txt87
-rw-r--r--inc/lang/fo/subscr_digest.txt20
-rw-r--r--inc/lang/fo/updateprofile.txt3
-rw-r--r--inc/lang/fr/admin.txt4
-rw-r--r--inc/lang/fr/adminplugins.txt1
-rw-r--r--inc/lang/fr/backlinks.txt4
-rw-r--r--inc/lang/fr/conflict.txt6
-rw-r--r--inc/lang/fr/denied.txt3
-rw-r--r--inc/lang/fr/diff.txt4
-rw-r--r--inc/lang/fr/draft.txt6
-rw-r--r--inc/lang/fr/edit.txt2
-rw-r--r--inc/lang/fr/editrev.txt2
-rw-r--r--inc/lang/fr/index.txt4
-rw-r--r--inc/lang/fr/install.html13
-rw-r--r--inc/lang/fr/lang.php327
-rw-r--r--inc/lang/fr/locked.txt3
-rw-r--r--inc/lang/fr/login.txt3
-rw-r--r--inc/lang/fr/mailtext.txt19
-rw-r--r--inc/lang/fr/newpage.txt4
-rw-r--r--inc/lang/fr/norev.txt4
-rw-r--r--inc/lang/fr/password.txt10
-rw-r--r--inc/lang/fr/preview.txt4
-rw-r--r--inc/lang/fr/pwconfirm.txt15
-rw-r--r--inc/lang/fr/read.txt2
-rw-r--r--inc/lang/fr/recent.txt5
-rw-r--r--inc/lang/fr/register.txt3
-rw-r--r--inc/lang/fr/registermail.txt14
-rw-r--r--inc/lang/fr/resendpwd.txt4
-rw-r--r--inc/lang/fr/revisions.txt4
-rw-r--r--inc/lang/fr/searchpage.txt5
-rw-r--r--inc/lang/fr/showrev.txt2
-rw-r--r--inc/lang/fr/stopwords.txt112
-rw-r--r--inc/lang/fr/subscr_digest.txt19
-rw-r--r--inc/lang/fr/subscr_form.txt3
-rw-r--r--inc/lang/fr/subscr_list.txt16
-rw-r--r--inc/lang/fr/subscr_single.txt22
-rw-r--r--inc/lang/fr/updateprofile.txt5
-rw-r--r--inc/lang/fr/uploadmail.txt14
-rw-r--r--inc/lang/gl/admin.txt4
-rw-r--r--inc/lang/gl/adminplugins.txt1
-rw-r--r--inc/lang/gl/backlinks.txt4
-rw-r--r--inc/lang/gl/conflict.txt6
-rw-r--r--inc/lang/gl/denied.txt4
-rw-r--r--inc/lang/gl/diff.txt4
-rw-r--r--inc/lang/gl/draft.txt6
-rw-r--r--inc/lang/gl/edit.txt2
-rw-r--r--inc/lang/gl/editrev.txt2
-rw-r--r--inc/lang/gl/index.txt4
-rw-r--r--inc/lang/gl/install.html25
-rw-r--r--inc/lang/gl/lang.php315
-rw-r--r--inc/lang/gl/locked.txt3
-rw-r--r--inc/lang/gl/login.txt4
-rw-r--r--inc/lang/gl/mailtext.txt17
-rw-r--r--inc/lang/gl/newpage.txt4
-rw-r--r--inc/lang/gl/norev.txt4
-rw-r--r--inc/lang/gl/password.txt10
-rw-r--r--inc/lang/gl/preview.txt4
-rw-r--r--inc/lang/gl/pwconfirm.txt15
-rw-r--r--inc/lang/gl/read.txt2
-rw-r--r--inc/lang/gl/recent.txt5
-rw-r--r--inc/lang/gl/register.txt4
-rw-r--r--inc/lang/gl/registermail.txt14
-rw-r--r--inc/lang/gl/resendpwd.txt3
-rw-r--r--inc/lang/gl/revisions.txt4
-rw-r--r--inc/lang/gl/searchpage.txt5
-rw-r--r--inc/lang/gl/showrev.txt2
-rw-r--r--inc/lang/gl/stopwords.txt692
-rw-r--r--inc/lang/gl/subscr_digest.txt20
-rw-r--r--inc/lang/gl/subscr_form.txt3
-rw-r--r--inc/lang/gl/subscr_list.txt17
-rw-r--r--inc/lang/gl/subscr_single.txt23
-rw-r--r--inc/lang/gl/updateprofile.txt5
-rw-r--r--inc/lang/gl/uploadmail.txt14
-rw-r--r--inc/lang/gl/wordblock.txt4
-rw-r--r--inc/lang/he/admin.txt4
-rw-r--r--inc/lang/he/adminplugins.txt1
-rw-r--r--inc/lang/he/backlinks.txt3
-rw-r--r--inc/lang/he/conflict.txt6
-rw-r--r--inc/lang/he/denied.txt3
-rw-r--r--inc/lang/he/diff.txt4
-rw-r--r--inc/lang/he/draft.txt5
-rw-r--r--inc/lang/he/edit.txt1
-rw-r--r--inc/lang/he/editrev.txt2
-rw-r--r--inc/lang/he/index.txt4
-rw-r--r--inc/lang/he/install.html13
-rw-r--r--inc/lang/he/lang.php270
-rw-r--r--inc/lang/he/locked.txt3
-rw-r--r--inc/lang/he/login.txt3
-rw-r--r--inc/lang/he/mailtext.txt17
-rw-r--r--inc/lang/he/newpage.txt3
-rw-r--r--inc/lang/he/norev.txt4
-rw-r--r--inc/lang/he/password.txt10
-rw-r--r--inc/lang/he/preview.txt4
-rw-r--r--inc/lang/he/pwconfirm.txt13
-rw-r--r--inc/lang/he/read.txt2
-rw-r--r--inc/lang/he/recent.txt5
-rw-r--r--inc/lang/he/register.txt3
-rw-r--r--inc/lang/he/registermail.txt14
-rw-r--r--inc/lang/he/resendpwd.txt4
-rw-r--r--inc/lang/he/revisions.txt4
-rw-r--r--inc/lang/he/searchpage.txt5
-rw-r--r--inc/lang/he/showrev.txt2
-rw-r--r--inc/lang/he/stopwords.txt29
-rw-r--r--inc/lang/he/subscr_digest.txt20
-rw-r--r--inc/lang/he/subscr_single.txt22
-rw-r--r--inc/lang/he/updateprofile.txt5
-rw-r--r--inc/lang/he/uploadmail.txt14
-rw-r--r--inc/lang/hi/lang.php118
-rw-r--r--inc/lang/hr/admin.txt3
-rw-r--r--inc/lang/hr/backlinks.txt3
-rw-r--r--inc/lang/hr/conflict.txt5
-rw-r--r--inc/lang/hr/denied.txt5
-rw-r--r--inc/lang/hr/diff.txt3
-rw-r--r--inc/lang/hr/edit.txt1
-rw-r--r--inc/lang/hr/editrev.txt2
-rw-r--r--inc/lang/hr/index.txt1
-rw-r--r--inc/lang/hr/lang.php268
-rw-r--r--inc/lang/hr/locked.txt3
-rw-r--r--inc/lang/hr/login.txt3
-rw-r--r--inc/lang/hr/mailtext.txt16
-rw-r--r--inc/lang/hr/newpage.txt3
-rw-r--r--inc/lang/hr/norev.txt3
-rw-r--r--inc/lang/hr/password.txt9
-rw-r--r--inc/lang/hr/preview.txt3
-rw-r--r--inc/lang/hr/read.txt1
-rw-r--r--inc/lang/hr/recent.txt3
-rw-r--r--inc/lang/hr/register.txt3
-rw-r--r--inc/lang/hr/resendpwd.txt3
-rw-r--r--inc/lang/hr/revisions.txt3
-rw-r--r--inc/lang/hr/searchpage.txt1
-rw-r--r--inc/lang/hr/showrev.txt2
-rw-r--r--inc/lang/hr/stopwords.txt29
-rw-r--r--inc/lang/hr/updateprofile.txt3
-rw-r--r--inc/lang/hu/admin.txt3
-rw-r--r--inc/lang/hu/adminplugins.txt1
-rw-r--r--inc/lang/hu/backlinks.txt5
-rw-r--r--inc/lang/hu/conflict.txt7
-rw-r--r--inc/lang/hu/denied.txt4
-rw-r--r--inc/lang/hu/diff.txt4
-rw-r--r--inc/lang/hu/draft.txt5
-rw-r--r--inc/lang/hu/edit.txt1
-rw-r--r--inc/lang/hu/editrev.txt2
-rw-r--r--inc/lang/hu/index.txt4
-rw-r--r--inc/lang/hu/install.html26
-rw-r--r--inc/lang/hu/lang.php273
-rw-r--r--inc/lang/hu/locked.txt4
-rw-r--r--inc/lang/hu/login.txt5
-rw-r--r--inc/lang/hu/mailtext.txt16
-rw-r--r--inc/lang/hu/newpage.txt3
-rw-r--r--inc/lang/hu/norev.txt5
-rw-r--r--inc/lang/hu/password.txt10
-rw-r--r--inc/lang/hu/preview.txt4
-rw-r--r--inc/lang/hu/pwconfirm.txt14
-rw-r--r--inc/lang/hu/read.txt2
-rw-r--r--inc/lang/hu/recent.txt5
-rw-r--r--inc/lang/hu/register.txt4
-rw-r--r--inc/lang/hu/registermail.txt13
-rw-r--r--inc/lang/hu/resendpwd.txt3
-rw-r--r--inc/lang/hu/revisions.txt3
-rw-r--r--inc/lang/hu/searchpage.txt5
-rw-r--r--inc/lang/hu/showrev.txt2
-rw-r--r--inc/lang/hu/stopwords.txt39
-rw-r--r--inc/lang/hu/subscr_digest.txt17
-rw-r--r--inc/lang/hu/subscr_form.txt3
-rw-r--r--inc/lang/hu/subscr_list.txt14
-rw-r--r--inc/lang/hu/subscr_single.txt20
-rw-r--r--inc/lang/hu/updateprofile.txt3
-rw-r--r--inc/lang/hu/uploadmail.txt13
-rw-r--r--inc/lang/ia/admin.txt3
-rw-r--r--inc/lang/ia/adminplugins.txt1
-rw-r--r--inc/lang/ia/backlinks.txt3
-rw-r--r--inc/lang/ia/conflict.txt5
-rw-r--r--inc/lang/ia/denied.txt3
-rw-r--r--inc/lang/ia/diff.txt3
-rw-r--r--inc/lang/ia/draft.txt5
-rw-r--r--inc/lang/ia/edit.txt1
-rw-r--r--inc/lang/ia/editrev.txt2
-rw-r--r--inc/lang/ia/index.txt3
-rw-r--r--inc/lang/ia/install.html13
-rw-r--r--inc/lang/ia/lang.php267
-rw-r--r--inc/lang/ia/locked.txt3
-rw-r--r--inc/lang/ia/login.txt3
-rw-r--r--inc/lang/ia/mailtext.txt17
-rw-r--r--inc/lang/ia/newpage.txt3
-rw-r--r--inc/lang/ia/norev.txt3
-rw-r--r--inc/lang/ia/password.txt10
-rw-r--r--inc/lang/ia/preview.txt3
-rw-r--r--inc/lang/ia/pwconfirm.txt14
-rw-r--r--inc/lang/ia/read.txt1
-rw-r--r--inc/lang/ia/recent.txt3
-rw-r--r--inc/lang/ia/register.txt3
-rw-r--r--inc/lang/ia/registermail.txt14
-rw-r--r--inc/lang/ia/resendpwd.txt3
-rw-r--r--inc/lang/ia/revisions.txt3
-rw-r--r--inc/lang/ia/searchpage.txt5
-rw-r--r--inc/lang/ia/showrev.txt2
-rw-r--r--inc/lang/ia/stopwords.txt38
-rw-r--r--inc/lang/ia/subscr_digest.txt20
-rw-r--r--inc/lang/ia/subscr_form.txt4
-rw-r--r--inc/lang/ia/subscr_list.txt17
-rw-r--r--inc/lang/ia/subscr_single.txt26
-rw-r--r--inc/lang/ia/updateprofile.txt3
-rw-r--r--inc/lang/ia/uploadmail.txt14
-rw-r--r--inc/lang/id-ni/lang.php79
-rw-r--r--inc/lang/id/admin.txt4
-rw-r--r--inc/lang/id/backlinks.txt3
-rw-r--r--inc/lang/id/conflict.txt6
-rw-r--r--inc/lang/id/denied.txt4
-rw-r--r--inc/lang/id/diff.txt4
-rw-r--r--inc/lang/id/draft.txt5
-rw-r--r--inc/lang/id/edit.txt2
-rw-r--r--inc/lang/id/editrev.txt2
-rw-r--r--inc/lang/id/index.txt4
-rw-r--r--inc/lang/id/install.html25
-rw-r--r--inc/lang/id/lang.php199
-rw-r--r--inc/lang/id/locked.txt3
-rw-r--r--inc/lang/id/login.txt4
-rw-r--r--inc/lang/id/mailtext.txt17
-rw-r--r--inc/lang/id/newpage.txt3
-rw-r--r--inc/lang/id/norev.txt4
-rw-r--r--inc/lang/id/password.txt10
-rw-r--r--inc/lang/id/preview.txt4
-rw-r--r--inc/lang/id/pwconfirm.txt13
-rw-r--r--inc/lang/id/read.txt2
-rw-r--r--inc/lang/id/recent.txt5
-rw-r--r--inc/lang/id/register.txt4
-rw-r--r--inc/lang/id/registermail.txt14
-rw-r--r--inc/lang/id/resendpwd.txt3
-rw-r--r--inc/lang/id/revisions.txt4
-rw-r--r--inc/lang/id/searchpage.txt5
-rw-r--r--inc/lang/id/showrev.txt2
-rw-r--r--inc/lang/id/stopwords.txt37
-rw-r--r--inc/lang/id/updateprofile.txt3
-rw-r--r--inc/lang/id/uploadmail.txt14
-rw-r--r--inc/lang/is/adminplugins.txt1
-rw-r--r--inc/lang/is/diff.txt3
-rw-r--r--inc/lang/is/lang.php187
-rw-r--r--inc/lang/is/login.txt3
-rw-r--r--inc/lang/is/recent.txt3
-rw-r--r--inc/lang/is/resendpwd.txt3
-rw-r--r--inc/lang/it/admin.txt4
-rw-r--r--inc/lang/it/adminplugins.txt1
-rw-r--r--inc/lang/it/backlinks.txt4
-rw-r--r--inc/lang/it/conflict.txt6
-rw-r--r--inc/lang/it/denied.txt5
-rw-r--r--inc/lang/it/diff.txt4
-rw-r--r--inc/lang/it/draft.txt6
-rw-r--r--inc/lang/it/edit.txt2
-rw-r--r--inc/lang/it/editrev.txt2
-rw-r--r--inc/lang/it/index.txt4
-rw-r--r--inc/lang/it/install.html24
-rw-r--r--inc/lang/it/lang.php273
-rw-r--r--inc/lang/it/locked.txt3
-rw-r--r--inc/lang/it/login.txt4
-rw-r--r--inc/lang/it/mailtext.txt17
-rw-r--r--inc/lang/it/newpage.txt3
-rw-r--r--inc/lang/it/norev.txt3
-rw-r--r--inc/lang/it/password.txt10
-rw-r--r--inc/lang/it/preview.txt5
-rw-r--r--inc/lang/it/pwconfirm.txt15
-rw-r--r--inc/lang/it/read.txt1
-rw-r--r--inc/lang/it/recent.txt4
-rw-r--r--inc/lang/it/register.txt3
-rw-r--r--inc/lang/it/registermail.txt14
-rw-r--r--inc/lang/it/resendpwd.txt3
-rw-r--r--inc/lang/it/revisions.txt3
-rw-r--r--inc/lang/it/searchpage.txt5
-rw-r--r--inc/lang/it/showrev.txt2
-rw-r--r--inc/lang/it/stopwords.txt119
-rw-r--r--inc/lang/it/subscr_digest.txt20
-rw-r--r--inc/lang/it/subscr_form.txt3
-rw-r--r--inc/lang/it/subscr_list.txt18
-rw-r--r--inc/lang/it/subscr_single.txt24
-rw-r--r--inc/lang/it/updateprofile.txt3
-rw-r--r--inc/lang/it/uploadmail.txt14
-rw-r--r--inc/lang/ja/admin.txt4
-rw-r--r--inc/lang/ja/adminplugins.txt1
-rw-r--r--inc/lang/ja/backlinks.txt4
-rw-r--r--inc/lang/ja/conflict.txt6
-rw-r--r--inc/lang/ja/denied.txt4
-rw-r--r--inc/lang/ja/diff.txt4
-rw-r--r--inc/lang/ja/draft.txt6
-rw-r--r--inc/lang/ja/edit.txt4
-rw-r--r--inc/lang/ja/editrev.txt2
-rw-r--r--inc/lang/ja/index.txt4
-rw-r--r--inc/lang/ja/install.html14
-rw-r--r--inc/lang/ja/lang.php314
-rw-r--r--inc/lang/ja/locked.txt3
-rw-r--r--inc/lang/ja/login.txt4
-rw-r--r--inc/lang/ja/mailtext.txt17
-rw-r--r--inc/lang/ja/newpage.txt4
-rw-r--r--inc/lang/ja/norev.txt4
-rw-r--r--inc/lang/ja/password.txt10
-rw-r--r--inc/lang/ja/preview.txt4
-rw-r--r--inc/lang/ja/pwconfirm.txt13
-rw-r--r--inc/lang/ja/read.txt2
-rw-r--r--inc/lang/ja/recent.txt5
-rw-r--r--inc/lang/ja/register.txt4
-rw-r--r--inc/lang/ja/registermail.txt14
-rw-r--r--inc/lang/ja/resendpwd.txt4
-rw-r--r--inc/lang/ja/revisions.txt4
-rw-r--r--inc/lang/ja/searchpage.txt5
-rw-r--r--inc/lang/ja/showrev.txt2
-rw-r--r--inc/lang/ja/stopwords.txt29
-rw-r--r--inc/lang/ja/subscr_digest.txt21
-rw-r--r--inc/lang/ja/subscr_form.txt3
-rw-r--r--inc/lang/ja/subscr_list.txt19
-rw-r--r--inc/lang/ja/subscr_single.txt24
-rw-r--r--inc/lang/ja/updateprofile.txt5
-rw-r--r--inc/lang/ja/uploadmail.txt14
-rw-r--r--inc/lang/kk/lang.php116
-rw-r--r--inc/lang/km/admin.txt3
-rw-r--r--inc/lang/km/backlinks.txt5
-rw-r--r--inc/lang/km/conflict.txt3
-rw-r--r--inc/lang/km/denied.txt3
-rw-r--r--inc/lang/km/edit.txt3
-rw-r--r--inc/lang/km/editrev.txt2
-rw-r--r--inc/lang/km/index.txt2
-rw-r--r--inc/lang/km/lang.php227
-rw-r--r--inc/lang/km/login.txt5
-rw-r--r--inc/lang/km/newpage.txt4
-rw-r--r--inc/lang/km/norev.txt2
-rw-r--r--inc/lang/km/password.txt10
-rw-r--r--inc/lang/km/pwconfirm.txt13
-rw-r--r--inc/lang/km/recent.txt3
-rw-r--r--inc/lang/km/register.txt7
-rw-r--r--inc/lang/km/revisions.txt4
-rw-r--r--inc/lang/ko/admin.txt4
-rw-r--r--inc/lang/ko/adminplugins.txt1
-rw-r--r--inc/lang/ko/backlinks.txt4
-rw-r--r--inc/lang/ko/conflict.txt6
-rw-r--r--inc/lang/ko/denied.txt4
-rw-r--r--inc/lang/ko/diff.txt5
-rw-r--r--inc/lang/ko/draft.txt6
-rw-r--r--inc/lang/ko/edit.txt2
-rw-r--r--inc/lang/ko/editrev.txt2
-rw-r--r--inc/lang/ko/index.txt4
-rw-r--r--inc/lang/ko/install.html17
-rw-r--r--inc/lang/ko/lang.php273
-rw-r--r--inc/lang/ko/locked.txt3
-rw-r--r--inc/lang/ko/login.txt4
-rw-r--r--inc/lang/ko/mailtext.txt17
-rw-r--r--inc/lang/ko/newpage.txt3
-rw-r--r--inc/lang/ko/norev.txt3
-rw-r--r--inc/lang/ko/password.txt10
-rw-r--r--inc/lang/ko/preview.txt4
-rw-r--r--inc/lang/ko/pwconfirm.txt11
-rw-r--r--inc/lang/ko/read.txt2
-rw-r--r--inc/lang/ko/recent.txt5
-rw-r--r--inc/lang/ko/register.txt4
-rw-r--r--inc/lang/ko/registermail.txt14
-rw-r--r--inc/lang/ko/resendpwd.txt4
-rw-r--r--inc/lang/ko/revisions.txt4
-rw-r--r--inc/lang/ko/searchpage.txt5
-rw-r--r--inc/lang/ko/showrev.txt2
-rw-r--r--inc/lang/ko/stopwords.txt29
-rw-r--r--inc/lang/ko/subscr_digest.txt18
-rw-r--r--inc/lang/ko/subscr_form.txt3
-rw-r--r--inc/lang/ko/subscr_list.txt15
-rw-r--r--inc/lang/ko/subscr_single.txt21
-rw-r--r--inc/lang/ko/updateprofile.txt5
-rw-r--r--inc/lang/ko/uploadmail.txt15
-rw-r--r--inc/lang/ku/admin.txt4
-rw-r--r--inc/lang/ku/backlinks.txt4
-rw-r--r--inc/lang/ku/conflict.txt6
-rw-r--r--inc/lang/ku/denied.txt4
-rw-r--r--inc/lang/ku/diff.txt4
-rw-r--r--inc/lang/ku/edit.txt2
-rw-r--r--inc/lang/ku/editrev.txt2
-rw-r--r--inc/lang/ku/index.txt3
-rw-r--r--inc/lang/ku/lang.php163
-rw-r--r--inc/lang/ku/locked.txt3
-rw-r--r--inc/lang/ku/login.txt4
-rw-r--r--inc/lang/ku/mailtext.txt17
-rw-r--r--inc/lang/ku/newpage.txt3
-rw-r--r--inc/lang/ku/norev.txt4
-rw-r--r--inc/lang/ku/password.txt10
-rw-r--r--inc/lang/ku/preview.txt3
-rw-r--r--inc/lang/ku/read.txt2
-rw-r--r--inc/lang/ku/recent.txt3
-rw-r--r--inc/lang/ku/register.txt4
-rw-r--r--inc/lang/ku/revisions.txt4
-rw-r--r--inc/lang/ku/searchpage.txt5
-rw-r--r--inc/lang/ku/showrev.txt2
-rw-r--r--inc/lang/ku/stopwords.txt29
-rw-r--r--inc/lang/la/admin.txt3
-rw-r--r--inc/lang/la/adminplugins.txt1
-rw-r--r--inc/lang/la/backlinks.txt3
-rw-r--r--inc/lang/la/conflict.txt5
-rw-r--r--inc/lang/la/denied.txt3
-rw-r--r--inc/lang/la/diff.txt3
-rw-r--r--inc/lang/la/draft.txt5
-rw-r--r--inc/lang/la/edit.txt1
-rw-r--r--inc/lang/la/editrev.txt2
-rw-r--r--inc/lang/la/index.txt3
-rw-r--r--inc/lang/la/install.html8
-rw-r--r--inc/lang/la/lang.php267
-rw-r--r--inc/lang/la/locked.txt3
-rw-r--r--inc/lang/la/login.txt3
-rw-r--r--inc/lang/la/mailtext.txt16
-rw-r--r--inc/lang/la/newpage.txt3
-rw-r--r--inc/lang/la/norev.txt3
-rw-r--r--inc/lang/la/password.txt10
-rw-r--r--inc/lang/la/preview.txt3
-rw-r--r--inc/lang/la/pwconfirm.txt14
-rw-r--r--inc/lang/la/read.txt1
-rw-r--r--inc/lang/la/recent.txt3
-rw-r--r--inc/lang/la/register.txt3
-rw-r--r--inc/lang/la/registermail.txt14
-rw-r--r--inc/lang/la/resendpwd.txt3
-rw-r--r--inc/lang/la/revisions.txt3
-rw-r--r--inc/lang/la/searchpage.txt5
-rw-r--r--inc/lang/la/showrev.txt2
-rw-r--r--inc/lang/la/stopwords.txt37
-rw-r--r--inc/lang/la/subscr_digest.txt20
-rw-r--r--inc/lang/la/subscr_form.txt3
-rw-r--r--inc/lang/la/subscr_list.txt17
-rw-r--r--inc/lang/la/subscr_single.txt23
-rw-r--r--inc/lang/la/updateprofile.txt3
-rw-r--r--inc/lang/la/uploadmail.txt14
-rw-r--r--inc/lang/lb/admin.txt3
-rw-r--r--inc/lang/lb/adminplugins.txt1
-rw-r--r--inc/lang/lb/backlinks.txt3
-rw-r--r--inc/lang/lb/conflict.txt5
-rw-r--r--inc/lang/lb/denied.txt3
-rw-r--r--inc/lang/lb/diff.txt3
-rw-r--r--inc/lang/lb/draft.txt5
-rw-r--r--inc/lang/lb/edit.txt1
-rw-r--r--inc/lang/lb/editrev.txt2
-rw-r--r--inc/lang/lb/index.txt3
-rw-r--r--inc/lang/lb/lang.php199
-rw-r--r--inc/lang/lb/locked.txt3
-rw-r--r--inc/lang/lb/login.txt3
-rw-r--r--inc/lang/lb/mailtext.txt17
-rw-r--r--inc/lang/lb/newpage.txt4
-rw-r--r--inc/lang/lb/norev.txt3
-rw-r--r--inc/lang/lb/password.txt10
-rw-r--r--inc/lang/lb/preview.txt3
-rw-r--r--inc/lang/lb/pwconfirm.txt15
-rw-r--r--inc/lang/lb/read.txt1
-rw-r--r--inc/lang/lb/recent.txt4
-rw-r--r--inc/lang/lb/register.txt4
-rw-r--r--inc/lang/lb/registermail.txt14
-rw-r--r--inc/lang/lb/resendpwd.txt3
-rw-r--r--inc/lang/lb/revisions.txt3
-rw-r--r--inc/lang/lb/searchpage.txt5
-rw-r--r--inc/lang/lb/showrev.txt2
-rw-r--r--inc/lang/lb/updateprofile.txt4
-rw-r--r--inc/lang/lb/uploadmail.txt14
-rw-r--r--inc/lang/lt/admin.txt4
-rw-r--r--inc/lang/lt/backlinks.txt4
-rw-r--r--inc/lang/lt/conflict.txt6
-rw-r--r--inc/lang/lt/denied.txt4
-rw-r--r--inc/lang/lt/diff.txt4
-rw-r--r--inc/lang/lt/edit.txt2
-rw-r--r--inc/lang/lt/editrev.txt2
-rw-r--r--inc/lang/lt/index.txt4
-rw-r--r--inc/lang/lt/lang.php192
-rw-r--r--inc/lang/lt/locked.txt3
-rw-r--r--inc/lang/lt/login.txt5
-rw-r--r--inc/lang/lt/mailtext.txt18
-rw-r--r--inc/lang/lt/newpage.txt4
-rw-r--r--inc/lang/lt/norev.txt5
-rw-r--r--inc/lang/lt/password.txt9
-rw-r--r--inc/lang/lt/preview.txt5
-rw-r--r--inc/lang/lt/read.txt3
-rw-r--r--inc/lang/lt/recent.txt5
-rw-r--r--inc/lang/lt/register.txt4
-rw-r--r--inc/lang/lt/resendpwd.txt3
-rw-r--r--inc/lang/lt/revisions.txt4
-rw-r--r--inc/lang/lt/searchpage.txt5
-rw-r--r--inc/lang/lt/showrev.txt2
-rw-r--r--inc/lang/lt/updateprofile.txt4
-rw-r--r--inc/lang/lv/admin.txt6
-rw-r--r--inc/lang/lv/adminplugins.txt1
-rw-r--r--inc/lang/lv/backlinks.txt5
-rw-r--r--inc/lang/lv/conflict.txt8
-rw-r--r--inc/lang/lv/denied.txt6
-rw-r--r--inc/lang/lv/diff.txt7
-rw-r--r--inc/lang/lv/draft.txt5
-rw-r--r--inc/lang/lv/edit.txt2
-rw-r--r--inc/lang/lv/editrev.txt1
-rw-r--r--inc/lang/lv/index.txt4
-rw-r--r--inc/lang/lv/install.html12
-rw-r--r--inc/lang/lv/lang.php309
-rw-r--r--inc/lang/lv/locked.txt5
-rw-r--r--inc/lang/lv/login.txt3
-rw-r--r--inc/lang/lv/mailtext.txt18
-rw-r--r--inc/lang/lv/newpage.txt5
-rw-r--r--inc/lang/lv/norev.txt5
-rw-r--r--inc/lang/lv/password.txt9
-rw-r--r--inc/lang/lv/preview.txt5
-rw-r--r--inc/lang/lv/pwconfirm.txt14
-rw-r--r--inc/lang/lv/read.txt4
-rw-r--r--inc/lang/lv/recent.txt8
-rw-r--r--inc/lang/lv/register.txt4
-rw-r--r--inc/lang/lv/registermail.txt14
-rw-r--r--inc/lang/lv/resendpwd.txt3
-rw-r--r--inc/lang/lv/revisions.txt5
-rw-r--r--inc/lang/lv/searchpage.txt4
-rw-r--r--inc/lang/lv/showrev.txt2
-rw-r--r--inc/lang/lv/stopwords.txt48
-rw-r--r--inc/lang/lv/subscr_digest.txt19
-rw-r--r--inc/lang/lv/subscr_form.txt3
-rw-r--r--inc/lang/lv/subscr_list.txt16
-rw-r--r--inc/lang/lv/subscr_single.txt23
-rw-r--r--inc/lang/lv/updateprofile.txt8
-rw-r--r--inc/lang/lv/uploadmail.txt14
-rw-r--r--inc/lang/mg/admin.txt4
-rw-r--r--inc/lang/mg/backlinks.txt5
-rw-r--r--inc/lang/mg/conflict.txt6
-rw-r--r--inc/lang/mg/denied.txt4
-rw-r--r--inc/lang/mg/diff.txt4
-rw-r--r--inc/lang/mg/edit.txt2
-rw-r--r--inc/lang/mg/editrev.txt2
-rw-r--r--inc/lang/mg/index.txt4
-rw-r--r--inc/lang/mg/lang.php135
-rw-r--r--inc/lang/mg/locked.txt4
-rw-r--r--inc/lang/mg/login.txt4
-rw-r--r--inc/lang/mg/mailtext.txt17
-rw-r--r--inc/lang/mg/newpage.txt3
-rw-r--r--inc/lang/mg/norev.txt4
-rw-r--r--inc/lang/mg/password.txt11
-rw-r--r--inc/lang/mg/preview.txt5
-rw-r--r--inc/lang/mg/read.txt3
-rw-r--r--inc/lang/mg/recent.txt5
-rw-r--r--inc/lang/mg/register.txt5
-rw-r--r--inc/lang/mg/revisions.txt5
-rw-r--r--inc/lang/mg/searchpage.txt7
-rw-r--r--inc/lang/mg/showrev.txt2
-rw-r--r--inc/lang/mk/adminplugins.txt1
-rw-r--r--inc/lang/mk/lang.php232
-rw-r--r--inc/lang/mk/read.txt1
-rw-r--r--inc/lang/mk/recent.txt3
-rw-r--r--inc/lang/mk/showrev.txt2
-rw-r--r--inc/lang/mr/admin.txt3
-rw-r--r--inc/lang/mr/backlinks.txt3
-rw-r--r--inc/lang/mr/conflict.txt5
-rw-r--r--inc/lang/mr/denied.txt3
-rw-r--r--inc/lang/mr/diff.txt3
-rw-r--r--inc/lang/mr/draft.txt5
-rw-r--r--inc/lang/mr/edit.txt1
-rw-r--r--inc/lang/mr/editrev.txt2
-rw-r--r--inc/lang/mr/index.txt3
-rw-r--r--inc/lang/mr/install.html10
-rw-r--r--inc/lang/mr/lang.php212
-rw-r--r--inc/lang/mr/locked.txt3
-rw-r--r--inc/lang/mr/login.txt3
-rw-r--r--inc/lang/mr/mailtext.txt15
-rw-r--r--inc/lang/mr/newpage.txt3
-rw-r--r--inc/lang/mr/norev.txt3
-rw-r--r--inc/lang/mr/password.txt9
-rw-r--r--inc/lang/mr/preview.txt3
-rw-r--r--inc/lang/mr/pwconfirm.txt11
-rw-r--r--inc/lang/mr/read.txt1
-rw-r--r--inc/lang/mr/recent.txt3
-rw-r--r--inc/lang/mr/register.txt3
-rw-r--r--inc/lang/mr/registermail.txt13
-rw-r--r--inc/lang/mr/resendpwd.txt3
-rw-r--r--inc/lang/mr/revisions.txt3
-rw-r--r--inc/lang/mr/searchpage.txt5
-rw-r--r--inc/lang/mr/showrev.txt2
-rw-r--r--inc/lang/mr/stopwords.txt39
-rw-r--r--inc/lang/mr/updateprofile.txt3
-rw-r--r--inc/lang/mr/uploadmail.txt13
-rw-r--r--inc/lang/ms/lang.php97
-rw-r--r--inc/lang/ne/admin.txt2
-rw-r--r--inc/lang/ne/backlinks.txt2
-rw-r--r--inc/lang/ne/conflict.txt5
-rw-r--r--inc/lang/ne/denied.txt3
-rw-r--r--inc/lang/ne/diff.txt3
-rw-r--r--inc/lang/ne/draft.txt5
-rw-r--r--inc/lang/ne/edit.txt1
-rw-r--r--inc/lang/ne/editrev.txt2
-rw-r--r--inc/lang/ne/index.txt3
-rw-r--r--inc/lang/ne/lang.php203
-rw-r--r--inc/lang/ne/locked.txt3
-rw-r--r--inc/lang/ne/norev.txt2
-rw-r--r--inc/lang/ne/pwconfirm.txt12
-rw-r--r--inc/lang/ne/read.txt1
-rw-r--r--inc/lang/ne/recent.txt2
-rw-r--r--inc/lang/ne/resendpwd.txt3
-rw-r--r--inc/lang/ne/searchpage.txt3
-rw-r--r--inc/lang/ne/showrev.txt2
-rw-r--r--inc/lang/ne/updateprofile.txt3
-rw-r--r--inc/lang/ne/uploadmail.txt13
-rw-r--r--inc/lang/nl/admin.txt3
-rw-r--r--inc/lang/nl/adminplugins.txt1
-rw-r--r--inc/lang/nl/backlinks.txt4
-rw-r--r--inc/lang/nl/conflict.txt5
-rw-r--r--inc/lang/nl/denied.txt3
-rw-r--r--inc/lang/nl/diff.txt3
-rw-r--r--inc/lang/nl/draft.txt5
-rw-r--r--inc/lang/nl/edit.txt1
-rw-r--r--inc/lang/nl/editrev.txt2
-rw-r--r--inc/lang/nl/index.txt4
-rw-r--r--inc/lang/nl/install.html14
-rw-r--r--inc/lang/nl/lang.php322
-rw-r--r--inc/lang/nl/locked.txt3
-rw-r--r--inc/lang/nl/login.txt3
-rw-r--r--inc/lang/nl/mailtext.txt17
-rw-r--r--inc/lang/nl/newpage.txt3
-rw-r--r--inc/lang/nl/norev.txt4
-rw-r--r--inc/lang/nl/password.txt10
-rw-r--r--inc/lang/nl/preview.txt4
-rw-r--r--inc/lang/nl/pwconfirm.txt13
-rw-r--r--inc/lang/nl/read.txt2
-rw-r--r--inc/lang/nl/recent.txt3
-rw-r--r--inc/lang/nl/register.txt4
-rw-r--r--inc/lang/nl/registermail.txt14
-rw-r--r--inc/lang/nl/resendpwd.txt3
-rw-r--r--inc/lang/nl/revisions.txt4
-rw-r--r--inc/lang/nl/searchpage.txt5
-rw-r--r--inc/lang/nl/showrev.txt2
-rw-r--r--inc/lang/nl/stopwords.txt37
-rw-r--r--inc/lang/nl/subscr_digest.txt15
-rw-r--r--inc/lang/nl/subscr_form.txt3
-rw-r--r--inc/lang/nl/subscr_list.txt12
-rw-r--r--inc/lang/nl/subscr_single.txt18
-rw-r--r--inc/lang/nl/updateprofile.txt3
-rw-r--r--inc/lang/nl/uploadmail.txt14
-rw-r--r--inc/lang/no/admin.txt3
-rw-r--r--inc/lang/no/adminplugins.txt1
-rw-r--r--inc/lang/no/backlinks.txt3
-rw-r--r--inc/lang/no/conflict.txt6
-rw-r--r--inc/lang/no/denied.txt3
-rw-r--r--inc/lang/no/diff.txt4
-rw-r--r--inc/lang/no/draft.txt6
-rw-r--r--inc/lang/no/edit.txt2
-rw-r--r--inc/lang/no/editrev.txt2
-rw-r--r--inc/lang/no/index.txt4
-rw-r--r--inc/lang/no/install.html24
-rw-r--r--inc/lang/no/lang.php328
-rw-r--r--inc/lang/no/locked.txt3
-rw-r--r--inc/lang/no/login.txt4
-rw-r--r--inc/lang/no/mailtext.txt17
-rw-r--r--inc/lang/no/newpage.txt3
-rw-r--r--inc/lang/no/norev.txt4
-rw-r--r--inc/lang/no/password.txt10
-rw-r--r--inc/lang/no/preview.txt4
-rw-r--r--inc/lang/no/pwconfirm.txt15
-rw-r--r--inc/lang/no/read.txt2
-rw-r--r--inc/lang/no/recent.txt5
-rw-r--r--inc/lang/no/register.txt4
-rw-r--r--inc/lang/no/registermail.txt14
-rw-r--r--inc/lang/no/resendpwd.txt4
-rw-r--r--inc/lang/no/revisions.txt4
-rw-r--r--inc/lang/no/searchpage.txt5
-rw-r--r--inc/lang/no/showrev.txt2
-rw-r--r--inc/lang/no/stopwords.txt68
-rw-r--r--inc/lang/no/subscr_digest.txt20
-rw-r--r--inc/lang/no/subscr_form.txt3
-rw-r--r--inc/lang/no/subscr_list.txt17
-rw-r--r--inc/lang/no/subscr_single.txt23
-rw-r--r--inc/lang/no/updateprofile.txt5
-rw-r--r--inc/lang/no/uploadmail.txt15
-rw-r--r--inc/lang/pl/admin.txt4
-rw-r--r--inc/lang/pl/adminplugins.txt1
-rw-r--r--inc/lang/pl/backlinks.txt4
-rw-r--r--inc/lang/pl/conflict.txt6
-rw-r--r--inc/lang/pl/denied.txt4
-rw-r--r--inc/lang/pl/diff.txt4
-rw-r--r--inc/lang/pl/draft.txt6
-rw-r--r--inc/lang/pl/edit.txt4
-rw-r--r--inc/lang/pl/editrev.txt2
-rw-r--r--inc/lang/pl/index.txt4
-rw-r--r--inc/lang/pl/install.html23
-rw-r--r--inc/lang/pl/lang.php325
-rw-r--r--inc/lang/pl/locked.txt3
-rw-r--r--inc/lang/pl/login.txt4
-rw-r--r--inc/lang/pl/mailtext.txt18
-rw-r--r--inc/lang/pl/newpage.txt4
-rw-r--r--inc/lang/pl/norev.txt4
-rw-r--r--inc/lang/pl/password.txt10
-rw-r--r--inc/lang/pl/preview.txt4
-rw-r--r--inc/lang/pl/pwconfirm.txt13
-rw-r--r--inc/lang/pl/read.txt2
-rw-r--r--inc/lang/pl/recent.txt5
-rw-r--r--inc/lang/pl/register.txt4
-rw-r--r--inc/lang/pl/registermail.txt15
-rw-r--r--inc/lang/pl/resendpwd.txt4
-rw-r--r--inc/lang/pl/revisions.txt4
-rw-r--r--inc/lang/pl/searchpage.txt5
-rw-r--r--inc/lang/pl/showrev.txt2
-rw-r--r--inc/lang/pl/stopwords.txt89
-rw-r--r--inc/lang/pl/subscr_digest.txt21
-rw-r--r--inc/lang/pl/subscr_form.txt3
-rw-r--r--inc/lang/pl/subscr_list.txt18
-rw-r--r--inc/lang/pl/subscr_single.txt24
-rw-r--r--inc/lang/pl/updateprofile.txt5
-rw-r--r--inc/lang/pl/uploadmail.txt16
-rw-r--r--inc/lang/pt-br/admin.txt4
-rw-r--r--inc/lang/pt-br/adminplugins.txt1
-rw-r--r--inc/lang/pt-br/backlinks.txt4
-rw-r--r--inc/lang/pt-br/conflict.txt5
-rw-r--r--inc/lang/pt-br/denied.txt3
-rw-r--r--inc/lang/pt-br/diff.txt3
-rw-r--r--inc/lang/pt-br/draft.txt5
-rw-r--r--inc/lang/pt-br/edit.txt2
-rw-r--r--inc/lang/pt-br/editrev.txt4
-rw-r--r--inc/lang/pt-br/index.txt3
-rw-r--r--inc/lang/pt-br/install.html7
-rw-r--r--inc/lang/pt-br/lang.php282
-rw-r--r--inc/lang/pt-br/locked.txt3
-rw-r--r--inc/lang/pt-br/login.txt3
-rw-r--r--inc/lang/pt-br/mailtext.txt17
-rw-r--r--inc/lang/pt-br/newpage.txt3
-rw-r--r--inc/lang/pt-br/norev.txt3
-rw-r--r--inc/lang/pt-br/password.txt10
-rw-r--r--inc/lang/pt-br/preview.txt3
-rw-r--r--inc/lang/pt-br/pwconfirm.txt13
-rw-r--r--inc/lang/pt-br/read.txt1
-rw-r--r--inc/lang/pt-br/recent.txt4
-rw-r--r--inc/lang/pt-br/register.txt4
-rw-r--r--inc/lang/pt-br/registermail.txt14
-rw-r--r--inc/lang/pt-br/resendpwd.txt3
-rw-r--r--inc/lang/pt-br/revisions.txt4
-rw-r--r--inc/lang/pt-br/searchpage.txt5
-rw-r--r--inc/lang/pt-br/showrev.txt2
-rw-r--r--inc/lang/pt-br/stopwords.txt55
-rw-r--r--inc/lang/pt-br/subscr_digest.txt20
-rw-r--r--inc/lang/pt-br/subscr_form.txt3
-rw-r--r--inc/lang/pt-br/subscr_list.txt28
-rw-r--r--inc/lang/pt-br/subscr_single.txt22
-rw-r--r--inc/lang/pt-br/updateprofile.txt5
-rw-r--r--inc/lang/pt-br/uploadmail.txt14
-rw-r--r--inc/lang/pt/admin.txt3
-rw-r--r--inc/lang/pt/adminplugins.txt1
-rw-r--r--inc/lang/pt/backlinks.txt4
-rw-r--r--inc/lang/pt/conflict.txt9
-rw-r--r--inc/lang/pt/denied.txt3
-rw-r--r--inc/lang/pt/diff.txt5
-rw-r--r--inc/lang/pt/draft.txt7
-rw-r--r--inc/lang/pt/edit.txt4
-rw-r--r--inc/lang/pt/editrev.txt1
-rw-r--r--inc/lang/pt/index.txt3
-rw-r--r--inc/lang/pt/install.html8
-rw-r--r--inc/lang/pt/lang.php322
-rw-r--r--inc/lang/pt/locked.txt3
-rw-r--r--inc/lang/pt/login.txt3
-rw-r--r--inc/lang/pt/mailtext.txt20
-rw-r--r--inc/lang/pt/newpage.txt3
-rw-r--r--inc/lang/pt/norev.txt7
-rw-r--r--inc/lang/pt/password.txt10
-rw-r--r--inc/lang/pt/preview.txt3
-rw-r--r--inc/lang/pt/pwconfirm.txt13
-rw-r--r--inc/lang/pt/read.txt1
-rw-r--r--inc/lang/pt/recent.txt3
-rw-r--r--inc/lang/pt/register.txt3
-rw-r--r--inc/lang/pt/registermail.txt14
-rw-r--r--inc/lang/pt/resendpwd.txt3
-rw-r--r--inc/lang/pt/revisions.txt3
-rw-r--r--inc/lang/pt/searchpage.txt5
-rw-r--r--inc/lang/pt/showrev.txt1
-rw-r--r--inc/lang/pt/stopwords.txt141
-rw-r--r--inc/lang/pt/subscr_digest.txt20
-rw-r--r--inc/lang/pt/subscr_form.txt3
-rw-r--r--inc/lang/pt/subscr_list.txt17
-rw-r--r--inc/lang/pt/subscr_single.txt23
-rw-r--r--inc/lang/pt/updateprofile.txt3
-rw-r--r--inc/lang/pt/uploadmail.txt15
-rw-r--r--inc/lang/ro/admin.txt3
-rw-r--r--inc/lang/ro/adminplugins.txt1
-rw-r--r--inc/lang/ro/backlinks.txt4
-rw-r--r--inc/lang/ro/conflict.txt6
-rw-r--r--inc/lang/ro/denied.txt4
-rw-r--r--inc/lang/ro/diff.txt4
-rw-r--r--inc/lang/ro/draft.txt5
-rw-r--r--inc/lang/ro/edit.txt2
-rw-r--r--inc/lang/ro/editrev.txt2
-rw-r--r--inc/lang/ro/index.txt4
-rw-r--r--inc/lang/ro/install.html10
-rw-r--r--inc/lang/ro/lang.php316
-rw-r--r--inc/lang/ro/locked.txt3
-rw-r--r--inc/lang/ro/login.txt4
-rw-r--r--inc/lang/ro/mailtext.txt16
-rw-r--r--inc/lang/ro/newpage.txt3
-rw-r--r--inc/lang/ro/norev.txt4
-rw-r--r--inc/lang/ro/password.txt10
-rw-r--r--inc/lang/ro/preview.txt4
-rw-r--r--inc/lang/ro/pwconfirm.txt13
-rw-r--r--inc/lang/ro/read.txt2
-rw-r--r--inc/lang/ro/recent.txt5
-rw-r--r--inc/lang/ro/register.txt3
-rw-r--r--inc/lang/ro/registermail.txt14
-rw-r--r--inc/lang/ro/resendpwd.txt3
-rw-r--r--inc/lang/ro/revisions.txt4
-rw-r--r--inc/lang/ro/searchpage.txt5
-rw-r--r--inc/lang/ro/showrev.txt2
-rw-r--r--inc/lang/ro/stopwords.txt29
-rw-r--r--inc/lang/ro/subscr_digest.txt20
-rw-r--r--inc/lang/ro/subscr_form.txt3
-rw-r--r--inc/lang/ro/subscr_list.txt17
-rw-r--r--inc/lang/ro/subscr_single.txt23
-rw-r--r--inc/lang/ro/updateprofile.txt3
-rw-r--r--inc/lang/ro/uploadmail.txt14
-rw-r--r--inc/lang/ru/admin.txt4
-rw-r--r--inc/lang/ru/adminplugins.txt1
-rw-r--r--inc/lang/ru/backlinks.txt4
-rw-r--r--inc/lang/ru/conflict.txt5
-rw-r--r--inc/lang/ru/denied.txt3
-rw-r--r--inc/lang/ru/diff.txt4
-rw-r--r--inc/lang/ru/draft.txt6
-rw-r--r--inc/lang/ru/edit.txt2
-rw-r--r--inc/lang/ru/editrev.txt2
-rw-r--r--inc/lang/ru/index.txt4
-rw-r--r--inc/lang/ru/install.html7
-rw-r--r--inc/lang/ru/lang.php346
-rw-r--r--inc/lang/ru/locked.txt3
-rw-r--r--inc/lang/ru/login.txt4
-rw-r--r--inc/lang/ru/mailtext.txt17
-rw-r--r--inc/lang/ru/newpage.txt3
-rw-r--r--inc/lang/ru/norev.txt4
-rw-r--r--inc/lang/ru/password.txt11
-rw-r--r--inc/lang/ru/preview.txt4
-rw-r--r--inc/lang/ru/pwconfirm.txt13
-rw-r--r--inc/lang/ru/read.txt2
-rw-r--r--inc/lang/ru/recent.txt5
-rw-r--r--inc/lang/ru/register.txt3
-rw-r--r--inc/lang/ru/registermail.txt14
-rw-r--r--inc/lang/ru/resendpwd.txt3
-rw-r--r--inc/lang/ru/revisions.txt3
-rw-r--r--inc/lang/ru/searchpage.txt5
-rw-r--r--inc/lang/ru/showrev.txt2
-rw-r--r--inc/lang/ru/stopwords.txt93
-rw-r--r--inc/lang/ru/subscr_digest.txt20
-rw-r--r--inc/lang/ru/subscr_form.txt3
-rw-r--r--inc/lang/ru/subscr_list.txt17
-rw-r--r--inc/lang/ru/subscr_single.txt25
-rw-r--r--inc/lang/ru/updateprofile.txt5
-rw-r--r--inc/lang/ru/uploadmail.txt15
-rw-r--r--inc/lang/ru/wordblock.txt3
-rw-r--r--inc/lang/sk/admin.txt5
-rw-r--r--inc/lang/sk/adminplugins.txt1
-rw-r--r--inc/lang/sk/backlinks.txt3
-rw-r--r--inc/lang/sk/conflict.txt5
-rw-r--r--inc/lang/sk/denied.txt3
-rw-r--r--inc/lang/sk/diff.txt4
-rw-r--r--inc/lang/sk/draft.txt6
-rw-r--r--inc/lang/sk/edit.txt1
-rw-r--r--inc/lang/sk/editrev.txt1
-rw-r--r--inc/lang/sk/index.txt3
-rw-r--r--inc/lang/sk/install.html23
-rw-r--r--inc/lang/sk/lang.php313
-rw-r--r--inc/lang/sk/locked.txt3
-rw-r--r--inc/lang/sk/login.txt3
-rw-r--r--inc/lang/sk/mailtext.txt17
-rw-r--r--inc/lang/sk/newpage.txt3
-rw-r--r--inc/lang/sk/norev.txt3
-rw-r--r--inc/lang/sk/password.txt11
-rw-r--r--inc/lang/sk/preview.txt3
-rw-r--r--inc/lang/sk/pwconfirm.txt15
-rw-r--r--inc/lang/sk/read.txt2
-rw-r--r--inc/lang/sk/recent.txt3
-rw-r--r--inc/lang/sk/register.txt3
-rw-r--r--inc/lang/sk/registermail.txt14
-rw-r--r--inc/lang/sk/resendpwd.txt3
-rw-r--r--inc/lang/sk/revisions.txt3
-rw-r--r--inc/lang/sk/searchpage.txt5
-rw-r--r--inc/lang/sk/showrev.txt3
-rw-r--r--inc/lang/sk/stopwords.txt28
-rw-r--r--inc/lang/sk/subscr_digest.txt20
-rw-r--r--inc/lang/sk/subscr_form.txt3
-rw-r--r--inc/lang/sk/subscr_list.txt17
-rw-r--r--inc/lang/sk/subscr_single.txt23
-rw-r--r--inc/lang/sk/updateprofile.txt6
-rw-r--r--inc/lang/sk/uploadmail.txt14
-rw-r--r--inc/lang/sl/admin.txt3
-rw-r--r--inc/lang/sl/adminplugins.txt1
-rw-r--r--inc/lang/sl/backlinks.txt3
-rw-r--r--inc/lang/sl/conflict.txt5
-rw-r--r--inc/lang/sl/denied.txt3
-rw-r--r--inc/lang/sl/diff.txt3
-rw-r--r--inc/lang/sl/draft.txt5
-rw-r--r--inc/lang/sl/edit.txt1
-rw-r--r--inc/lang/sl/editrev.txt2
-rw-r--r--inc/lang/sl/index.txt4
-rw-r--r--inc/lang/sl/install.html20
-rw-r--r--inc/lang/sl/lang.php316
-rw-r--r--inc/lang/sl/locked.txt3
-rw-r--r--inc/lang/sl/login.txt3
-rw-r--r--inc/lang/sl/mailtext.txt15
-rw-r--r--inc/lang/sl/newpage.txt3
-rw-r--r--inc/lang/sl/norev.txt3
-rw-r--r--inc/lang/sl/password.txt9
-rw-r--r--inc/lang/sl/preview.txt3
-rw-r--r--inc/lang/sl/pwconfirm.txt11
-rw-r--r--inc/lang/sl/read.txt2
-rw-r--r--inc/lang/sl/recent.txt3
-rw-r--r--inc/lang/sl/register.txt3
-rw-r--r--inc/lang/sl/registermail.txt14
-rw-r--r--inc/lang/sl/resendpwd.txt3
-rw-r--r--inc/lang/sl/revisions.txt3
-rw-r--r--inc/lang/sl/searchpage.txt5
-rw-r--r--inc/lang/sl/showrev.txt2
-rw-r--r--inc/lang/sl/stopwords.txt18
-rw-r--r--inc/lang/sl/subscr_digest.txt19
-rw-r--r--inc/lang/sl/subscr_form.txt3
-rw-r--r--inc/lang/sl/subscr_list.txt16
-rw-r--r--inc/lang/sl/subscr_single.txt22
-rw-r--r--inc/lang/sl/updateprofile.txt3
-rw-r--r--inc/lang/sl/uploadmail.txt14
-rw-r--r--inc/lang/sq/admin.txt3
-rw-r--r--inc/lang/sq/adminplugins.txt1
-rw-r--r--inc/lang/sq/backlinks.txt3
-rw-r--r--inc/lang/sq/conflict.txt5
-rw-r--r--inc/lang/sq/denied.txt3
-rw-r--r--inc/lang/sq/diff.txt3
-rw-r--r--inc/lang/sq/draft.txt5
-rw-r--r--inc/lang/sq/edit.txt1
-rw-r--r--inc/lang/sq/editrev.txt2
-rw-r--r--inc/lang/sq/index.txt3
-rw-r--r--inc/lang/sq/install.html8
-rw-r--r--inc/lang/sq/lang.php242
-rw-r--r--inc/lang/sq/locked.txt3
-rw-r--r--inc/lang/sq/login.txt3
-rw-r--r--inc/lang/sq/mailtext.txt16
-rw-r--r--inc/lang/sq/newpage.txt3
-rw-r--r--inc/lang/sq/norev.txt3
-rw-r--r--inc/lang/sq/password.txt10
-rw-r--r--inc/lang/sq/preview.txt3
-rw-r--r--inc/lang/sq/pwconfirm.txt13
-rw-r--r--inc/lang/sq/read.txt1
-rw-r--r--inc/lang/sq/recent.txt3
-rw-r--r--inc/lang/sq/register.txt3
-rw-r--r--inc/lang/sq/registermail.txt14
-rw-r--r--inc/lang/sq/resendpwd.txt3
-rw-r--r--inc/lang/sq/revisions.txt3
-rw-r--r--inc/lang/sq/searchpage.txt5
-rw-r--r--inc/lang/sq/showrev.txt2
-rw-r--r--inc/lang/sq/stopwords.txt39
-rw-r--r--inc/lang/sq/subscr_digest.txt20
-rw-r--r--inc/lang/sq/subscr_form.txt3
-rw-r--r--inc/lang/sq/subscr_list.txt13
-rw-r--r--inc/lang/sq/subscr_single.txt23
-rw-r--r--inc/lang/sq/updateprofile.txt3
-rw-r--r--inc/lang/sq/uploadmail.txt14
-rw-r--r--inc/lang/sr/admin.txt4
-rw-r--r--inc/lang/sr/adminplugins.txt1
-rw-r--r--inc/lang/sr/backlinks.txt4
-rw-r--r--inc/lang/sr/conflict.txt6
-rw-r--r--inc/lang/sr/denied.txt4
-rw-r--r--inc/lang/sr/diff.txt4
-rw-r--r--inc/lang/sr/draft.txt5
-rw-r--r--inc/lang/sr/edit.txt2
-rw-r--r--inc/lang/sr/editrev.txt2
-rw-r--r--inc/lang/sr/index.txt4
-rw-r--r--inc/lang/sr/install.html12
-rw-r--r--inc/lang/sr/lang.php265
-rw-r--r--inc/lang/sr/locked.txt3
-rw-r--r--inc/lang/sr/login.txt4
-rw-r--r--inc/lang/sr/mailtext.txt17
-rw-r--r--inc/lang/sr/newpage.txt3
-rw-r--r--inc/lang/sr/norev.txt4
-rw-r--r--inc/lang/sr/password.txt10
-rw-r--r--inc/lang/sr/preview.txt4
-rw-r--r--inc/lang/sr/pwconfirm.txt13
-rw-r--r--inc/lang/sr/read.txt2
-rw-r--r--inc/lang/sr/recent.txt5
-rw-r--r--inc/lang/sr/register.txt4
-rw-r--r--inc/lang/sr/registermail.txt15
-rw-r--r--inc/lang/sr/resendpwd.txt3
-rw-r--r--inc/lang/sr/revisions.txt4
-rw-r--r--inc/lang/sr/searchpage.txt5
-rw-r--r--inc/lang/sr/showrev.txt2
-rw-r--r--inc/lang/sr/stopwords.txt12
-rw-r--r--inc/lang/sr/subscr_digest.txt20
-rw-r--r--inc/lang/sr/subscr_form.txt3
-rw-r--r--inc/lang/sr/subscr_list.txt17
-rw-r--r--inc/lang/sr/subscr_single.txt23
-rw-r--r--inc/lang/sr/updateprofile.txt3
-rw-r--r--inc/lang/sr/uploadmail.txt14
-rw-r--r--inc/lang/sv/admin.txt4
-rw-r--r--inc/lang/sv/adminplugins.txt2
-rw-r--r--inc/lang/sv/backlinks.txt3
-rw-r--r--inc/lang/sv/conflict.txt6
-rw-r--r--inc/lang/sv/denied.txt4
-rw-r--r--inc/lang/sv/diff.txt4
-rw-r--r--inc/lang/sv/draft.txt6
-rw-r--r--inc/lang/sv/edit.txt2
-rw-r--r--inc/lang/sv/editrev.txt2
-rw-r--r--inc/lang/sv/index.txt4
-rw-r--r--inc/lang/sv/install.html25
-rw-r--r--inc/lang/sv/lang.php267
-rw-r--r--inc/lang/sv/locked.txt3
-rw-r--r--inc/lang/sv/login.txt4
-rw-r--r--inc/lang/sv/mailtext.txt17
-rw-r--r--inc/lang/sv/newpage.txt3
-rw-r--r--inc/lang/sv/norev.txt4
-rw-r--r--inc/lang/sv/password.txt10
-rw-r--r--inc/lang/sv/preview.txt4
-rw-r--r--inc/lang/sv/pwconfirm.txt16
-rw-r--r--inc/lang/sv/read.txt2
-rw-r--r--inc/lang/sv/recent.txt5
-rw-r--r--inc/lang/sv/register.txt4
-rw-r--r--inc/lang/sv/registermail.txt14
-rw-r--r--inc/lang/sv/resendpwd.txt4
-rw-r--r--inc/lang/sv/revisions.txt4
-rw-r--r--inc/lang/sv/searchpage.txt5
-rw-r--r--inc/lang/sv/showrev.txt2
-rw-r--r--inc/lang/sv/stopwords.txt129
-rw-r--r--inc/lang/sv/updateprofile.txt5
-rw-r--r--inc/lang/sv/uploadmail.txt14
-rw-r--r--inc/lang/th/admin.txt3
-rw-r--r--inc/lang/th/adminplugins.txt1
-rw-r--r--inc/lang/th/backlinks.txt3
-rw-r--r--inc/lang/th/conflict.txt5
-rw-r--r--inc/lang/th/denied.txt3
-rw-r--r--inc/lang/th/diff.txt3
-rw-r--r--inc/lang/th/draft.txt5
-rw-r--r--inc/lang/th/edit.txt1
-rw-r--r--inc/lang/th/editrev.txt2
-rw-r--r--inc/lang/th/index.txt2
-rw-r--r--inc/lang/th/lang.php230
-rw-r--r--inc/lang/th/locked.txt3
-rw-r--r--inc/lang/th/login.txt4
-rw-r--r--inc/lang/th/mailtext.txt17
-rw-r--r--inc/lang/th/newpage.txt3
-rw-r--r--inc/lang/th/norev.txt3
-rw-r--r--inc/lang/th/password.txt10
-rw-r--r--inc/lang/th/preview.txt3
-rw-r--r--inc/lang/th/pwconfirm.txt14
-rw-r--r--inc/lang/th/read.txt1
-rw-r--r--inc/lang/th/recent.txt3
-rw-r--r--inc/lang/th/register.txt3
-rw-r--r--inc/lang/th/registermail.txt14
-rw-r--r--inc/lang/th/resendpwd.txt3
-rw-r--r--inc/lang/th/revisions.txt3
-rw-r--r--inc/lang/th/searchpage.txt4
-rw-r--r--inc/lang/th/showrev.txt2
-rw-r--r--inc/lang/th/updateprofile.txt3
-rw-r--r--inc/lang/th/uploadmail.txt14
-rw-r--r--inc/lang/tr/admin.txt3
-rw-r--r--inc/lang/tr/backlinks.txt4
-rw-r--r--inc/lang/tr/conflict.txt6
-rw-r--r--inc/lang/tr/denied.txt4
-rw-r--r--inc/lang/tr/diff.txt4
-rw-r--r--inc/lang/tr/draft.txt5
-rw-r--r--inc/lang/tr/edit.txt2
-rw-r--r--inc/lang/tr/editrev.txt2
-rw-r--r--inc/lang/tr/index.txt4
-rw-r--r--inc/lang/tr/install.html8
-rw-r--r--inc/lang/tr/lang.php237
-rw-r--r--inc/lang/tr/locked.txt4
-rw-r--r--inc/lang/tr/login.txt4
-rw-r--r--inc/lang/tr/mailtext.txt16
-rw-r--r--inc/lang/tr/newpage.txt4
-rw-r--r--inc/lang/tr/norev.txt4
-rw-r--r--inc/lang/tr/password.txt10
-rw-r--r--inc/lang/tr/preview.txt4
-rw-r--r--inc/lang/tr/pwconfirm.txt13
-rw-r--r--inc/lang/tr/read.txt2
-rw-r--r--inc/lang/tr/recent.txt5
-rw-r--r--inc/lang/tr/register.txt4
-rw-r--r--inc/lang/tr/registermail.txt13
-rw-r--r--inc/lang/tr/resendpwd.txt3
-rw-r--r--inc/lang/tr/revisions.txt4
-rw-r--r--inc/lang/tr/searchpage.txt5
-rw-r--r--inc/lang/tr/showrev.txt2
-rw-r--r--inc/lang/tr/stopwords.txt29
-rw-r--r--inc/lang/tr/updateprofile.txt3
-rw-r--r--inc/lang/tr/uploadmail.txt13
-rw-r--r--inc/lang/uk/admin.txt4
-rw-r--r--inc/lang/uk/adminplugins.txt1
-rw-r--r--inc/lang/uk/backlinks.txt3
-rw-r--r--inc/lang/uk/conflict.txt8
-rw-r--r--inc/lang/uk/denied.txt4
-rw-r--r--inc/lang/uk/diff.txt4
-rw-r--r--inc/lang/uk/draft.txt6
-rw-r--r--inc/lang/uk/edit.txt1
-rw-r--r--inc/lang/uk/editrev.txt2
-rw-r--r--inc/lang/uk/index.txt4
-rw-r--r--inc/lang/uk/install.html21
-rw-r--r--inc/lang/uk/lang.php274
-rw-r--r--inc/lang/uk/locked.txt3
-rw-r--r--inc/lang/uk/login.txt4
-rw-r--r--inc/lang/uk/mailtext.txt17
-rw-r--r--inc/lang/uk/newpage.txt4
-rw-r--r--inc/lang/uk/norev.txt4
-rw-r--r--inc/lang/uk/password.txt10
-rw-r--r--inc/lang/uk/preview.txt4
-rw-r--r--inc/lang/uk/pwconfirm.txt13
-rw-r--r--inc/lang/uk/read.txt2
-rw-r--r--inc/lang/uk/recent.txt4
-rw-r--r--inc/lang/uk/register.txt4
-rw-r--r--inc/lang/uk/registermail.txt13
-rw-r--r--inc/lang/uk/resendpwd.txt3
-rw-r--r--inc/lang/uk/revisions.txt4
-rw-r--r--inc/lang/uk/searchpage.txt5
-rw-r--r--inc/lang/uk/showrev.txt2
-rw-r--r--inc/lang/uk/stopwords.txt3
-rw-r--r--inc/lang/uk/subscr_digest.txt17
-rw-r--r--inc/lang/uk/subscr_form.txt3
-rw-r--r--inc/lang/uk/subscr_list.txt14
-rw-r--r--inc/lang/uk/subscr_single.txt20
-rw-r--r--inc/lang/uk/updateprofile.txt5
-rw-r--r--inc/lang/uk/uploadmail.txt14
-rw-r--r--inc/lang/vi/admin.txt3
-rw-r--r--inc/lang/vi/backlinks.txt3
-rw-r--r--inc/lang/vi/conflict.txt5
-rw-r--r--inc/lang/vi/denied.txt3
-rw-r--r--inc/lang/vi/diff.txt4
-rw-r--r--inc/lang/vi/edit.txt1
-rw-r--r--inc/lang/vi/editrev.txt2
-rw-r--r--inc/lang/vi/index.txt3
-rw-r--r--inc/lang/vi/lang.php106
-rw-r--r--inc/lang/vi/locked.txt3
-rw-r--r--inc/lang/vi/login.txt3
-rw-r--r--inc/lang/vi/mailtext.txt16
-rw-r--r--inc/lang/vi/newpage.txt3
-rw-r--r--inc/lang/vi/norev.txt3
-rw-r--r--inc/lang/vi/password.txt9
-rw-r--r--inc/lang/vi/preview.txt3
-rw-r--r--inc/lang/vi/read.txt1
-rw-r--r--inc/lang/vi/recent.txt3
-rw-r--r--inc/lang/vi/register.txt3
-rw-r--r--inc/lang/vi/revisions.txt3
-rw-r--r--inc/lang/vi/searchpage.txt5
-rw-r--r--inc/lang/vi/showrev.txt2
-rw-r--r--inc/lang/zh-tw/admin.txt4
-rw-r--r--inc/lang/zh-tw/adminplugins.txt1
-rw-r--r--inc/lang/zh-tw/backlinks.txt4
-rw-r--r--inc/lang/zh-tw/conflict.txt5
-rw-r--r--inc/lang/zh-tw/denied.txt4
-rw-r--r--inc/lang/zh-tw/diff.txt4
-rw-r--r--inc/lang/zh-tw/draft.txt5
-rw-r--r--inc/lang/zh-tw/edit.txt1
-rw-r--r--inc/lang/zh-tw/editrev.txt2
-rw-r--r--inc/lang/zh-tw/index.txt3
-rw-r--r--inc/lang/zh-tw/install.html8
-rw-r--r--inc/lang/zh-tw/lang.php317
-rw-r--r--inc/lang/zh-tw/locked.txt3
-rw-r--r--inc/lang/zh-tw/login.txt5
-rw-r--r--inc/lang/zh-tw/mailtext.txt17
-rw-r--r--inc/lang/zh-tw/newpage.txt3
-rw-r--r--inc/lang/zh-tw/norev.txt3
-rw-r--r--inc/lang/zh-tw/password.txt10
-rw-r--r--inc/lang/zh-tw/preview.txt4
-rw-r--r--inc/lang/zh-tw/pwconfirm.txt13
-rw-r--r--inc/lang/zh-tw/read.txt1
-rw-r--r--inc/lang/zh-tw/recent.txt5
-rw-r--r--inc/lang/zh-tw/register.txt4
-rw-r--r--inc/lang/zh-tw/registermail.txt14
-rw-r--r--inc/lang/zh-tw/resendpwd.txt3
-rw-r--r--inc/lang/zh-tw/revisions.txt3
-rw-r--r--inc/lang/zh-tw/searchpage.txt5
-rw-r--r--inc/lang/zh-tw/showrev.txt2
-rw-r--r--inc/lang/zh-tw/stopwords.txt31
-rw-r--r--inc/lang/zh-tw/subscr_digest.txt19
-rw-r--r--inc/lang/zh-tw/subscr_form.txt3
-rw-r--r--inc/lang/zh-tw/subscr_list.txt16
-rw-r--r--inc/lang/zh-tw/subscr_single.txt22
-rw-r--r--inc/lang/zh-tw/updateprofile.txt3
-rw-r--r--inc/lang/zh-tw/uploadmail.txt14
-rw-r--r--inc/lang/zh/admin.txt3
-rw-r--r--inc/lang/zh/adminplugins.txt1
-rw-r--r--inc/lang/zh/backlinks.txt3
-rw-r--r--inc/lang/zh/conflict.txt5
-rw-r--r--inc/lang/zh/denied.txt3
-rw-r--r--inc/lang/zh/diff.txt3
-rw-r--r--inc/lang/zh/draft.txt7
-rw-r--r--inc/lang/zh/edit.txt1
-rw-r--r--inc/lang/zh/editrev.txt2
-rw-r--r--inc/lang/zh/index.txt3
-rw-r--r--inc/lang/zh/install.html8
-rw-r--r--inc/lang/zh/lang.php326
-rw-r--r--inc/lang/zh/locked.txt3
-rw-r--r--inc/lang/zh/login.txt3
-rw-r--r--inc/lang/zh/mailtext.txt17
-rw-r--r--inc/lang/zh/newpage.txt3
-rw-r--r--inc/lang/zh/norev.txt3
-rw-r--r--inc/lang/zh/password.txt10
-rw-r--r--inc/lang/zh/preview.txt3
-rw-r--r--inc/lang/zh/pwconfirm.txt15
-rw-r--r--inc/lang/zh/read.txt2
-rw-r--r--inc/lang/zh/recent.txt5
-rw-r--r--inc/lang/zh/register.txt3
-rw-r--r--inc/lang/zh/registermail.txt16
-rw-r--r--inc/lang/zh/resendpwd.txt5
-rw-r--r--inc/lang/zh/revisions.txt3
-rw-r--r--inc/lang/zh/searchpage.txt5
-rw-r--r--inc/lang/zh/showrev.txt2
-rw-r--r--inc/lang/zh/stopwords.txt29
-rw-r--r--inc/lang/zh/subscr_digest.txt19
-rw-r--r--inc/lang/zh/subscr_form.txt3
-rw-r--r--inc/lang/zh/subscr_list.txt16
-rw-r--r--inc/lang/zh/subscr_single.txt22
-rw-r--r--inc/lang/zh/updateprofile.txt5
-rw-r--r--inc/lang/zh/uploadmail.txt20
-rw-r--r--inc/load.php102
-rw-r--r--inc/mail.php318
-rw-r--r--inc/media.php2019
-rw-r--r--inc/pageutils.php622
-rw-r--r--inc/parser/code.php58
-rw-r--r--inc/parser/handler.php1623
-rw-r--r--inc/parser/lexer.php600
-rw-r--r--inc/parser/metadata.php485
-rw-r--r--inc/parser/parser.php959
-rw-r--r--inc/parser/renderer.php322
-rw-r--r--inc/parser/xhtml.php1232
-rw-r--r--inc/parser/xhtmlsummary.php90
-rw-r--r--inc/parserutils.php777
-rw-r--r--inc/plugin.php259
-rw-r--r--inc/plugincontroller.class.php286
-rw-r--r--inc/pluginutils.php42
-rw-r--r--inc/search.php610
-rw-r--r--inc/subscription.php394
-rw-r--r--inc/template.php1613
-rw-r--r--inc/toolbar.php255
-rw-r--r--inc/utf8.php1624
-rw-r--r--index.php8
-rw-r--r--install.php548
-rw-r--r--lib/exe/ajax.php435
-rw-r--r--lib/exe/css.php343
-rw-r--r--lib/exe/detail.php48
-rw-r--r--lib/exe/fetch.php205
-rw-r--r--lib/exe/index.html12
-rw-r--r--lib/exe/indexer.php271
-rw-r--r--lib/exe/js.php358
-rw-r--r--lib/exe/mediamanager.php122
-rw-r--r--lib/exe/opensearch.php38
-rw-r--r--lib/exe/xmlrpc.php888
-rw-r--r--lib/images/admin/README2
-rw-r--r--lib/images/admin/acl.pngbin0 -> 1074 bytes
-rw-r--r--lib/images/admin/config.pngbin0 -> 1496 bytes
-rw-r--r--lib/images/admin/plugin.pngbin0 -> 1127 bytes
-rw-r--r--lib/images/admin/popularity.pngbin0 -> 1189 bytes
-rw-r--r--lib/images/admin/revert.pngbin0 -> 1295 bytes
-rw-r--r--lib/images/admin/usermanager.pngbin0 -> 1467 bytes
-rw-r--r--lib/images/arrow_down.gifbin0 -> 273 bytes
-rw-r--r--lib/images/arrow_up.gifbin0 -> 274 bytes
-rw-r--r--lib/images/at.gifbin0 -> 57 bytes
-rw-r--r--lib/images/blank.gifbin0 -> 42 bytes
-rw-r--r--lib/images/close.pngbin0 -> 137 bytes
-rw-r--r--lib/images/del.pngbin0 -> 355 bytes
-rw-r--r--lib/images/diff.pngbin0 -> 206 bytes
-rw-r--r--lib/images/edit.gifbin0 -> 142 bytes
-rw-r--r--lib/images/error.pngbin0 -> 648 bytes
-rw-r--r--lib/images/fileicons/7z.pngbin0 -> 651 bytes
-rw-r--r--lib/images/fileicons/audio.pngbin0 -> 727 bytes
-rw-r--r--lib/images/fileicons/bz2.pngbin0 -> 641 bytes
-rw-r--r--lib/images/fileicons/c.pngbin0 -> 759 bytes
-rw-r--r--lib/images/fileicons/conf.pngbin0 -> 664 bytes
-rw-r--r--lib/images/fileicons/cpp.pngbin0 -> 822 bytes
-rw-r--r--lib/images/fileicons/cs.pngbin0 -> 771 bytes
-rw-r--r--lib/images/fileicons/css.pngbin0 -> 843 bytes
-rw-r--r--lib/images/fileicons/csv.pngbin0 -> 400 bytes
-rw-r--r--lib/images/fileicons/deb.pngbin0 -> 646 bytes
-rw-r--r--lib/images/fileicons/doc.pngbin0 -> 583 bytes
-rw-r--r--lib/images/fileicons/docx.pngbin0 -> 583 bytes
-rw-r--r--lib/images/fileicons/file.pngbin0 -> 581 bytes
-rw-r--r--lib/images/fileicons/gif.pngbin0 -> 907 bytes
-rw-r--r--lib/images/fileicons/gz.pngbin0 -> 643 bytes
-rw-r--r--lib/images/fileicons/htm.pngbin0 -> 695 bytes
-rw-r--r--lib/images/fileicons/html.pngbin0 -> 695 bytes
-rw-r--r--lib/images/fileicons/index.php50
-rw-r--r--lib/images/fileicons/java.pngbin0 -> 739 bytes
-rw-r--r--lib/images/fileicons/jpeg.pngbin0 -> 907 bytes
-rw-r--r--lib/images/fileicons/jpg.pngbin0 -> 907 bytes
-rw-r--r--lib/images/fileicons/js.pngbin0 -> 809 bytes
-rw-r--r--lib/images/fileicons/lua.pngbin0 -> 440 bytes
-rw-r--r--lib/images/fileicons/mp3.pngbin0 -> 831 bytes
-rw-r--r--lib/images/fileicons/odc.pngbin0 -> 682 bytes
-rw-r--r--lib/images/fileicons/odf.pngbin0 -> 746 bytes
-rw-r--r--lib/images/fileicons/odg.pngbin0 -> 735 bytes
-rw-r--r--lib/images/fileicons/odi.pngbin0 -> 735 bytes
-rw-r--r--lib/images/fileicons/odp.pngbin0 -> 687 bytes
-rw-r--r--lib/images/fileicons/ods.pngbin0 -> 682 bytes
-rw-r--r--lib/images/fileicons/odt.pngbin0 -> 522 bytes
-rw-r--r--lib/images/fileicons/ogg.pngbin0 -> 807 bytes
-rw-r--r--lib/images/fileicons/pdf.pngbin0 -> 592 bytes
-rw-r--r--lib/images/fileicons/php.pngbin0 -> 749 bytes
-rw-r--r--lib/images/fileicons/pl.pngbin0 -> 685 bytes
-rw-r--r--lib/images/fileicons/png.pngbin0 -> 907 bytes
-rw-r--r--lib/images/fileicons/ppt.pngbin0 -> 697 bytes
-rw-r--r--lib/images/fileicons/pptx.pngbin0 -> 697 bytes
-rw-r--r--lib/images/fileicons/ps.pngbin0 -> 470 bytes
-rw-r--r--lib/images/fileicons/py.pngbin0 -> 683 bytes
-rw-r--r--lib/images/fileicons/rar.pngbin0 -> 557 bytes
-rw-r--r--lib/images/fileicons/rb.pngbin0 -> 802 bytes
-rw-r--r--lib/images/fileicons/rpm.pngbin0 -> 555 bytes
-rw-r--r--lib/images/fileicons/rtf.pngbin0 -> 402 bytes
-rw-r--r--lib/images/fileicons/sql.pngbin0 -> 813 bytes
-rw-r--r--lib/images/fileicons/swf.pngbin0 -> 732 bytes
-rw-r--r--lib/images/fileicons/sxc.pngbin0 -> 682 bytes
-rw-r--r--lib/images/fileicons/sxd.pngbin0 -> 735 bytes
-rw-r--r--lib/images/fileicons/sxi.pngbin0 -> 687 bytes
-rw-r--r--lib/images/fileicons/sxw.pngbin0 -> 522 bytes
-rw-r--r--lib/images/fileicons/tar.pngbin0 -> 663 bytes
-rw-r--r--lib/images/fileicons/tgz.pngbin0 -> 643 bytes
-rw-r--r--lib/images/fileicons/txt.pngbin0 -> 466 bytes
-rw-r--r--lib/images/fileicons/wav.pngbin0 -> 820 bytes
-rw-r--r--lib/images/fileicons/xls.pngbin0 -> 670 bytes
-rw-r--r--lib/images/fileicons/xlsx.pngbin0 -> 670 bytes
-rw-r--r--lib/images/fileicons/xml.pngbin0 -> 409 bytes
-rw-r--r--lib/images/fileicons/zip.pngbin0 -> 800 bytes
-rw-r--r--lib/images/history.pngbin0 -> 149 bytes
-rw-r--r--lib/images/icon-file.pngbin0 -> 3363 bytes
-rw-r--r--lib/images/icon-list.pngbin0 -> 3342 bytes
-rw-r--r--lib/images/icon-sort.pngbin0 -> 316 bytes
-rw-r--r--lib/images/icon-thumb.pngbin0 -> 969 bytes
-rw-r--r--lib/images/index.html12
-rw-r--r--lib/images/info.pngbin0 -> 725 bytes
-rw-r--r--lib/images/interwiki.pngbin0 -> 443 bytes
-rw-r--r--lib/images/interwiki/amazon.de.gifbin0 -> 110 bytes
-rw-r--r--lib/images/interwiki/amazon.gifbin0 -> 110 bytes
-rw-r--r--lib/images/interwiki/amazon.uk.gifbin0 -> 110 bytes
-rw-r--r--lib/images/interwiki/callto.gifbin0 -> 178 bytes
-rw-r--r--lib/images/interwiki/coral.gifbin0 -> 85 bytes
-rw-r--r--lib/images/interwiki/doku.gifbin0 -> 188 bytes
-rw-r--r--lib/images/interwiki/dokubug.gifbin0 -> 166 bytes
-rw-r--r--lib/images/interwiki/google.gifbin0 -> 170 bytes
-rw-r--r--lib/images/interwiki/meatball.gifbin0 -> 339 bytes
-rw-r--r--lib/images/interwiki/paypal.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/phpfn.gifbin0 -> 164 bytes
-rw-r--r--lib/images/interwiki/sb.gifbin0 -> 195 bytes
-rw-r--r--lib/images/interwiki/skype.pngbin0 -> 675 bytes
-rw-r--r--lib/images/interwiki/wiki.gifbin0 -> 131 bytes
-rw-r--r--lib/images/interwiki/wp.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpde.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpes.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpfr.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpjp.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wpmeta.gifbin0 -> 171 bytes
-rw-r--r--lib/images/interwiki/wppl.gifbin0 -> 171 bytes
-rw-r--r--lib/images/larger.gifbin0 -> 87 bytes
-rw-r--r--lib/images/license/badge/cc-by-nc-nd.pngbin0 -> 1475 bytes
-rw-r--r--lib/images/license/badge/cc-by-nc-sa.pngbin0 -> 1587 bytes
-rw-r--r--lib/images/license/badge/cc-by-nc.pngbin0 -> 1421 bytes
-rw-r--r--lib/images/license/badge/cc-by-nd.pngbin0 -> 1283 bytes
-rw-r--r--lib/images/license/badge/cc-by-sa.pngbin0 -> 1421 bytes
-rw-r--r--lib/images/license/badge/cc-by.pngbin0 -> 1204 bytes
-rw-r--r--lib/images/license/badge/cc-zero.pngbin0 -> 1202 bytes
-rw-r--r--lib/images/license/badge/cc.pngbin0 -> 898 bytes
-rw-r--r--lib/images/license/badge/gnufdl.pngbin0 -> 1667 bytes
-rw-r--r--lib/images/license/badge/publicdomain.pngbin0 -> 1345 bytes
-rw-r--r--lib/images/license/button/cc-by-nc-nd.pngbin0 -> 396 bytes
-rw-r--r--lib/images/license/button/cc-by-nc-sa.pngbin0 -> 403 bytes
-rw-r--r--lib/images/license/button/cc-by-nc.pngbin0 -> 388 bytes
-rw-r--r--lib/images/license/button/cc-by-nd.pngbin0 -> 386 bytes
-rw-r--r--lib/images/license/button/cc-by-sa.pngbin0 -> 386 bytes
-rw-r--r--lib/images/license/button/cc-by.pngbin0 -> 369 bytes
-rw-r--r--lib/images/license/button/cc-zero.pngbin0 -> 386 bytes
-rw-r--r--lib/images/license/button/cc.pngbin0 -> 399 bytes
-rw-r--r--lib/images/license/button/gnufdl.pngbin0 -> 509 bytes
-rw-r--r--lib/images/license/button/publicdomain.pngbin0 -> 368 bytes
-rw-r--r--lib/images/list-minus.gifbin0 -> 64 bytes
-rw-r--r--lib/images/list-plus.gifbin0 -> 67 bytes
-rw-r--r--lib/images/loading.gifbin0 -> 337 bytes
-rw-r--r--lib/images/magnifier.pngbin0 -> 569 bytes
-rw-r--r--lib/images/media_align_center.pngbin0 -> 250 bytes
-rw-r--r--lib/images/media_align_left.pngbin0 -> 251 bytes
-rw-r--r--lib/images/media_align_noalign.pngbin0 -> 220 bytes
-rw-r--r--lib/images/media_align_right.pngbin0 -> 252 bytes
-rw-r--r--lib/images/media_link_direct.pngbin0 -> 720 bytes
-rw-r--r--lib/images/media_link_displaylnk.pngbin0 -> 306 bytes
-rw-r--r--lib/images/media_link_lnk.pngbin0 -> 580 bytes
-rw-r--r--lib/images/media_link_nolnk.pngbin0 -> 464 bytes
-rw-r--r--lib/images/media_size_large.pngbin0 -> 102 bytes
-rw-r--r--lib/images/media_size_medium.pngbin0 -> 231 bytes
-rw-r--r--lib/images/media_size_original.pngbin0 -> 212 bytes
-rw-r--r--lib/images/media_size_small.pngbin0 -> 210 bytes
-rw-r--r--lib/images/mediamanager.pngbin0 -> 507 bytes
-rw-r--r--lib/images/minus.gifbin0 -> 85 bytes
-rw-r--r--lib/images/notify.pngbin0 -> 736 bytes
-rw-r--r--lib/images/ns.pngbin0 -> 800 bytes
-rw-r--r--lib/images/page.pngbin0 -> 582 bytes
-rw-r--r--lib/images/pencil.pngbin0 -> 391 bytes
-rw-r--r--lib/images/plus.gifbin0 -> 88 bytes
-rw-r--r--lib/images/smaller.gifbin0 -> 86 bytes
-rw-r--r--lib/images/smileys/delete.gifbin0 -> 448 bytes
-rw-r--r--lib/images/smileys/facepalm.gifbin0 -> 185 bytes
-rw-r--r--lib/images/smileys/fixme.gifbin0 -> 450 bytes
-rw-r--r--lib/images/smileys/icon_arrow.gifbin0 -> 170 bytes
-rw-r--r--lib/images/smileys/icon_biggrin.gifbin0 -> 172 bytes
-rw-r--r--lib/images/smileys/icon_confused.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_cool.gifbin0 -> 172 bytes
-rw-r--r--lib/images/smileys/icon_cry.gifbin0 -> 424 bytes
-rw-r--r--lib/images/smileys/icon_doubt.gifbin0 -> 178 bytes
-rw-r--r--lib/images/smileys/icon_doubt2.gifbin0 -> 180 bytes
-rw-r--r--lib/images/smileys/icon_eek.gifbin0 -> 170 bytes
-rw-r--r--lib/images/smileys/icon_evil.gifbin0 -> 188 bytes
-rw-r--r--lib/images/smileys/icon_exclaim.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_frown.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_fun.gifbin0 -> 179 bytes
-rw-r--r--lib/images/smileys/icon_idea.gifbin0 -> 176 bytes
-rw-r--r--lib/images/smileys/icon_kaddi.gifbin0 -> 179 bytes
-rw-r--r--lib/images/smileys/icon_lol.gifbin0 -> 344 bytes
-rw-r--r--lib/images/smileys/icon_mrgreen.gifbin0 -> 168 bytes
-rw-r--r--lib/images/smileys/icon_neutral.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_question.gifbin0 -> 182 bytes
-rw-r--r--lib/images/smileys/icon_razz.gifbin0 -> 176 bytes
-rw-r--r--lib/images/smileys/icon_redface.gifbin0 -> 669 bytes
-rw-r--r--lib/images/smileys/icon_rolleyes.gifbin0 -> 471 bytes
-rw-r--r--lib/images/smileys/icon_sad.gifbin0 -> 171 bytes
-rw-r--r--lib/images/smileys/icon_silenced.gifbin0 -> 177 bytes
-rw-r--r--lib/images/smileys/icon_smile.gifbin0 -> 174 bytes
-rw-r--r--lib/images/smileys/icon_smile2.gifbin0 -> 174 bytes
-rw-r--r--lib/images/smileys/icon_surprised.gifbin0 -> 174 bytes
-rw-r--r--lib/images/smileys/icon_twisted.gifbin0 -> 180 bytes
-rw-r--r--lib/images/smileys/icon_wink.gifbin0 -> 170 bytes
-rw-r--r--lib/images/success.pngbin0 -> 728 bytes
-rw-r--r--lib/images/throbber.gifbin0 -> 746 bytes
-rw-r--r--lib/images/toolbar/bold.pngbin0 -> 251 bytes
-rw-r--r--lib/images/toolbar/chars.pngbin0 -> 496 bytes
-rw-r--r--lib/images/toolbar/h.pngbin0 -> 258 bytes
-rw-r--r--lib/images/toolbar/h1.pngbin0 -> 290 bytes
-rw-r--r--lib/images/toolbar/h2.pngbin0 -> 328 bytes
-rw-r--r--lib/images/toolbar/h3.pngbin0 -> 322 bytes
-rw-r--r--lib/images/toolbar/h4.pngbin0 -> 310 bytes
-rw-r--r--lib/images/toolbar/h5.pngbin0 -> 325 bytes
-rw-r--r--lib/images/toolbar/hequal.pngbin0 -> 311 bytes
-rw-r--r--lib/images/toolbar/hminus.pngbin0 -> 409 bytes
-rw-r--r--lib/images/toolbar/hplus.pngbin0 -> 396 bytes
-rw-r--r--lib/images/toolbar/hr.pngbin0 -> 254 bytes
-rw-r--r--lib/images/toolbar/image.pngbin0 -> 554 bytes
-rw-r--r--lib/images/toolbar/italic.pngbin0 -> 241 bytes
-rw-r--r--lib/images/toolbar/link.pngbin0 -> 405 bytes
-rw-r--r--lib/images/toolbar/linkextern.pngbin0 -> 904 bytes
-rw-r--r--lib/images/toolbar/mono.pngbin0 -> 296 bytes
-rw-r--r--lib/images/toolbar/ol.pngbin0 -> 304 bytes
-rw-r--r--lib/images/toolbar/sig.pngbin0 -> 471 bytes
-rw-r--r--lib/images/toolbar/smiley.pngbin0 -> 684 bytes
-rw-r--r--lib/images/toolbar/strike.pngbin0 -> 318 bytes
-rw-r--r--lib/images/toolbar/ul.pngbin0 -> 291 bytes
-rw-r--r--lib/images/toolbar/underline.pngbin0 -> 317 bytes
-rw-r--r--lib/images/trash.pngbin0 -> 423 bytes
-rw-r--r--lib/images/up.pngbin0 -> 248 bytes
-rw-r--r--lib/images/wrap.gifbin0 -> 86 bytes
-rw-r--r--lib/index.html12
-rw-r--r--lib/plugins/acl/admin.php824
-rw-r--r--lib/plugins/acl/ajax.php53
-rw-r--r--lib/plugins/acl/lang/af/lang.php10
-rw-r--r--lib/plugins/acl/lang/ar/help.txt11
-rw-r--r--lib/plugins/acl/lang/ar/lang.php38
-rw-r--r--lib/plugins/acl/lang/bg/help.txt11
-rw-r--r--lib/plugins/acl/lang/bg/lang.php37
-rw-r--r--lib/plugins/acl/lang/ca-valencia/help.txt15
-rw-r--r--lib/plugins/acl/lang/ca-valencia/lang.php37
-rw-r--r--lib/plugins/acl/lang/ca/help.txt11
-rw-r--r--lib/plugins/acl/lang/ca/lang.php38
-rw-r--r--lib/plugins/acl/lang/cs/help.txt11
-rw-r--r--lib/plugins/acl/lang/cs/lang.php41
-rw-r--r--lib/plugins/acl/lang/da/help.txt11
-rw-r--r--lib/plugins/acl/lang/da/lang.php44
-rw-r--r--lib/plugins/acl/lang/de-informal/help.txt11
-rw-r--r--lib/plugins/acl/lang/de-informal/lang.php39
-rw-r--r--lib/plugins/acl/lang/de/help.txt11
-rw-r--r--lib/plugins/acl/lang/de/lang.php52
-rw-r--r--lib/plugins/acl/lang/el/help.txt10
-rw-r--r--lib/plugins/acl/lang/el/lang.php45
-rw-r--r--lib/plugins/acl/lang/en/help.txt12
-rw-r--r--lib/plugins/acl/lang/en/lang.php46
-rw-r--r--lib/plugins/acl/lang/eo/help.txt11
-rw-r--r--lib/plugins/acl/lang/eo/lang.php42
-rw-r--r--lib/plugins/acl/lang/es/help.txt11
-rw-r--r--lib/plugins/acl/lang/es/lang.php53
-rw-r--r--lib/plugins/acl/lang/et/lang.php28
-rw-r--r--lib/plugins/acl/lang/eu/help.txt11
-rw-r--r--lib/plugins/acl/lang/eu/lang.php34
-rw-r--r--lib/plugins/acl/lang/fa/help.txt11
-rw-r--r--lib/plugins/acl/lang/fa/lang.php38
-rw-r--r--lib/plugins/acl/lang/fi/help.txt11
-rw-r--r--lib/plugins/acl/lang/fi/lang.php37
-rw-r--r--lib/plugins/acl/lang/fr/help.txt9
-rw-r--r--lib/plugins/acl/lang/fr/lang.php53
-rw-r--r--lib/plugins/acl/lang/gl/help.txt11
-rw-r--r--lib/plugins/acl/lang/gl/lang.php35
-rw-r--r--lib/plugins/acl/lang/he/help.txt11
-rw-r--r--lib/plugins/acl/lang/he/lang.php37
-rw-r--r--lib/plugins/acl/lang/hi/lang.php7
-rw-r--r--lib/plugins/acl/lang/hr/help.txt11
-rw-r--r--lib/plugins/acl/lang/hr/lang.php36
-rw-r--r--lib/plugins/acl/lang/hu/help.txt12
-rw-r--r--lib/plugins/acl/lang/hu/lang.php39
-rw-r--r--lib/plugins/acl/lang/ia/help.txt11
-rw-r--r--lib/plugins/acl/lang/ia/lang.php35
-rw-r--r--lib/plugins/acl/lang/id-ni/lang.php7
-rw-r--r--lib/plugins/acl/lang/id/lang.php21
-rw-r--r--lib/plugins/acl/lang/is/lang.php15
-rw-r--r--lib/plugins/acl/lang/it/help.txt11
-rw-r--r--lib/plugins/acl/lang/it/lang.php44
-rw-r--r--lib/plugins/acl/lang/ja/help.txt11
-rw-r--r--lib/plugins/acl/lang/ja/lang.php39
-rw-r--r--lib/plugins/acl/lang/kk/lang.php6
-rw-r--r--lib/plugins/acl/lang/ko/help.txt11
-rw-r--r--lib/plugins/acl/lang/ko/lang.php42
-rw-r--r--lib/plugins/acl/lang/la/help.txt11
-rw-r--r--lib/plugins/acl/lang/la/lang.php34
-rw-r--r--lib/plugins/acl/lang/lb/help.txt11
-rw-r--r--lib/plugins/acl/lang/lb/lang.php6
-rw-r--r--lib/plugins/acl/lang/lt/lang.php22
-rw-r--r--lib/plugins/acl/lang/lv/help.txt11
-rw-r--r--lib/plugins/acl/lang/lv/lang.php35
-rw-r--r--lib/plugins/acl/lang/mk/lang.php22
-rw-r--r--lib/plugins/acl/lang/mr/help.txt12
-rw-r--r--lib/plugins/acl/lang/mr/lang.php37
-rw-r--r--lib/plugins/acl/lang/ms/lang.php6
-rw-r--r--lib/plugins/acl/lang/ne/lang.php27
-rw-r--r--lib/plugins/acl/lang/nl/help.txt11
-rw-r--r--lib/plugins/acl/lang/nl/lang.php49
-rw-r--r--lib/plugins/acl/lang/no/help.txt11
-rw-r--r--lib/plugins/acl/lang/no/lang.php49
-rw-r--r--lib/plugins/acl/lang/pl/help.txt11
-rw-r--r--lib/plugins/acl/lang/pl/lang.php44
-rw-r--r--lib/plugins/acl/lang/pt-br/help.txt11
-rw-r--r--lib/plugins/acl/lang/pt-br/lang.php50
-rw-r--r--lib/plugins/acl/lang/pt/help.txt9
-rw-r--r--lib/plugins/acl/lang/pt/lang.php40
-rw-r--r--lib/plugins/acl/lang/ro/help.txt11
-rw-r--r--lib/plugins/acl/lang/ro/lang.php41
-rw-r--r--lib/plugins/acl/lang/ru/help.txt7
-rw-r--r--lib/plugins/acl/lang/ru/lang.php46
-rw-r--r--lib/plugins/acl/lang/sk/help.txt11
-rw-r--r--lib/plugins/acl/lang/sk/lang.php38
-rw-r--r--lib/plugins/acl/lang/sl/help.txt11
-rw-r--r--lib/plugins/acl/lang/sl/lang.php37
-rw-r--r--lib/plugins/acl/lang/sq/help.txt11
-rw-r--r--lib/plugins/acl/lang/sq/lang.php34
-rw-r--r--lib/plugins/acl/lang/sr/help.txt11
-rw-r--r--lib/plugins/acl/lang/sr/lang.php38
-rw-r--r--lib/plugins/acl/lang/sv/help.txt8
-rw-r--r--lib/plugins/acl/lang/sv/lang.php47
-rw-r--r--lib/plugins/acl/lang/th/help.txt11
-rw-r--r--lib/plugins/acl/lang/th/lang.php27
-rw-r--r--lib/plugins/acl/lang/tr/help.txt11
-rw-r--r--lib/plugins/acl/lang/tr/lang.php39
-rw-r--r--lib/plugins/acl/lang/uk/help.txt11
-rw-r--r--lib/plugins/acl/lang/uk/lang.php40
-rw-r--r--lib/plugins/acl/lang/vi/lang.php21
-rw-r--r--lib/plugins/acl/lang/zh-tw/help.txt12
-rw-r--r--lib/plugins/acl/lang/zh-tw/lang.php42
-rw-r--r--lib/plugins/acl/lang/zh/help.txt11
-rw-r--r--lib/plugins/acl/lang/zh/lang.php46
-rw-r--r--lib/plugins/acl/pix/group.pngbin0 -> 700 bytes
-rw-r--r--lib/plugins/acl/pix/ns.pngbin0 -> 800 bytes
-rw-r--r--lib/plugins/acl/pix/page.pngbin0 -> 582 bytes
-rw-r--r--lib/plugins/acl/pix/user.pngbin0 -> 653 bytes
-rw-r--r--lib/plugins/acl/plugin.info.txt6
-rw-r--r--lib/plugins/acl/rtl.css40
-rw-r--r--lib/plugins/acl/script.js127
-rw-r--r--lib/plugins/acl/style.css97
-rw-r--r--lib/plugins/action.php23
-rw-r--r--lib/plugins/admin.php46
-rw-r--r--lib/plugins/config/admin.php357
-rw-r--r--lib/plugins/config/images/danger.pngbin0 -> 648 bytes
-rw-r--r--lib/plugins/config/images/security.pngbin0 -> 706 bytes
-rw-r--r--lib/plugins/config/images/warning.pngbin0 -> 613 bytes
-rw-r--r--lib/plugins/config/lang/af/lang.php23
-rw-r--r--lib/plugins/config/lang/ar/intro.txt7
-rw-r--r--lib/plugins/config/lang/ar/lang.php185
-rw-r--r--lib/plugins/config/lang/bg/intro.txt7
-rw-r--r--lib/plugins/config/lang/bg/lang.php191
-rw-r--r--lib/plugins/config/lang/ca-valencia/intro.txt10
-rw-r--r--lib/plugins/config/lang/ca-valencia/lang.php182
-rw-r--r--lib/plugins/config/lang/ca/intro.txt7
-rw-r--r--lib/plugins/config/lang/ca/lang.php182
-rw-r--r--lib/plugins/config/lang/cs/intro.txt8
-rw-r--r--lib/plugins/config/lang/cs/lang.php201
-rw-r--r--lib/plugins/config/lang/da/intro.txt8
-rw-r--r--lib/plugins/config/lang/da/lang.php192
-rw-r--r--lib/plugins/config/lang/de-informal/intro.txt7
-rw-r--r--lib/plugins/config/lang/de-informal/lang.php191
-rw-r--r--lib/plugins/config/lang/de/intro.txt10
-rw-r--r--lib/plugins/config/lang/de/lang.php202
-rw-r--r--lib/plugins/config/lang/el/intro.txt7
-rw-r--r--lib/plugins/config/lang/el/lang.php195
-rw-r--r--lib/plugins/config/lang/en/intro.txt9
-rw-r--r--lib/plugins/config/lang/en/lang.php245
-rw-r--r--lib/plugins/config/lang/eo/intro.txt7
-rw-r--r--lib/plugins/config/lang/eo/lang.php196
-rw-r--r--lib/plugins/config/lang/es/intro.txt7
-rw-r--r--lib/plugins/config/lang/es/lang.php205
-rw-r--r--lib/plugins/config/lang/et/lang.php32
-rw-r--r--lib/plugins/config/lang/eu/intro.txt7
-rw-r--r--lib/plugins/config/lang/eu/lang.php184
-rw-r--r--lib/plugins/config/lang/fa/intro.txt8
-rw-r--r--lib/plugins/config/lang/fa/lang.php187
-rw-r--r--lib/plugins/config/lang/fi/intro.txt7
-rw-r--r--lib/plugins/config/lang/fi/lang.php191
-rw-r--r--lib/plugins/config/lang/fr/intro.txt9
-rw-r--r--lib/plugins/config/lang/fr/lang.php201
-rw-r--r--lib/plugins/config/lang/gl/intro.txt7
-rw-r--r--lib/plugins/config/lang/gl/lang.php188
-rw-r--r--lib/plugins/config/lang/he/intro.txt9
-rw-r--r--lib/plugins/config/lang/he/lang.php169
-rw-r--r--lib/plugins/config/lang/hi/lang.php14
-rw-r--r--lib/plugins/config/lang/hr/lang.php8
-rw-r--r--lib/plugins/config/lang/hu/intro.txt9
-rw-r--r--lib/plugins/config/lang/hu/lang.php190
-rw-r--r--lib/plugins/config/lang/ia/intro.txt7
-rw-r--r--lib/plugins/config/lang/ia/lang.php180
-rw-r--r--lib/plugins/config/lang/id-ni/intro.txt7
-rw-r--r--lib/plugins/config/lang/id-ni/lang.php69
-rw-r--r--lib/plugins/config/lang/id/intro.txt5
-rw-r--r--lib/plugins/config/lang/id/lang.php7
-rw-r--r--lib/plugins/config/lang/is/lang.php58
-rw-r--r--lib/plugins/config/lang/it/intro.txt9
-rw-r--r--lib/plugins/config/lang/it/lang.php195
-rw-r--r--lib/plugins/config/lang/ja/intro.txt9
-rw-r--r--lib/plugins/config/lang/ja/lang.php193
-rw-r--r--lib/plugins/config/lang/kk/lang.php6
-rw-r--r--lib/plugins/config/lang/ko/intro.txt9
-rw-r--r--lib/plugins/config/lang/ko/lang.php192
-rw-r--r--lib/plugins/config/lang/la/intro.txt7
-rw-r--r--lib/plugins/config/lang/la/lang.php181
-rw-r--r--lib/plugins/config/lang/lb/intro.txt7
-rw-r--r--lib/plugins/config/lang/lb/lang.php6
-rw-r--r--lib/plugins/config/lang/lt/intro.txt7
-rw-r--r--lib/plugins/config/lang/lt/lang.php22
-rw-r--r--lib/plugins/config/lang/lv/intro.txt7
-rw-r--r--lib/plugins/config/lang/lv/lang.php185
-rw-r--r--lib/plugins/config/lang/mk/lang.php6
-rw-r--r--lib/plugins/config/lang/mr/intro.txt10
-rw-r--r--lib/plugins/config/lang/mr/lang.php182
-rw-r--r--lib/plugins/config/lang/ms/lang.php6
-rw-r--r--lib/plugins/config/lang/ne/lang.php70
-rw-r--r--lib/plugins/config/lang/nl/intro.txt9
-rw-r--r--lib/plugins/config/lang/nl/lang.php198
-rw-r--r--lib/plugins/config/lang/no/intro.txt7
-rw-r--r--lib/plugins/config/lang/no/lang.php204
-rw-r--r--lib/plugins/config/lang/pl/intro.txt9
-rw-r--r--lib/plugins/config/lang/pl/lang.php199
-rw-r--r--lib/plugins/config/lang/pt-br/intro.txt7
-rw-r--r--lib/plugins/config/lang/pt-br/lang.php200
-rw-r--r--lib/plugins/config/lang/pt/intro.txt7
-rw-r--r--lib/plugins/config/lang/pt/lang.php189
-rw-r--r--lib/plugins/config/lang/ro/intro.txt7
-rw-r--r--lib/plugins/config/lang/ro/lang.php193
-rw-r--r--lib/plugins/config/lang/ru/intro.txt9
-rw-r--r--lib/plugins/config/lang/ru/lang.php196
-rw-r--r--lib/plugins/config/lang/sk/intro.txt7
-rw-r--r--lib/plugins/config/lang/sk/lang.php189
-rw-r--r--lib/plugins/config/lang/sl/intro.txt7
-rw-r--r--lib/plugins/config/lang/sl/lang.php191
-rw-r--r--lib/plugins/config/lang/sq/intro.txt7
-rw-r--r--lib/plugins/config/lang/sq/lang.php180
-rw-r--r--lib/plugins/config/lang/sr/intro.txt7
-rw-r--r--lib/plugins/config/lang/sr/lang.php184
-rw-r--r--lib/plugins/config/lang/sv/intro.txt9
-rw-r--r--lib/plugins/config/lang/sv/lang.php194
-rw-r--r--lib/plugins/config/lang/th/lang.php106
-rw-r--r--lib/plugins/config/lang/tr/intro.txt7
-rw-r--r--lib/plugins/config/lang/tr/lang.php135
-rw-r--r--lib/plugins/config/lang/uk/intro.txt7
-rw-r--r--lib/plugins/config/lang/uk/lang.php192
-rw-r--r--lib/plugins/config/lang/zh-tw/intro.txt7
-rw-r--r--lib/plugins/config/lang/zh-tw/lang.php192
-rw-r--r--lib/plugins/config/lang/zh/intro.txt9
-rw-r--r--lib/plugins/config/lang/zh/lang.php200
-rw-r--r--lib/plugins/config/plugin.info.txt6
-rw-r--r--lib/plugins/config/rtl.css45
-rw-r--r--lib/plugins/config/settings/config.class.php1057
-rw-r--r--lib/plugins/config/settings/config.metadata.php216
-rw-r--r--lib/plugins/config/settings/extra.class.php175
-rw-r--r--lib/plugins/config/style.css136
-rw-r--r--lib/plugins/index.html12
-rw-r--r--lib/plugins/info/lang/sl/lang.php12
-rw-r--r--lib/plugins/info/plugin.info.txt6
-rw-r--r--lib/plugins/info/syntax.php256
-rw-r--r--lib/plugins/plugin/admin.php151
-rw-r--r--lib/plugins/plugin/classes/ap_delete.class.php28
-rw-r--r--lib/plugins/plugin/classes/ap_download.class.php294
-rw-r--r--lib/plugins/plugin/classes/ap_enable.class.php49
-rw-r--r--lib/plugins/plugin/classes/ap_info.class.php144
-rw-r--r--lib/plugins/plugin/classes/ap_manage.class.php197
-rw-r--r--lib/plugins/plugin/classes/ap_update.class.php38
-rw-r--r--lib/plugins/plugin/lang/af/lang.php13
-rw-r--r--lib/plugins/plugin/lang/ar/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/ar/lang.php52
-rw-r--r--lib/plugins/plugin/lang/bg/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/bg/lang.php54
-rw-r--r--lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/ca-valencia/lang.php53
-rw-r--r--lib/plugins/plugin/lang/ca/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/ca/lang.php53
-rw-r--r--lib/plugins/plugin/lang/cs/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/cs/lang.php60
-rw-r--r--lib/plugins/plugin/lang/da/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/da/lang.php58
-rw-r--r--lib/plugins/plugin/lang/de-informal/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/de-informal/lang.php56
-rw-r--r--lib/plugins/plugin/lang/de/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/de/lang.php66
-rw-r--r--lib/plugins/plugin/lang/el/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/el/lang.php60
-rw-r--r--lib/plugins/plugin/lang/en/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/en/lang.php78
-rw-r--r--lib/plugins/plugin/lang/eo/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/eo/lang.php60
-rw-r--r--lib/plugins/plugin/lang/es/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/es/lang.php70
-rw-r--r--lib/plugins/plugin/lang/et/lang.php32
-rw-r--r--lib/plugins/plugin/lang/eu/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/eu/lang.php51
-rw-r--r--lib/plugins/plugin/lang/fa/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/fa/lang.php55
-rw-r--r--lib/plugins/plugin/lang/fi/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/fi/lang.php54
-rw-r--r--lib/plugins/plugin/lang/fr/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/fr/lang.php65
-rw-r--r--lib/plugins/plugin/lang/gl/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/gl/lang.php52
-rw-r--r--lib/plugins/plugin/lang/he/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/he/lang.php55
-rw-r--r--lib/plugins/plugin/lang/hi/lang.php12
-rw-r--r--lib/plugins/plugin/lang/hr/lang.php8
-rw-r--r--lib/plugins/plugin/lang/hu/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/hu/lang.php56
-rw-r--r--lib/plugins/plugin/lang/ia/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/ia/lang.php51
-rw-r--r--lib/plugins/plugin/lang/id-ni/lang.php7
-rw-r--r--lib/plugins/plugin/lang/id/lang.php31
-rw-r--r--lib/plugins/plugin/lang/is/lang.php47
-rw-r--r--lib/plugins/plugin/lang/it/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/it/lang.php60
-rw-r--r--lib/plugins/plugin/lang/ja/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/ja/lang.php56
-rw-r--r--lib/plugins/plugin/lang/kk/lang.php6
-rw-r--r--lib/plugins/plugin/lang/ko/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/ko/lang.php56
-rw-r--r--lib/plugins/plugin/lang/la/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/la/lang.php50
-rw-r--r--lib/plugins/plugin/lang/lb/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/lb/lang.php6
-rw-r--r--lib/plugins/plugin/lang/lt/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/lt/lang.php13
-rw-r--r--lib/plugins/plugin/lang/lv/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/lv/lang.php50
-rw-r--r--lib/plugins/plugin/lang/mk/lang.php43
-rw-r--r--lib/plugins/plugin/lang/mr/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/mr/lang.php53
-rw-r--r--lib/plugins/plugin/lang/ms/lang.php6
-rw-r--r--lib/plugins/plugin/lang/ne/lang.php45
-rw-r--r--lib/plugins/plugin/lang/nl/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/nl/lang.php61
-rw-r--r--lib/plugins/plugin/lang/no/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/no/lang.php63
-rw-r--r--lib/plugins/plugin/lang/pl/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/pl/lang.php62
-rw-r--r--lib/plugins/plugin/lang/pt-br/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/pt-br/lang.php64
-rw-r--r--lib/plugins/plugin/lang/pt/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/pt/lang.php55
-rw-r--r--lib/plugins/plugin/lang/ro/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/ro/lang.php58
-rw-r--r--lib/plugins/plugin/lang/ru/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/ru/lang.php63
-rw-r--r--lib/plugins/plugin/lang/sk/admin_plugin.txt4
-rw-r--r--lib/plugins/plugin/lang/sk/lang.php54
-rw-r--r--lib/plugins/plugin/lang/sl/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/sl/lang.php54
-rw-r--r--lib/plugins/plugin/lang/sq/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/sq/lang.php50
-rw-r--r--lib/plugins/plugin/lang/sr/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/sr/lang.php52
-rw-r--r--lib/plugins/plugin/lang/sv/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/sv/lang.php63
-rw-r--r--lib/plugins/plugin/lang/th/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/th/lang.php50
-rw-r--r--lib/plugins/plugin/lang/tr/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/tr/lang.php53
-rw-r--r--lib/plugins/plugin/lang/uk/admin_plugin.txt7
-rw-r--r--lib/plugins/plugin/lang/uk/lang.php58
-rw-r--r--lib/plugins/plugin/lang/zh-tw/admin_plugin.txt3
-rw-r--r--lib/plugins/plugin/lang/zh-tw/lang.php57
-rw-r--r--lib/plugins/plugin/lang/zh/admin_plugin.txt5
-rw-r--r--lib/plugins/plugin/lang/zh/lang.php63
-rw-r--r--lib/plugins/plugin/rtl.css51
-rw-r--r--lib/plugins/plugin/style.css156
-rw-r--r--lib/plugins/popularity/action.php57
-rw-r--r--lib/plugins/popularity/admin.php148
-rw-r--r--lib/plugins/popularity/helper.php292
-rw-r--r--lib/plugins/popularity/lang/af/lang.php6
-rw-r--r--lib/plugins/popularity/lang/ar/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ar/lang.php15
-rw-r--r--lib/plugins/popularity/lang/ar/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/bg/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/bg/lang.php14
-rw-r--r--lib/plugins/popularity/lang/bg/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ca-valencia/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ca-valencia/lang.php9
-rw-r--r--lib/plugins/popularity/lang/ca/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ca/lang.php10
-rw-r--r--lib/plugins/popularity/lang/cs/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/cs/lang.php18
-rw-r--r--lib/plugins/popularity/lang/cs/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/da/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/da/lang.php14
-rw-r--r--lib/plugins/popularity/lang/de-informal/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/de-informal/lang.php18
-rw-r--r--lib/plugins/popularity/lang/de-informal/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/de/intro.txt11
-rw-r--r--lib/plugins/popularity/lang/de/lang.php25
-rw-r--r--lib/plugins/popularity/lang/de/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/el/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/el/lang.php15
-rw-r--r--lib/plugins/popularity/lang/el/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/en/intro.txt11
-rw-r--r--lib/plugins/popularity/lang/en/lang.php9
-rw-r--r--lib/plugins/popularity/lang/en/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/eo/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/eo/lang.php20
-rw-r--r--lib/plugins/popularity/lang/eo/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/es/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/es/lang.php29
-rw-r--r--lib/plugins/popularity/lang/es/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/et/lang.php7
-rw-r--r--lib/plugins/popularity/lang/eu/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/eu/lang.php13
-rw-r--r--lib/plugins/popularity/lang/eu/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/fa/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/fa/lang.php17
-rw-r--r--lib/plugins/popularity/lang/fa/submitted.txt2
-rw-r--r--lib/plugins/popularity/lang/fi/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/fi/lang.php15
-rw-r--r--lib/plugins/popularity/lang/fi/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/fr/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/fr/lang.php24
-rw-r--r--lib/plugins/popularity/lang/fr/submitted.txt2
-rw-r--r--lib/plugins/popularity/lang/gl/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/gl/lang.php14
-rw-r--r--lib/plugins/popularity/lang/gl/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/he/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/he/lang.php11
-rw-r--r--lib/plugins/popularity/lang/hi/lang.php8
-rw-r--r--lib/plugins/popularity/lang/hr/lang.php8
-rw-r--r--lib/plugins/popularity/lang/hu/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/hu/lang.php18
-rw-r--r--lib/plugins/popularity/lang/hu/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ia/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ia/lang.php9
-rw-r--r--lib/plugins/popularity/lang/id-ni/intro.txt7
-rw-r--r--lib/plugins/popularity/lang/id-ni/lang.php9
-rw-r--r--lib/plugins/popularity/lang/id/lang.php6
-rw-r--r--lib/plugins/popularity/lang/is/lang.php9
-rw-r--r--lib/plugins/popularity/lang/it/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/it/lang.php19
-rw-r--r--lib/plugins/popularity/lang/it/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ja/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ja/lang.php16
-rw-r--r--lib/plugins/popularity/lang/ja/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/kk/lang.php6
-rw-r--r--lib/plugins/popularity/lang/ko/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ko/lang.php17
-rw-r--r--lib/plugins/popularity/lang/ko/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/la/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/la/lang.php13
-rw-r--r--lib/plugins/popularity/lang/la/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/lb/lang.php6
-rw-r--r--lib/plugins/popularity/lang/lt/lang.php9
-rw-r--r--lib/plugins/popularity/lang/lv/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/lv/lang.php13
-rw-r--r--lib/plugins/popularity/lang/lv/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/mk/lang.php6
-rw-r--r--lib/plugins/popularity/lang/mr/intro.txt8
-rw-r--r--lib/plugins/popularity/lang/mr/lang.php11
-rw-r--r--lib/plugins/popularity/lang/ms/lang.php6
-rw-r--r--lib/plugins/popularity/lang/ne/lang.php9
-rw-r--r--lib/plugins/popularity/lang/nl/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/nl/lang.php22
-rw-r--r--lib/plugins/popularity/lang/nl/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/no/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/no/lang.php23
-rw-r--r--lib/plugins/popularity/lang/no/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/pl/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/pl/lang.php22
-rw-r--r--lib/plugins/popularity/lang/pl/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/pt-br/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/pt-br/lang.php25
-rw-r--r--lib/plugins/popularity/lang/pt-br/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/pt/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/pt/lang.php16
-rw-r--r--lib/plugins/popularity/lang/pt/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ro/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/ro/lang.php18
-rw-r--r--lib/plugins/popularity/lang/ro/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/ru/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/ru/lang.php23
-rw-r--r--lib/plugins/popularity/lang/ru/submitted.txt2
-rw-r--r--lib/plugins/popularity/lang/sk/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/sk/lang.php15
-rw-r--r--lib/plugins/popularity/lang/sk/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/sl/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/sl/lang.php13
-rw-r--r--lib/plugins/popularity/lang/sl/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/sq/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/sq/lang.php8
-rw-r--r--lib/plugins/popularity/lang/sr/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/sr/lang.php10
-rw-r--r--lib/plugins/popularity/lang/sv/intro.txt11
-rw-r--r--lib/plugins/popularity/lang/sv/lang.php23
-rw-r--r--lib/plugins/popularity/lang/sv/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/th/lang.php11
-rw-r--r--lib/plugins/popularity/lang/tr/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/tr/lang.php11
-rw-r--r--lib/plugins/popularity/lang/uk/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/uk/lang.php18
-rw-r--r--lib/plugins/popularity/lang/uk/submitted.txt2
-rw-r--r--lib/plugins/popularity/lang/zh-tw/intro.txt10
-rw-r--r--lib/plugins/popularity/lang/zh-tw/lang.php19
-rw-r--r--lib/plugins/popularity/lang/zh-tw/submitted.txt3
-rw-r--r--lib/plugins/popularity/lang/zh/intro.txt9
-rw-r--r--lib/plugins/popularity/lang/zh/lang.php24
-rw-r--r--lib/plugins/popularity/lang/zh/submitted.txt3
-rw-r--r--lib/plugins/popularity/plugin.info.txt7
-rw-r--r--lib/plugins/revert/admin.php185
-rw-r--r--lib/plugins/revert/lang/af/lang.php5
-rw-r--r--lib/plugins/revert/lang/ar/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ar/lang.php18
-rw-r--r--lib/plugins/revert/lang/bg/intro.txt4
-rw-r--r--lib/plugins/revert/lang/bg/lang.php16
-rw-r--r--lib/plugins/revert/lang/ca-valencia/intro.txt4
-rw-r--r--lib/plugins/revert/lang/ca-valencia/lang.php15
-rw-r--r--lib/plugins/revert/lang/ca/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ca/lang.php18
-rw-r--r--lib/plugins/revert/lang/cs/intro.txt3
-rw-r--r--lib/plugins/revert/lang/cs/lang.php26
-rw-r--r--lib/plugins/revert/lang/da/intro.txt3
-rw-r--r--lib/plugins/revert/lang/da/lang.php21
-rw-r--r--lib/plugins/revert/lang/de-informal/intro.txt3
-rw-r--r--lib/plugins/revert/lang/de-informal/lang.php20
-rw-r--r--lib/plugins/revert/lang/de/intro.txt3
-rw-r--r--lib/plugins/revert/lang/de/lang.php28
-rw-r--r--lib/plugins/revert/lang/el/intro.txt3
-rw-r--r--lib/plugins/revert/lang/el/lang.php22
-rw-r--r--lib/plugins/revert/lang/en/intro.txt3
-rw-r--r--lib/plugins/revert/lang/en/lang.php23
-rw-r--r--lib/plugins/revert/lang/eo/intro.txt3
-rw-r--r--lib/plugins/revert/lang/eo/lang.php24
-rw-r--r--lib/plugins/revert/lang/es/intro.txt3
-rw-r--r--lib/plugins/revert/lang/es/lang.php32
-rw-r--r--lib/plugins/revert/lang/et/lang.php7
-rw-r--r--lib/plugins/revert/lang/eu/intro.txt3
-rw-r--r--lib/plugins/revert/lang/eu/lang.php17
-rw-r--r--lib/plugins/revert/lang/fa/intro.txt3
-rw-r--r--lib/plugins/revert/lang/fa/lang.php19
-rw-r--r--lib/plugins/revert/lang/fi/intro.txt3
-rw-r--r--lib/plugins/revert/lang/fi/lang.php18
-rw-r--r--lib/plugins/revert/lang/fr/intro.txt3
-rw-r--r--lib/plugins/revert/lang/fr/lang.php27
-rw-r--r--lib/plugins/revert/lang/gl/intro.txt3
-rw-r--r--lib/plugins/revert/lang/gl/lang.php16
-rw-r--r--lib/plugins/revert/lang/he/intro.txt3
-rw-r--r--lib/plugins/revert/lang/he/lang.php18
-rw-r--r--lib/plugins/revert/lang/hi/lang.php7
-rw-r--r--lib/plugins/revert/lang/hr/lang.php8
-rw-r--r--lib/plugins/revert/lang/hu/intro.txt3
-rw-r--r--lib/plugins/revert/lang/hu/lang.php20
-rw-r--r--lib/plugins/revert/lang/ia/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ia/lang.php16
-rw-r--r--lib/plugins/revert/lang/id-ni/lang.php7
-rw-r--r--lib/plugins/revert/lang/id/lang.php7
-rw-r--r--lib/plugins/revert/lang/is/lang.php10
-rw-r--r--lib/plugins/revert/lang/it/intro.txt3
-rw-r--r--lib/plugins/revert/lang/it/lang.php22
-rw-r--r--lib/plugins/revert/lang/ja/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ja/lang.php17
-rw-r--r--lib/plugins/revert/lang/kk/lang.php6
-rw-r--r--lib/plugins/revert/lang/ko/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ko/lang.php19
-rw-r--r--lib/plugins/revert/lang/la/intro.txt3
-rw-r--r--lib/plugins/revert/lang/la/lang.php15
-rw-r--r--lib/plugins/revert/lang/lb/intro.txt3
-rw-r--r--lib/plugins/revert/lang/lb/lang.php6
-rw-r--r--lib/plugins/revert/lang/lt/lang.php7
-rw-r--r--lib/plugins/revert/lang/lv/intro.txt3
-rw-r--r--lib/plugins/revert/lang/lv/lang.php15
-rw-r--r--lib/plugins/revert/lang/mk/lang.php6
-rw-r--r--lib/plugins/revert/lang/mr/intro.txt5
-rw-r--r--lib/plugins/revert/lang/mr/lang.php18
-rw-r--r--lib/plugins/revert/lang/ms/lang.php6
-rw-r--r--lib/plugins/revert/lang/ne/lang.php16
-rw-r--r--lib/plugins/revert/lang/nl/intro.txt3
-rw-r--r--lib/plugins/revert/lang/nl/lang.php25
-rw-r--r--lib/plugins/revert/lang/no/intro.txt3
-rw-r--r--lib/plugins/revert/lang/no/lang.php29
-rw-r--r--lib/plugins/revert/lang/pl/intro.txt3
-rw-r--r--lib/plugins/revert/lang/pl/lang.php23
-rw-r--r--lib/plugins/revert/lang/pt-br/intro.txt3
-rw-r--r--lib/plugins/revert/lang/pt-br/lang.php28
-rw-r--r--lib/plugins/revert/lang/pt/intro.txt3
-rw-r--r--lib/plugins/revert/lang/pt/lang.php19
-rw-r--r--lib/plugins/revert/lang/ro/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ro/lang.php22
-rw-r--r--lib/plugins/revert/lang/ru/intro.txt3
-rw-r--r--lib/plugins/revert/lang/ru/lang.php26
-rw-r--r--lib/plugins/revert/lang/sk/intro.txt0
-rw-r--r--lib/plugins/revert/lang/sk/lang.php17
-rw-r--r--lib/plugins/revert/lang/sl/intro.txt3
-rw-r--r--lib/plugins/revert/lang/sl/lang.php15
-rw-r--r--lib/plugins/revert/lang/sq/intro.txt3
-rw-r--r--lib/plugins/revert/lang/sq/lang.php15
-rw-r--r--lib/plugins/revert/lang/sr/intro.txt3
-rw-r--r--lib/plugins/revert/lang/sr/lang.php17
-rw-r--r--lib/plugins/revert/lang/sv/intro.txt3
-rw-r--r--lib/plugins/revert/lang/sv/lang.php29
-rw-r--r--lib/plugins/revert/lang/th/intro.txt3
-rw-r--r--lib/plugins/revert/lang/th/lang.php19
-rw-r--r--lib/plugins/revert/lang/tr/intro.txt3
-rw-r--r--lib/plugins/revert/lang/tr/lang.php18
-rw-r--r--lib/plugins/revert/lang/uk/intro.txt3
-rw-r--r--lib/plugins/revert/lang/uk/lang.php20
-rw-r--r--lib/plugins/revert/lang/zh-tw/intro.txt3
-rw-r--r--lib/plugins/revert/lang/zh-tw/lang.php21
-rw-r--r--lib/plugins/revert/lang/zh/intro.txt3
-rw-r--r--lib/plugins/revert/lang/zh/lang.php27
-rw-r--r--lib/plugins/revert/plugin.info.txt6
-rw-r--r--lib/plugins/safefnrecode/action.php68
-rw-r--r--lib/plugins/safefnrecode/plugin.info.txt7
-rw-r--r--lib/plugins/syntax.php282
-rw-r--r--lib/plugins/usermanager/admin.php630
-rw-r--r--lib/plugins/usermanager/images/search.pngbin0 -> 550 bytes
-rw-r--r--lib/plugins/usermanager/lang/af/lang.php14
-rw-r--r--lib/plugins/usermanager/lang/ar/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ar/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ar/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ar/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ar/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/ar/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/bg/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/bg/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/ca-valencia/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ca/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/ca/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/cs/lang.php54
-rw-r--r--lib/plugins/usermanager/lang/cs/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/da/lang.php54
-rw-r--r--lib/plugins/usermanager/lang/da/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/de-informal/lang.php52
-rw-r--r--lib/plugins/usermanager/lang/de-informal/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/de/lang.php61
-rw-r--r--lib/plugins/usermanager/lang/de/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/el/lang.php55
-rw-r--r--lib/plugins/usermanager/lang/el/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/en/lang.php58
-rw-r--r--lib/plugins/usermanager/lang/en/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/eo/lang.php56
-rw-r--r--lib/plugins/usermanager/lang/eo/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/es/lang.php65
-rw-r--r--lib/plugins/usermanager/lang/es/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/et/lang.php30
-rw-r--r--lib/plugins/usermanager/lang/eu/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/eu/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/eu/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/eu/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/eu/lang.php47
-rw-r--r--lib/plugins/usermanager/lang/eu/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/fa/lang.php51
-rw-r--r--lib/plugins/usermanager/lang/fa/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/fi/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/fi/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/fr/lang.php60
-rw-r--r--lib/plugins/usermanager/lang/fr/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/gl/lang.php48
-rw-r--r--lib/plugins/usermanager/lang/gl/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/he/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/he/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/hi/lang.php7
-rw-r--r--lib/plugins/usermanager/lang/hr/lang.php8
-rw-r--r--lib/plugins/usermanager/lang/hu/add.txt2
-rw-r--r--lib/plugins/usermanager/lang/hu/delete.txt2
-rw-r--r--lib/plugins/usermanager/lang/hu/edit.txt2
-rw-r--r--lib/plugins/usermanager/lang/hu/intro.txt2
-rw-r--r--lib/plugins/usermanager/lang/hu/lang.php52
-rw-r--r--lib/plugins/usermanager/lang/hu/list.txt2
-rw-r--r--lib/plugins/usermanager/lang/ia/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ia/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ia/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ia/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ia/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/ia/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/id-ni/lang.php7
-rw-r--r--lib/plugins/usermanager/lang/id/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/id/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/id/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/id/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/id/lang.php47
-rw-r--r--lib/plugins/usermanager/lang/id/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/is/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/is/lang.php18
-rw-r--r--lib/plugins/usermanager/lang/it/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/it/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/it/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/it/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/it/lang.php56
-rw-r--r--lib/plugins/usermanager/lang/it/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ja/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/ja/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/kk/lang.php6
-rw-r--r--lib/plugins/usermanager/lang/ko/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ko/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ko/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ko/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ko/lang.php51
-rw-r--r--lib/plugins/usermanager/lang/ko/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/la/lang.php47
-rw-r--r--lib/plugins/usermanager/lang/la/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/lb/lang.php6
-rw-r--r--lib/plugins/usermanager/lang/lb/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/lt/add.txt2
-rw-r--r--lib/plugins/usermanager/lang/lt/delete.txt2
-rw-r--r--lib/plugins/usermanager/lang/lt/edit.txt2
-rw-r--r--lib/plugins/usermanager/lang/lt/intro.txt2
-rw-r--r--lib/plugins/usermanager/lang/lt/lang.php48
-rw-r--r--lib/plugins/usermanager/lang/lt/list.txt2
-rw-r--r--lib/plugins/usermanager/lang/lv/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/lv/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/lv/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/lv/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/lv/lang.php48
-rw-r--r--lib/plugins/usermanager/lang/lv/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/mk/lang.php38
-rw-r--r--lib/plugins/usermanager/lang/mk/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/mr/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/mr/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ms/lang.php6
-rw-r--r--lib/plugins/usermanager/lang/ne/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ne/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ne/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ne/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ne/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/ne/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/nl/lang.php57
-rw-r--r--lib/plugins/usermanager/lang/nl/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/no/lang.php59
-rw-r--r--lib/plugins/usermanager/lang/no/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/pl/lang.php56
-rw-r--r--lib/plugins/usermanager/lang/pl/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt-br/lang.php60
-rw-r--r--lib/plugins/usermanager/lang/pt-br/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/pt/lang.php51
-rw-r--r--lib/plugins/usermanager/lang/pt/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ro/lang.php54
-rw-r--r--lib/plugins/usermanager/lang/ro/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/ru/lang.php60
-rw-r--r--lib/plugins/usermanager/lang/ru/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/sk/add.txt2
-rw-r--r--lib/plugins/usermanager/lang/sk/delete.txt2
-rw-r--r--lib/plugins/usermanager/lang/sk/edit.txt2
-rw-r--r--lib/plugins/usermanager/lang/sk/intro.txt2
-rw-r--r--lib/plugins/usermanager/lang/sk/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/sk/list.txt2
-rw-r--r--lib/plugins/usermanager/lang/sl/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/sl/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/sl/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/sl/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/sl/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/sl/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/sq/lang.php48
-rw-r--r--lib/plugins/usermanager/lang/sq/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/sr/lang.php49
-rw-r--r--lib/plugins/usermanager/lang/sr/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/sv/lang.php59
-rw-r--r--lib/plugins/usermanager/lang/sv/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/th/lang.php47
-rw-r--r--lib/plugins/usermanager/lang/th/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/tr/lang.php50
-rw-r--r--lib/plugins/usermanager/lang/tr/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/uk/lang.php53
-rw-r--r--lib/plugins/usermanager/lang/uk/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/lang.php54
-rw-r--r--lib/plugins/usermanager/lang/zh-tw/list.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/add.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/delete.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/edit.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/intro.txt1
-rw-r--r--lib/plugins/usermanager/lang/zh/lang.php58
-rw-r--r--lib/plugins/usermanager/lang/zh/list.txt1
-rw-r--r--lib/plugins/usermanager/plugin.info.txt6
-rw-r--r--lib/plugins/usermanager/script.js8
-rw-r--r--lib/plugins/usermanager/style.css20
-rw-r--r--lib/scripts/behaviour.js180
-rw-r--r--lib/scripts/compatibility.js414
-rw-r--r--lib/scripts/cookie.js64
-rw-r--r--lib/scripts/delay.js70
-rw-r--r--lib/scripts/drag.js87
-rw-r--r--lib/scripts/edit.js268
-rw-r--r--lib/scripts/editor.js204
-rw-r--r--lib/scripts/fileuploader.js1247
-rw-r--r--lib/scripts/fileuploaderextended.js344
-rw-r--r--lib/scripts/helpers.js70
-rw-r--r--lib/scripts/hotkeys.js302
-rw-r--r--lib/scripts/index.html12
-rw-r--r--lib/scripts/index.js16
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_0_aaaaaa_40x100.pngbin0 -> 180 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_75_ffffff_40x100.pngbin0 -> 178 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.pngbin0 -> 120 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.pngbin0 -> 105 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.pngbin0 -> 111 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.pngbin0 -> 110 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.pngbin0 -> 119 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.pngbin0 -> 101 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.pngbin0 -> 4369 bytes
-rw-r--r--lib/scripts/jquery/jquery-ui-theme/smoothness.css568
-rw-r--r--lib/scripts/jquery/jquery-ui.js11767
-rw-r--r--lib/scripts/jquery/jquery-ui.min.js414
-rw-r--r--lib/scripts/jquery/jquery.cookie.js41
-rw-r--r--lib/scripts/jquery/jquery.js9046
-rw-r--r--lib/scripts/jquery/jquery.min.js4
-rwxr-xr-xlib/scripts/jquery/update.sh28
-rw-r--r--lib/scripts/linkwiz.js308
-rw-r--r--lib/scripts/locktimer.js126
-rw-r--r--lib/scripts/media.js940
-rw-r--r--lib/scripts/page.js141
-rw-r--r--lib/scripts/qsearch.js146
-rw-r--r--lib/scripts/script.js63
-rw-r--r--lib/scripts/textselection.js233
-rw-r--r--lib/scripts/toolbar.js255
-rw-r--r--lib/scripts/tree.js93
-rw-r--r--lib/scripts/tw-sack.js139
-rw-r--r--lib/styles/all.css65
-rw-r--r--lib/styles/feed.css63
-rw-r--r--lib/styles/index.html12
-rw-r--r--lib/styles/print.css23
-rw-r--r--lib/styles/screen.css103
-rw-r--r--lib/tpl/default/_admin.css48
-rw-r--r--lib/tpl/default/_fileuploader.css111
-rw-r--r--lib/tpl/default/_linkwiz.css40
-rw-r--r--lib/tpl/default/_mediamanager.css432
-rw-r--r--lib/tpl/default/_mediaoptions.css18
-rw-r--r--lib/tpl/default/_subscription.css21
-rw-r--r--lib/tpl/default/_tabs.css37
-rw-r--r--lib/tpl/default/design.css851
-rw-r--r--lib/tpl/default/detail.php89
-rw-r--r--lib/tpl/default/footer.html41
-rw-r--r--lib/tpl/default/images/UWEB.pngbin0 -> 462 bytes
-rw-r--r--lib/tpl/default/images/UWEBshadow.pngbin0 -> 900 bytes
-rw-r--r--lib/tpl/default/images/apple-touch-icon.pngbin0 -> 17728 bytes
-rw-r--r--lib/tpl/default/images/bullet.gifbin0 -> 50 bytes
-rw-r--r--lib/tpl/default/images/button-cc.gifbin0 -> 359 bytes
-rw-r--r--lib/tpl/default/images/button-css.pngbin0 -> 299 bytes
-rw-r--r--lib/tpl/default/images/button-donate.gifbin0 -> 187 bytes
-rw-r--r--lib/tpl/default/images/button-dw.pngbin0 -> 404 bytes
-rw-r--r--lib/tpl/default/images/button-php.gifbin0 -> 207 bytes
-rw-r--r--lib/tpl/default/images/button-rss.pngbin0 -> 191 bytes
-rw-r--r--lib/tpl/default/images/button-xhtml.pngbin0 -> 321 bytes
-rw-r--r--lib/tpl/default/images/buttonshadow.pngbin0 -> 218 bytes
-rw-r--r--lib/tpl/default/images/closed.gifbin0 -> 54 bytes
-rw-r--r--lib/tpl/default/images/favicon.icobin0 -> 7406 bytes
-rw-r--r--lib/tpl/default/images/inputshadow.pngbin0 -> 93 bytes
-rw-r--r--lib/tpl/default/images/link_icon.gifbin0 -> 168 bytes
-rw-r--r--lib/tpl/default/images/mail_icon.gifbin0 -> 151 bytes
-rw-r--r--lib/tpl/default/images/open.gifbin0 -> 54 bytes
-rw-r--r--lib/tpl/default/images/resizecol.pngbin0 -> 225 bytes
-rw-r--r--lib/tpl/default/images/tocdot2.gifbin0 -> 50 bytes
-rw-r--r--lib/tpl/default/images/windows.gifbin0 -> 170 bytes
-rw-r--r--lib/tpl/default/layout.css79
-rw-r--r--lib/tpl/default/main.php138
-rw-r--r--lib/tpl/default/media.css213
-rw-r--r--lib/tpl/default/mediamanager.php44
-rw-r--r--lib/tpl/default/print.css228
-rw-r--r--lib/tpl/default/rtl.css154
-rw-r--r--lib/tpl/default/style.ini72
-rw-r--r--lib/tpl/index.php68
3377 files changed, 239872 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..f9155eaed
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,41 @@
+/conf/*.local.conf
+/conf/acl.auth.php
+/conf/local.php
+/conf/local.protected.php
+/conf/users.auth.php
+/conf/user*.css
+/conf/user*.js
+/conf/words.aspell
+/conf/lang/*
+/conf/plugin_lang/*
+/conf/plugins.local.*
+.htaccess
+*.swp
+*.bak
+*.old
+*~
+*.DS_Store
+/data/attic/*
+/data/cache/*
+/data/index/*
+/data/locks/*
+/data/media/*
+/data/media_meta/*
+/data/media_attic/*
+/data/meta/*
+/data/pages/*
+/data/tmp/*
+/lib/tpl/*
+/lib/plugins/*
+!/lib/plugins/acl
+!/lib/plugins/config
+!/lib/plugins/info
+!/lib/plugins/plugin
+!/lib/plugins/popularity
+!/lib/plugins/revert
+!/lib/plugins/safefnrecode
+!/lib/plugins/usermanager
+!/lib/plugins/action.php
+!/lib/plugins/admin.php
+!/lib/plugins/index.html
+!/lib/plugins/syntax.php
diff --git a/.htaccess.dist b/.htaccess.dist
new file mode 100644
index 000000000..aa2437b95
--- /dev/null
+++ b/.htaccess.dist
@@ -0,0 +1,36 @@
+## Enable this to restrict editing to logged in users only
+
+## 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$)">
+ Order allow,deny
+ Deny from all
+ Satisfy All
+</Files>
+
+## Uncomment these rules if you want to have nice URLs using
+## $conf['userewrite'] = 1 - not needed for rewrite mode 2
+#RewriteEngine on
+#
+## 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]
+#
+#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
diff --git a/COPYING b/COPYING
new file mode 100644
index 000000000..d159169d1
--- /dev/null
+++ b/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/README b/README
new file mode 100644
index 000000000..0490040f2
--- /dev/null
+++ b/README
@@ -0,0 +1,10 @@
+All documentation for DokuWiki is available online
+at http://www.dokuwiki.org/
+
+For Installation Instructions see
+http://www.dokuwiki.org/install
+
+DokuWiki - 2004-2012 (c) Andreas Gohr <andi@splitbrain.org>
+ and the DokuWiki Community
+See COPYING and file headers for license info
+
diff --git a/_cs/DokuWiki/DokuWikiCodingStandard.php b/_cs/DokuWiki/DokuWikiCodingStandard.php
new file mode 100644
index 000000000..36133fc46
--- /dev/null
+++ b/_cs/DokuWiki/DokuWikiCodingStandard.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * DokuWiki Coding Standard.
+ *
+ * @category PHP
+ * @package PHP_CodeSniffer
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if (class_exists('PHP_CodeSniffer_Standards_CodingStandard', true) === false) {
+ throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_CodingStandard not found');
+}
+
+/**
+ * DokuWiki Coding Standard.
+ *
+ * @category PHP
+ * @package PHP_CodeSniffer
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class PHP_CodeSniffer_Standards_DokuWiki_DokuWikiCodingStandard extends PHP_CodeSniffer_Standards_CodingStandard {
+
+
+ /**
+ * Return a list of external sniffs to include with this standard.
+ *
+ * @return array
+ */
+ public function getIncludedSniffs() {
+ return array(
+ 'Generic/Sniffs/Classes/DuplicateClassNameSniff.php',
+ 'Generic/Sniffs/CodeAnalysis/JumbledIncrementerSniff.php',
+ 'Generic/Sniffs/CodeAnalysis/UnnecessaryFinalModifierSniff.php',
+ 'Generic/Sniffs/CodeAnalysis/UnconditionalIfStatementSniff.php',
+ 'Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php',
+ 'Generic/Sniffs/CodeAnalysis/ForLoopWithTestFunctionCallSniff.php',
+ 'Generic/Sniffs/CodeAnalysis/UnusedFunctionParameterSniff.php',
+ 'Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php',
+ 'Generic/Sniffs/CodeAnalysis/UselessOverridingMethodSniff.php',
+ 'Generic/Sniffs/Commenting/TodoSniff.php',
+ 'Generic/Sniffs/Files/LineEndingsSniff.php',
+ 'Generic/Sniffs/Formatting/DisallowMultipleStatementsSniff.php',
+ 'Generic/Sniffs/Metrics/NestingLevelSniff.php',
+// 'Generic/Sniffs/Metrics/CyclomaticComplexitySniff.php', //FIXME we might need to tune this first
+ 'Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php',
+ 'Generic/Sniffs/PHP/LowerCaseConstantSniff.php',
+ 'Generic/Sniffs/PHP/DisallowShortOpenTagSniff.php',
+ 'Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php',
+ 'Generic/Sniffs/WhiteSpace/DisallowTabIndentSniff.php',
+ 'DokuWiki/Sniffs/WhiteSpace/ScopeIndentSniff.php',
+ 'Zend/Sniffs/Files/ClosingTagSniff.php',
+ 'PEAR/Sniffs/Functions/ValidDefaultValueSniff.php',
+ 'Squiz/Sniffs/PHP/EvalSniff.php',
+ 'Squiz/Sniffs/PHP/NonExecutableCodeSniff.php',
+// 'Squiz/Sniffs/PHP/CommentedOutCodeSniff.php', //FIXME should ignore oneliners
+ 'Squiz/Sniffs/WhiteSpace/SuperfluousWhitespaceSniff.php',
+ 'Squiz/Sniffs/PHP/NonExecutableCodeSniff.php',
+ 'Squiz/Sniffs/CSS/LowercaseStyleDefinitionSniff.php',
+ 'Squiz/Sniffs/CSS/MissingColonSniff.php',
+ 'Squiz/Sniffs/CSS/DisallowMultipleStyleDefinitionsSniff.php',
+ 'Squiz/Sniffs/CSS/ColonSpacingSniff.php',
+ 'Squiz/Sniffs/CSS/ClassDefinitionClosingBraceSpaceSniff.php',
+ 'Squiz/Sniffs/CSS/SemicolonSpacingSniff.php',
+ 'Squiz/Sniffs/CSS/IndentationSniff.php',
+ 'Squiz/Sniffs/CSS/EmptyClassDefinitionSniff.php',
+ 'Squiz/Sniffs/CSS/ClassDefinitionNameSpacingSniff.php',
+ 'Squiz/Sniffs/CSS/EmptyStyleDefinitionSniff.php',
+ 'Squiz/Sniffs/CSS/OpacitySniff.php',
+ 'Squiz/Sniffs/CSS/ColourDefinitionSniff.php',
+ 'Squiz/Sniffs/CSS/DuplicateClassDefinitionSniff.php',
+ 'Squiz/Sniffs/CSS/ClassDefinitionOpeningBraceSpaceSniff.php',
+
+ 'Squiz/Sniffs/Commenting/DocCommentAlignmentSniff.php',
+
+ );
+ }
+
+}//end class
diff --git a/_cs/DokuWiki/Sniffs/Functions/OpeningFunctionBraceSniff.php b/_cs/DokuWiki/Sniffs/Functions/OpeningFunctionBraceSniff.php
new file mode 100644
index 000000000..6c582b3af
--- /dev/null
+++ b/_cs/DokuWiki/Sniffs/Functions/OpeningFunctionBraceSniff.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Generic_Sniffs_Functions_OpeningFunctionBraceKernighanRitchieSniff.
+ */
+
+class DokuWiki_Sniffs_Functions_OpeningFunctionBraceSniff implements PHP_CodeSniffer_Sniff {
+
+
+ /**
+ * Registers the tokens that this sniff wants to listen for.
+ *
+ * @return void
+ */
+ public function register()
+ {
+ return array(T_FUNCTION);
+
+ }//end register()
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]['scope_opener']) === false) {
+ return;
+ }
+
+ $openingBrace = $tokens[$stackPtr]['scope_opener'];
+
+ // The end of the function occurs at the end of the argument list. Its
+ // like this because some people like to break long function declarations
+ // over multiple lines.
+ $functionLine = $tokens[$tokens[$stackPtr]['parenthesis_closer']]['line'];
+ $braceLine = $tokens[$openingBrace]['line'];
+
+ $lineDifference = ($braceLine - $functionLine);
+
+ if ($lineDifference > 0) {
+ $error = 'Opening brace should be on the same line as the declaration';
+ $phpcsFile->addError($error, $openingBrace);
+ return;
+ }
+
+ // Checks that the closing parenthesis and the opening brace are
+ // separated by a whitespace character.
+ $closerColumn = $tokens[$tokens[$stackPtr]['parenthesis_closer']]['column'];
+ $braceColumn = $tokens[$openingBrace]['column'];
+
+ $columnDifference = ($braceColumn - $closerColumn);
+
+ if ($columnDifference > 2) {
+ $error = 'Expected 0 or 1 space between the closing parenthesis and the opening brace; found '.($columnDifference - 1).'.';
+ $phpcsFile->addError($error, $openingBrace);
+ return;
+ }
+
+ // Check that a tab was not used instead of a space.
+ $spaceTokenPtr = ($tokens[$stackPtr]['parenthesis_closer'] + 1);
+ $spaceContent = $tokens[$spaceTokenPtr]['content'];
+ if ($columnDifference == 2 && $spaceContent !== ' ') {
+ $error = 'Expected a none or a single space character between closing parenthesis and opening brace; found "'.$spaceContent.'".';
+ $phpcsFile->addError($error, $openingBrace);
+ return;
+ }
+
+ }//end process()
+
+
+}//end class
+
+?>
diff --git a/_cs/DokuWiki/Sniffs/PHP/DiscouragedFunctionsSniff.php b/_cs/DokuWiki/Sniffs/PHP/DiscouragedFunctionsSniff.php
new file mode 100644
index 000000000..c95e0fd33
--- /dev/null
+++ b/_cs/DokuWiki/Sniffs/PHP/DiscouragedFunctionsSniff.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * DokuWiki_Sniffs_PHP_DiscouragedFunctionsSniff.
+ *
+ * PHP version 5
+ *
+ * @category PHP
+ * @package PHP_CodeSniffer
+ * @author Greg Sherwood <gsherwood@squiz.net>
+ * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
+ * @version CVS: $Id: DiscouragedFunctionsSniff.php 265110 2008-08-19 06:36:11Z squiz $
+ * @link http://pear.php.net/package/PHP_CodeSniffer
+ */
+
+if (class_exists('Generic_Sniffs_PHP_ForbiddenFunctionsSniff', true) === false) {
+ throw new PHP_CodeSniffer_Exception('Class Generic_Sniffs_PHP_ForbiddenFunctionsSniff not found');
+}
+
+/**
+ * DokuWiki_Sniffs_PHP_DiscouragedFunctionsSniff.
+ *
+ * @category PHP
+ * @package PHP_CodeSniffer
+ * @author Greg Sherwood <gsherwood@squiz.net>
+ * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
+ * @version Release: 1.2.2
+ * @link http://pear.php.net/package/PHP_CodeSniffer
+ */
+class DokuWiki_Sniffs_PHP_DiscouragedFunctionsSniff extends Generic_Sniffs_PHP_ForbiddenFunctionsSniff
+{
+
+ /**
+ * A list of forbidden functions with their alternatives.
+ *
+ * The value is NULL if no alternative exists. IE, the
+ * function should just not be used.
+ *
+ * @var array(string => string|null)
+ */
+ protected $forbiddenFunctions = array(
+ 'date' => 'dformat',
+ 'strftime' => 'dformat',
+ );
+
+ /**
+ * If true, an error will be thrown; otherwise a warning.
+ *
+ * @var bool
+ */
+ protected $error = false;
+
+}//end class
+
+?>
diff --git a/_cs/DokuWiki/Sniffs/WhiteSpace/ScopeIndentSniff.php b/_cs/DokuWiki/Sniffs/WhiteSpace/ScopeIndentSniff.php
new file mode 100644
index 000000000..72064bda0
--- /dev/null
+++ b/_cs/DokuWiki/Sniffs/WhiteSpace/ScopeIndentSniff.php
@@ -0,0 +1,319 @@
+<?php
+/**
+ * DokuWiki_Sniffs_Whitespace_ScopeIndentSniff based on
+ * Generic_Sniffs_Whitespace_ScopeIndentSniff.
+ *
+ * PHP version 5
+ *
+ * @category PHP
+ * @package PHP_CodeSniffer
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Greg Sherwood <gsherwood@squiz.net>
+ * @author Marc McIntyre <mmcintyre@squiz.net>
+ * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
+ * @version CVS: $Id: ScopeIndentSniff.php 270281 2008-12-02 02:38:34Z squiz $
+ * @link http://pear.php.net/package/PHP_CodeSniffer
+ */
+
+/**
+ * Generic_Sniffs_Whitespace_ScopeIndentSniff.
+ *
+ * Checks that control structures are structured correctly, and their content
+ * is indented correctly.
+ *
+ * @category PHP
+ * @package PHP_CodeSniffer
+ * @author Greg Sherwood <gsherwood@squiz.net>
+ * @author Marc McIntyre <mmcintyre@squiz.net>
+ * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
+ * @version Release: 1.2.0
+ * @link http://pear.php.net/package/PHP_CodeSniffer
+ */
+class DokuWiki_Sniffs_WhiteSpace_ScopeIndentSniff implements PHP_CodeSniffer_Sniff
+{
+
+ /**
+ * The number of spaces code should be indented.
+ *
+ * @var int
+ */
+ protected $indent = 4;
+
+ /**
+ * Does the indent need to be exactly right.
+ *
+ * If TRUE, indent needs to be exactly $ident spaces. If FALSE,
+ * indent needs to be at least $ident spaces (but can be more).
+ *
+ * @var bool
+ */
+ protected $exact = false;
+
+ /**
+ * Any scope openers that should not cause an indent.
+ *
+ * @var array(int)
+ */
+ protected $nonIndentingScopes = array();
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return PHP_CodeSniffer_Tokens::$scopeOpeners;
+
+ }//end register()
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // If this is an inline condition (ie. there is no scope opener), then
+ // return, as this is not a new scope.
+ if (isset($tokens[$stackPtr]['scope_opener']) === false) {
+ return;
+ }
+
+ if ($tokens[$stackPtr]['code'] === T_ELSE) {
+ $next = $phpcsFile->findNext(
+ PHP_CodeSniffer_Tokens::$emptyTokens,
+ ($stackPtr + 1),
+ null,
+ true
+ );
+
+ // We will handle the T_IF token in another call to process.
+ if ($tokens[$next]['code'] === T_IF) {
+ return;
+ }
+ }
+
+ // Find the first token on this line.
+ $firstToken = $stackPtr;
+ for ($i = $stackPtr; $i >= 0; $i--) {
+ // Record the first code token on the line.
+ if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$emptyTokens) === false) {
+ $firstToken = $i;
+ }
+
+ // It's the start of the line, so we've found our first php token.
+ if ($tokens[$i]['column'] === 1) {
+ break;
+ }
+ }
+
+ // Based on the conditions that surround this token, determine the
+ // indent that we expect this current content to be.
+ $expectedIndent = $this->calculateExpectedIndent($tokens, $firstToken);
+
+ if ($tokens[$firstToken]['column'] !== $expectedIndent) {
+ if($this->exact || $tokens[$firstToken]['column'] < $expectedIndent){
+ $error = 'Line indented incorrectly; expected ';
+ $error .= ($expectedIndent - 1).' spaces, found ';
+ $error .= ($tokens[$firstToken]['column'] - 1);
+ $phpcsFile->addError($error, $stackPtr);
+ }elseif((($tokens[$firstToken]['column'] - 1) % $this->indent)){
+ $error = 'Line indented not by multiple of '.$this->indent.'; expected ';
+ $error .= ($expectedIndent - 1).' spaces, found ';
+ $error .= ($tokens[$firstToken]['column'] - 1);
+ $phpcsFile->addError($error, $stackPtr);
+ }
+ }
+
+ $scopeOpener = $tokens[$stackPtr]['scope_opener'];
+ $scopeCloser = $tokens[$stackPtr]['scope_closer'];
+
+ // Some scopes are expected not to have indents.
+ if (in_array($tokens[$firstToken]['code'], $this->nonIndentingScopes) === false) {
+ $indent = ($expectedIndent + $this->indent);
+ } else {
+ $indent = $expectedIndent;
+ }
+
+ $newline = false;
+ $commentOpen = false;
+ $inHereDoc = false;
+
+ // Only loop over the content beween the opening and closing brace, not
+ // the braces themselves.
+ for ($i = ($scopeOpener + 1); $i < $scopeCloser; $i++) {
+
+ // If this token is another scope, skip it as it will be handled by
+ // another call to this sniff.
+ if (in_array($tokens[$i]['code'], PHP_CodeSniffer_Tokens::$scopeOpeners) === true) {
+ if (isset($tokens[$i]['scope_opener']) === true) {
+ $i = $tokens[$i]['scope_closer'];
+ } else {
+ // If this token does not have a scope_opener indice, then
+ // it's probably an inline scope, so let's skip to the next
+ // semicolon. Inline scopes include inline if's, abstract
+ // methods etc.
+ $nextToken = $phpcsFile->findNext(T_SEMICOLON, $i, $scopeCloser);
+ if ($nextToken !== false) {
+ $i = $nextToken;
+ }
+ }
+
+ continue;
+ }
+
+ // If this is a HEREDOC then we need to ignore it as the
+ // whitespace before the contents within the HEREDOC are
+ // considered part of the content.
+ if ($tokens[$i]['code'] === T_START_HEREDOC) {
+ $inHereDoc = true;
+ continue;
+ } else if ($inHereDoc === true) {
+ if ($tokens[$i]['code'] === T_END_HEREDOC) {
+ $inHereDoc = false;
+ }
+
+ continue;
+ }
+
+ if ($tokens[$i]['column'] === 1) {
+ // We started a newline.
+ $newline = true;
+ }
+
+ if ($newline === true && $tokens[$i]['code'] !== T_WHITESPACE) {
+ // If we started a newline and we find a token that is not
+ // whitespace, then this must be the first token on the line that
+ // must be indented.
+ $newline = false;
+ $firstToken = $i;
+
+ $column = $tokens[$firstToken]['column'];
+
+ // Special case for non-PHP code.
+ if ($tokens[$firstToken]['code'] === T_INLINE_HTML) {
+ $trimmedContentLength
+ = strlen(ltrim($tokens[$firstToken]['content']));
+ if ($trimmedContentLength === 0) {
+ continue;
+ }
+
+ $contentLength = strlen($tokens[$firstToken]['content']);
+ $column = ($contentLength - $trimmedContentLength + 1);
+ }
+
+ // Check to see if this constant string spans multiple lines.
+ // If so, then make sure that the strings on lines other than the
+ // first line are indented appropriately, based on their whitespace.
+ if (in_array($tokens[$firstToken]['code'], PHP_CodeSniffer_Tokens::$stringTokens) === true) {
+ if (in_array($tokens[($firstToken - 1)]['code'], PHP_CodeSniffer_Tokens::$stringTokens) === true) {
+ // If we find a string that directly follows another string
+ // then its just a string that spans multiple lines, so we
+ // don't need to check for indenting.
+ continue;
+ }
+ }
+
+ // This is a special condition for T_DOC_COMMENT and C-style
+ // comments, which contain whitespace between each line.
+ $comments = array(
+ T_COMMENT,
+ T_DOC_COMMENT
+ );
+
+ if (in_array($tokens[$firstToken]['code'], $comments) === true) {
+ $content = trim($tokens[$firstToken]['content']);
+ if (preg_match('|^/\*|', $content) !== 0) {
+ // Check to see if the end of the comment is on the same line
+ // as the start of the comment. If it is, then we don't
+ // have to worry about opening a comment.
+ if (preg_match('|\*/$|', $content) === 0) {
+ // We don't have to calculate the column for the
+ // start of the comment as there is a whitespace
+ // token before it.
+ $commentOpen = true;
+ }
+ } else if ($commentOpen === true) {
+ if ($content === '') {
+ // We are in a comment, but this line has nothing on it
+ // so let's skip it.
+ continue;
+ }
+
+ $contentLength = strlen($tokens[$firstToken]['content']);
+ $trimmedContentLength
+ = strlen(ltrim($tokens[$firstToken]['content']));
+
+ $column = ($contentLength - $trimmedContentLength + 1);
+ if (preg_match('|\*/$|', $content) !== 0) {
+ $commentOpen = false;
+ }
+ }//end if
+ }//end if
+
+ // The token at the start of the line, needs to have its' column
+ // greater than the relative indent we set above. If it is less,
+ // an error should be shown.
+ if ($column !== $indent) {
+ if ($this->exact === true || $column < $indent) {
+ $error = 'Line indented incorrectly; expected ';
+ if ($this->exact === false) {
+ $error .= 'at least ';
+ }
+
+ $error .= ($indent - 1).' spaces, found ';
+ $error .= ($column - 1);
+ $phpcsFile->addError($error, $firstToken);
+ }
+ }
+ }//end if
+ }//end for
+
+ }//end process()
+
+
+ /**
+ * Calculates the expected indent of a token.
+ *
+ * @param array $tokens The stack of tokens for this file.
+ * @param int $stackPtr The position of the token to get indent for.
+ *
+ * @return int
+ */
+ protected function calculateExpectedIndent(array $tokens, $stackPtr)
+ {
+ $conditionStack = array();
+
+ // Empty conditions array (top level structure).
+ if (empty($tokens[$stackPtr]['conditions']) === true) {
+ return 1;
+ }
+
+ $tokenConditions = $tokens[$stackPtr]['conditions'];
+ foreach ($tokenConditions as $id => $condition) {
+ // If it's an indenting scope ie. it's not in our array of
+ // scopes that don't indent, add it to our condition stack.
+ if (in_array($condition, $this->nonIndentingScopes) === false) {
+ $conditionStack[$id] = $condition;
+ }
+ }
+
+ return ((count($conditionStack) * $this->indent) + 1);
+
+ }//end calculateExpectedIndent()
+
+
+}//end class
+
+?>
diff --git a/_cs/README b/_cs/README
new file mode 100644
index 000000000..7aac73161
--- /dev/null
+++ b/_cs/README
@@ -0,0 +1,18 @@
+This directory contains the Coding Standard tests to be used with PHP
+CodeSniffer on DokuWiki's code.
+
+1. Install PHP CodeSniffer:
+
+ #> pear install PHP_CodeSniffer
+
+2. Link the Coding Standard to the CodeSniffer directory:
+
+ #> ln -s /path/to/dokuwiki/_cs/DokuWiki /usr/share/pear/PHP/CodeSniffer/Standards/DokuWiki
+
+3. Set DokuWiki to be the default standard:
+
+ #> phpcs --config-set default_standard DokuWiki
+
+
+
+The coding standard is work in progress.
diff --git a/_test/README b/_test/README
new file mode 100644
index 000000000..099290a0d
--- /dev/null
+++ b/_test/README
@@ -0,0 +1,84 @@
+--------------------------------------------------------------------------------
+ Dokuwiki Unit Test Suite
+--------------------------------------------------------------------------------
+$Date: 2004/02/14 02:14:50 $
+
+Credits: to the WACT team - http://www.phpwact.org, from whom the basis of
+this test suite was stolen
+
+--------------------------------------------------------------------------------
+INSTALLING & SETUP
+
+1. Grab a copy of the SimpleTest unit testing framework an extract somewhere
+
+ http://www.lastcraft.com/simple_test.php
+ or
+ http://sourceforge.net/projects/simpletest
+
+2. Edit ./tests.ini
+
+ - TEST_ENABLED - set to "1" to allow the test suite to be used
+ by vistors to your site. Generally best to leave as 0 for
+ a productive site - running tests alot will hammer the server
+ Note: you will still be able to run the tests from the command
+ line even when this is set to 0
+
+ - WEB_TEST_URL - this is for running "web tests" where SimpleTest
+ acts as a web browser and executes HTTP requests against pages.
+ Should point at your Dokuwiki URL e.g.
+
+ http://localhost/dokuwiki
+
+ - PROXY - if you're behind a proxy, specify it here
+ Note: username / password are optional e.g.
+
+ http://proxyuser:proxypwd@proxy.yourdomain.com:8080
+
+ - REMOTE_TEST_URL - it's possible to run the full test suite
+ remotely (over HTTP) with some XML goodness. This should
+ point at the URL of the test suite you want to test
+ See the following URL for more info;
+ http://www.sitepoint.com/blogs/2004/06/15/simple-test-remote-testing/
+
+ - Simple Test
+ Update the library_path to point at the directory where you installed
+ Simple Test
+
+--------------------------------------------------------------------------------
+RUNNING THE TESTS
+
+You can run the tests in three ways. From the command line:
+
+ $ ./runtests.php -h
+
+Using a web browser;
+
+ http://localhost/dokuwiki/_test/index.php
+
+As remote tests run on a remote serveri (specified in tests.ini with REMOTE_TEST_URL) and driven locally from the command line using;
+
+ $ ./remotetests.php -h
+
+
+--------------------------------------------------------------------------------
+ADDING TESTS
+
+The test cases are kept in the './cases' directory in a directory structure
+mirroring that of the Dokuwiki's
+
+Files with the extension .group.php are group tests (collections of
+one or more seperate unit test files) - there should be one group
+test per file in Dokuwiki's real directory.
+
+Individual tests files have the extension .test.php
+
+To add tests, create a .test.php file in the correct directory under ./cases
+Probably best to use one of the existing scripts as a basis
+
+The test will not be executable via one of the test runners (see above).
+
+To add it to a group of tests, modify the corresponding .group.php file.
+
+One exception to the naming convention - files named .webtest.php and
+.webgroup.php are run using SimpleTest's browser simulator.
+
diff --git a/_test/cases/inc/DifferenceEngine.test.php b/_test/cases/inc/DifferenceEngine.test.php
new file mode 100644
index 000000000..aa1756114
--- /dev/null
+++ b/_test/cases/inc/DifferenceEngine.test.php
@@ -0,0 +1,31 @@
+<?php
+require_once DOKU_INC.'inc/DifferenceEngine.php';
+
+class differenceengine_test extends UnitTestCase {
+
+ function test_white_between_words(){
+ // From FS#2161
+ global $lang;
+
+ $df = new Diff(explode("\n","example"),
+ explode("\n","example example2"));
+
+ $idf = new InlineDiffFormatter();
+ $tdf = new TableDiffFormatter();
+
+ $this->assertEqual($idf->format($df), '<tr><td colspan="4" class="diff-blockheader">@@ ' . $lang['line'] .
+ ' -1 +1 @@&nbsp;<span class="diff-deletedline"><del>' . $lang['deleted'] .
+ '</del></span>&nbsp;<span class="diff-addedline">' . $lang['created'] .
+ '</span></td></tr>
+
+<tr><td colspan="4">example&nbsp;<span class="diff-addedline">example2</span></td></tr>
+');
+ $this->assertEqual($tdf->format($df),
+ '<tr><td class="diff-blockheader" colspan="2">' . $lang['line'] . ' 1:</td>
+<td class="diff-blockheader" colspan="2">' . $lang['line'] . ' 1:</td>
+</tr>
+<tr><td>-</td><td class="diff-deletedline">example</td><td>+</td><td class="diff-addedline">example&nbsp;<strong>example2</strong></td></tr>
+');
+ }
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/IXR_Library_IXR_Message.test.php b/_test/cases/inc/IXR_Library_IXR_Message.test.php
new file mode 100644
index 000000000..bc9be572d
--- /dev/null
+++ b/_test/cases/inc/IXR_Library_IXR_Message.test.php
@@ -0,0 +1,139 @@
+<?php
+require_once DOKU_INC.'inc/IXR_Library.php';
+
+class ixr_library_ixr_message_test extends UnitTestCase {
+
+
+
+
+
+ function test_untypedvalue1(){
+ $xml = '<?xml version="1.0" encoding="UTF-8"?><methodCall><methodName>wiki.getBackLinks</methodName><params><param><value> change </value></param></params></methodCall>';
+
+ $ixrmsg = new IXR_Message($xml);
+ $ixrmsg->parse();
+
+ $this->assertEqual($ixrmsg->messageType,'methodCall');
+ $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+ $this->assertEqual($ixrmsg->params,array(' change '));
+ }
+
+ function test_untypedvalue2(){
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>
+ <methodCall>
+ <methodName>wiki.getBackLinks</methodName>
+ <params>
+ <param>
+ <value> change </value>
+ </param>
+ </params>
+ </methodCall>';
+
+ $ixrmsg = new IXR_Message($xml);
+ $ixrmsg->parse();
+
+ $this->assertEqual($ixrmsg->messageType,'methodCall');
+ $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+ $this->assertEqual($ixrmsg->params,array(' change '));
+ }
+
+ function test_stringvalue1(){
+ $xml = '<?xml version="1.0" encoding="UTF-8"?><methodCall><methodName>wiki.getBackLinks</methodName><params><param><value><string> change </string></value></param></params></methodCall>';
+
+ $ixrmsg = new IXR_Message($xml);
+ $ixrmsg->parse();
+
+ $this->assertEqual($ixrmsg->messageType,'methodCall');
+ $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+ $this->assertEqual($ixrmsg->params,array(' change '));
+ }
+
+ function test_stringvalue2(){
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>
+ <methodCall>
+ <methodName>wiki.getBackLinks</methodName>
+ <params>
+ <param>
+ <value>
+ <string> change </string>
+ </value>
+ </param>
+ </params>
+ </methodCall>';
+
+ $ixrmsg = new IXR_Message($xml);
+ $ixrmsg->parse();
+
+ $this->assertEqual($ixrmsg->messageType,'methodCall');
+ $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+ $this->assertEqual($ixrmsg->params,array(' change '));
+ }
+
+ function test_emptyvalue1(){
+ $xml = '<?xml version="1.0" encoding="UTF-8"?><methodCall><methodName>wiki.getBackLinks</methodName><params><param><value><string></string></value></param></params></methodCall>';
+
+ $ixrmsg = new IXR_Message($xml);
+ $ixrmsg->parse();
+
+ $this->assertEqual($ixrmsg->messageType,'methodCall');
+ $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+ $this->assertEqual($ixrmsg->params,array(''));
+ }
+
+ function test_emptyvalue2(){
+ $xml = '<?xml version="1.0" encoding="UTF-8"?>
+ <methodCall>
+ <methodName>wiki.getBackLinks</methodName>
+ <params>
+ <param>
+ <value>
+ <string></string>
+ </value>
+ </param>
+ </params>
+ </methodCall>';
+
+ $ixrmsg = new IXR_Message($xml);
+ $ixrmsg->parse();
+
+ $this->assertEqual($ixrmsg->messageType,'methodCall');
+ $this->assertEqual($ixrmsg->methodName,'wiki.getBackLinks');
+ $this->assertEqual($ixrmsg->params,array(''));
+ }
+
+ function test_struct(){
+ $xml = '<?xml version=\'1.0\'?>
+ <methodCall>
+ <methodName>wiki.putPage</methodName>
+ <params>
+ <param>
+ <value><string>start</string></value>
+ </param>
+ <param>
+ <value><string>test text</string></value>
+ </param>
+ <param>
+ <value><struct>
+ <member>
+ <name>sum</name>
+ <value><string>xmlrpc edit</string></value>
+ </member>
+ <member>
+ <name>minor</name>
+ <value><string>1</string></value>
+ </member>
+ </struct></value>
+ </param>
+ </params>
+ </methodCall>';
+
+ $ixrmsg = new IXR_Message($xml);
+ $ixrmsg->parse();
+
+ $this->assertEqual($ixrmsg->messageType,'methodCall');
+ $this->assertEqual($ixrmsg->methodName,'wiki.putPage');
+ $this->assertEqual($ixrmsg->params,array('start','test text',array('sum'=>'xmlrpc edit','minor'=>'1')));
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/IXR_Library_date.test.php b/_test/cases/inc/IXR_Library_date.test.php
new file mode 100644
index 000000000..28fa86486
--- /dev/null
+++ b/_test/cases/inc/IXR_Library_date.test.php
@@ -0,0 +1,34 @@
+<?php
+require_once DOKU_INC.'inc/IXR_Library.php';
+
+class ixr_library_date_test extends UnitTestCase {
+
+
+ function test_parseIso(){
+ // multiple tests
+ $tests = array(
+ // full datetime, different formats
+ array('2010-08-17T09:23:14', 1282036994),
+ array('20100817T09:23:14', 1282036994),
+ array('2010-08-17 09:23:14', 1282036994),
+ array('20100817 09:23:14', 1282036994),
+ array('2010-08-17T09:23:14Z', 1282036994),
+ array('20100817T09:23:14Z', 1282036994),
+
+ // no seconds
+ array('2010-08-17T09:23', 1282036980),
+ array('20100817T09:23', 1282036980),
+
+ // no time
+ array('2010-08-17', 1282003200),
+ //array('20100817', 1282003200), #this will NOT be parsed, but is assumed to be timestamp
+ );
+
+ foreach($tests as $test){
+ $dt = new IXR_Date($test[0]);
+ $this->assertEqual($dt->getTimeStamp(),$test[1]);
+ }
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/auth_aclcheck.test.php b/_test/cases/inc/auth_aclcheck.test.php
new file mode 100644
index 000000000..ff092c2de
--- /dev/null
+++ b/_test/cases/inc/auth_aclcheck.test.php
@@ -0,0 +1,231 @@
+<?php
+
+require_once DOKU_INC.'inc/init.php';
+require_once DOKU_INC.'inc/auth.php';
+
+class auth_acl_test extends UnitTestCase {
+
+ function teardown() {
+ global $conf;
+ global $AUTH_ACL;
+ unset($conf);
+ unset($AUTH_ACL);
+
+ }
+
+ function test_restricted(){
+ global $conf;
+ global $AUTH_ACL;
+ $conf['superuser'] = 'john';
+ $conf['useacl'] = 1;
+
+ $AUTH_ACL = array(
+ '* @ALL 0',
+ '* @user 8',
+ );
+
+ // anonymous user
+ $this->assertEqual(auth_aclcheck('page', '',array()), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:page','',array()), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:*', '',array()), AUTH_NONE);
+
+ // user with no matching group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo')), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo')), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo')), AUTH_NONE);
+
+ // user with matching group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo','user')), AUTH_UPLOAD);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo','user')), AUTH_UPLOAD);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo','user')), AUTH_UPLOAD);
+
+ // super user
+ $this->assertEqual(auth_aclcheck('page', 'john',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','john',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'john',array('foo')), AUTH_ADMIN);
+ }
+
+ function test_restricted_ropage(){
+ global $conf;
+ global $AUTH_ACL;
+ $conf['superuser'] = 'john';
+ $conf['useacl'] = 1;
+
+ $AUTH_ACL = array(
+ '* @ALL 0',
+ '* @user 8',
+ 'namespace:page @user 1',
+ );
+
+ // anonymous user
+ $this->assertEqual(auth_aclcheck('page', '',array()), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:page','',array()), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:*', '',array()), AUTH_NONE);
+
+ // user with no matching group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo')), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo')), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo')), AUTH_NONE);
+
+ // user with matching group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo','user')), AUTH_UPLOAD);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo','user')), AUTH_READ);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo','user')), AUTH_UPLOAD);
+
+ // super user
+ $this->assertEqual(auth_aclcheck('page', 'john',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','john',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'john',array('foo')), AUTH_ADMIN);
+ }
+
+ function test_aclexample(){
+ global $conf;
+ global $AUTH_ACL;
+ $conf['superuser'] = 'john';
+ $conf['useacl'] = 1;
+
+ $AUTH_ACL = array(
+ '* @ALL 4',
+ '* bigboss 16',
+ 'start @ALL 1',
+ 'marketing:* @marketing 8',
+ 'devel:* @ALL 0',
+ 'devel:* @devel 8',
+ 'devel:* bigboss 16',
+ 'devel:funstuff bigboss 0',
+ 'devel:* @marketing 1',
+ 'devel:marketing @marketing 2',
+ );
+
+
+ $this->assertEqual(auth_aclcheck('page', '' ,array()) , AUTH_CREATE);
+ $this->assertEqual(auth_aclcheck('page', 'bigboss' ,array('foo')) , AUTH_DELETE);
+ $this->assertEqual(auth_aclcheck('page', 'jill' ,array('marketing')) , AUTH_CREATE);
+ $this->assertEqual(auth_aclcheck('page', 'jane' ,array('devel')) , AUTH_CREATE);
+
+ $this->assertEqual(auth_aclcheck('start', '' ,array()) , AUTH_READ);
+ $this->assertEqual(auth_aclcheck('start', 'bigboss' ,array('foo')) , AUTH_READ);
+ $this->assertEqual(auth_aclcheck('start', 'jill' ,array('marketing')) , AUTH_READ);
+ $this->assertEqual(auth_aclcheck('start', 'jane' ,array('devel')) , AUTH_READ);
+
+ $this->assertEqual(auth_aclcheck('marketing:page', '' ,array()) , AUTH_CREATE);
+ $this->assertEqual(auth_aclcheck('marketing:page', 'bigboss' ,array('foo')) , AUTH_DELETE);
+ $this->assertEqual(auth_aclcheck('marketing:page', 'jill' ,array('marketing')) , AUTH_UPLOAD);
+ $this->assertEqual(auth_aclcheck('marketing:page', 'jane' ,array('devel')) , AUTH_CREATE);
+
+
+ $this->assertEqual(auth_aclcheck('devel:page', '' ,array()) , AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('devel:page', 'bigboss' ,array('foo')) , AUTH_DELETE);
+ $this->assertEqual(auth_aclcheck('devel:page', 'jill' ,array('marketing')) , AUTH_READ);
+ $this->assertEqual(auth_aclcheck('devel:page', 'jane' ,array('devel')) , AUTH_UPLOAD);
+
+ $this->assertEqual(auth_aclcheck('devel:funstuff', '' ,array()) , AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('devel:funstuff', 'bigboss' ,array('foo')) , AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('devel:funstuff', 'jill' ,array('marketing')) , AUTH_READ);
+ $this->assertEqual(auth_aclcheck('devel:funstuff', 'jane' ,array('devel')) , AUTH_UPLOAD);
+
+ $this->assertEqual(auth_aclcheck('devel:marketing', '' ,array()) , AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('devel:marketing', 'bigboss' ,array('foo')) , AUTH_DELETE);
+ $this->assertEqual(auth_aclcheck('devel:marketing', 'jill' ,array('marketing')) , AUTH_EDIT);
+ $this->assertEqual(auth_aclcheck('devel:marketing', 'jane' ,array('devel')) , AUTH_UPLOAD);
+
+ }
+
+ function test_multiadmin_restricted(){
+ global $conf;
+ global $AUTH_ACL;
+ $conf['superuser'] = 'john,@admin,doe,@roots';
+ $conf['useacl'] = 1;
+
+ $AUTH_ACL = array(
+ '* @ALL 0',
+ '* @user 8',
+ );
+
+ // anonymous user
+ $this->assertEqual(auth_aclcheck('page', '',array()), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:page','',array()), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:*', '',array()), AUTH_NONE);
+
+ // user with no matching group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo')), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo')), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo')), AUTH_NONE);
+
+ // user with matching group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo','user')), AUTH_UPLOAD);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo','user')), AUTH_UPLOAD);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo','user')), AUTH_UPLOAD);
+
+ // super user john
+ $this->assertEqual(auth_aclcheck('page', 'john',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','john',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'john',array('foo')), AUTH_ADMIN);
+
+ // super user doe
+ $this->assertEqual(auth_aclcheck('page', 'doe',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','doe',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'doe',array('foo')), AUTH_ADMIN);
+
+ // user with matching admin group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo','admin')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo','admin')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo','admin')), AUTH_ADMIN);
+
+ // user with matching another admin group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo','roots')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo','roots')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo','roots')), AUTH_ADMIN);
+ }
+
+ function test_multiadmin_restricted_ropage(){
+ global $conf;
+ global $AUTH_ACL;
+ $conf['superuser'] = 'john,@admin,doe,@roots';
+ $conf['useacl'] = 1;
+
+ $AUTH_ACL = array(
+ '* @ALL 0',
+ '* @user 8',
+ 'namespace:page @user 1',
+ );
+
+ // anonymous user
+ $this->assertEqual(auth_aclcheck('page', '',array()), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:page','',array()), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:*', '',array()), AUTH_NONE);
+
+ // user with no matching group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo')), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo')), AUTH_NONE);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo')), AUTH_NONE);
+
+ // user with matching group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo','user')), AUTH_UPLOAD);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo','user')), AUTH_READ);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo','user')), AUTH_UPLOAD);
+
+ // super user john
+ $this->assertEqual(auth_aclcheck('page', 'john',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','john',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'john',array('foo')), AUTH_ADMIN);
+
+ // super user doe
+ $this->assertEqual(auth_aclcheck('page', 'doe',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','doe',array('foo')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'doe',array('foo')), AUTH_ADMIN);
+
+ // user with matching admin group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo','admin')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo','admin')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo','admin')), AUTH_ADMIN);
+
+ // user with matching another admin group
+ $this->assertEqual(auth_aclcheck('page', 'jill',array('foo','roots')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:page','jill',array('foo','roots')), AUTH_ADMIN);
+ $this->assertEqual(auth_aclcheck('namespace:*', 'jill',array('foo','roots')), AUTH_ADMIN);
+ }
+
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/auth_admincheck.test.php b/_test/cases/inc/auth_admincheck.test.php
new file mode 100644
index 000000000..2a420ffd4
--- /dev/null
+++ b/_test/cases/inc/auth_admincheck.test.php
@@ -0,0 +1,132 @@
+<?php
+
+require_once DOKU_INC.'inc/init.php';
+require_once DOKU_INC.'inc/auth.php';
+require_once DOKU_INC.'inc/auth/basic.class.php';
+
+class auth_admin_test_AuthInSensitive extends auth_basic {
+ function isCaseSensitive(){
+ return false;
+ }
+}
+
+class auth_admin_test extends UnitTestCase {
+
+ private $oldauth;
+
+ function setup() {
+ global $auth;
+ $this->oldauth = $auth;
+ parent::setup();
+ }
+
+ function setSensitive() {
+ global $auth;
+ $auth = new auth_basic;
+ }
+
+ function setInSensitive() {
+ global $auth;
+ $auth = new auth_admin_test_AuthInSensitive;
+ }
+
+ function teardown() {
+ global $auth;
+ global $conf;
+ global $AUTH_ACL;
+ unset($conf);
+ unset($AUTH_ACL);
+ $auth = $this->oldauth;
+ parent::teardown();
+ }
+
+ function test_ismanager_insensitive(){
+ $this->setInSensitive();
+ global $conf;
+ $conf['superuser'] = 'john,@admin,@Mötly Görls, Dörte';
+ $conf['manager'] = 'john,@managers,doe, @Mötly Böys, Dänny';
+
+ // anonymous user
+ $this->assertEqual(auth_ismanager('jill', null,false), false);
+
+ // admin or manager users
+ $this->assertEqual(auth_ismanager('john', null,false), true);
+ $this->assertEqual(auth_ismanager('doe', null,false), true);
+
+ $this->assertEqual(auth_ismanager('dörte', null,false), true);
+ $this->assertEqual(auth_ismanager('dänny', null,false), true);
+
+ // admin or manager groups
+ $this->assertEqual(auth_ismanager('jill', array('admin'),false), true);
+ $this->assertEqual(auth_ismanager('jill', array('managers'),false), true);
+
+ $this->assertEqual(auth_ismanager('jill', array('mötly görls'),false), true);
+ $this->assertEqual(auth_ismanager('jill', array('mötly böys'),false), true);
+ }
+
+ function test_isadmin_insensitive(){
+ $this->setInSensitive();
+ global $conf;
+ $conf['superuser'] = 'john,@admin,doe,@roots';
+
+ // anonymous user
+ $this->assertEqual(auth_ismanager('jill', null,true), false);
+
+ // admin user
+ $this->assertEqual(auth_ismanager('john', null,true), true);
+ $this->assertEqual(auth_ismanager('doe', null,true), true);
+
+ // admin groups
+ $this->assertEqual(auth_ismanager('jill', array('admin'),true), true);
+ $this->assertEqual(auth_ismanager('jill', array('roots'),true), true);
+ $this->assertEqual(auth_ismanager('john', array('admin'),true), true);
+ $this->assertEqual(auth_ismanager('doe', array('admin'),true), true);
+ }
+
+ function test_ismanager_sensitive(){
+ $this->setSensitive();
+ global $conf;
+ $conf['superuser'] = 'john,@admin,@Mötly Görls, Dörte';
+ $conf['manager'] = 'john,@managers,doe, @Mötly Böys, Dänny';
+
+ // anonymous user
+ $this->assertEqual(auth_ismanager('jill', null,false), false);
+
+ // admin or manager users
+ $this->assertEqual(auth_ismanager('john', null,false), true);
+ $this->assertEqual(auth_ismanager('doe', null,false), true);
+
+ $this->assertEqual(auth_ismanager('dörte', null,false), false);
+ $this->assertEqual(auth_ismanager('dänny', null,false), false);
+
+ // admin or manager groups
+ $this->assertEqual(auth_ismanager('jill', array('admin'),false), true);
+ $this->assertEqual(auth_ismanager('jill', array('managers'),false), true);
+
+ $this->assertEqual(auth_ismanager('jill', array('mötly görls'),false), false);
+ $this->assertEqual(auth_ismanager('jill', array('mötly böys'),false), false);
+ }
+
+ function test_isadmin_sensitive(){
+ $this->setSensitive();
+ global $conf;
+ $conf['superuser'] = 'john,@admin,doe,@roots';
+
+ // anonymous user
+ $this->assertEqual(auth_ismanager('jill', null,true), false);
+
+ // admin user
+ $this->assertEqual(auth_ismanager('john', null,true), true);
+ $this->assertEqual(auth_ismanager('Doe', null,true), false);
+
+ // admin groups
+ $this->assertEqual(auth_ismanager('jill', array('admin'),true), true);
+ $this->assertEqual(auth_ismanager('jill', array('roots'),true), true);
+ $this->assertEqual(auth_ismanager('john', array('admin'),true), true);
+ $this->assertEqual(auth_ismanager('doe', array('admin'),true), true);
+ $this->assertEqual(auth_ismanager('Doe', array('admin'),true), true);
+ }
+
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/auth_nameencode.test.php b/_test/cases/inc/auth_nameencode.test.php
new file mode 100644
index 000000000..56806a862
--- /dev/null
+++ b/_test/cases/inc/auth_nameencode.test.php
@@ -0,0 +1,50 @@
+<?php
+
+require_once DOKU_INC.'inc/init.php';
+require_once DOKU_INC.'inc/auth.php';
+
+class auth_nameencode_test extends UnitTestCase {
+
+ function teardown() {
+ global $cache_authname;
+ $cache_authname = array();
+ }
+
+ function test_simple(){
+ $in = 'hey$you';
+ $out = 'hey%24you';
+ $this->assertEqual(auth_nameencode($in),$out);
+ }
+
+ function test_quote(){
+ $in = 'hey"you';
+ $out = 'hey%22you';
+ $this->assertEqual(auth_nameencode($in),$out);
+ }
+
+ function test_complex(){
+ $in = 'hey $ you !$%! foo ';
+ $out = 'hey%20%24%20you%20%21%24%25%21%20foo%20';
+ $this->assertEqual(auth_nameencode($in),$out);
+ }
+
+ function test_complexutf8(){
+ $in = 'häü $ yü !$%! foo ';
+ $out = 'häü%20%24%20yü%20%21%24%25%21%20foo%20';
+ $this->assertEqual(auth_nameencode($in),$out);
+ }
+
+ function test_groupskipon(){
+ $in = '@hey$you';
+ $out = '@hey%24you';
+ $this->assertEqual(auth_nameencode($in,true),$out);
+ }
+
+ function test_groupskipoff(){
+ $in = '@hey$you';
+ $out = '%40hey%24you';
+ $this->assertEqual(auth_nameencode($in),$out);
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/auth_password.test.php b/_test/cases/inc/auth_password.test.php
new file mode 100644
index 000000000..394f0b2f5
--- /dev/null
+++ b/_test/cases/inc/auth_password.test.php
@@ -0,0 +1,68 @@
+<?php
+
+require_once DOKU_INC.'inc/init.php';
+require_once DOKU_INC.'inc/auth.php';
+
+class auth_password_test extends UnitTestCase {
+
+ // hashes for the password foo$method, using abcdefgh as salt
+ var $passes = array(
+ 'smd5' => '$1$abcdefgh$SYbjm2AEvSoHG7Xapi8so.',
+ 'apr1' => '$apr1$abcdefgh$C/GzYTF4kOVByYLEoD5X4.',
+ 'md5' => '8fa22d62408e5351553acdd91c6b7003',
+ 'sha1' => 'b456d3b0efd105d613744ffd549514ecafcfc7e1',
+ 'ssha' => '{SSHA}QMHG+uC7bHNYKkmoLbNsNI38/dJhYmNk',
+ 'lsmd5' => '{SMD5}HGbkPrkWgy9KgcRGWlrsUWFiY2RlZmdo',
+ 'crypt' => 'ablvoGr1hvZ5k',
+ 'mysql' => '4a1fa3780bd6fd55',
+ 'my411' => '*e5929347e25f82e19e4ebe92f1dc6b6e7c2dbd29',
+ 'kmd5' => 'a579299436d7969791189acadd86fcb716',
+ 'pmd5' => '$P$abcdefgh1RC6Fd32heUzl7EYCG9uGw.',
+ 'hmd5' => '$H$abcdefgh1ZbJodHxmeXVAhEzTG7IAp.',
+ 'djangomd5' => 'md5$abcde$d0fdddeda8cd92725d2b54148ac09158',
+ 'djangosha1' => 'sha1$abcde$c8e65a7f0acc9158843048a53dcc5a6bc4d17678',
+ );
+
+
+ function test_cryptPassword(){
+ foreach($this->passes as $method => $hash){
+ $info = "testing method $method";
+ $this->signal('failinfo',$info);
+ $this->assertEqual(auth_cryptPassword('foo'.$method,$method,'abcdefgh12345678912345678912345678'),$hash);
+ }
+ }
+
+ function test_verifyPassword(){
+ foreach($this->passes as $method => $hash){
+ $info = "testing method $method";
+ $this->signal('failinfo',$info);
+ $this->assertTrue(auth_verifyPassword('foo'.$method,$hash));
+ }
+ }
+
+ function test_verifySelf(){
+ foreach($this->passes as $method => $hash){
+ $info = "testing method $method";
+ $this->signal('failinfo',$info);
+ $hash = auth_cryptPassword('foo'.$method,$method);
+ $this->assertTrue(auth_verifyPassword('foo'.$method,$hash));
+ }
+ }
+
+ function test_bcrypt_self(){
+ $hash = auth_cryptPassword('foobcrypt','bcrypt');
+ $this->assertTrue(auth_verifyPassword('foobcrypt',$hash));
+ }
+
+ function test_verifyPassword_nohash(){
+ $this->assertTrue(auth_verifyPassword('foo','$1$$n1rTiFE0nRifwV/43bVon/'));
+ }
+
+ function test_verifyPassword_fixedpmd5(){
+ $this->assertTrue(auth_verifyPassword('test12345','$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'));
+ $this->assertTrue(auth_verifyPassword('test12345','$H$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'));
+ }
+
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/common_clientip.test.php b/_test/cases/inc/common_clientip.test.php
new file mode 100644
index 000000000..68c108165
--- /dev/null
+++ b/_test/cases/inc/common_clientip.test.php
@@ -0,0 +1,155 @@
+<?php
+
+require_once DOKU_INC.'inc/init.php';
+require_once DOKU_INC.'inc/common.php';
+
+class common_clientIP_test extends UnitTestCase {
+
+ function test_simple_all(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '';
+ $out = '123.123.123.123';
+ $this->assertEqual(clientIP(),$out);
+ }
+
+ function test_proxy1_all(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '77.77.77.77';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '';
+ $out = '123.123.123.123,77.77.77.77';
+ $this->assertEqual(clientIP(),$out);
+ }
+
+ function test_proxy2_all(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77';
+ $out = '123.123.123.123,77.77.77.77';
+ $this->assertEqual(clientIP(),$out);
+ }
+
+ function test_proxyhops_all(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77,66.66.66.66';
+ $out = '123.123.123.123,77.77.77.77,66.66.66.66';
+ $this->assertEqual(clientIP(),$out);
+ }
+
+ function test_simple_single(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '';
+ $out = '123.123.123.123';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_proxy1_single(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '77.77.77.77';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '';
+ $out = '77.77.77.77';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_proxy2_single(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77';
+ $out = '77.77.77.77';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_proxyhops_single(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '77.77.77.77,66.66.66.66';
+ $out = '66.66.66.66';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_local_all(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1';
+ $out = '123.123.123.123,127.0.0.1';
+ $this->assertEqual(clientIP(),$out);
+ }
+
+ function test_local1_single(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1';
+ $out = '123.123.123.123';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_local2_single(){
+ $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '123.123.123.123';
+ $out = '123.123.123.123';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_local3_single(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.1,10.0.0.1,192.168.0.2,172.17.1.1,172.21.1.1,172.31.1.1';
+ $out = '123.123.123.123';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_local4_single(){
+ $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '192.168.0.5';
+ $out = '192.168.0.5';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_garbage_all(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = 'some garbage, or something, 222';
+ $out = '123.123.123.123';
+ $this->assertEqual(clientIP(),$out);
+ }
+
+ function test_garbage_single(){
+ $_SERVER['REMOTE_ADDR'] = '123.123.123.123';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = 'some garbage, or something, 222';
+ $out = '123.123.123.123';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_garbageonly_all(){
+ $_SERVER['REMOTE_ADDR'] = 'argh';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = 'some garbage, or something, 222';
+ $out = '0.0.0.0';
+ $this->assertEqual(clientIP(),$out);
+ }
+
+ function test_garbageonly_single(){
+ $_SERVER['REMOTE_ADDR'] = 'argh';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = 'some garbage, or something, 222';
+ $out = '0.0.0.0';
+ $this->assertEqual(clientIP(true),$out);
+ }
+
+ function test_malicious(){
+ $_SERVER['REMOTE_ADDR'] = '';
+ $_SERVER['HTTP_X_REAL_IP'] = '';
+ $_SERVER['HTTP_X_FORWARDED_FOR'] = '<?php set_time_limit(0);echo \'my_delim\';passthru(123.123.123.123);die;?>';
+ $out = '0.0.0.0';
+ $this->assertEqual(clientIP(),$out);
+ }
+
+
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/common_obfuscate.test.php b/_test/cases/inc/common_obfuscate.test.php
new file mode 100644
index 000000000..31321bea1
--- /dev/null
+++ b/_test/cases/inc/common_obfuscate.test.php
@@ -0,0 +1,28 @@
+<?php
+
+require_once DOKU_INC.'inc/common.php';
+
+class common_obfuscate_test extends UnitTestCase {
+
+ function test_none(){
+ global $conf;
+ $conf['mailguard'] = 'none';
+ $this->assertEqual(obfuscate('jon-doe@example.com'), 'jon-doe@example.com');
+ }
+
+ function test_hex(){
+ global $conf;
+ $conf['mailguard'] = 'hex';
+ $this->assertEqual(obfuscate('jon-doe@example.com'),
+ '&#x6a;&#x6f;&#x6e;&#x2d;&#x64;&#x6f;&#x65;&#x40;&#x65;&#x78;&#x61;&#x6d;&#x70;&#x6c;&#x65;&#x2e;&#x63;&#x6f;&#x6d;');
+ }
+
+ function test_visible(){
+ global $conf;
+ $conf['mailguard'] = 'visible';
+ $this->assertEqual(obfuscate('jon-doe@example.com'), 'jon [dash] doe [at] example [dot] com');
+ }
+
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/common_pagetemplate.test.php b/_test/cases/inc/common_pagetemplate.test.php
new file mode 100644
index 000000000..2db8b64ae
--- /dev/null
+++ b/_test/cases/inc/common_pagetemplate.test.php
@@ -0,0 +1,19 @@
+<?php
+
+require_once DOKU_INC.'inc/common.php';
+
+class common_pagetemplate_test extends UnitTestCase {
+
+ function test_none(){
+ global $conf;
+ $conf['sepchar'] = '-';
+ $data = array(
+ 'id' => 'page-id-long',
+ 'tpl' => '"@PAGE@" "@!PAGE@" "@!!PAGE@" "@!PAGE!@"',
+ );
+ $old = error_reporting(E_ALL & ~E_NOTICE);
+ $this->assertEqual(parsePageTemplate($data), '"page id long" "Page id long" "Page Id Long" "PAGE ID LONG"');
+ error_reporting($old);
+ }
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/form_form.test.php b/_test/cases/inc/form_form.test.php
new file mode 100644
index 000000000..5d5fa72af
--- /dev/null
+++ b/_test/cases/inc/form_form.test.php
@@ -0,0 +1,105 @@
+<?php
+
+require_once DOKU_INC.'inc/auth.php';
+require_once DOKU_INC.'inc/form.php';
+
+class form_test extends UnitTestCase {
+
+ function _testform() {
+ $form = new Doku_Form(array('id' => 'dw__testform', 'action' => '/test'));
+ $form->startFieldset('Test');
+ $form->addHidden('summary', 'changes &c');
+ $form->addElement(form_makeTextField('t', 'v', 'Text', 'text__id', 'block'));
+ $form->addElement(form_makeCheckboxField('r', '1', 'Check', 'check__id', 'simple'));
+ $form->addElement(form_makeButton('submit', 'save', 'Save', array('accesskey'=>'s')));
+ $form->addElement(form_makeButton('submit', 'cancel', 'Cancel'));
+ $form->endFieldset();
+ return $form;
+ }
+
+ function _realoutput() {
+ global $lang;
+ $realoutput = '<form id="dw__testform" action="/test" method="post" ';
+ $realoutput .= 'accept-charset="'.$lang['encoding'].'">';
+ $realoutput .= "\n";
+ $realoutput .= '<div class="no"><input type="hidden" name="sectok" value="'.getSecurityToken().'" />';
+ $realoutput .= '<input type="hidden" name="summary" value="changes &amp;c" />';
+ $realoutput .= "\n";
+ $realoutput .= "<fieldset ><legend>Test</legend>\n";
+ $realoutput .= '<label class="block" for="text__id"><span>Text</span> ';
+ $realoutput .= '<input type="text" id="text__id" name="t" value="v" class="edit" /></label><br />';
+ $realoutput .= "\n";
+ $realoutput .= '<label class="simple" for="check__id">';
+ $realoutput .= '<input type="checkbox" id="check__id" name="r" value="1" /> ';
+ $realoutput .= '<span>Check</span></label>';
+ $realoutput .= "\n";
+ $realoutput .= '<input name="do[save]" type="submit" value="Save" class="button" accesskey="s" title="Save [S]" />';
+ $realoutput .= "\n";
+ $realoutput .= '<input name="do[cancel]" type="submit" value="Cancel" class="button" />';
+ $realoutput .= "\n";
+ $realoutput .= "</fieldset>\n</div></form>\n";
+ return $realoutput;
+ }
+
+ function _ignoreTagWS($data){
+ return preg_replace('/>\s+</','><',$data);
+ }
+
+ function test_form_print() {
+ $form = $this->_testform();
+ ob_start();
+ $form->printForm();
+ $output = ob_get_contents();
+ ob_end_clean();
+ $form->addHidden('sectok', getSecurityToken());
+ $this->assertEqual($this->_ignoreTagWS($output),$this->_ignoreTagWS($this->_realoutput()));
+ }
+
+ function test_get_element_at() {
+ $form = $this->_testform();
+ $e1 =& $form->getElementAt(1);
+ $this->assertEqual($e1, array('_elem'=>'textfield',
+ '_text'=>'Text',
+ '_class'=>'block',
+ 'id'=>'text__id',
+ 'name'=>'t',
+ 'value'=>'v',
+ 'class'=>'edit'));
+ $e2 =& $form->getElementAt(99);
+ $this->assertEqual($e2, array('_elem'=>'closefieldset'));
+ }
+
+ function test_find_element_by_type() {
+ $form = $this->_testform();
+ $this->assertEqual($form->findElementByType('button'), 3);
+ $this->assertFalse($form->findElementByType('text'));
+ }
+
+ function test_find_element_by_id() {
+ $form = $this->_testform();
+ $this->assertEqual($form->findElementById('check__id'), 2);
+ $this->assertFalse($form->findElementById('dw__testform'));
+ }
+
+ function test_find_element_by_attribute() {
+ $form = $this->_testform();
+ $this->assertEqual($form->findElementByAttribute('value','Cancel'), 4);
+ $this->assertFalse($form->findElementByAttribute('name','cancel'));
+ }
+
+ function test_close_fieldset() {
+ $form = new Doku_Form(array('id' => 'dw__testform', 'action' => '/test'));
+ $form->startFieldset('Test');
+ $form->addHidden('summary', 'changes &c');
+ $form->addElement(form_makeTextField('t', 'v', 'Text', 'text__id', 'block'));
+ $form->addElement(form_makeCheckboxField('r', '1', 'Check', 'check__id', 'simple'));
+ $form->addElement(form_makeButton('submit', 'save', 'Save', array('accesskey'=>'s')));
+ $form->addElement(form_makeButton('submit', 'cancel', 'Cancel'));
+ ob_start();
+ $form->printForm();
+ $output = ob_get_contents();
+ ob_end_clean();
+ $this->assertEqual($this->_ignoreTagWS($output),$this->_ignoreTagWS($this->_realoutput()));
+ }
+
+}
diff --git a/_test/cases/inc/html_hilight.test.php b/_test/cases/inc/html_hilight.test.php
new file mode 100644
index 000000000..cc5579c71
--- /dev/null
+++ b/_test/cases/inc/html_hilight.test.php
@@ -0,0 +1,104 @@
+<?php
+
+require_once DOKU_INC.'inc/html.php';
+
+if (!extension_loaded('runkit')) {
+ SimpleTestOptions::ignore('html_hilight_test');
+ trigger_error('Skipping html_hilight_test - http://www.php.net/runkit required');
+}
+
+function html_hilight_test_unslash($string,$char="'"){
+ $str= str_replace('\\'.$char,$char,$string);
+ return $str;
+}
+
+class html_hilight_test extends UnitTestCase{
+
+ function setup() {
+ if ( function_exists('unslash') ) {
+ runkit_function_rename('unslash','html_hilight_test_unslash_real');
+ }
+ runkit_function_rename('html_hilight_test_unslash','unslash');
+ }
+
+ function teardown() {
+ runkit_function_rename('unslash','html_hilight_test_unslash');
+ if ( function_exists('html_hilight_test_unslash_real') ) {
+ runkit_function_rename('html_hilight_test_unslash_real','unslash');
+ }
+ }
+
+ function testHighlightOneWord() {
+ $html = 'Foo bar Foo';
+ $this->assertPattern(
+ '/Foo <span.*>bar<\/span> Foo/',
+ html_hilight($html,'bar')
+ );
+ }
+
+ function testHighlightTwoWords() {
+ $html = 'Foo bar Foo php Foo';
+ $this->assertPattern(
+ '/Foo <span.*>bar<\/span> Foo <span.*>php<\/span> Foo/',
+ html_hilight($html,array('bar','php'))
+ );
+ }
+
+ function testHighlightTwoWordsHtml() {
+ $html = 'Foo <b>bar</b> <i>Foo</i> php Foo';
+ $this->assertPattern(
+ '/Foo <b><span.*>bar<\/span><\/b> <i>Foo<\/i> <span.*>php<\/span> Foo/',
+ html_hilight($html,array('bar','php'))
+ );
+ }
+
+ function testNoHighlight() {
+ $html = 'Foo bar Foo';
+ $this->assertPattern(
+ '/Foo bar Foo/',
+ html_hilight($html,'php')
+ );
+ }
+
+ function testHighlightPHP() {
+ $html = 'Foo $_GET[\'bar\'] Foo';
+ $this->assertEqual(
+ 'Foo <span class="search_hit">$_GET[\'bar\']</span> Foo',
+ html_hilight($html,'$_GET[\'bar\']')
+ );
+ }
+
+ function testMatchAttribute() {
+ $html = 'Foo <b class="x">bar</b> Foo';
+ $this->assertPattern(
+ '/Foo <b class="x">bar<\/b> Foo/',
+ html_hilight($html,'class="x"')
+ );
+ }
+
+ function testMatchAttributeWord() {
+ $html = 'Foo <b class="x">bar</b> Foo';
+ $this->assertEqual(
+ 'Foo <b class="x">bar</b> Foo',
+ html_hilight($html,'class="x">bar')
+ );
+ }
+
+ function testRegexInjection() {
+ $html = 'Foo bar Foo';
+ $this->assertPattern(
+ '/Foo bar Foo/',
+ html_hilight($html,'*')
+ );
+ }
+
+ function testRegexInjectionSlash() {
+ $html = 'Foo bar Foo';
+ $this->assertPattern(
+ '/Foo bar Foo/',
+ html_hilight($html,'x/')
+ );
+ }
+
+}
+
diff --git a/_test/cases/inc/indexer_idx_indexlengths.test.php b/_test/cases/inc/indexer_idx_indexlengths.test.php
new file mode 100644
index 000000000..a0f7c9224
--- /dev/null
+++ b/_test/cases/inc/indexer_idx_indexlengths.test.php
@@ -0,0 +1,60 @@
+<?php
+
+require_once DOKU_INC.'inc/indexer.php';
+
+class indexer_idx_indexlengths_test extends UnitTestCase {
+
+ /**
+ * Test the function with an array of one value
+ */
+ function test_oneWord(){
+ global $conf;
+ $filter[8] = array('dokuwiki');
+ // one word should return the index
+ $ref[] = 8;
+ sort($ref);
+ $result = idx_indexLengths(&$filter);
+ sort($result);
+ $this->assertIdentical($result, $ref);
+ }
+
+ /**
+ * Test the function with an array of values
+ */
+ function test_moreWords() {
+ global $conf;
+ $filter = array( 4 => array('test'), 8 => array('dokuwiki'), 7 => array('powered'));
+ // more words should return the indexes
+ $ref = array(4, 7, 8);
+ sort($ref);
+ $result = idx_indexLengths(&$filter);
+ sort($result);
+ $this->assertIdentical($result, $ref);
+ }
+
+ /**
+ * Test a minimal value in case of wildcard search
+ */
+ function test_minValue() {
+ global $conf;
+ $filter = 5;
+ // construction of the list of the index to compare
+ $dir = @opendir($conf['indexdir']);
+ $ref = 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) && $i >= $filter)
+ $ref[] = (int)$i;
+ }
+ }
+ closedir($dir);
+ sort($ref);
+ $result = idx_indexLengths(&$filter);
+ sort($result);
+ $this->assertIdentical($result, $ref);
+ }
+}
+
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/init_fullpath.test.php b/_test/cases/inc/init_fullpath.test.php
new file mode 100644
index 000000000..aa63b0ce9
--- /dev/null
+++ b/_test/cases/inc/init_fullpath.test.php
@@ -0,0 +1,89 @@
+<?php
+require_once DOKU_INC.'inc/init.php';
+
+class init_fullpath_test extends UnitTestCase {
+
+ function test_unix_paths(){
+ $base = $_SERVER['SCRIPT_FILENAME'];
+ $_SERVER['SCRIPT_FILENAME'] = '/absolute/path/self.php';
+ $GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS'] = false;
+
+ // paths to check
+ $tests = array(
+ '/foo/bar/baz' => '/foo/bar/baz',
+ '/foo//bar/baz' => '/foo/bar/baz',
+ '/foo/../bar/baz' => '/bar/baz',
+ '/foo/./bar/baz' => '/foo/bar/baz',
+ '/foo/bar/..' => '/foo',
+ '/foo/bar/../../../baz' => '/baz',
+
+ 'foo/bar/baz' => '/absolute/path/foo/bar/baz',
+ 'foo//bar/baz' => '/absolute/path/foo/bar/baz',
+ 'foo/../bar/baz' => '/absolute/path/bar/baz',
+ 'foo/./bar/baz' => '/absolute/path/foo/bar/baz',
+ 'foo/bar/..' => '/absolute/path/foo',
+ 'foo/bar/../../../baz' => '/absolute/baz',
+ );
+
+ foreach($tests as $from => $to){
+ $info = "Testing '$from' resulted in '".fullpath($from)."'";
+ $this->signal('failinfo',$info);
+
+ $this->assertEqual(fullpath($from),$to);
+ }
+
+
+ $_SERVER['SCRIPT_FILENAME'] = $base;
+ unset($GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS']);
+ }
+
+ function test_windows_paths(){
+ $base = $_SERVER['SCRIPT_FILENAME'];
+ $_SERVER['SCRIPT_FILENAME'] = '/absolute/path/self.php';
+ $GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS'] = true;
+
+ // paths to check
+ $tests = array(
+ 'c:foo/bar/baz' => 'c:/foo/bar/baz',
+ 'c:foo//bar/baz' => 'c:/foo/bar/baz',
+ 'c:foo/../bar/baz' => 'c:/bar/baz',
+ 'c:foo/./bar/baz' => 'c:/foo/bar/baz',
+ 'c:foo/bar/..' => 'c:/foo',
+ 'c:foo/bar/../../../baz' => 'c:/baz',
+
+ 'c:/foo/bar/baz' => 'c:/foo/bar/baz',
+ 'c:/foo//bar/baz' => 'c:/foo/bar/baz',
+ 'c:/foo/../bar/baz' => 'c:/bar/baz',
+ 'c:/foo/./bar/baz' => 'c:/foo/bar/baz',
+ 'c:/foo/bar/..' => 'c:/foo',
+ 'c:/foo/bar/../../../baz' => 'c:/baz',
+
+ 'c:\\foo\\bar\\baz' => 'c:/foo/bar/baz',
+ 'c:\\foo\\\\bar\\baz' => 'c:/foo/bar/baz',
+ 'c:\\foo\\..\\bar\\baz' => 'c:/bar/baz',
+ 'c:\\foo\\.\\bar\\baz' => 'c:/foo/bar/baz',
+ 'c:\\foo\\bar\\..' => 'c:/foo',
+ 'c:\\foo\\bar\\..\\..\\..\\baz' => 'c:/baz',
+
+ '\\\\server\\share/foo/bar/baz' => '\\\\server\\share/foo/bar/baz',
+ '\\\\server\\share/foo//bar/baz' => '\\\\server\\share/foo/bar/baz',
+ '\\\\server\\share/foo/../bar/baz' => '\\\\server\\share/bar/baz',
+ '\\\\server\\share/foo/./bar/baz' => '\\\\server\\share/foo/bar/baz',
+ '\\\\server\\share/foo/bar/..' => '\\\\server\\share/foo',
+ '\\\\server\\share/foo/bar/../../../baz' => '\\\\server\\share/baz',
+ );
+
+ foreach($tests as $from => $to){
+ $info = "Testing '$from' resulted in '".fullpath($from)."'";
+ $this->signal('failinfo',$info);
+
+ $this->assertEqual(fullpath($from),$to);
+ }
+
+
+ $_SERVER['SCRIPT_FILENAME'] = $base;
+ unset($GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS']);
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/init_getbaseurl.test.php b/_test/cases/inc/init_getbaseurl.test.php
new file mode 100644
index 000000000..a22172feb
--- /dev/null
+++ b/_test/cases/inc/init_getbaseurl.test.php
@@ -0,0 +1,305 @@
+<?php
+
+require_once DOKU_INC.'inc/init.php';
+
+class init_getBaseURL_test extends UnitTestCase {
+
+ /**
+ * Apache, mod_php, subdirectory
+ *
+ * data provided by Andreas Gohr <andi@splitbrain.org>
+ */
+ function test1(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/';
+ $_SERVER['HTTP_HOST'] = 'xerxes.my.home';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/dokuwiki/doku.php?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/dokuwiki/doku.php';
+ $_SERVER['PATH_INFO'] = null;
+ $_SERVER['PATH_TRANSLATED'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['PHP_SELF'] = '/dokuwiki/doku.php';
+
+ $this->assertEqual(getBaseURL(),'/dokuwiki/');
+ }
+
+ /**
+ * Apache, CGI, mod_userdir, subdirectory
+ *
+ * data provided by Hilko Bengen <bengen@hilluzination.de>
+ */
+ function test2(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/localhost';
+ $_SERVER['HTTP_HOST'] = 'localhost';
+ $_SERVER['SCRIPT_FILENAME'] = '/usr/lib/cgi-bin/php4';
+ $_SERVER['REQUEST_URI'] = '/~bengen/dokuwiki/doku.php?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/cgi-bin/php4';
+ $_SERVER['PATH_INFO'] = '/~bengen/dokuwiki/doku.php';
+ $_SERVER['PATH_TRANSLATED'] = '/home/bengen/public_html/dokuwiki/doku.php';
+ $_SERVER['PHP_SELF'] = '/~bengen/dokuwiki/doku.php';
+
+ $this->assertEqual(getBaseURL(),'/~bengen/dokuwiki/');
+ }
+
+ /**
+ * Apache, FastCGI, mod_userdir, subdirectory
+ *
+ * data provided by Hilko Bengen <bengen@hilluzination.de>
+ */
+ function test3(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/localhost';
+ $_SERVER['HTTP_HOST'] = 'localhost';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/run/php-fastcgi/fcgi-bin/bengen/php4';
+ $_SERVER['REQUEST_URI'] = '/~bengen/dokuwiki/doku.php?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/fcgi-bin/php4-bengen';
+ $_SERVER['PATH_INFO'] = '/~bengen/dokuwiki/doku.php';
+ $_SERVER['PATH_TRANSLATED'] = '/home/bengen/public_html/dokuwiki/doku.php';
+ $_SERVER['PHP_SELF'] = '/~bengen/dokuwiki/doku.php';
+
+ $this->assertEqual(getBaseURL(),'/~bengen/dokuwiki/');
+ }
+
+ /**
+ * Apache, mod_php, mod_userdir, subdirectory
+ *
+ * data provided by Hilko Bengen <bengen@hilluzination.de>
+ */
+ function test4(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/localhost';
+ $_SERVER['HTTP_HOST'] = 'localhost';
+ $_SERVER['SCRIPT_FILENAME'] = '/home/bengen/public_html/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/~bengen/dokuwiki/doku.php?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/~bengen/dokuwiki/doku.php';
+ $_SERVER['PATH_INFO'] = null;
+ $_SERVER['PATH_TRANSLATED'] = '/home/bengen/public_html/dokuwiki/doku.php';
+ $_SERVER['PHP_SELF'] = '/~bengen/dokuwiki/doku.php';
+
+ $this->assertEqual(getBaseURL(),'/~bengen/dokuwiki/');
+ }
+
+ /**
+ * IIS
+ *
+ * data provided by David Mach <david.mach@centrum.cz>
+ */
+ function test5(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = null;
+ $_SERVER['HTTP_HOST'] = 'intranet';
+ $_SERVER['SCRIPT_FILENAME'] = null;
+ $_SERVER['REQUEST_URI'] = null;
+ $_SERVER['SCRIPT_NAME'] = '/wiki/doku.php';
+ $_SERVER['PATH_INFO'] = '/wiki/doku.php';
+ $_SERVER['PATH_TRANSLATED'] = 'C:\\Inetpub\\wwwroot\\wiki\\doku.php';
+ $_SERVER['PHP_SELF'] = '/wiki/doku.php';
+
+ $this->assertEqual(getBaseURL(),'/wiki/');
+ }
+
+ /**
+ * Apache 2, mod_php, real URL rewriting, useslash (bug #292)
+ *
+ * data provided by Ted <bugsX2904@elcsplace.com>
+ */
+ function test6(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = '/home/websites/wiki/htdocs';
+ $_SERVER['HTTP_HOST'] = 'wiki.linuxwan.net';
+ $_SERVER['SCRIPT_FILENAME'] = '/home/websites/wiki/htdocs/doku.php';
+ $_SERVER['REQUEST_URI'] = '/wiki/syntax?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/wiki/syntax';
+ $_SERVER['PATH_INFO'] = null;
+ $_SERVER['PATH_TRANSLATED'] = null;
+ $_SERVER['PHP_SELF'] = '/wiki/syntax';
+
+ $this->assertEqual(getBaseURL(),'/');
+ }
+
+ /**
+ * lighttpd, fastcgi
+ *
+ * data provided by Andreas Gohr <andi@splitbrain.org>
+ */
+ function test7(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/';
+ $_SERVER['HTTP_HOST'] = 'localhost';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/dokuwiki/doku.php?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/dokuwiki/doku.php';
+ $_SERVER['PATH_INFO'] = '';
+ $_SERVER['PATH_TRANSLATED'] = null;
+ $_SERVER['PHP_SELF'] = '';
+
+ $this->assertEqual(getBaseURL(),'/dokuwiki/');
+ }
+
+ /**
+ * Apache, mod_php, Pseudo URL rewrite, useslash
+ *
+ * data provided by Andreas Gohr <andi@splitbrain.org>
+ */
+ function test8(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/';
+ $_SERVER['HTTP_HOST'] = 'xerxes.my.home';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/dokuwiki/doku.php/wiki/syntax?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/dokuwiki/doku.php';
+ $_SERVER['PATH_INFO'] = '/wiki/syntax';
+ $_SERVER['PATH_TRANSLATED'] = '/var/www/wiki/syntax';
+ $_SERVER['PHP_SELF'] = '/dokuwiki/doku.php/wiki/syntax';
+
+ $this->assertEqual(getBaseURL(),'/dokuwiki/');
+ }
+
+ /**
+ * Apache, mod_php, real URL rewrite, useslash
+ *
+ * data provided by Andreas Gohr <andi@splitbrain.org>
+ */
+ function test9(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/';
+ $_SERVER['HTTP_HOST'] = 'xerxes.my.home';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/dokuwiki/wiki/syntax?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/dokuwiki/doku.php';
+ $_SERVER['PATH_INFO'] = null;
+ $_SERVER['PATH_TRANSLATED'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['PHP_SELF'] = '/dokuwiki/doku.php';
+
+ $this->assertEqual(getBaseURL(),'/dokuwiki/');
+ }
+
+ /**
+ * Possible user settings of $conf['baseurl'] & absolute baseURL required
+ *
+ * data provided by Andreas Gohr <andi@splitbrain.org>
+ */
+ function test10(){
+ // values for $conf['baseurl'] and expected results
+ $tests = array(
+ 'http://www.mysite.com' => 'http://www.mysite.com/dokuwiki/',
+ 'http://www.mysite.com/' => 'http://www.mysite.com/dokuwiki/',
+ 'http://www.mysite.com/path/to/wiki' => 'http://www.mysite.com/path/to/wiki/dokuwiki/',
+ 'http://www.mysite.com/path/to/wiki/' => 'http://www.mysite.com/path/to/wiki/dokuwiki/',
+ );
+
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/';
+ $_SERVER['HTTP_HOST'] = 'xerxes.my.home';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/dokuwiki/wiki/syntax?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/dokuwiki/doku.php';
+ $_SERVER['PATH_INFO'] = null;
+ $_SERVER['PATH_TRANSLATED'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['PHP_SELF'] = '/dokuwiki/doku.php';
+
+ foreach ($tests as $test => $correct_result) {
+ $conf['baseurl'] = $test;
+ $this->assertEqual(getBaseURL(true),$correct_result);
+ }
+ }
+ /**
+ * Possible user settings of $conf['baseurl'] & absolute baseURL required
+ *
+ * data provided by Andreas Gohr <andi@splitbrain.org>
+ */
+ function test11(){
+ // values for $conf['baseurl'] and expected results
+ $tests = array(
+ 'http://www.mysite.com' => 'http://www.mysite.com/dokuwiki/',
+ 'http://www.mysite.com/' => 'http://www.mysite.com/dokuwiki/',
+ 'http://www.mysite.com/path/to/wiki' => 'http://www.mysite.com/path/to/wiki/dokuwiki/',
+ 'http://www.mysite.com/path/to/wiki/' => 'http://www.mysite.com/path/to/wiki/dokuwiki/',
+ );
+
+ global $conf;
+ $conf['basedir'] = '/dokuwiki';
+ $conf['baseurl'] = '';
+
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/';
+ $_SERVER['HTTP_HOST'] = 'xerxes.my.home';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/dokuwiki/wiki/syntax?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/dokuwiki/doku.php';
+ $_SERVER['PATH_INFO'] = null;
+ $_SERVER['PATH_TRANSLATED'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['PHP_SELF'] = '/dokuwiki/doku.php';
+
+ foreach ($tests as $test => $correct_result) {
+ $conf['baseurl'] = $test;
+ $this->assertEqual(getBaseURL(true),$correct_result);
+ }
+ }
+
+ /**
+ * Absolute URL with IPv6 domain name.
+ * lighttpd, fastcgi
+ *
+ * data provided by Michael Hamann <michael@content-space.de>
+ */
+ function test12() {
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['baseurl'] = '';
+ $conf['canonical'] = 0;
+
+ $_SERVER['DOCUMENT_ROOT'] = '/srv/http/';
+ $_SERVER['HTTP_HOST'] = '[fd00::6592:39ed:a2ed:2c78]';
+ $_SERVER['SCRIPT_FILENAME'] = '/srv/http/~michitux/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/~michitux/dokuwiki/doku.php?do=debug';
+ $_SERVER['SCRIPT_NAME'] = '/~michitux/dokuwiki/doku.php';
+ $_SERVER['PATH_INFO'] = null;
+ $_SERVER['PATH_TRANSLATED'] = null;
+ $_SERVER['PHP_SELF'] = '/~michitux/dokuwiki/doku.php';
+ $_SERVER['SERVER_PORT'] = '80';
+ $_SERVER['SERVER_NAME'] = '[fd00';
+ $this->assertEqual(getBaseURL(true), 'http://[fd00::6592:39ed:a2ed:2c78]/~michitux/dokuwiki/');
+ }
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/_test/cases/inc/mail_isvalid.test.php b/_test/cases/inc/mail_isvalid.test.php
new file mode 100644
index 000000000..d8c88765e
--- /dev/null
+++ b/_test/cases/inc/mail_isvalid.test.php
@@ -0,0 +1,83 @@
+<?php
+// use no mbstring help here
+require_once DOKU_INC.'inc/mail.php';
+
+class mail_isvalid extends UnitTestCase {
+
+
+ function test1(){
+ $tests = array();
+
+ // our own tests
+ $tests[] = array('bugs@php.net',true);
+ $tests[] = array('~someone@somewhere.com',true);
+ $tests[] = array('no+body.here@somewhere.com.au',true);
+ $tests[] = array('username+tag@domain.com',true); // FS#1447
+ $tests[] = array("rfc2822+allthesechars_#*!'`/-={}are.legal@somewhere.com.au",true);
+ $tests[] = array('_foo@test.com',true); // FS#1049
+ $tests[] = array('bugs@php.net1',true); // new ICAN rulez seem to allow this
+ $tests[] = array('.bugs@php.net1',false);
+ $tests[] = array('bu..gs@php.net',false);
+ $tests[] = array('bugs@php..net',false);
+ $tests[] = array('bugs@.php.net',false);
+ $tests[] = array('bugs@php.net.',false);
+ $tests[] = array('bu(g)s@php.net1',false);
+ $tests[] = array('bu[g]s@php.net1',false);
+ $tests[] = array('somebody@somewhere.museum',true);
+ $tests[] = array('somebody@somewhere.travel',true);
+ $tests[] = array('root@[2010:fb:fdac::311:2101]',true);
+ $tests[] = array('test@example', true); // we allow local addresses
+
+ // tests from http://code.google.com/p/php-email-address-validation/ below
+
+ $tests[] = array('test@example.com', true);
+ $tests[] = array('TEST@example.com', true);
+ $tests[] = array('1234567890@example.com', true);
+ $tests[] = array('test+test@example.com', true);
+ $tests[] = array('test-test@example.com', true);
+ $tests[] = array('t*est@example.com', true);
+ $tests[] = array('+1~1+@example.com', true);
+ $tests[] = array('{_test_}@example.com', true);
+ $tests[] = array('"[[ test ]]"@example.com', true);
+ $tests[] = array('test.test@example.com', true);
+ $tests[] = array('test."test"@example.com', true);
+ $tests[] = array('"test@test"@example.com', true);
+ $tests[] = array('test@123.123.123.123', true);
+ $tests[] = array('test@[123.123.123.123]', true);
+ $tests[] = array('test@example.example.com', true);
+ $tests[] = array('test@example.example.example.com', true);
+
+ $tests[] = array('test.example.com', false);
+ $tests[] = array('test.@example.com', false);
+ $tests[] = array('test..test@example.com', false);
+ $tests[] = array('.test@example.com', false);
+ $tests[] = array('test@test@example.com', false);
+ $tests[] = array('test@@example.com', false);
+ $tests[] = array('-- test --@example.com', false); // No spaces allowed in local part
+ $tests[] = array('[test]@example.com', false); // Square brackets only allowed within quotes
+ $tests[] = array('"test\test"@example.com', false); // Quotes cannot contain backslash
+ $tests[] = array('"test"test"@example.com', false); // Quotes cannot be nested
+ $tests[] = array('()[]\;:,<>@example.com', false); // Disallowed Characters
+ $tests[] = array('test@.', false);
+ $tests[] = array('test@example.', false);
+ $tests[] = array('test@.org', false);
+ $tests[] = array('12345678901234567890123456789012345678901234567890123456789012345@example.com', false); // 64 characters is maximum length for local part. This is 65.
+ $tests[] = array('test@123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012.com', false); // 255 characters is maximum length for domain. This is 256.
+ $tests[] = array('test@[123.123.123.123', false);
+ $tests[] = array('test@123.123.123.123]', false);
+
+
+ foreach($tests as $test){
+ $info = 'Testing '.$test[0];
+ $this->signal('failinfo',$info);
+
+ if($test[1]){
+ $this->assertTrue((bool) mail_isvalid($test[0]));
+ }else{
+ $this->assertFalse((bool) mail_isvalid($test[0]));
+ }
+ }
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/mail_quoted_printable_encode.php b/_test/cases/inc/mail_quoted_printable_encode.php
new file mode 100644
index 000000000..a5a36e35b
--- /dev/null
+++ b/_test/cases/inc/mail_quoted_printable_encode.php
@@ -0,0 +1,44 @@
+<?php
+
+require_once DOKU_INC.'inc/mail.php';
+
+class mail_quotedprintable_encode extends UnitTestCase {
+
+ function test_simple(){
+ $in = 'hello';
+ $out = 'hello';
+ $this->assertEqual(mail_quotedprintable_encode($in),$out);
+ }
+
+ function test_spaceend(){
+ $in = "hello \nhello";
+ $out = "hello=20\nhello";
+ $this->assertEqual(mail_quotedprintable_encode($in),$out);
+ }
+
+ function test_german_utf8(){
+ $in = 'hello überlänge';
+ $out = 'hello =C3=BCberl=C3=A4nge';
+ $this->assertEqual(mail_quotedprintable_encode($in),$out);
+ }
+
+ function test_wrap(){
+ $in = '123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789';
+ $out = "123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234=\n56789 123456789";
+ $this->assertEqual(mail_quotedprintable_encode($in,74),$out);
+ }
+
+ function test_nowrap(){
+ $in = '123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789';
+ $out = '123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789';
+ $this->assertEqual(mail_quotedprintable_encode($in,0),$out);
+ }
+
+ function test_russian_utf8(){
+ $in = 'Ваш пароль для системы Доку Вики';
+ $out = '=D0=92=D0=B0=D1=88 =D0=BF=D0=B0=D1=80=D0=BE=D0=BB=D1=8C =D0=B4=D0=BB=D1=8F =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B =D0=94=D0=BE=D0=BA=D1=83 =D0=92=D0=B8=D0=BA=D0=B8';
+ $this->assertEqual(mail_quotedprintable_encode($in,0),$out);
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/mail_send.php b/_test/cases/inc/mail_send.php
new file mode 100644
index 000000000..e41c501fe
--- /dev/null
+++ b/_test/cases/inc/mail_send.php
@@ -0,0 +1,49 @@
+<?php
+require_once DOKU_INC.'inc/mail.php';
+
+class mail_send extends UnitTestCase {
+
+ /**
+ * These tests will try to send a bunch of mails to dokuwiki1@spam.la and
+ * dokuwiki2@spam.la - check the correctness at http://spam.la
+ */
+ function test1(){
+ $addr = array(
+ 'dokuwiki1@spam.la',
+ 'dokuwiki2@spam.la',
+ 'Test User <dokuwiki1@spam.la>',
+ 'dokuwiki1@spam.la, dokuwiki2@spam.la',
+ 'Test User 1 <dokuwiki1@spam.la>, Test User 2 <dokuwiki2@spam.la>'
+ );
+
+
+ $run = 0;
+ foreach($addr as $ad){
+ $run++;
+ $data = array(
+ 'to' => $ad,
+ 'subject' => 'mailtest 1-'.$run,
+ 'body' => "Mailtest run 1-$run using to: $ad from:",
+ );
+ $this->assertTrue((bool) _mail_send_action($data));
+
+ $data = array(
+ 'to' => $ad,
+ 'from' => 'dokuwiki1@spam.la',
+ 'subject' => 'mailtest 2-'.$run,
+ 'body' => "Mailtest run 2-$run using to: $ad from: dokuwiki1@spam.la",
+ );
+ $this->assertTrue((bool) _mail_send_action($data));
+
+ $data = array(
+ 'to' => $ad,
+ 'from' => '"Foo Bar" <dokuwiki@spam.la>',
+ 'subject' => 'mailtest 3-'.$run,
+ 'body' => "Mailtest run 3-$run using to: $ad from: \"Foo Bar\" <dokuwiki@spam.la>",
+ );
+ $this->assertTrue((bool) _mail_send_action($data));
+ }
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/pageutils_clean_id.test.php b/_test/cases/inc/pageutils_clean_id.test.php
new file mode 100644
index 000000000..167229c7f
--- /dev/null
+++ b/_test/cases/inc/pageutils_clean_id.test.php
@@ -0,0 +1,157 @@
+<?php
+require_once DOKU_INC.'inc/utf8.php';
+require_once DOKU_INC.'inc/pageutils.php';
+
+class init_clean_id_test extends UnitTestCase {
+
+ function teardown() {
+ global $cache_cleanid;
+ $cache_cleanid = array();
+ }
+
+ function test_default(){
+ // we test multiple cases here
+ // format: $id, $ascii, $correct_output
+ $tests = array();
+
+ // set dokuwiki defaults
+ global $conf;
+ $conf['sepchar'] = '_';
+ $conf['deaccent'] = 1;
+
+ $tests[] = array('page',false,'page');
+ $tests[] = array('pa_ge',false,'pa_ge');
+ $tests[] = array('pa%ge',false,'pa_ge');
+ $tests[] = array('pa#ge',false,'pa_ge');
+ $tests[] = array('pàge',false,'page');
+ $tests[] = array('pagĖ',false,'page');
+ $tests[] = array('pa$%^*#ge',false,'pa_ge');
+ $tests[] = array('*page*',false,'page');
+ $tests[] = array('ښ',false,'ښ');
+ $tests[] = array('päge',false,'paege');
+ $tests[] = array('foo bar',false,'foo_bar');
+ $tests[] = array('PÄGÖ',false,'paegoe');
+ $tests[] = array('Faß','false','fass');
+ $tests[] = array('ښ侧化并곦 β',false,'ښ侧化并곦_β');
+ $tests[] = array('page:page',false,'page:page');
+ $tests[] = array('page;page',false,'page:page');
+ $tests[] = array('page:page 1.2',false,'page:page_1.2');
+
+ $tests[] = array('page._#!','false','page');
+ $tests[] = array('._#!page','false','page');
+ $tests[] = array('page._#!page','false','page._page');
+ $tests[] = array('ns._#!:page','false','ns:page');
+ $tests[] = array('ns:._#!page','false','ns:page');
+ $tests[] = array('ns._#!ns:page','false','ns._ns:page');
+ $tests[] = array('ns_:page',false,'ns:page');
+ $tests[] = array('page...page','false','page...page');
+
+ $conf['useslash'] = 0;
+ $tests[] = array('page/page',false,'page_page');
+
+ foreach($tests as $test){
+ $this->assertEqual(cleanID($test[0],$test[1]),$test[2]);
+ }
+
+ $conf['useslash'] = 1;
+ $tests = array();
+ $tests[] = array('page/page',false,'page:page');
+
+ $this->teardown();
+
+ foreach($tests as $test){
+ $this->assertEqual(cleanID($test[0],$test[1]),$test[2]);
+ }
+ }
+
+ function test_sepchar(){
+ // we test multiple cases here
+ // format: $id, $ascii, $correct_output
+ $tests = array();
+
+ global $conf;
+ $conf['sepchar'] = '-';
+ $conf['deaccent'] = 1;
+
+ $tests[] = array('pa-ge',false,'pa-ge');
+ $tests[] = array('pa%ge',false,'pa-ge');
+
+ foreach($tests as $test){
+ $this->assertEqual(cleanID($test[0],$test[1]),$test[2]);
+ }
+ }
+
+ function test_deaccent_keep(){
+ // we test multiple cases here
+ // format: $id, $ascii, $correct_output
+ $tests = array();
+
+ global $conf;
+ $conf['sepchar'] = '_';
+ $conf['deaccent'] = 0;
+
+ $tests[] = array('pàge',false,'pàge');
+ $tests[] = array('pagĖ',false,'pagė');
+ $tests[] = array('pagĒēĔĕĖėĘęĚě',false,'pagēēĕĕėėęęěě');
+ $tests[] = array('ښ',false,'ښ');
+ $tests[] = array('ښ侧化并곦ঝഈβ',false,'ښ侧化并곦ঝഈβ');
+
+ foreach($tests as $test){
+ $this->assertEqual(cleanID($test[0],$test[1]),$test[2]);
+ }
+ }
+
+ function test_deaccent_romanize(){
+ // we test multiple cases here
+ // format: $id, $ascii, $correct_output
+ $tests = array();
+
+ global $conf;
+ $conf['sepchar'] = '_';
+ $conf['deaccent'] = 2;
+
+ $tests[] = array('pàge',false,'page');
+ $tests[] = array('pagĖ',false,'page');
+ $tests[] = array('pagĒēĔĕĖėĘęĚě',false,'pageeeeeeeeee');
+ $tests[] = array('ښ',false,'ښ');
+ $tests[] = array('ښ侧化并곦ঝഈβ',false,'ښ侧化并곦ঝഈβ');
+
+ foreach($tests as $test){
+ $this->assertEqual(cleanID($test[0],$test[1]),$test[2]);
+ }
+ }
+
+ function test_deaccent_ascii(){
+ // we test multiple cases here
+ // format: $id, $ascii, $correct_output
+ $tests = array();
+
+ global $conf;
+ $conf['sepchar'] = '_';
+ $conf['deaccent'] = 0;
+
+ $tests[] = array('pàge',true,'page');
+ $tests[] = array('pagĖ',true,'page');
+ $tests[] = array('pagĒēĔĕĖėĘęĚě',true,'pageeeeeeeeee');
+ $tests[] = array('ښ',true,'');
+ $tests[] = array('ښ侧化并곦ঝഈβ',true,'');
+
+ foreach($tests as $test){
+ $this->assertEqual(cleanID($test[0],$test[1]),$test[2]);
+ }
+
+ $conf['deaccent'] = 1;
+
+ foreach($tests as $test){
+ $this->assertEqual(cleanID($test[0],$test[1]),$test[2]);
+ }
+
+ $conf['deaccent'] = 2;
+
+ foreach($tests as $test){
+ $this->assertEqual(cleanID($test[0],$test[1]),$test[2]);
+ }
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/pageutils_getid.test.php b/_test/cases/inc/pageutils_getid.test.php
new file mode 100644
index 000000000..6eddeb5ea
--- /dev/null
+++ b/_test/cases/inc/pageutils_getid.test.php
@@ -0,0 +1,106 @@
+<?php
+require_once DOKU_INC.'inc/utf8.php';
+require_once DOKU_INC.'inc/pageutils.php';
+
+class init_getID_test extends UnitTestCase {
+
+ /**
+ * fetch media files with basedir and urlrewrite=2
+ *
+ * data provided by Jan Decaluwe <jan@jandecaluwe.com>
+ */
+ function test1(){
+ global $conf;
+ $conf['basedir'] = '//';
+ $conf['userewrite'] = 2;
+ $conf['deaccent'] = 0; // the default (1) gives me strange exceptions
+
+
+ $_SERVER['SCRIPT_FILENAME'] = '/lib/exe/fetch.php';
+ $_SERVER['REQUEST_URI'] = '/lib/exe/fetch.php/myhdl-0.5dev1.tar.gz?id=snapshots&cache=cache';
+
+ $this->assertEqual(getID('media'), 'myhdl-0.5dev1.tar.gz');
+ }
+
+
+ /**
+ * getID with internal mediafile, urlrewrite=2, no basedir set, apache, mod_php
+ */
+ function test2(){
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['userewrite'] = '2';
+ $conf['baseurl'] = '';
+ $conf['useslash'] = '1';
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/';
+ $_SERVER['HTTP_HOST'] = 'xerxes.my.home';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/dokuwiki/lib/exe/detail.php';
+ $_SERVER['PHP_SELF'] = '/dokuwiki/lib/exe/detail.php/wiki/discussion/button-dw.png';
+ $_SERVER['REQUEST_URI'] = '/dokuwiki/lib/exe/detail.php/wiki/discussion/button-dw.png?id=test&debug=1';
+ $_SERVER['SCRIPT_NAME'] = '/dokuwiki/lib/exe/detail.php';
+ $_SERVER['PATH_INFO'] = '/wiki/discussion/button-dw.png';
+ $_SERVER['PATH_TRANSLATED'] = '/var/www/wiki/discussion/button-dw.png';
+
+ $this->assertEqual(getID('media',true), 'wiki:discussion:button-dw.png');
+ $this->assertEqual(getID('media',false), 'wiki/discussion/button-dw.png');
+ }
+
+ /**
+ * getID with given id in url and userewrite=2, no basedir set, dokuwiki not in document root.
+ */
+ function test3() {
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['userewrite'] = '2';
+ $conf['baseurl'] = '';
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/';
+ $_SERVER['SCRIPT_FILENAME'] = '/usr/share/dokuwiki/doku.php';
+ $_SERVER['SCRIPT_NAME'] = '/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/dokuwiki/doku.php/wiki:dokuwiki';
+ $_SERVER['PATH_INFO'] = '/wiki:dokuwiki';
+ $_SERVER['PATH_TRANSLATED'] = '/var/www/wiki:dokuwiki';
+ $_SERVER['PHP_SELF'] = '/dokuwiki/doku.php/wiki:dokuwiki';
+
+ $this->assertEqual(getID(), 'wiki:dokuwiki');
+ }
+
+ /**
+ * getID with given id in url and userewrite=2, no basedir set, Apache and CGI.
+ */
+ function test4() {
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['userewrite'] = '2';
+ $conf['baseurl'] = '';
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/vhosts/example.com/htdocs';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/vhosts/example.com/htdocs/doku.php';
+ $_SERVER['SCRIPT_NAME'] = '/doku.php';
+ $_SERVER['REQUEST_URI'] = '/doku.php/wiki/dokuwiki';
+ $_SERVER['PATH_INFO'] = '/wiki/dokuwiki';
+ $_SERVER['PATH_TRANSLATED'] = '/var/www/vhosts/example.com/htdocs/doku.php';
+ $_SERVER['PHP_SELF'] = '/doku.php/wiki/dokuwiki';
+
+ $this->assertEqual(getID(), 'wiki:dokuwiki');
+ }
+
+ /**
+ * getID with given id / in url and userewrite=2, no basedir set, Apache and CGI.
+ */
+ function test5() {
+ global $conf;
+ $conf['basedir'] = '';
+ $conf['userewrite'] = '2';
+ $conf['baseurl'] = '';
+ $_SERVER['DOCUMENT_ROOT'] = '/var/www/';
+ $_SERVER['SCRIPT_FILENAME'] = '/var/www/dokuwiki/doku.php';
+ $_SERVER['SCRIPT_NAME'] = '/dokuwiki/doku.php';
+ $_SERVER['REQUEST_URI'] = '/dokuwiki/doku.php/?do=debug';
+ $_SERVER['PATH_INFO'] = '/';
+ $_SERVER['PATH_TRANSLATED'] = '/var/www/index.html';
+ $_SERVER['PHP_SELF'] = '/dokuwiki/doku.php/';
+
+ $this->assertEqual(getID(), cleanID($conf['start']));
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/pageutils_resolve_id.test.php b/_test/cases/inc/pageutils_resolve_id.test.php
new file mode 100644
index 000000000..9aa4ee8b7
--- /dev/null
+++ b/_test/cases/inc/pageutils_resolve_id.test.php
@@ -0,0 +1,45 @@
+<?php
+require_once DOKU_INC.'inc/utf8.php';
+require_once DOKU_INC.'inc/pageutils.php';
+
+class init_resolve_id_test extends UnitTestCase {
+
+
+ function test1(){
+ // we test multiple cases here
+ // format: $ns, $page, $output
+ $tests = array();
+
+ // relative current in root
+ $tests[] = array('','page','page');
+ $tests[] = array('','.page','page');
+ $tests[] = array('','.:page','page');
+
+ // relative current in namespace
+ $tests[] = array('lev1:lev2','page','lev1:lev2:page');
+ $tests[] = array('lev1:lev2','.page','lev1:lev2:page');
+ $tests[] = array('lev1:lev2','.:page','lev1:lev2:page');
+
+ // relative upper in root
+ $tests[] = array('','..page','page');
+ $tests[] = array('','..:page','page');
+
+ // relative upper in namespace
+ $tests[] = array('lev1:lev2','..page','lev1:page');
+ $tests[] = array('lev1:lev2','..:page','lev1:page');
+ $tests[] = array('lev1:lev2','..:..:page','page');
+ $tests[] = array('lev1:lev2','..:..:..:page','page');
+
+ // strange and broken ones
+ $tests[] = array('lev1:lev2','....:....:page','lev1:lev2:page');
+ $tests[] = array('lev1:lev2','..:..:lev3:page','lev3:page');
+ $tests[] = array('lev1:lev2','..:..:lev3:..:page','page');
+ $tests[] = array('lev1:lev2','..:..:lev3:..:page:....:...','page');
+
+ foreach($tests as $test){
+ $this->assertEqual(resolve_id($test[0],$test[1]),$test[2]);
+ }
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/pageutils_resolve_pageid.test.php b/_test/cases/inc/pageutils_resolve_pageid.test.php
new file mode 100644
index 000000000..c65ed1866
--- /dev/null
+++ b/_test/cases/inc/pageutils_resolve_pageid.test.php
@@ -0,0 +1,85 @@
+<?php
+require_once DOKU_INC.'inc/utf8.php';
+require_once DOKU_INC.'inc/pageutils.php';
+
+global $conf;
+if (!isset($conf['datadir'])) $conf['datadir'] = $conf['savedir'].'/pages';
+
+class init_resolve_pageid_test extends UnitTestCase {
+
+
+ function test1(){
+ global $conf;
+
+ // we test multiple cases here
+ // format: $ns, $page, $output
+ $tests = array();
+
+ // relative current in root
+ $tests[] = array('','page','page');
+ $tests[] = array('','.page','page');
+ $tests[] = array('','.:page','page');
+
+ // relative current in namespace
+ $tests[] = array('lev1:lev2','page','lev1:lev2:page');
+ $tests[] = array('lev1:lev2','.page','lev1:lev2:page');
+ $tests[] = array('lev1:lev2','.:page','lev1:lev2:page');
+
+ // relative upper in root
+ $tests[] = array('','..page','page');
+ $tests[] = array('','..:page','page');
+
+ // relative upper in namespace
+ $tests[] = array('lev1:lev2','..page','lev1:page');
+ $tests[] = array('lev1:lev2','..:page','lev1:page');
+ $tests[] = array('lev1:lev2','..:..:page','page');
+ $tests[] = array('lev1:lev2','..:..:..:page','page');
+
+ // strange and broken ones
+ $tests[] = array('lev1:lev2','....:....:page','lev1:lev2:page');
+ $tests[] = array('lev1:lev2','..:..:lev3:page','lev3:page');
+ $tests[] = array('lev1:lev2','..:..:lev3:..:page','page');
+ $tests[] = array('lev1:lev2','..:..:lev3:..:page:....:...','page');
+
+ // now some tests with existing and none existing files
+ $conf['start'] = 'start';
+
+ $tests[] = array('','.:','start');
+ $tests[] = array('foo','.:','foo:start');
+ $tests[] = array('','foo:','foo:start');
+ $tests[] = array('foo','foo:','foo:start');
+ $tests[] = array('foo','playground:','playground:playground');
+
+ // empty $page
+ global $ID;
+ $ID = 'my:space';
+ $tests[] = array('my', '', 'my:space');
+
+ foreach($tests as $test){
+ $page = $test[1];
+ resolve_pageid($test[0],$page,$foo);
+
+ $this->assertEqual($page,$test[2]);
+ }
+ }
+
+ /**
+ * Empty page on homepage should resolve to start page
+ */
+ function test_resolve_pageid_empty_homepage() {
+ global $ID;
+ $ID = '';
+
+ global $conf;
+ $conf['start'] = 'someverystrangestartname';
+
+ $ns = '';
+ $page = '';
+ $exist = true;
+
+ resolve_pageid($ns, $page, $exist);
+ $this->assertEqual($page, $conf['start']);
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/parser/lexer.group.php b/_test/cases/inc/parser/lexer.group.php
new file mode 100644
index 000000000..6e9ef0742
--- /dev/null
+++ b/_test/cases/inc/parser/lexer.group.php
@@ -0,0 +1,21 @@
+<?php
+/**
+* @version $Id: lexer.group.php,v 1.2 2005/03/25 21:00:22 harryf Exp $
+* @package JPSpan
+* @subpackage Tests
+*/
+
+/**
+* @package JPSpan
+* @subpackage Tests
+*/
+class LexerGroupTest extends GroupTest {
+
+ function LexerGroupTest() {
+ $this->GroupTest('LexerGroupTest');
+ $this->addTestFile(dirname(__FILE__).'/lexer.test.php');
+ }
+
+}
+
+?>
diff --git a/_test/cases/inc/parser/lexer.test.php b/_test/cases/inc/parser/lexer.test.php
new file mode 100644
index 000000000..e802277f1
--- /dev/null
+++ b/_test/cases/inc/parser/lexer.test.php
@@ -0,0 +1,625 @@
+<?php
+/**
+* @version $Id: lexer.test.php,v 1.2 2005/03/25 21:00:22 harryf Exp $
+* @package Doku
+* @subpackage Tests
+*/
+
+/**
+* Includes
+*/
+require_once DOKU_INC . 'inc/parser/lexer.php';
+
+/**
+* @package Doku
+* @subpackage Tests
+*/
+class TestOfLexerParallelRegex extends UnitTestCase {
+ function TestOfLexerParallelRegex() {
+ $this->UnitTestCase();
+ }
+ function testNoPatterns() {
+ $regex = new Doku_LexerParallelRegex(false);
+ $this->assertFalse($regex->match("Hello", $match));
+ $this->assertEqual($match, "");
+ }
+ function testNoSubject() {
+ $regex = new Doku_LexerParallelRegex(false);
+ $regex->addPattern(".*");
+ $this->assertTrue($regex->match("", $match));
+ $this->assertEqual($match, "");
+ }
+ function testMatchAll() {
+ $regex = new Doku_LexerParallelRegex(false);
+ $regex->addPattern(".*");
+ $this->assertTrue($regex->match("Hello", $match));
+ $this->assertEqual($match, "Hello");
+ }
+ function testCaseSensitive() {
+ $regex = new Doku_LexerParallelRegex(true);
+ $regex->addPattern("abc");
+ $this->assertTrue($regex->match("abcdef", $match));
+ $this->assertEqual($match, "abc");
+ $this->assertTrue($regex->match("AAABCabcdef", $match));
+ $this->assertEqual($match, "abc");
+ }
+ function testCaseInsensitive() {
+ $regex = new Doku_LexerParallelRegex(false);
+ $regex->addPattern("abc");
+ $this->assertTrue($regex->match("abcdef", $match));
+ $this->assertEqual($match, "abc");
+ $this->assertTrue($regex->match("AAABCabcdef", $match));
+ $this->assertEqual($match, "ABC");
+ }
+ function testMatchMultiple() {
+ $regex = new Doku_LexerParallelRegex(true);
+ $regex->addPattern("abc");
+ $regex->addPattern("ABC");
+ $this->assertTrue($regex->match("abcdef", $match));
+ $this->assertEqual($match, "abc");
+ $this->assertTrue($regex->match("AAABCabcdef", $match));
+ $this->assertEqual($match, "ABC");
+ $this->assertFalse($regex->match("Hello", $match));
+ }
+ function testPatternLabels() {
+ $regex = new Doku_LexerParallelRegex(false);
+ $regex->addPattern("abc", "letter");
+ $regex->addPattern("123", "number");
+ $this->assertIdentical($regex->match("abcdef", $match), "letter");
+ $this->assertEqual($match, "abc");
+ $this->assertIdentical($regex->match("0123456789", $match), "number");
+ $this->assertEqual($match, "123");
+ }
+ function testMatchMultipleWithLookaheadNot() {
+ $regex = new Doku_LexerParallelRegex(true);
+ $regex->addPattern("abc");
+ $regex->addPattern("ABC");
+ $regex->addPattern("a(?!\n).{1}");
+ $this->assertTrue($regex->match("abcdef", $match));
+ $this->assertEqual($match, "abc");
+ $this->assertTrue($regex->match("AAABCabcdef", $match));
+ $this->assertEqual($match, "ABC");
+ $this->assertTrue($regex->match("a\nab", $match));
+ $this->assertEqual($match, "ab");
+ $this->assertFalse($regex->match("Hello", $match));
+ }
+ function testMatchSetOptionCaseless() {
+ $regex = new Doku_LexerParallelRegex(true);
+ $regex->addPattern("a(?i)b(?i)c");
+ $this->assertTrue($regex->match("aBc", $match));
+ $this->assertEqual($match, "aBc");
+ }
+ function testMatchSetOptionUngreedy() {
+ $regex = new Doku_LexerParallelRegex(true);
+ $regex->addPattern("(?U)\w+");
+ $this->assertTrue($regex->match("aaaaaa", $match));
+ $this->assertEqual($match, "a");
+ }
+ function testMatchLookaheadEqual() {
+ $regex = new Doku_LexerParallelRegex(true);
+ $regex->addPattern("\w(?=c)");
+ $this->assertTrue($regex->match("xbyczd", $match));
+ $this->assertEqual($match, "y");
+ }
+ function testMatchLookaheadNot() {
+ $regex = new Doku_LexerParallelRegex(true);
+ $regex->addPattern("\w(?!b|c)");
+ $this->assertTrue($regex->match("xbyczd", $match));
+ $this->assertEqual($match, "b");
+ }
+ function testMatchLookbehindEqual() {
+ $regex = new Doku_LexerParallelRegex(true);
+ $regex->addPattern("(?<=c)\w");
+ $this->assertTrue($regex->match("xbyczd", $match));
+ $this->assertEqual($match, "z");
+ }
+ function testMatchLookbehindNot() {
+ $regex = new Doku_LexerParallelRegex(true);
+ $regex->addPattern("(?<!\A|x|b)\w");
+ $this->assertTrue($regex->match("xbyczd", $match));
+ $this->assertEqual($match, "c");
+ }
+}
+
+
+class TestOfLexerStateStack extends UnitTestCase {
+ function TestOfLexerStateStack() {
+ $this->UnitTestCase();
+ }
+ function testStartState() {
+ $stack = new Doku_LexerStateStack("one");
+ $this->assertEqual($stack->getCurrent(), "one");
+ }
+ function testExhaustion() {
+ $stack = new Doku_LexerStateStack("one");
+ $this->assertFalse($stack->leave());
+ }
+ function testStateMoves() {
+ $stack = new Doku_LexerStateStack("one");
+ $stack->enter("two");
+ $this->assertEqual($stack->getCurrent(), "two");
+ $stack->enter("three");
+ $this->assertEqual($stack->getCurrent(), "three");
+ $this->assertTrue($stack->leave());
+ $this->assertEqual($stack->getCurrent(), "two");
+ $stack->enter("third");
+ $this->assertEqual($stack->getCurrent(), "third");
+ $this->assertTrue($stack->leave());
+ $this->assertTrue($stack->leave());
+ $this->assertEqual($stack->getCurrent(), "one");
+ }
+}
+
+class TestParser {
+ function TestParser() {
+ }
+ function accept() {
+ }
+ function a() {
+ }
+ function b() {
+ }
+}
+Mock::generate('TestParser');
+
+class TestOfLexer extends UnitTestCase {
+ function TestOfLexer() {
+ $this->UnitTestCase();
+ }
+ function testNoPatterns() {
+ $handler = new MockTestParser($this);
+ $handler->expectNever("accept");
+ $handler->setReturnValue("accept", true);
+ $lexer = new Doku_Lexer($handler);
+ $this->assertFalse($lexer->parse("abcdef"));
+ }
+ function testEmptyPage() {
+ $handler = new MockTestParser($this);
+ $handler->expectNever("accept");
+ $handler->setReturnValue("accept", true);
+ $handler->expectNever("accept");
+ $handler->setReturnValue("accept", true);
+ $lexer = new Doku_Lexer($handler);
+ $lexer->addPattern("a+");
+ $this->assertTrue($lexer->parse(""));
+ }
+ function testSinglePattern() {
+ $handler = new MockTestParser($this);
+ $handler->expectArgumentsAt(0, "accept", array("aaa", DOKU_LEXER_MATCHED, 0));
+ $handler->expectArgumentsAt(1, "accept", array("x", DOKU_LEXER_UNMATCHED, 3));
+ $handler->expectArgumentsAt(2, "accept", array("a", DOKU_LEXER_MATCHED, 4));
+ $handler->expectArgumentsAt(3, "accept", array("yyy", DOKU_LEXER_UNMATCHED, 5));
+ $handler->expectArgumentsAt(4, "accept", array("a", DOKU_LEXER_MATCHED, 8));
+ $handler->expectArgumentsAt(5, "accept", array("x", DOKU_LEXER_UNMATCHED, 9));
+ $handler->expectArgumentsAt(6, "accept", array("aaa", DOKU_LEXER_MATCHED, 10));
+ $handler->expectArgumentsAt(7, "accept", array("z", DOKU_LEXER_UNMATCHED, 13));
+ $handler->expectCallCount("accept", 8);
+ $handler->setReturnValue("accept", true);
+ $lexer = new Doku_Lexer($handler);
+ $lexer->addPattern("a+");
+ $this->assertTrue($lexer->parse("aaaxayyyaxaaaz"));
+ $handler->tally();
+ }
+ function testMultiplePattern() {
+ $handler = new MockTestParser($this);
+ $target = array("a", "b", "a", "bb", "x", "b", "a", "xxxxxx", "a", "x");
+ $positions = array(0,1,2,3,5,6,7,8,14,15);
+ for ($i = 0; $i < count($target); $i++) {
+ $handler->expectArgumentsAt($i, "accept", array($target[$i], '*', $positions[$i]));
+ }
+ $handler->expectCallCount("accept", count($target));
+ $handler->setReturnValue("accept", true);
+ $lexer = new Doku_Lexer($handler);
+ $lexer->addPattern("a+");
+ $lexer->addPattern("b+");
+ $this->assertTrue($lexer->parse("ababbxbaxxxxxxax"));
+ $handler->tally();
+ }
+}
+
+class TestOfLexerModes extends UnitTestCase {
+ function TestOfLexerModes() {
+ $this->UnitTestCase();
+ }
+ function testIsolatedPattern() {
+ $handler = new MockTestParser($this);
+ $handler->expectArgumentsAt(0, "a", array("a", DOKU_LEXER_MATCHED,0));
+ $handler->expectArgumentsAt(1, "a", array("b", DOKU_LEXER_UNMATCHED,1));
+ $handler->expectArgumentsAt(2, "a", array("aa", DOKU_LEXER_MATCHED,2));
+ $handler->expectArgumentsAt(3, "a", array("bxb", DOKU_LEXER_UNMATCHED,4));
+ $handler->expectArgumentsAt(4, "a", array("aaa", DOKU_LEXER_MATCHED,7));
+ $handler->expectArgumentsAt(5, "a", array("x", DOKU_LEXER_UNMATCHED,10));
+ $handler->expectArgumentsAt(6, "a", array("aaaa", DOKU_LEXER_MATCHED,11));
+ $handler->expectArgumentsAt(7, "a", array("x", DOKU_LEXER_UNMATCHED,15));
+ $handler->expectCallCount("a", 8);
+ $handler->setReturnValue("a", true);
+ $lexer = new Doku_Lexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addPattern("b+", "b");
+ $this->assertTrue($lexer->parse("abaabxbaaaxaaaax"));
+ $handler->tally();
+ }
+ function testModeChange() {
+ $handler = new MockTestParser($this);
+ $handler->expectArgumentsAt(0, "a", array("a", DOKU_LEXER_MATCHED,0));
+ $handler->expectArgumentsAt(1, "a", array("b", DOKU_LEXER_UNMATCHED,1));
+ $handler->expectArgumentsAt(2, "a", array("aa", DOKU_LEXER_MATCHED,2));
+ $handler->expectArgumentsAt(3, "a", array("b", DOKU_LEXER_UNMATCHED,4));
+ $handler->expectArgumentsAt(4, "a", array("aaa", DOKU_LEXER_MATCHED,5));
+ $handler->expectArgumentsAt(0, "b", array(":", DOKU_LEXER_ENTER,8));
+ $handler->expectArgumentsAt(1, "b", array("a", DOKU_LEXER_UNMATCHED,9));
+ $handler->expectArgumentsAt(2, "b", array("b", DOKU_LEXER_MATCHED, 10));
+ $handler->expectArgumentsAt(3, "b", array("a", DOKU_LEXER_UNMATCHED,11));
+ $handler->expectArgumentsAt(4, "b", array("bb", DOKU_LEXER_MATCHED,12));
+ $handler->expectArgumentsAt(5, "b", array("a", DOKU_LEXER_UNMATCHED,14));
+ $handler->expectArgumentsAt(6, "b", array("bbb", DOKU_LEXER_MATCHED,15));
+ $handler->expectArgumentsAt(7, "b", array("a", DOKU_LEXER_UNMATCHED,18));
+ $handler->expectCallCount("a", 5);
+ $handler->expectCallCount("b", 8);
+ $handler->setReturnValue("a", true);
+ $handler->setReturnValue("b", true);
+ $lexer = new Doku_Lexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addEntryPattern(":", "a", "b");
+ $lexer->addPattern("b+", "b");
+ $this->assertTrue($lexer->parse("abaabaaa:ababbabbba"));
+ $handler->tally();
+ }
+ function testNesting() {
+ $handler = new MockTestParser($this);
+ $handler->setReturnValue("a", true);
+ $handler->setReturnValue("b", true);
+ $handler->expectArgumentsAt(0, "a", array("aa", DOKU_LEXER_MATCHED,0));
+ $handler->expectArgumentsAt(1, "a", array("b", DOKU_LEXER_UNMATCHED,2));
+ $handler->expectArgumentsAt(2, "a", array("aa", DOKU_LEXER_MATCHED,3));
+ $handler->expectArgumentsAt(3, "a", array("b", DOKU_LEXER_UNMATCHED,5));
+ $handler->expectArgumentsAt(0, "b", array("(", DOKU_LEXER_ENTER,6));
+ $handler->expectArgumentsAt(1, "b", array("bb", DOKU_LEXER_MATCHED,7));
+ $handler->expectArgumentsAt(2, "b", array("a", DOKU_LEXER_UNMATCHED,9));
+ $handler->expectArgumentsAt(3, "b", array("bb", DOKU_LEXER_MATCHED,10));
+ $handler->expectArgumentsAt(4, "b", array(")", DOKU_LEXER_EXIT,12));
+ $handler->expectArgumentsAt(4, "a", array("aa", DOKU_LEXER_MATCHED,13));
+ $handler->expectArgumentsAt(5, "a", array("b", DOKU_LEXER_UNMATCHED,15));
+ $handler->expectCallCount("a", 6);
+ $handler->expectCallCount("b", 5);
+ $lexer = new Doku_Lexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addEntryPattern("(", "a", "b");
+ $lexer->addPattern("b+", "b");
+ $lexer->addExitPattern(")", "b");
+ $this->assertTrue($lexer->parse("aabaab(bbabb)aab"));
+ $handler->tally();
+ }
+ function testSingular() {
+ $handler = new MockTestParser($this);
+ $handler->setReturnValue("a", true);
+ $handler->setReturnValue("b", true);
+ $handler->expectArgumentsAt(0, "a", array("aa", DOKU_LEXER_MATCHED,0));
+ $handler->expectArgumentsAt(1, "a", array("aa", DOKU_LEXER_MATCHED,3));
+ $handler->expectArgumentsAt(2, "a", array("xx", DOKU_LEXER_UNMATCHED,5));
+ $handler->expectArgumentsAt(3, "a", array("xx", DOKU_LEXER_UNMATCHED,10));
+ $handler->expectArgumentsAt(0, "b", array("b", DOKU_LEXER_SPECIAL,2));
+ $handler->expectArgumentsAt(1, "b", array("bbb", DOKU_LEXER_SPECIAL,7));
+ $handler->expectCallCount("a", 4);
+ $handler->expectCallCount("b", 2);
+ $lexer = new Doku_Lexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addSpecialPattern("b+", "a", "b");
+ $this->assertTrue($lexer->parse("aabaaxxbbbxx"));
+ $handler->tally();
+ }
+ function testUnwindTooFar() {
+ $handler = new MockTestParser($this);
+ $handler->setReturnValue("a", true);
+ $handler->expectArgumentsAt(0, "a", array("aa", DOKU_LEXER_MATCHED,0));
+ $handler->expectArgumentsAt(1, "a", array(")", DOKU_LEXER_EXIT,2));
+ $handler->expectCallCount("a", 2);
+ $lexer = new Doku_Lexer($handler, "a");
+ $lexer->addPattern("a+", "a");
+ $lexer->addExitPattern(")", "a");
+ $this->assertFalse($lexer->parse("aa)aa"));
+ $handler->tally();
+ }
+}
+
+class TestOfLexerHandlers extends UnitTestCase {
+ function TestOfLexerHandlers() {
+ $this->UnitTestCase();
+ }
+ function testModeMapping() {
+ $handler = new MockTestParser($this);
+ $handler->setReturnValue("a", true);
+ $handler->expectArgumentsAt(0, "a", array("aa", DOKU_LEXER_MATCHED,0));
+ $handler->expectArgumentsAt(1, "a", array("(", DOKU_LEXER_ENTER,2));
+ $handler->expectArgumentsAt(2, "a", array("bb", DOKU_LEXER_MATCHED,3));
+ $handler->expectArgumentsAt(3, "a", array("a", DOKU_LEXER_UNMATCHED,5));
+ $handler->expectArgumentsAt(4, "a", array("bb", DOKU_LEXER_MATCHED,6));
+ $handler->expectArgumentsAt(5, "a", array(")", DOKU_LEXER_EXIT,8));
+ $handler->expectArgumentsAt(6, "a", array("b", DOKU_LEXER_UNMATCHED,9));
+ $handler->expectCallCount("a", 7);
+ $lexer = new Doku_Lexer($handler, "mode_a");
+ $lexer->addPattern("a+", "mode_a");
+ $lexer->addEntryPattern("(", "mode_a", "mode_b");
+ $lexer->addPattern("b+", "mode_b");
+ $lexer->addExitPattern(")", "mode_b");
+ $lexer->mapHandler("mode_a", "a");
+ $lexer->mapHandler("mode_b", "a");
+ $this->assertTrue($lexer->parse("aa(bbabb)b"));
+ $handler->tally();
+ }
+}
+
+class TestParserByteIndex {
+
+ function TestParserByteIndex() {}
+
+ function ignore() {}
+
+ function caught() {}
+}
+
+Mock::generate('TestParserByteIndex');
+
+class TestOfLexerByteIndices extends UnitTestCase {
+
+ function TestOfLexerByteIndices() {
+ $this->UnitTestCase();
+ }
+
+ function testIndex() {
+ $doc = "aaa<file>bcd</file>eee";
+
+ $handler = new MockTestParserByteIndex($this);
+ $handler->setReturnValue("ignore", true);
+ $handler->setReturnValue("caught", true);
+
+ $handler->expectArgumentsAt(
+ 0,
+ "caught",
+ array("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))
+ );
+ $handler->expectArgumentsAt(
+ 1,
+ "caught",
+ array("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))
+ );
+ $handler->expectArgumentsAt(
+ 2,
+ "caught",
+ array("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))
+ );
+ $handler->expectArgumentsAt(
+ 3,
+ "caught",
+ array("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))
+ );
+ $handler->expectArgumentsAt(
+ 4,
+ "caught",
+ array("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))
+ );
+ $handler->expectCallCount("caught", 5);
+
+ $lexer = new Doku_Lexer($handler, "ignore");
+ $lexer->addEntryPattern("<file>", "ignore", "caught");
+ $lexer->addExitPattern("</file>", "caught");
+ $lexer->addSpecialPattern('b','caught','special');
+ $lexer->mapHandler('special','caught');
+ $lexer->addPattern('c','caught');
+
+ $this->assertTrue($lexer->parse($doc));
+ $handler->tally();
+ }
+
+ function testIndexLookaheadEqual() {
+ $doc = "aaa<file>bcd</file>eee";
+
+ $handler = new MockTestParserByteIndex($this);
+ $handler->setReturnValue("ignore", true);
+ $handler->setReturnValue("caught", true);
+
+ $handler->expectArgumentsAt(
+ 0,
+ "caught",
+ array("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))
+ );
+ $handler->expectArgumentsAt(
+ 1,
+ "caught",
+ array("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))
+ );
+ $handler->expectArgumentsAt(
+ 2,
+ "caught",
+ array("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))
+ );
+ $handler->expectArgumentsAt(
+ 3,
+ "caught",
+ array("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))
+ );
+ $handler->expectArgumentsAt(
+ 4,
+ "caught",
+ array("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))
+ );
+ $handler->expectCallCount("caught", 5);
+
+ $lexer = new Doku_Lexer($handler, "ignore");
+ $lexer->addEntryPattern('<file>(?=.*</file>)', "ignore", "caught");
+ $lexer->addExitPattern("</file>", "caught");
+ $lexer->addSpecialPattern('b','caught','special');
+ $lexer->mapHandler('special','caught');
+ $lexer->addPattern('c','caught');
+
+ $this->assertTrue($lexer->parse($doc));
+ $handler->tally();
+ }
+
+ function testIndexLookaheadNotEqual() {
+ $doc = "aaa<file>bcd</file>eee";
+
+ $handler = new MockTestParserByteIndex($this);
+ $handler->setReturnValue("ignore", true);
+ $handler->setReturnValue("caught", true);
+
+ $handler->expectArgumentsAt(
+ 0,
+ "caught",
+ array("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))
+ );
+ $handler->expectArgumentsAt(
+ 1,
+ "caught",
+ array("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))
+ );
+ $handler->expectArgumentsAt(
+ 2,
+ "caught",
+ array("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))
+ );
+ $handler->expectArgumentsAt(
+ 3,
+ "caught",
+ array("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))
+ );
+ $handler->expectArgumentsAt(
+ 4,
+ "caught",
+ array("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))
+ );
+ $handler->expectCallCount("caught", 5);
+
+ $lexer = new Doku_Lexer($handler, "ignore");
+ $lexer->addEntryPattern('<file>(?!foo)', "ignore", "caught");
+ $lexer->addExitPattern("</file>", "caught");
+ $lexer->addSpecialPattern('b','caught','special');
+ $lexer->mapHandler('special','caught');
+ $lexer->addPattern('c','caught');
+
+ $this->assertTrue($lexer->parse($doc));
+ $handler->tally();
+ }
+
+ function testIndexLookbehindEqual() {
+ $doc = "aaa<file>bcd</file>eee";
+
+ $handler = new MockTestParserByteIndex($this);
+ $handler->setReturnValue("ignore", true);
+ $handler->setReturnValue("caught", true);
+
+ $handler->expectArgumentsAt(
+ 0,
+ "caught",
+ array("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))
+ );
+ $handler->expectArgumentsAt(
+ 1,
+ "caught",
+ array("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))
+ );
+ $handler->expectArgumentsAt(
+ 2,
+ "caught",
+ array("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))
+ );
+ $handler->expectArgumentsAt(
+ 3,
+ "caught",
+ array("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))
+ );
+ $handler->expectArgumentsAt(
+ 4,
+ "caught",
+ array("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))
+ );
+ $handler->expectCallCount("caught", 5);
+
+ $lexer = new Doku_Lexer($handler, "ignore");
+ $lexer->addEntryPattern('<file>', "ignore", "caught");
+ $lexer->addExitPattern("(?<=d)</file>", "caught");
+ $lexer->addSpecialPattern('b','caught','special');
+ $lexer->mapHandler('special','caught');
+ $lexer->addPattern('c','caught');
+
+ $this->assertTrue($lexer->parse($doc));
+ $handler->tally();
+ }
+
+ function testIndexLookbehindNotEqual() {
+ $doc = "aaa<file>bcd</file>eee";
+
+ $handler = new MockTestParserByteIndex($this);
+ $handler->setReturnValue("ignore", true);
+ $handler->setReturnValue("caught", true);
+
+ $handler->expectArgumentsAt(
+ 0,
+ "caught",
+ array("<file>", DOKU_LEXER_ENTER, strpos($doc,'<file>'))
+ );
+ $handler->expectArgumentsAt(
+ 1,
+ "caught",
+ array("b", DOKU_LEXER_SPECIAL, strpos($doc,'b'))
+ );
+ $handler->expectArgumentsAt(
+ 2,
+ "caught",
+ array("c", DOKU_LEXER_MATCHED, strpos($doc,'c'))
+ );
+ $handler->expectArgumentsAt(
+ 3,
+ "caught",
+ array("d", DOKU_LEXER_UNMATCHED, strpos($doc,'d'))
+ );
+ $handler->expectArgumentsAt(
+ 4,
+ "caught",
+ array("</file>", DOKU_LEXER_EXIT, strpos($doc,'</file>'))
+ );
+ $handler->expectCallCount("caught", 5);
+
+ $lexer = new Doku_Lexer($handler, "ignore");
+ $lexer->addEntryPattern('<file>', "ignore", "caught");
+ $lexer->addExitPattern("(?<!c)</file>", "caught");
+ $lexer->addSpecialPattern('b','caught','special');
+ $lexer->mapHandler('special','caught');
+ $lexer->addPattern('c','caught');
+
+ $this->assertTrue($lexer->parse($doc));
+ $handler->tally();
+ }
+
+ /**
+ * This test is primarily to ensure the correct match is chosen
+ * when there are non-captured elements in the pattern.
+ */
+ function testIndexSelectCorrectMatch() {
+ $doc = "ALL FOOLS ARE FOO";
+ $pattern = '\bFOO\b';
+
+ $handler = new MockTestParserByteIndex($this);
+ $handler->setReturnValue("ignore", true);
+ $handler->setReturnValue("caught", true);
+
+ $matches = array();
+ preg_match('/'.$pattern.'/',$doc,$matches,PREG_OFFSET_CAPTURE);
+
+ $handler->expectArgumentsAt(
+ 0,
+ "caught",
+ array("FOO", DOKU_LEXER_SPECIAL, $matches[0][1])
+ );
+ $handler->expectCallCount("caught", 1);
+
+ $lexer = new Doku_Lexer($handler, "ignore");
+ $lexer->addSpecialPattern($pattern,'ignore','caught');
+
+ $this->assertTrue($lexer->parse($doc));
+ $handler->tally();
+ }
+
+}
+
+?>
diff --git a/_test/cases/inc/parser/parser.group.php b/_test/cases/inc/parser/parser.group.php
new file mode 100644
index 000000000..ed7fce76e
--- /dev/null
+++ b/_test/cases/inc/parser/parser.group.php
@@ -0,0 +1,34 @@
+<?php
+/**
+* @version $Id: parser.group.php,v 1.3 2005/03/30 13:42:10 harryf Exp $
+* @package Dokuwiki
+* @subpackage Tests
+*/
+
+/**
+* @package Dokuwiki
+* @subpackage Tests
+*/
+class ParserGroupTest extends GroupTest {
+
+ function ParserGroupTest() {
+ $dir = dirname(__FILE__).'/';
+ $this->GroupTest('ParserGroupTest');
+ $this->addTestFile($dir . 'parser_eol.test.php');
+ $this->addTestFile($dir . 'parser_footnote.test.php');
+ $this->addTestFile($dir .'parser_formatting.test.php');
+ $this->addTestFile($dir .'parser_headers.test.php');
+ $this->addTestFile($dir .'parser_i18n.test.php');
+ $this->addTestFile($dir .'parser_links.test.php');
+ $this->addTestFile($dir .'parser_lists.test.php');
+ $this->addTestFile($dir .'parser_preformatted.test.php');
+ $this->addTestFile($dir .'parser_quote.test.php');
+ $this->addTestFile($dir .'parser_replacements.test.php');
+ $this->addTestFile($dir .'parser_table.test.php');
+# $this->addTestFile($dir .'parser_tocsections.test.php');
+ $this->addTestFile($dir .'parser_unformatted.test.php');
+ }
+
+}
+
+?>
diff --git a/_test/cases/inc/parser/parser.inc.php b/_test/cases/inc/parser/parser.inc.php
new file mode 100644
index 000000000..74d956f43
--- /dev/null
+++ b/_test/cases/inc/parser/parser.inc.php
@@ -0,0 +1,53 @@
+<?php
+/**
+* @version $Id: parser.inc.php,v 1.2 2005/03/25 21:00:22 harryf Exp $
+* @package Doku
+* @subpackage Tests
+*/
+
+/**
+* Includes
+*/
+require_once DOKU_INC . 'inc/init.php';
+require_once DOKU_INC . 'inc/confutils.php';
+require_once DOKU_INC . 'inc/parser/parser.php';
+require_once DOKU_INC . 'inc/parser/handler.php';
+require_once DOKU_INC . 'inc/events.php';
+require_once DOKU_INC . 'inc/mail.php';
+
+//require_once DOKU . 'parser/renderer.php';
+
+//Mock::generate('Doku_Renderer');
+
+/**
+* @package Doku
+* @subpackage Tests
+*/
+class TestOfDoku_Parser extends UnitTestCase {
+
+ var $P;
+ var $H;
+
+ function TestOfDoku_Parser() {
+ $this->UnitTestCase('TestOfDoku_Parser');
+ }
+
+ function setup() {
+ $this->P = new Doku_Parser();
+ $this->H = new Doku_Handler();
+ $this->P->Handler = & $this->H;
+ }
+
+ function tearDown() {
+ unset($this->P);
+ unset($this->H);
+ }
+}
+
+function stripByteIndex($call) {
+ unset($call[2]);
+ if ($call[0] == "nest") {
+ $call[1][0] = array_map('stripByteIndex',$call[1][0]);
+ }
+ return $call;
+}
diff --git a/_test/cases/inc/parser/parser_eol.test.php b/_test/cases/inc/parser/parser_eol.test.php
new file mode 100644
index 000000000..692882c6c
--- /dev/null
+++ b/_test/cases/inc/parser/parser_eol.test.php
@@ -0,0 +1,100 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Eol extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Eol() {
+ $this->UnitTestCase('TestOfDoku_Parser_Eol');
+ }
+
+ function testEol() {
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse("Foo\nBar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("Foo".DOKU_PARSER_EOL."Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testEolMultiple() {
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse("Foo\n\nbar\nFoo");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("Foo")),
+ array('p_close',array()),
+ array('p_open',array()),
+ array('cdata',array("bar".DOKU_PARSER_EOL."Foo")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testWinEol() {
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse("Foo\r\nBar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("Foo".DOKU_PARSER_EOL."Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testLinebreak() {
+ $this->P->addMode('linebreak',new Doku_Parser_Mode_Linebreak());
+ $this->P->parse('Foo\\\\ Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nFoo")),
+ array('linebreak',array()),
+ array('cdata',array("Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testLinebreakPlusEol() {
+ $this->P->addMode('linebreak',new Doku_Parser_Mode_Linebreak());
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse('Foo\\\\'."\n\n".'Bar');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("Foo")),
+ array('linebreak',array()),
+ array('p_close',array()),
+ array('p_open',array()),
+ array('cdata',array("Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testLinebreakInvalid() {
+ $this->P->addMode('linebreak',new Doku_Parser_Mode_Linebreak());
+ $this->P->parse('Foo\\\\Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo\\\\Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+}
+
diff --git a/_test/cases/inc/parser/parser_footnote.test.php b/_test/cases/inc/parser/parser_footnote.test.php
new file mode 100644
index 000000000..e3571d8e7
--- /dev/null
+++ b/_test/cases/inc/parser/parser_footnote.test.php
@@ -0,0 +1,392 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Footnote extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Footnote() {
+ $this->UnitTestCase('TestOfDoku_Parser_Footnote');
+ }
+
+ function setup() {
+ parent::setup();
+ $this->P->addMode('footnote',new Doku_Parser_Mode_Footnote());
+ }
+
+ function testFootnote() {
+ $this->P->parse('Foo (( testing )) Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(' testing ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotAFootnote() {
+ $this->P->parse("Foo (( testing\n Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nFoo (( testing\n Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteLinefeed() {
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse("Foo (( testing\ntesting )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array('Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(" testing\ntesting ")),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteNested() {
+ $this->P->parse('Foo (( x((y))z )) Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(' x((y')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array('z )) Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteEol() {
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse("Foo \nX(( test\ning ))Y\n Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array('Foo '.DOKU_PARSER_EOL.'X')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(" test\ning ")),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array('Y'.DOKU_PARSER_EOL.' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteStrong() {
+ $this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
+ $this->P->parse('Foo (( **testing** )) Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(' ')),
+ array('strong_open',array()),
+ array('cdata',array('testing')),
+ array('strong_close',array()),
+ array('cdata',array(' ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteHr() {
+ $this->P->addMode('hr',new Doku_Parser_Mode_HR());
+ $this->P->parse("Foo (( \n ---- \n )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(' ')),
+ array('hr',array()),
+ array('cdata',array("\n ")),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteCode() {
+ $this->P->addMode('code',new Doku_Parser_Mode_Code());
+ $this->P->parse("Foo (( <code>Test</code> )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(' ')),
+ array('code',array('Test',null,null)),
+ array('cdata',array(' ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnotePreformatted() {
+ $this->P->addMode('preformatted',new Doku_Parser_Mode_Preformatted());
+ $this->P->parse("Foo (( \n Test\n )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(' ')),
+ array('preformatted',array('Test')),
+ array('cdata',array(' ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnotePreformattedEol() {
+ $this->P->addMode('preformatted',new Doku_Parser_Mode_Preformatted());
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse("Foo (( \n Test\n )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array('Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(' ')),
+ array('preformatted',array('Test')),
+ array('cdata',array(' ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteUnformatted() {
+ $this->P->addMode('unformatted',new Doku_Parser_Mode_Unformatted());
+ $this->P->parse("Foo (( <nowiki>Test</nowiki> )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(' ')),
+ array('unformatted',array('Test')),
+ array('cdata',array(' ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteNotHeader() {
+ $this->P->addMode('unformatted',new Doku_Parser_Mode_Unformatted());
+ $this->P->parse("Foo (( \n====Test====\n )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(" \n====Test====\n ")),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteTable() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->parse("Foo ((
+| Row 0 Col 1 | Row 0 Col 2 | Row 0 Col 3 |
+| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+ )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('table_open',array(3, 2, 8)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(123)),
+ array('cdata',array(' ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteList() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->parse("Foo ((
+ *A
+ * B
+ * C
+ )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array("A")),
+ array('listcontent_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('cdata',array(' B')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('listitem_close',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(' C')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('cdata',array(' ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteQuote() {
+ $this->P->addMode('quote',new Doku_Parser_Mode_Quote());
+ $this->P->parse("Foo ((
+> def
+>>ghi
+ )) Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('quote_open',array()),
+ array('cdata',array(" def")),
+ array('quote_open',array()),
+ array('cdata',array("ghi")),
+ array('quote_close',array()),
+ array('quote_close',array()),
+ array('cdata',array(' ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testFootnoteNesting() {
+ $this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
+ $this->P->parse("(( a ** (( b )) ** c ))");
+
+ $calls = array(
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n")),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array(' a ')),
+ array('strong_open',array()),
+ array('cdata',array(' (( b ')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(" ")),
+ array('strong_close',array()),
+ array('cdata',array(" c ))")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+}
+
diff --git a/_test/cases/inc/parser/parser_formatting.test.php b/_test/cases/inc/parser/parser_formatting.test.php
new file mode 100644
index 000000000..69c57dfb5
--- /dev/null
+++ b/_test/cases/inc/parser/parser_formatting.test.php
@@ -0,0 +1,434 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Formatting extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Formatting() {
+ $this->UnitTestCase('TestOfDoku_Parser_Formatting');
+ }
+
+ function testStrong() {
+ $this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
+ $this->P->parse('abc **bar** def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('strong_open',array()),
+ array('cdata',array('bar')),
+ array('strong_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotStrong() {
+ $this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
+ $this->P->parse('abc **bar def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc **bar def")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testEm() {
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('abc //bar// def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('emphasis_open',array()),
+ array('cdata',array('bar')),
+ array('emphasis_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testEmColon() {
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('abc //Тест: // def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('emphasis_open',array()),
+ array('cdata',array('Тест: ')),
+ array('emphasis_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testEmSingleChar() {
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('abc //b// def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('emphasis_open',array()),
+ array('cdata',array('b')),
+ array('emphasis_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testEmWithUnknownSchema() {
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('abc //foo:// bar// def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('emphasis_open',array()),
+ array('cdata',array('foo:')),
+ array('emphasis_close',array()),
+ array('cdata',array(' bar// def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testEmWithKnownSchema() {
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
+ $this->P->parse('abc //foo http://www.google.com bar// def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('emphasis_open',array()),
+ array('cdata',array('foo ')),
+ array('externallink',array('http://www.google.com', NULL)),
+ array('cdata',array(' bar')),
+ array('emphasis_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotEm() {
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('abc //bar def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc //bar def")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotEmSchemaAtOpen() {
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('abc foo://bar// def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc foo:')),
+ array('emphasis_open',array()),
+ array('cdata',array('bar')),
+ array('emphasis_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotEmSchemaAtClose() {
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('abc //http:// def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc //http:// def")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testEmWithMultiOccurence() {
+ // Case from #763
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('//text:// Blablabla Blablabla
+
+//text:// another Blablabla Blablabla');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n")),
+ array('emphasis_open',array()),
+ array('cdata',array('text:')),
+ array('emphasis_close',array()),
+ array('cdata',array(" Blablabla Blablabla\n\n")),
+ array('emphasis_open',array()),
+ array('cdata',array('text:')),
+ array('emphasis_close',array()),
+ array('cdata',array(" another Blablabla Blablabla")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testEmWithUnicode() {
+ // Case from #1468
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('//Тест://');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n")),
+ array('emphasis_open',array()),
+ array('cdata',array('Тест:')),
+ array('emphasis_close',array()),
+ array('cdata', array('')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNoEmWithInvalidURL() {
+ // Case from #1629
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('http://<CertificateServerName>/certsrv/certcarc.asp');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array('http://<CertificateServerName>/certsrv/certcarc.asp')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNoEmWithUnknownURL() {
+ // Case from #1640
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('svn://example.com/foo/bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array('svn://example.com/foo/bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testUnderline() {
+ $this->P->addMode('underline',new Doku_Parser_Mode_Formatting('underline'));
+ $this->P->parse('abc __bar__ def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('underline_open',array()),
+ array('cdata',array('bar')),
+ array('underline_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotUnderline() {
+ $this->P->addMode('underline',new Doku_Parser_Mode_Formatting('underline'));
+ $this->P->parse('abc __bar def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc __bar def")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testMonospace() {
+ $this->P->addMode('monospace',new Doku_Parser_Mode_Formatting('monospace'));
+ $this->P->parse("abc ''bar'' def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('monospace_open',array()),
+ array('cdata',array('bar')),
+ array('monospace_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotMonospace() {
+ $this->P->addMode('monospace',new Doku_Parser_Mode_Formatting('monospace'));
+ $this->P->parse("abc ''bar def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ''bar def")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSubscript() {
+ $this->P->addMode('subscript',new Doku_Parser_Mode_Formatting('subscript'));
+ $this->P->parse('abc <sub>bar</sub> def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('subscript_open',array()),
+ array('cdata',array('bar')),
+ array('subscript_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotSubscript() {
+ $this->P->addMode('subscript',new Doku_Parser_Mode_Formatting('subscript'));
+ $this->P->parse('abc <sub>bar def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc <sub>bar def")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSuperscript() {
+ $this->P->addMode('superscript',new Doku_Parser_Mode_Formatting('superscript'));
+ $this->P->parse("abc <sup>bar</sup> def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('superscript_open',array()),
+ array('cdata',array('bar')),
+ array('superscript_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotSuperscript() {
+ $this->P->addMode('superscript',new Doku_Parser_Mode_Formatting('superscript'));
+ $this->P->parse("abc <sup>bar def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc <sup>bar def")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testDeleted() {
+ $this->P->addMode('deleted',new Doku_Parser_Mode_Formatting('deleted'));
+ $this->P->parse('abc <del>bar</del> def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('deleted_open',array()),
+ array('cdata',array('bar')),
+ array('deleted_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotDeleted() {
+ $this->P->addMode('deleted',new Doku_Parser_Mode_Formatting('deleted'));
+ $this->P->parse('abc <del>bar def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc <del>bar def")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNestedFormatting() {
+ $this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
+ $this->P->addMode('emphasis',new Doku_Parser_Mode_Formatting('emphasis'));
+ $this->P->parse('abc **a//b//c** def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('strong_open',array()),
+ array('cdata',array('a')),
+ array('emphasis_open',array()),
+ array('cdata',array('b')),
+ array('emphasis_close',array()),
+ array('cdata',array('c')),
+ array('strong_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testIllegalNestedFormatting() {
+ $this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
+ $this->P->parse('abc **a**b**c** def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('strong_open',array()),
+ array('cdata',array('a')),
+ array('strong_close',array()),
+ array('cdata',array('b')),
+ array('strong_open',array()),
+ array('cdata',array('c')),
+ array('strong_close',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+}
+
diff --git a/_test/cases/inc/parser/parser_headers.test.php b/_test/cases/inc/parser/parser_headers.test.php
new file mode 100644
index 000000000..688bac2eb
--- /dev/null
+++ b/_test/cases/inc/parser/parser_headers.test.php
@@ -0,0 +1,286 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Headers extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Headers() {
+ $this->UnitTestCase('TestOfDoku_Parser_Headers');
+ }
+
+ function testHeader1() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n ====== Header ====== \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('Header',1,6)),
+ array('section_open',array(1)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeader2() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n ===== Header ===== \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('Header',2,6)),
+ array('section_open',array(2)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeader3() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n ==== Header ==== \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('Header',3,6)),
+ array('section_open',array(3)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeader4() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n === Header === \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('Header',4,6)),
+ array('section_open',array(4)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeader5() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n == Header == \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('Header',5,6)),
+ array('section_open',array(5)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeader2UnevenSmaller() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n ===== Header == \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('Header',2,6)),
+ array('section_open',array(2)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeader2UnevenBigger() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n ===== Header =========== \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('Header',2,6)),
+ array('section_open',array(2)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeaderLarge() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n ======= Header ======= \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('Header',1,6)),
+ array('section_open',array(1)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeaderSmall() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n= Header =\n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc \n= Header =\n def")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+
+ function testHeader1Mixed() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n====== == Header == ======\n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('== Header ==',1,6)),
+ array('section_open',array(1)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeader5Mixed() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n== ====== Header ====== ==\n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('====== Header ======',5,6)),
+ array('section_open',array(5)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testHeaderMultiline() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n== ====== Header\n ====== ==\n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc \n== ====== Header")),
+ array('p_close',array()),
+ array('header',array('',1,23)),
+ array('section_open',array(1)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+# function testNoToc() {
+# $this->P->addMode('notoc',new Doku_Parser_Mode_NoToc());
+# $this->P->parse('abc ~~NOTOC~~ def');
+# $this->assertFalse($this->H->meta['toc']);
+# }
+
+ function testHeader1Eol() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse("abc \n ====== Header ====== \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array('abc ')),
+ array('p_close',array()),
+ array('header',array('Header',1, 6)),
+ array('section_open',array(1)),
+ array('p_open',array()),
+ array('cdata',array(' def')),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+
+ }
+
+ function testHeaderMulti2() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("abc \n ====== Header ====== \n def abc \n ===== Header2 ===== \n def");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc ")),
+ array('p_close',array()),
+ array('header',array('Header',1,6)),
+ array('section_open',array(1)),
+ array('p_open',array()),
+ array('cdata',array("\n def abc ")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('header',array('Header2',2,39)),
+ array('section_open',array(2)),
+ array('p_open',array()),
+ array('cdata',array("\n def")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array())
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+}
+
diff --git a/_test/cases/inc/parser/parser_i18n.test.php b/_test/cases/inc/parser/parser_i18n.test.php
new file mode 100644
index 000000000..27ec3c78b
--- /dev/null
+++ b/_test/cases/inc/parser/parser_i18n.test.php
@@ -0,0 +1,166 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_i18n extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_i18n() {
+ $this->UnitTestCase('TestOfDoku_Parser_i18n');
+ }
+
+ function testFormatting() {
+ $formats = array (
+ 'strong', 'emphasis', 'underline', 'monospace',
+ 'subscript', 'superscript', 'deleted',
+ );
+ foreach ( $formats as $format ) {
+ $this->P->addMode($format,new Doku_Parser_Mode_Formatting($format));
+ }
+ $this->P->parse("I**ñ**t__ë__r//n//â<sup>t</sup>i<sub>ô</sub>n''à''liz<del>æ</del>tiøn");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nI")),
+ array('strong_open',array()),
+ array('cdata',array('ñ')),
+ array('strong_close',array()),
+ array('cdata',array('t')),
+ array('underline_open',array()),
+ array('cdata',array('ë')),
+ array('underline_close',array()),
+ array('cdata',array('r')),
+ array('emphasis_open',array()),
+ array('cdata',array('n')),
+ array('emphasis_close',array()),
+ array('cdata',array('â')),
+ array('superscript_open',array()),
+ array('cdata',array('t')),
+ array('superscript_close',array()),
+ array('cdata',array('i')),
+ array('subscript_open',array()),
+ array('cdata',array('ô')),
+ array('subscript_close',array()),
+ array('cdata',array('n')),
+ array('monospace_open',array()),
+ array('cdata',array('à')),
+ array('monospace_close',array()),
+ array('cdata',array('liz')),
+ array('deleted_open',array()),
+ array('cdata',array('æ')),
+ array('deleted_close',array()),
+ array('cdata',array("tiøn")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testHeader() {
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->parse("Foo\n ==== Iñtërnâtiônàlizætiøn ==== \n Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nFoo")),
+ array('p_close',array()),
+ array('header',array('Iñtërnâtiônàlizætiøn',3,5)),
+ array('section_open',array(3)),
+ array('p_open',array()),
+ array('cdata',array("\n Bar")),
+ array('p_close',array()),
+ array('section_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testTable() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->parse('
+abc
+| Row 0 Col 1 | Iñtërnâtiônàlizætiøn | Row 0 Col 3 |
+| Row 1 Col 1 | Iñtërnâtiônàlizætiøn | Row 1 Col 3 |
+def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 2, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Iñtërnâtiônàlizætiøn ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Iñtërnâtiônàlizætiøn ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(153)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testAcronym() {
+ $t = array('Iñtërnâtiônàlizætiøn');
+ $this->P->addMode('acronym',new Doku_Parser_Mode_Acronym($t));
+ $this->P->parse("Foo Iñtërnâtiônàlizætiøn Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nFoo ")),
+ array('acronym',array('Iñtërnâtiônàlizætiøn')),
+ array('cdata',array(" Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testInterwiki() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[wp>Iñtërnâtiônàlizætiøn|Iñtërnâtiônàlizætiøn]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('interwikilink',array('wp>Iñtërnâtiônàlizætiøn','Iñtërnâtiônàlizætiøn','wp','Iñtërnâtiônàlizætiøn')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testInternalLink() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[x:Iñtërnâtiônàlizætiøn:y:foo_bar:z|Iñtërnâtiônàlizætiøn]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internallink',array('x:Iñtërnâtiônàlizætiøn:y:foo_bar:z','Iñtërnâtiônàlizætiøn')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+}
+
diff --git a/_test/cases/inc/parser/parser_links.test.php b/_test/cases/inc/parser/parser_links.test.php
new file mode 100644
index 000000000..53871e110
--- /dev/null
+++ b/_test/cases/inc/parser/parser_links.test.php
@@ -0,0 +1,683 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Links extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Links() {
+ $this->UnitTestCase('TestOfDoku_Parser_Links');
+ }
+
+
+ function testExternalLinkSimple() {
+ $this->P->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
+ $this->P->parse("Foo http://www.google.com Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externallink',array('http://www.google.com', NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testExternalLinkCase() {
+ $this->P->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
+ $this->P->parse("Foo HTTP://WWW.GOOGLE.COM Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externallink',array('HTTP://WWW.GOOGLE.COM', NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testExternalIPv4() {
+ $this->P->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
+ $this->P->parse("Foo http://123.123.3.21/foo Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externallink',array('http://123.123.3.21/foo', NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testExternalIPv6() {
+ $this->P->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
+ $this->P->parse("Foo http://[3ffe:2a00:100:7031::1]/foo Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externallink',array('http://[3ffe:2a00:100:7031::1]/foo', NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testExternalMulti(){
+ $this->teardown();
+
+ $links = array(
+ 'http://www.google.com',
+ 'HTTP://WWW.GOOGLE.COM',
+ 'http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html',
+ 'http://[1080:0:0:0:8:800:200C:417A]/index.html',
+ 'http://[3ffe:2a00:100:7031::1]',
+ 'http://[1080::8:800:200C:417A]/foo',
+ 'http://[::192.9.5.5]/ipng',
+ 'http://[::FFFF:129.144.52.38]:80/index.html',
+ 'http://[2010:836B:4179::836B:4179]',
+ );
+ $titles = array(false,null,'foo bar');
+ foreach($links as $link){
+ foreach($titles as $title){
+ if($title === false){
+ $source = $link;
+ $name = null;
+ }elseif($title === null){
+ $source = "[[$link]]";
+ $name = null;
+ }else{
+ $source = "[[$link|$title]]";
+ $name = $title;
+ }
+ $this->signal('failinfo',$source);
+
+ $this->setup();
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
+ $this->P->parse("Foo $source Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externallink',array($link, $name)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ $this->teardown();
+ }
+ }
+
+ $this->setup();
+ }
+
+ function testExternalLinkJavascript() {
+ $this->P->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
+ $this->P->parse("Foo javascript:alert('XSS'); Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nFoo javascript:alert('XSS'); Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testExternalWWWLink() {
+ $this->P->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
+ $this->P->parse("Foo www.google.com Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externallink',array('http://www.google.com', 'www.google.com')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testExternalFTPLink() {
+ $this->P->addMode('externallink',new Doku_Parser_Mode_ExternalLink());
+ $this->P->parse("Foo ftp.sunsite.com Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externallink',array('ftp://ftp.sunsite.com', 'ftp.sunsite.com')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+ function testEmail() {
+ $this->P->addMode('emaillink',new Doku_Parser_Mode_Emaillink());
+ $this->P->parse("Foo <bugs@php.net> Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('emaillink',array('bugs@php.net', NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testEmailRFC2822() {
+ $this->P->addMode('emaillink',new Doku_Parser_Mode_Emaillink());
+ $this->P->parse("Foo <~fix+bug's.for/ev{e}r@php.net> Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('emaillink',array("~fix+bug's.for/ev{e}r@php.net", NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testEmailCase() {
+ $this->P->addMode('emaillink',new Doku_Parser_Mode_Emaillink());
+ $this->P->parse("Foo <bugs@pHp.net> Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('emaillink',array('bugs@pHp.net', NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+
+ function testInternalLinkOneChar() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[l]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internallink',array('l',NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testInternalLinkNoChar() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internallink',array('',NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testInternalLinkNamespaceNoTitle() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[foo:bar]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internallink',array('foo:bar',NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testInternalLinkNamespace() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[x:1:y:foo_bar:z|Test]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internallink',array('x:1:y:foo_bar:z','Test')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testInternalLinkSectionRef() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[wiki:syntax#internal|Syntax]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internallink',array('wiki:syntax#internal','Syntax')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testExternalInInternalLink() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[http://www.google.com|Google]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externallink',array('http://www.google.com','Google')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testInterwikiLink() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[iw>somepage|Some Page]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('interwikilink',array('iw>somepage','Some Page','iw','somepage')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testInterwikiLinkCase() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[IW>somepage|Some Page]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('interwikilink',array('IW>somepage','Some Page','iw','somepage')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testInterwikiPedia() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[wp>Callback_(computer_science)|callbacks]] Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('interwikilink',array('wp>Callback_(computer_science)','callbacks','wp','Callback_(computer_science)')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testCamelCase() {
+ $this->P->addMode('camelcaselink',new Doku_Parser_Mode_CamelCaseLink());
+ $this->P->parse("Foo FooBar Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('camelcaselink',array('FooBar')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testFileLink() {
+ $this->P->addMode('filelink',new Doku_Parser_Mode_FileLink());
+ $this->P->parse('Foo file://temp/file.txt Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('filelink',array('file://temp/file.txt ',NULL)),
+ array('cdata',array('Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testFileLinkInternal() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse('Foo [[file://temp/file.txt|Some File]] Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externallink',array('file://temp/file.txt','Some File')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testWindowsShareLink() {
+ $this->P->addMode('windowssharelink',new Doku_Parser_Mode_WindowsShareLink());
+ $this->P->parse('Foo \\\server\share Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('windowssharelink',array('\\\server\share',NULL)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testWindowsShareLinkInternal() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse('Foo [[\\\server\share|My Documents]] Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('windowssharelink',array('\\\server\share','My Documents')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaInternal() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{img.gif}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internalmedia',array('img.gif',NULL,NULL,NULL,NULL,'cache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaInternalLinkOnly() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{img.gif?linkonly}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internalmedia',array('img.gif',NULL,NULL,NULL,NULL,'cache','linkonly')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaNotImage() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{foo.txt?10x10|Some File}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internalmedia',array('foo.txt','Some File',null,10,10,'cache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaInternalLAlign() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{img.gif }} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internalmedia',array('img.gif',NULL,'left',NULL,NULL,'cache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaInternalRAlign() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{ img.gif}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internalmedia',array('img.gif',NULL,'right',NULL,NULL,'cache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaInternalCenter() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{ img.gif }} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internalmedia',array('img.gif',NULL,'center',NULL,NULL,'cache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaInternalParams() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{img.gif?50x100nocache}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internalmedia',array('img.gif',NULL,NULL,'50','100','nocache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaInternalTitle() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{img.gif?50x100|Some Image}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internalmedia',array('img.gif','Some Image',NULL,'50','100','cache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaExternal() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{http://www.google.com/img.gif}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externalmedia',array('http://www.google.com/img.gif',NULL,NULL,NULL,NULL,'cache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaExternalParams() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{http://www.google.com/img.gif?50x100nocache}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externalmedia',array('http://www.google.com/img.gif',NULL,NULL,'50','100','nocache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaExternalTitle() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{http://www.google.com/img.gif?50x100|Some Image}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('externalmedia',
+ array('http://www.google.com/img.gif','Some Image',NULL,'50','100','cache','details')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaInInternalLink() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[x:1:y:foo_bar:z|{{img.gif?10x20nocache|Some Image}}]] Bar");
+
+ $image = array(
+ 'type'=>'internalmedia',
+ 'src'=>'img.gif',
+ 'title'=>'Some Image',
+ 'align'=>NULL,
+ 'width'=>10,
+ 'height'=>20,
+ 'cache'=>'nocache',
+ 'linking'=>'details',
+ );
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internallink',array('x:1:y:foo_bar:z',$image)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaNoImageInInternalLink() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[x:1:y:foo_bar:z|{{foo.txt?10x20nocache|Some Image}}]] Bar");
+
+ $image = array(
+ 'type'=>'internalmedia',
+ 'src'=>'foo.txt',
+ 'title'=>'Some Image',
+ 'align'=>NULL,
+ 'width'=>10,
+ 'height'=>20,
+ 'cache'=>'nocache',
+ 'linking'=>'details',
+ );
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internallink',array('x:1:y:foo_bar:z',$image)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testMediaInEmailLink() {
+ $this->P->addMode('internallink',new Doku_Parser_Mode_InternalLink());
+ $this->P->parse("Foo [[foo@example.com|{{img.gif?10x20nocache|Some Image}}]] Bar");
+
+ $image = array(
+ 'type'=>'internalmedia',
+ 'src'=>'img.gif',
+ 'title'=>'Some Image',
+ 'align'=>NULL,
+ 'width'=>10,
+ 'height'=>20,
+ 'cache'=>'nocache',
+ 'linking'=>'details',
+ );
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('emaillink',array('foo@example.com',$image)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+ function testNestedMedia() {
+ $this->P->addMode('media',new Doku_Parser_Mode_Media());
+ $this->P->parse('Foo {{img.gif|{{foo.gif|{{bar.gif|Bar}}}}}} Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('internalmedia',
+ array('img.gif','{{foo.gif|{{bar.gif|Bar',NULL,NULL,NULL,'cache','details')),
+ array('cdata',array('}}}} Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+
+}
+
diff --git a/_test/cases/inc/parser/parser_lists.test.php b/_test/cases/inc/parser/parser_lists.test.php
new file mode 100644
index 000000000..6e61da1a1
--- /dev/null
+++ b/_test/cases/inc/parser/parser_lists.test.php
@@ -0,0 +1,397 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Lists extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Lists() {
+ $this->UnitTestCase('TestOfDoku_Parser_Lists');
+ }
+
+ function testUnorderedList() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->parse('
+ *A
+ * B
+ * C
+');
+ $calls = array (
+ array('document_start',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array("A")),
+ array('listcontent_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('cdata',array(' B')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('listitem_close',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(' C')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testOrderedList() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->parse('
+ -A
+ - B
+ - C
+');
+ $calls = array (
+ array('document_start',array()),
+ array('listo_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array("A")),
+ array('listcontent_close',array()),
+ array('listo_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('cdata',array(' B')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listo_close',array()),
+ array('listitem_close',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(' C')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listo_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+
+ function testMixedList() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->parse('
+ -A
+ * B
+ - C
+');
+ $calls = array (
+ array('document_start',array()),
+ array('listo_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array("A")),
+ array('listcontent_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('cdata',array(' B')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('listitem_close',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(' C')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listo_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testUnorderedListWinEOL() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->parse("\r\n *A\r\n * B\r\n * C\r\n");
+ $calls = array (
+ array('document_start',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array("A")),
+ array('listcontent_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('cdata',array(' B')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('listitem_close',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(' C')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testOrderedListWinEOL() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->parse("\r\n -A\r\n - B\r\n - C\r\n");
+ $calls = array (
+ array('document_start',array()),
+ array('listo_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array("A")),
+ array('listcontent_close',array()),
+ array('listo_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('cdata',array(' B')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listo_close',array()),
+ array('listitem_close',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(' C')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listo_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testNotAList() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->parse("Foo -bar *foo Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nFoo -bar *foo Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testUnorderedListParagraph() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse('Foo
+ *A
+ * B
+ * C
+Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("Foo")),
+ array('p_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array("A")),
+ array('listcontent_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('cdata',array(' B')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('listitem_close',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(' C')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('p_open',array()),
+ array('cdata',array("Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ // This is really a failing test - formatting able to spread across list items
+ // Problem is fixing it would mean a major rewrite of lists
+ function testUnorderedListStrong() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
+ $this->P->parse('
+ ***A**
+ *** B
+ * C**
+');
+ $calls = array (
+ array('document_start',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('strong_open',array()),
+ array('cdata',array("A")),
+ array('strong_close',array()),
+ array('listcontent_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('strong_open',array()),
+ array('cdata',array(" B\n * C")),
+ array('strong_close',array()),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ // This is really a failing test - unformatted able to spread across list items
+ // Problem is fixing it would mean a major rewrite of lists
+ function testUnorderedListUnformatted() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->addMode('unformatted',new Doku_Parser_Mode_Unformatted());
+ $this->P->parse('
+ *%%A%%
+ *%% B
+ * C%%
+');
+ $calls = array (
+ array('document_start',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('unformatted',array("A")),
+ array('listcontent_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('unformatted',array(" B\n * C")),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testUnorderedListLinebreak() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->addMode('linebreak',new Doku_Parser_Mode_Linebreak());
+ $this->P->parse('
+ *A\\\\ D
+ * B
+ * C
+');
+ $calls = array (
+ array('document_start',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array("A")),
+ array('linebreak',array()),
+ array('cdata',array("D")),
+ array('listcontent_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('cdata',array(' B')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('listitem_close',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(' C')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testUnorderedListLinebreak2() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->addMode('linebreak',new Doku_Parser_Mode_Linebreak());
+ $this->P->parse('
+ *A\\\\
+ * B
+');
+ $calls = array (
+ array('document_start',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array("A")),
+ array('linebreak',array()),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(' B')),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testUnorderedListFootnote() {
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->addMode('footnote',new Doku_Parser_Mode_Footnote());
+ $this->P->parse('
+ *((A))
+ *(( B
+ * C ))
+
+');
+ $calls = array (
+ array('document_start',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('nest', array( array(
+ array('footnote_open',array()),
+ array('cdata',array("A")),
+ array('footnote_close',array())
+ ))),
+ array('listcontent_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(2)),
+ array('listcontent_open',array()),
+ array('nest', array( array(
+ array('footnote_open',array()),
+ array('cdata',array(" B")),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(" C )) ")),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('cdata',array("\n\n")),
+ array('footnote_close',array())
+ ))),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('document_end',array())
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+}
+
diff --git a/_test/cases/inc/parser/parser_preformatted.test.php b/_test/cases/inc/parser/parser_preformatted.test.php
new file mode 100644
index 000000000..7a00f3599
--- /dev/null
+++ b/_test/cases/inc/parser/parser_preformatted.test.php
@@ -0,0 +1,235 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Preformatted extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Preformatted() {
+ $this->UnitTestCase('TestOfDoku_Parser_Preformatted');
+ }
+
+ function testFile() {
+ $this->P->addMode('file',new Doku_Parser_Mode_File());
+ $this->P->parse('Foo <file>testing</file> Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('p_close',array()),
+ array('file',array('testing',null,null)),
+ array('p_open',array()),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testCode() {
+ $this->P->addMode('code',new Doku_Parser_Mode_Code());
+ $this->P->parse('Foo <code>testing</code> Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('p_close',array()),
+ array('code',array('testing', null, null)),
+ array('p_open',array()),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testCodeWhitespace() {
+ $this->P->addMode('code',new Doku_Parser_Mode_Code());
+ $this->P->parse("Foo <code \n>testing</code> Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('p_close',array()),
+ array('code',array('testing', null, null)),
+ array('p_open',array()),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testCodeLang() {
+ $this->P->addMode('code',new Doku_Parser_Mode_Code());
+ $this->P->parse("Foo <code php>testing</code> Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('p_close',array()),
+ array('code',array('testing', 'php', null)),
+ array('p_open',array()),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testPreformatted() {
+ $this->P->addMode('preformatted',new Doku_Parser_Mode_Preformatted());
+ $this->P->parse("F oo\n x \n y \nBar\n");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nF oo")),
+ array('p_close',array()),
+ array('preformatted',array("x \n y ")),
+ array('p_open',array()),
+ array('cdata',array('Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testPreformattedWinEOL() {
+ $this->P->addMode('preformatted',new Doku_Parser_Mode_Preformatted());
+ $this->P->parse("F oo\r\n x \r\n y \r\nBar\r\n");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nF oo")),
+ array('p_close',array()),
+ array('preformatted',array("x \n y ")),
+ array('p_open',array()),
+ array('cdata',array('Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testPreformattedTab() {
+ $this->P->addMode('preformatted',new Doku_Parser_Mode_Preformatted());
+ $this->P->parse("F oo\n\tx\t\n\t\ty\t\nBar\n");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nF oo")),
+ array('p_close',array()),
+ array('preformatted',array("x\t\n\ty\t")),
+ array('p_open',array()),
+ array('cdata',array("Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testPreformattedTabWinEOL() {
+ $this->P->addMode('preformatted',new Doku_Parser_Mode_Preformatted());
+ $this->P->parse("F oo\r\n\tx\t\r\n\t\ty\t\r\nBar\r\n");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nF oo")),
+ array('p_close',array()),
+ array('preformatted',array("x\t\n\ty\t")),
+ array('p_open',array()),
+ array('cdata',array("Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testPreformattedList() {
+ $this->P->addMode('preformatted',new Doku_Parser_Mode_Preformatted());
+ $this->P->addMode('listblock',new Doku_Parser_Mode_ListBlock());
+ $this->P->parse(" - x \n * y \nF oo\n x \n y \n -X\n *Y\nBar\n");
+ $calls = array (
+ array('document_start',array()),
+ array('listo_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(" x ")),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listo_close',array()),
+ array('listu_open',array()),
+ array('listitem_open',array(1)),
+ array('listcontent_open',array()),
+ array('cdata',array(" y ")),
+ array('listcontent_close',array()),
+ array('listitem_close',array()),
+ array('listu_close',array()),
+ array('p_open',array()),
+ array('cdata',array("F oo")),
+ array('p_close',array()),
+ array('preformatted',array("x \n y \n-X\n*Y")),
+ array('p_open',array()),
+ array('cdata',array("Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ // test for php
+ function testPHP() {
+
+ $this->P->addMode('php',new Doku_Parser_Mode_PHP());
+ $this->P->parse('Foo <php>testing</php> Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('php',array('testing')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ // test with for HTML
+ function testHTML() {
+
+ $this->P->addMode('html',new Doku_Parser_Mode_HTML());
+ $this->P->parse('Foo <html>testing</html> Bar');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('html',array('testing')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+
+
+ function testPreformattedPlusHeaderAndEol() {
+ // Note that EOL must come after preformatted!
+ $this->P->addMode('preformatted',new Doku_Parser_Mode_Preformatted());
+ $this->P->addMode('header',new Doku_Parser_Mode_Header());
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse("F oo\n ==Test==\n y \nBar\n");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("F oo")),
+ array('p_close',array()),
+ array('preformatted',array("==Test==\n y ")),
+ array('p_open',array()),
+ array('cdata',array('Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+}
+
diff --git a/_test/cases/inc/parser/parser_quote.test.php b/_test/cases/inc/parser/parser_quote.test.php
new file mode 100644
index 000000000..ebc5da604
--- /dev/null
+++ b/_test/cases/inc/parser/parser_quote.test.php
@@ -0,0 +1,98 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Quote extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Quote() {
+ $this->UnitTestCase('TestOfDoku_Parser_Quote');
+ }
+
+ function testQuote() {
+ $this->P->addMode('quote',new Doku_Parser_Mode_Quote());
+ $this->P->parse("abc\n> def\n>>ghi\nklm");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc")),
+ array('p_close',array()),
+ array('quote_open',array()),
+ array('cdata',array(" def")),
+ array('quote_open',array()),
+ array('cdata',array("ghi")),
+ array('quote_close',array()),
+ array('quote_close',array()),
+ array('p_open',array()),
+ array('cdata',array("klm")),
+ array('p_close',array()),
+ array('document_end',array()),
+
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testQuoteWinCr() {
+ $this->P->addMode('quote',new Doku_Parser_Mode_Quote());
+ $this->P->parse("abc\r\n> def\r\n>>ghi\r\nklm");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc")),
+ array('p_close',array()),
+ array('quote_open',array()),
+ array('cdata',array(" def")),
+ array('quote_open',array()),
+ array('cdata',array("ghi")),
+ array('quote_close',array()),
+ array('quote_close',array()),
+ array('p_open',array()),
+ array('cdata',array("klm")),
+ array('p_close',array()),
+ array('document_end',array()),
+
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testQuoteMinumumContext() {
+ $this->P->addMode('quote',new Doku_Parser_Mode_Quote());
+ $this->P->parse("\n> def\n>>ghi\n ");
+ $calls = array (
+ array('document_start',array()),
+ array('quote_open',array()),
+ array('cdata',array(" def")),
+ array('quote_open',array()),
+ array('cdata',array("ghi")),
+ array('quote_close',array()),
+ array('quote_close',array()),
+ array('document_end',array()),
+
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testQuoteEol() {
+ $this->P->addMode('quote',new Doku_Parser_Mode_Quote());
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse("abc\n> def\n>>ghi\nklm");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("abc")),
+ array('p_close',array()),
+ array('quote_open',array()),
+ array('cdata',array(" def")),
+ array('quote_open',array()),
+ array('cdata',array("ghi")),
+ array('quote_close',array()),
+ array('quote_close',array()),
+ array('p_open',array()),
+ array('cdata',array("klm")),
+ array('p_close',array()),
+ array('document_end',array()),
+
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+}
+
diff --git a/_test/cases/inc/parser/parser_quotes.test.php b/_test/cases/inc/parser/parser_quotes.test.php
new file mode 100644
index 000000000..77e323799
--- /dev/null
+++ b/_test/cases/inc/parser/parser_quotes.test.php
@@ -0,0 +1,273 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Quotes extends TestOfDoku_Parser {
+
+ function setup() {
+ parent::setup();
+ global $conf;
+ $conf['typography'] = 2;
+ }
+
+ function TestOfDoku_Parser_Quotes() {
+ $this->UnitTestCase('TestOfDoku_Parser_Quotes');
+ }
+
+ function testSingleQuoteOpening() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse("Foo 'hello Bar");
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('singlequoteopening',array()),
+ array('cdata',array('hello Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSingleQuoteOpeningSpecial() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse("Foo said:'hello Bar");
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo said:')),
+ array('singlequoteopening',array()),
+ array('cdata',array('hello Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSingleQuoteClosing() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse("Foo hello' Bar");
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo hello')),
+ array('singlequoteclosing',array()),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSingleQuoteClosingSpecial() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse("Foo hello') Bar");
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo hello')),
+ array('singlequoteclosing',array()),
+ array('cdata',array(') Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSingleQuotes() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse("Foo 'hello' Bar");
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('singlequoteopening',array()),
+ array('cdata',array('hello')),
+ array('singlequoteclosing',array()),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testApostrophe() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse("hey it's fine weather today");
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'hey it')),
+ array('apostrophe',array()),
+ array('cdata',array('s fine weather today')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+
+ function testSingleQuotesSpecial() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse("Foo ('hello') Bar");
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo (')),
+ array('singlequoteopening',array()),
+ array('cdata',array('hello')),
+ array('singlequoteclosing',array()),
+ array('cdata',array(') Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testDoubleQuoteOpening() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse('Foo "hello Bar');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('doublequoteopening',array()),
+ array('cdata',array('hello Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testDoubleQuoteOpeningSpecial() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse('Foo said:"hello Bar');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo said:')),
+ array('doublequoteopening',array()),
+ array('cdata',array('hello Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testDoubleQuoteClosing() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse('Foo hello" Bar');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo hello')),
+ array('doublequoteclosing',array()),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testDoubleQuoteClosingSpecial() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse('Foo hello") Bar');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo hello')),
+ array('doublequoteclosing',array()),
+ array('cdata',array(') Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testDoubleQuotes() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse('Foo "hello" Bar');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('doublequoteopening',array()),
+ array('cdata',array('hello')),
+ array('doublequoteclosing',array()),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testDoubleQuotesSpecial() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse('Foo ("hello") Bar');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo (')),
+ array('doublequoteopening',array()),
+ array('cdata',array('hello')),
+ array('doublequoteclosing',array()),
+ array('cdata',array(') Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testAllQuotes() {
+ $this->P->addMode('quotes',new Doku_Parser_Mode_Quotes());
+ $this->P->parse('There was written "He thought \'It\'s a man\'s world\'".');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'There was written ')),
+ array('doublequoteopening',array()),
+ array('cdata',array('He thought ')),
+ array('singlequoteopening',array()),
+ array('cdata',array('It')),
+ array('apostrophe',array()),
+ array('cdata',array('s a man')),
+ array('apostrophe',array()),
+ array('cdata',array('s world')),
+ array('singlequoteclosing',array()),
+ array('doublequoteclosing',array()),
+ array('cdata',array(".")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+}
+
diff --git a/_test/cases/inc/parser/parser_replacements.test.php b/_test/cases/inc/parser/parser_replacements.test.php
new file mode 100644
index 000000000..d277560c7
--- /dev/null
+++ b/_test/cases/inc/parser/parser_replacements.test.php
@@ -0,0 +1,384 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Replacements extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Replacements() {
+ $this->UnitTestCase('TestOfDoku_Parser_Replacements');
+ }
+
+
+ function testSingleAcronym() {
+ $this->P->addMode('acronym',new Doku_Parser_Mode_Acronym(array('FOOBAR')));
+ $this->P->parse('abc FOOBAR xyz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('acronym',array('FOOBAR')),
+ array('cdata',array(' xyz')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testAlmostAnAcronym() {
+ $this->P->addMode('acronym',new Doku_Parser_Mode_Acronym(array('FOOBAR')));
+ $this->P->parse('abcFOOBARxyz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abcFOOBARxyz')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testPickAcronymCorrectly() {
+ $this->P->addMode('acronym',new Doku_Parser_Mode_Acronym(array('FOO')));
+ $this->P->parse('FOOBAR FOO');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'FOOBAR ')),
+ array('acronym',array('FOO')),
+ array('cdata',array('')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testMultipleAcronyms() {
+ $this->P->addMode('acronym',new Doku_Parser_Mode_Acronym(array('FOO','BAR')));
+ $this->P->parse('abc FOO def BAR xyz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('acronym',array('FOO')),
+ array('cdata',array(' def ')),
+ array('acronym',array('BAR')),
+ array('cdata',array(' xyz')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+
+ }
+
+ function testMultipleAcronymsWithSubset1() {
+ $this->P->addMode('acronym',new Doku_Parser_Mode_Acronym(array('FOO','A.FOO','FOO.1','A.FOO.1')));
+ $this->P->parse('FOO A.FOO FOO.1 A.FOO.1');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n")),
+ array('acronym',array('FOO')),
+ array('cdata',array(" ")),
+ array('acronym',array('A.FOO')),
+ array('cdata',array(" ")),
+ array('acronym',array('FOO.1')),
+ array('cdata',array(" ")),
+ array('acronym',array('A.FOO.1')),
+ array('cdata',array('')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testMultipleAcronymsWithSubset2() {
+ $this->P->addMode('acronym',new Doku_Parser_Mode_Acronym(array('A.FOO.1','FOO.1','A.FOO','FOO')));
+ $this->P->parse('FOO A.FOO FOO.1 A.FOO.1');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n")),
+ array('acronym',array('FOO')),
+ array('cdata',array(" ")),
+ array('acronym',array('A.FOO')),
+ array('cdata',array(" ")),
+ array('acronym',array('FOO.1')),
+ array('cdata',array(" ")),
+ array('acronym',array('A.FOO.1')),
+ array('cdata',array('')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSingleSmileyFail() {
+ $this->P->addMode('smiley',new Doku_Parser_Mode_Smiley(array(':-)')));
+ $this->P->parse('abc:-)xyz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc:-)xyz")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSingleSmiley() {
+ $this->P->addMode('smiley',new Doku_Parser_Mode_Smiley(array(':-)')));
+ $this->P->parse('abc :-) xyz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('smiley',array(':-)')),
+ array('cdata',array(' xyz')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testMultipleSmileysFail() {
+ $this->P->addMode('smiley',new Doku_Parser_Mode_Smiley(array(':-)','^_^')));
+ $this->P->parse('abc:-)x^_^yz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc:-)x^_^yz")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testMultipleSmileys() {
+ $this->P->addMode('smiley',new Doku_Parser_Mode_Smiley(array(':-)','^_^')));
+ $this->P->parse('abc :-) x ^_^ yz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('smiley',array(':-)')),
+ array('cdata',array(' x ')),
+ array('smiley',array('^_^')),
+ array('cdata',array(' yz')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testBackslashSmileyFail() {
+ // This smiley is really :-\\ but escaping makes like interesting
+ $this->P->addMode('smiley',new Doku_Parser_Mode_Smiley(array(':-\\\\')));
+ $this->P->parse('abc:-\\\xyz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\nabc".':-\\\\'."xyz")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testBackslashSmiley() {
+ // This smiley is really :-\\ but escaping makes like interesting
+ $this->P->addMode('smiley',new Doku_Parser_Mode_Smiley(array(':-\\\\')));
+ $this->P->parse('abc :-\\\ xyz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('smiley',array(':-\\\\')),
+ array('cdata',array(' xyz')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSingleWordblock() {
+ $this->P->addMode('wordblock',new Doku_Parser_Mode_Wordblock(array('CAT')));
+ $this->P->parse('abc CAT xyz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('wordblock',array('CAT')),
+ array('cdata',array(' xyz')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testWordblockCase() {
+ $this->P->addMode('wordblock',new Doku_Parser_Mode_Wordblock(array('CAT')));
+ $this->P->parse('abc cat xyz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('wordblock',array('cat')),
+ array('cdata',array(' xyz')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testMultipleWordblock() {
+ $this->P->addMode('wordblock',new Doku_Parser_Mode_Wordblock(array('CAT','dog')));
+ $this->P->parse('abc cat x DOG yz');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'abc ')),
+ array('wordblock',array('cat')),
+ array('cdata',array(' x ')),
+ array('wordblock',array('DOG')),
+ array('cdata',array(' yz')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testSingleEntity() {
+ $this->P->addMode('entity',new Doku_Parser_Mode_Entity(array('->')));
+ $this->P->parse('x -> y');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'x ')),
+ array('entity',array('->')),
+ array('cdata',array(' y')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testMultipleEntities() {
+ $this->P->addMode('entity',new Doku_Parser_Mode_Entity(array('->','<-')));
+ $this->P->parse('x -> y <- z');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'x ')),
+ array('entity',array('->')),
+ array('cdata',array(' y ')),
+ array('entity',array('<-')),
+ array('cdata',array(' z')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testMultiplyEntity() {
+ $this->P->addMode('multiplyentity',new Doku_Parser_Mode_MultiplyEntity());
+ $this->P->parse('Foo 10x20 Bar');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('multiplyentity',array(10,20)),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testMultiplyEntityHex() {
+ // the multiply entity pattern should not match hex numbers, eg. 0x123
+ $this->P->addMode('multiplyentity',new Doku_Parser_Mode_MultiplyEntity());
+ $this->P->parse('Foo 0x123 Bar');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo 0x123 Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testHR() {
+ $this->P->addMode('hr',new Doku_Parser_Mode_HR());
+ $this->P->parse("Foo \n ---- \n Bar");
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('p_close',array()),
+ array('hr',array()),
+ array('p_open',array()),
+ array('cdata',array("\n Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testHREol() {
+ $this->P->addMode('hr',new Doku_Parser_Mode_HR());
+ $this->P->parse("Foo \n----\n Bar");
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('p_close',array()),
+ array('hr',array()),
+ array('p_open',array()),
+ array('cdata',array("\n Bar")),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+}
+
diff --git a/_test/cases/inc/parser/parser_table.test.php b/_test/cases/inc/parser/parser_table.test.php
new file mode 100644
index 000000000..12898860c
--- /dev/null
+++ b/_test/cases/inc/parser/parser_table.test.php
@@ -0,0 +1,576 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Table extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Table() {
+ $this->UnitTestCase('TestOfDoku_Parser_Table');
+ }
+
+ function testTable() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->parse('
+abc
+| Row 0 Col 1 | Row 0 Col 2 | Row 0 Col 3 |
+| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 2, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(121)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testTableWinEOL() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->parse("\r\nabc\r\n| Row 0 Col 1 | Row 0 Col 2 | Row 0 Col 3 |\r\n| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |\r\ndef");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 2, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(121)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testEmptyTable() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->parse('
+abc
+|
+def');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(0, 1, 6)),
+ array('tablerow_open',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(7)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testTableHeaders() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->parse('
+abc
+^ X | Y ^ Z |
+def');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 1, 6)),
+ array('tablerow_open',array()),
+ array('tableheader_open',array(1,NULL,1)),
+ array('cdata',array(' X ')),
+ array('tableheader_close',array()),
+ array('tablecell_open',array(1,NULL,1)),
+ array('cdata',array(' Y ')),
+ array('tablecell_close',array()),
+ array('tableheader_open',array(1,NULL,1)),
+ array('cdata',array(' Z ')),
+ array('tableheader_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(19)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+
+ }
+
+ function testCellAlignment() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->parse('
+abc
+| X | Y ^ Z |
+def');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 1, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'right',1)),
+ array('cdata',array(' X ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Y ')),
+ array('tablecell_close',array()),
+ array('tableheader_open',array(1,'center',1)),
+ array('cdata',array(' Z ')),
+ array('tableheader_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(23)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testCellSpan() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->parse('
+abc
+| d || e |
+| f ^ ^|
+||||
+def');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 3, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(2,'right',1)),
+ array('cdata',array(' d ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,NULL,1)),
+ array('cdata',array(' e ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,NULL,1)),
+ array('cdata',array(' f ')),
+ array('tablecell_close',array()),
+ array('tableheader_open',array(2,NULL,1)),
+ array('cdata',array(' ')),
+ array('tableheader_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(31)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testCellRowSpan() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->parse('
+abc
+| a | c:::||
+|:::^ d | e|
+|b ^ ::: |:::f|
+def');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 3, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,NULL,2)),
+ array('cdata',array(' a ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(2,'right',1)),
+ array('cdata',array(' c:::')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tableheader_open',array(1,'left',2)),
+ array('cdata',array(' d ')),
+ array('tableheader_close',array()),
+ array('tablecell_open',array(1,NULL,1)),
+ array('cdata',array(' e')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array('b ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,NULL,1)),
+ array('cdata',array(':::f')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(51)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testCellAlignmentFormatting() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
+ $this->P->parse('
+abc
+| **X** | Y ^ Z |
+def');
+
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 1, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'right',1)),
+ array('cdata',array(' ')),
+ array('strong_open',array()),
+ array('cdata',array('X')),
+ array('strong_close',array()),
+ array('cdata',array(' ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Y ')),
+ array('tablecell_close',array()),
+ array('tableheader_open',array(1,'center',1)),
+ array('cdata',array(' Z ')),
+ array('tableheader_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(27)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+
+ }
+
+ function testTableEol() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->addMode('eol',new Doku_Parser_Mode_Eol());
+ $this->P->parse('
+abc
+| Row 0 Col 1 | Row 0 Col 2 | Row 0 Col 3 |
+| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("abc")),
+ array('p_close',array()),
+ array('table_open',array(3, 2, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(121)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ // This is really a failing test - formatting able to spread across cols
+ // Problem is fixing it would mean a major rewrite of table handling
+ function testTableStrong() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->addMode('strong',new Doku_Parser_Mode_Formatting('strong'));
+ $this->P->parse('
+abc
+| **Row 0 Col 1** | **Row 0 Col 2 | Row 0 Col 3** |
+| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 2, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' ')),
+ array('strong_open',array()),
+ array('cdata',array('Row 0 Col 1')),
+ array('strong_close',array()),
+ array('cdata',array(' ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' ')),
+ array('strong_open',array()),
+ array('cdata',array('Row 0 Col 2 | Row 0 Col 3')),
+ array('strong_close',array()),
+ array('cdata',array(' ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,null,1)),
+ array('cdata',array('')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(129)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ // This is really a failing test - unformatted able to spread across cols
+ // Problem is fixing it would mean a major rewrite of table handling
+ function testTableUnformatted() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->addMode('unformatted',new Doku_Parser_Mode_Unformatted());
+ $this->P->parse('
+abc
+| <nowiki>Row 0 Col 1</nowiki> | <nowiki>Row 0 Col 2 | Row 0 Col 3</nowiki> |
+| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 2, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' ')),
+ array('unformatted',array('Row 0 Col 1')),
+ array('cdata',array(' ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' ')),
+ array('unformatted',array('Row 0 Col 2 | Row 0 Col 3')),
+ array('cdata',array(' ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,null,1)),
+ array('cdata',array('')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(155)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ function testTableLinebreak() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->addMode('linebreak',new Doku_Parser_Mode_Linebreak());
+ $this->P->parse('
+abc
+| Row 0\\\\ Col 1 | Row 0 Col 2 | Row 0 Col 3 |
+| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 2, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0')),
+ array('linebreak',array()),
+ array('cdata',array('Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 0 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(123)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+
+ // This is really a failing test - footnote able to spread across cols
+ // Problem is fixing it would mean a major rewrite of table handling
+ function testTableFootnote() {
+ $this->P->addMode('table',new Doku_Parser_Mode_Table());
+ $this->P->addMode('footnote',new Doku_Parser_Mode_Footnote());
+ $this->P->parse('
+abc
+| ((Row 0 Col 1)) | ((Row 0 Col 2 | Row 0 Col 3)) |
+| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+def');
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n\nabc")),
+ array('p_close',array()),
+ array('table_open',array(3, 2, 6)),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array('Row 0 Col 1')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' ')),
+ array('nest', array ( array (
+ array('footnote_open',array()),
+ array('cdata',array('Row 0 Col 2 | Row 0 Col 3')),
+ array('footnote_close',array()),
+ ))),
+ array('cdata',array(' ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,null,1)),
+ array('cdata',array('')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('tablerow_open',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 1 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 2 ')),
+ array('tablecell_close',array()),
+ array('tablecell_open',array(1,'left',1)),
+ array('cdata',array(' Row 1 Col 3 ')),
+ array('tablecell_close',array()),
+ array('tablerow_close',array()),
+ array('table_close',array(129)),
+ array('p_open',array()),
+ array('cdata',array('def')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripbyteindex',$this->H->calls),$calls);
+ }
+}
+
diff --git a/_test/cases/inc/parser/parser_unformatted.test.php b/_test/cases/inc/parser/parser_unformatted.test.php
new file mode 100644
index 000000000..dd69564b4
--- /dev/null
+++ b/_test/cases/inc/parser/parser_unformatted.test.php
@@ -0,0 +1,42 @@
+<?php
+require_once 'parser.inc.php';
+
+class TestOfDoku_Parser_Unformatted extends TestOfDoku_Parser {
+
+ function TestOfDoku_Parser_Unformatted() {
+ $this->UnitTestCase('TestOfDoku_Parser_Unformatted');
+ }
+
+ function testNowiki() {
+ $this->P->addMode('unformatted',new Doku_Parser_Mode_Unformatted());
+ $this->P->parse("Foo <nowiki>testing</nowiki> Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('unformatted',array('testing')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+
+ }
+
+ function testDoublePercent() {
+ $this->P->addMode('unformatted',new Doku_Parser_Mode_Unformatted());
+ $this->P->parse("Foo %%testing%% Bar");
+ $calls = array (
+ array('document_start',array()),
+ array('p_open',array()),
+ array('cdata',array("\n".'Foo ')),
+ array('unformatted',array('testing')),
+ array('cdata',array(' Bar')),
+ array('p_close',array()),
+ array('document_end',array()),
+ );
+ $this->assertEqual(array_map('stripByteIndex',$this->H->calls),$calls);
+ }
+}
+
diff --git a/_test/cases/inc/parser/xhtml_htmlphp.test.php b/_test/cases/inc/parser/xhtml_htmlphp.test.php
new file mode 100644
index 000000000..65d64e579
--- /dev/null
+++ b/_test/cases/inc/parser/xhtml_htmlphp.test.php
@@ -0,0 +1,203 @@
+<?php
+if (!defined('DOKU_BASE')) define('DOKU_BASE','./');
+
+require_once 'parser.inc.php';
+require_once DOKU_INC.'inc/parser/xhtml.php';
+require_once DOKU_INC.'inc/geshi.php';
+
+if (!extension_loaded('runkit')) {
+ SimpleTestOptions::ignore('xhtml_htmlphp_test');
+ trigger_error('Skipping xhtml_htmlphp_test - http://www.php.net/runkit required');
+}
+
+function xhtml_htmlphp_test_io_makefiledir() {
+ return;
+}
+function xhtml_htmlphp_test_io_savefile() {
+ return true;
+}
+
+
+class Doku_Renderer_tester extends Doku_Renderer_xhtml {
+
+/*
+ changes to these tests remove the need to redefine any xhtml methods
+ class left for future use
+ */
+
+}
+
+/*
+ * test case for parser/xhtml.php _headertolink method
+ * definition: function _headertolink($title,$create)
+ */
+
+class xhtml_htmlphp_test extends TestOfDoku_Parser {
+
+ var $purge;
+ var $cachedir;
+
+ function setup() {
+ global $conf;
+
+ // set purge to avoid trying to retrieve from cache
+ $this->purge = isset($_REQUEST['purge']) ? $_REQUEST['purge'] : null;
+ $_REQUEST['purge'] = 1;
+
+ if (!isset($conf['cachedir'])) {
+ $conf['cachedir'] = '';
+ $this->cachedir = false;
+ } else {
+ $this->cachedir = true;
+ }
+
+ if (function_exists('io_makefiledir')) {
+ runkit_function_rename('io_makefiledir', 'io_makefiledir_real');
+ }
+ runkit_function_rename('xhtml_htmlphp_test_io_makefiledir','io_makefiledir');
+
+ if (function_exists('io_savefile')) {
+ runkit_function_rename('io_savefile', 'io_savefile_real');
+ }
+ runkit_function_rename('xhtml_htmlphp_test_io_savefile','io_savefile');
+
+ runkit_method_rename('GeSHi','parse_code','parse_code_real');
+ runkit_method_add('GeSHi','parse_code','', '{ return hsc($this->source); }');
+
+ parent::setup();
+ }
+
+ function teardown() {
+ global $conf;
+
+ // restore purge
+ if (is_null($this->purge)) unset($_REQUEST['purge']);
+ else $_REQUEST['purge'] = $this->purge;
+
+ // restore $conf['cachedir'] if necessary
+ if (!$this->cachedir) unset($conf['cachedir']);
+
+ // restore io_functions
+ runkit_function_rename('io_makefiledir','xhtml_htmlphp_test_io_makefiledir');
+ if (function_exists('io_makefiledir_real')) {
+ runkit_function_rename('io_makefiledir_real', 'io_makefiledir');
+ }
+
+ runkit_function_rename('io_savefile','xhtml_htmlphp_test_io_savefile');
+ if (function_exists('io_savefile_real')) {
+ runkit_function_rename('io_savefile_real', 'io_savefile');
+ }
+
+ // restore GeSHi::parse_code
+ runkit_method_remove('GeSHi','parse_code');
+ runkit_method_rename('GeSHi','parse_code_real','parse_code');
+
+ parent::setup();
+ }
+
+ function _run_parser($modes,$data) {
+
+ foreach ($modes as $mode => $name) {
+ $class = 'Doku_Parser_Mode_'.$name;
+ $this->P->addMode($mode,new $class());
+ }
+
+ $R = new Doku_Renderer_tester();
+ $this->P->parse($data);
+ foreach ( $this->H->calls as $instruction ) {
+ // Execute the callback against the Renderer
+ call_user_func_array(array(&$R, $instruction[0]),$instruction[1]);
+ }
+
+ return str_replace("\n",'',$R->doc);
+ }
+
+ function test_html_off(){
+ $test = array('<html><b>bold</b></html>','<p><code class="code html4strict">&lt;b&gt;bold&lt;/b&gt;</code></p>');
+
+ global $conf;
+ $conf['htmlok'] = 0;
+
+ $result = $this->_run_parser(array('html'=>'html'),$test[0]);
+
+ $this->assertEqual($result,$test[1]);
+ }
+
+ function test_html_on(){
+ $test = array('<html><b>bold</b></html>','<p><b>bold</b></p>');
+
+ global $conf;
+ $conf['htmlok'] = 1;
+
+ $result = $this->_run_parser(array('html'=>'html'),$test[0]);
+
+ $this->assertEqual($result,$test[1]);
+ }
+
+ function test_htmlblock_off(){
+ $test = array('<HTML><b>bold</b></HTML>','<pre class="code html4strict">&lt;b&gt;bold&lt;/b&gt;</pre>');
+
+ global $conf;
+ $conf['htmlok'] = 0;
+
+ $result = $this->_run_parser(array('html'=>'html'),$test[0]);
+
+ $this->assertEqual($result,$test[1]);
+ }
+
+ function test_htmlblock_on(){
+ $test = array('<HTML><b>bold</b></HTML>','<b>bold</b>');
+
+ global $conf;
+ $conf['htmlok'] = 1;
+
+ $result = $this->_run_parser(array('html'=>'html'),$test[0]);
+
+ $this->assertEqual($result,$test[1]);
+ }
+
+ function test_php_off(){
+ $test = array('<php>echo(1+1);</php>','<p><code class="code php">echo(1+1);</code></p>');
+
+ global $conf;
+ $conf['phpok'] = 0;
+
+ $result = $this->_run_parser(array('php'=>'php'),$test[0]);
+
+ $this->assertEqual($result,$test[1]);
+ }
+
+ function test_php_on(){
+ $test = array('<php>echo(1+1);</php>','<p>2</p>');
+
+ global $conf;
+ $conf['phpok'] = 1;
+
+ $result = $this->_run_parser(array('php'=>'php'),$test[0]);
+
+ $this->assertEqual($result,$test[1]);
+ }
+
+ function test_phpblock_off(){
+ $test = array('<PHP>echo(1+1);</PHP>','<pre class="code php">echo(1+1);</pre>');
+
+ global $conf;
+ $conf['phpok'] = 0;
+
+ $result = $this->_run_parser(array('php'=>'php'),$test[0]);
+
+ $this->assertEqual($result,$test[1]);
+ }
+
+ function test_phpblock_on(){
+ $test = array('<PHP>echo(1+1);</PHP>',"2");
+
+ global $conf;
+ $conf['phpok'] = 1;
+
+ $result = $this->_run_parser(array('php'=>'php'),$test[0]);
+
+ $this->assertEqual($result,$test[1]);
+ }
+
+}
diff --git a/_test/cases/inc/parser/xhtml_links.test.php b/_test/cases/inc/parser/xhtml_links.test.php
new file mode 100644
index 000000000..a9a6dfdbc
--- /dev/null
+++ b/_test/cases/inc/parser/xhtml_links.test.php
@@ -0,0 +1,239 @@
+<?php
+if (!defined('DOKU_BASE')) define('DOKU_BASE','./');
+require_once DOKU_INC.'inc/parser/xhtml.php';
+require_once DOKU_INC.'inc/pageutils.php';
+
+class xhtml_links_test extends UnitTestCase {
+
+ function test_emaillink(){
+ global $conf;
+ $conf['mailguard'] = 'visible';
+ $conf['userewrite'] = 0;
+
+ $p = new Doku_Renderer_xhtml();
+ $p->emaillink('foo@example.com','<script>alert(\'"alert"\');</script>');
+
+ $expect = '<a href="mailto:foo%20%5Bat%5D%20example%20%5Bdot%5D%20com" class="mail" title="foo [at] example [dot] com">&lt;script&gt;alert(&#039;&quot;alert&quot;&#039;);&lt;/script&gt;</a>';
+
+ $this->assertEqual($p->doc,$expect);
+ }
+
+ function test_emaillink_with_media(){
+ global $conf;
+ $conf['mailguard'] = 'visible';
+ $conf['userewrite'] = 2;
+
+ $image = array(
+ 'type'=>'internalmedia',
+ 'src'=>'img.gif',
+ 'title'=>'Some Image',
+ 'align'=>NULL,
+ 'width'=>10,
+ 'height'=>20,
+ 'cache'=>'nocache',
+ 'linking'=>'details',
+ );
+
+ $p = new Doku_Renderer_xhtml();
+ $p->emaillink('foo@example.com',$image);
+
+ $expect = '<a href="mailto:foo%20%5Bat%5D%20example%20%5Bdot%5D%20com" class="media" title="foo [at] example [dot] com"><img src="'.DOKU_BASE.'lib/exe/fetch.php/img.gif?w=10&amp;h=20&amp;cache=nocache" class="media" title="Some Image" alt="Some Image" width="10" height="20" /></a>';
+
+ $this->assertEqual($p->doc,$expect);
+ }
+
+ /**
+ * Produced by syntax like [[ ]]
+ */
+ function test_empty_internallink(){
+ $page = 'my:space';
+
+ global $ID;
+ $ID = $page;
+
+ global $conf;
+ $conf['start'] = 'start';
+
+ global $conf;
+ $conf['basedir'] = '/';
+ $conf['useheading'] = 0;
+ $conf['userewrite'] = 0;
+ $conf['useslash'] = 0;
+ $conf['canonical'] = 0;
+
+ $p = new Doku_Renderer_xhtml();
+ $p->internallink('');
+
+
+ if (page_exists($page)) {
+ $class = 'wikilink1';
+ $rel = '';
+ }
+ else {
+ $class = 'wikilink2';
+ $rel = ' rel="nofollow"';
+ }
+
+ $parts = split(':', $page);
+ $caption = $parts[count($parts)-1];
+
+ $expect = '<span class="curid"><a href="/./doku.php?id='.$page.'" class="'.$class.'" title="'.$page.'"'.$rel.'>'.$caption.'</a></span>';
+
+ $this->assertEqual($p->doc, $expect);
+ }
+
+ /**
+ * Produced by syntax like [[ |my caption]]
+ */
+ function test_empty_internallink_with_caption(){
+ $page = 'my:space';
+ $caption = 'my caption';
+
+ global $ID;
+ $ID = $page;
+
+ global $conf;
+ $conf['basedir'] = '/';
+ $conf['useheading'] = 0;
+ $conf['userewrite'] = 0;
+ $conf['useslash'] = 0;
+ $conf['canonical'] = 0;
+
+ $p = new Doku_Renderer_xhtml();
+ $p->internallink('', $caption);
+
+ if (page_exists($page)) {
+ $class = 'wikilink1';
+ $rel = '';
+ }
+ else {
+ $class = 'wikilink2';
+ $rel = ' rel="nofollow"';
+ }
+
+ $expect = '<span class="curid"><a href="/./doku.php?id='.$page.'" class="'.$class.'" title="'.$page.'"'.$rel.'>'.$caption.'</a></span>';
+
+ $this->assertEqual($p->doc, $expect);
+ }
+
+ /**
+ * Produced by syntax like [[?do=index]]
+ */
+ function test_empty_internallink_index(){
+ $page = 'my:space';
+
+ global $ID;
+ $ID = $page;
+
+ global $conf;
+ $conf['start'] = 'start';
+
+ global $conf;
+ $conf['basedir'] = '/';
+ $conf['useheading'] = 0;
+ $conf['userewrite'] = 0;
+ $conf['useslash'] = 0;
+ $conf['canonical'] = 0;
+
+ $p = new Doku_Renderer_xhtml();
+ $p->internallink('?do=index');
+
+ if (page_exists($page)) {
+ $class = 'wikilink1';
+ $rel = '';
+ }
+ else {
+ $class = 'wikilink2';
+ $rel = ' rel="nofollow"';
+ }
+
+ $parts = split(':', $page);
+ $caption = $parts[count($parts)-1];
+
+ $expect = '<span class="curid"><a href="/./doku.php?id='.$page.'&amp;do=index" class="'.$class.'" title="'.$page.'"'.$rel.'>'.$caption.'</a></span>';
+
+ $this->assertEqual($p->doc, $expect);
+ }
+
+ /**
+ * Produced by syntax like [[?do=index|my caption]]
+ */
+ function test_empty_internallink_index_with_caption(){
+ $page = 'my:space';
+ $caption = 'my caption';
+
+ global $ID;
+ $ID = $page;
+
+ global $conf;
+ $conf['basedir'] = '/';
+ $conf['useheading'] = 0;
+ $conf['userewrite'] = 0;
+ $conf['useslash'] = 0;
+ $conf['canonical'] = 0;
+
+ $p = new Doku_Renderer_xhtml();
+ $p->internallink('?do=index', $caption);
+
+ if (page_exists($page)) {
+ $class = 'wikilink1';
+ $rel = '';
+ }
+ else {
+ $class = 'wikilink2';
+ $rel = ' rel="nofollow"';
+ }
+
+ $expect = '<span class="curid"><a href="/./doku.php?id='.$page.'&amp;do=index" class="'.$class.'" title="'.$page.'"'.$rel.'>'.$caption.'</a></span>';
+
+ $this->assertEqual($p->doc, $expect);
+ }
+
+ /**
+ * Produced by syntax like [[#test]]
+ */
+ function test_empty_locallink(){
+ $page = 'my:spacex';
+ global $ID;
+ $ID = $page;
+
+ global $conf;
+ $conf['basedir'] = '/';
+ $conf['useheading'] = 0;
+ $conf['userewrite'] = 0;
+ $conf['useslash'] = 0;
+ $conf['canonical'] = 0;
+
+ $p = new Doku_Renderer_xhtml();
+ $p->locallink('test');
+
+ $expect = '<a href="#test" title="'.$page.' &crarr;" class="wikilink1">test</a>';
+
+ $this->assertEqual($p->doc, $expect);
+ }
+
+ /**
+ * Produced by syntax like [[#test|my caption]]
+ */
+ function test_empty_locallink_with_caption(){
+ $page = 'my:spacex';
+ $caption = 'my caption';
+
+ global $ID;
+ $ID = $page;
+
+ global $conf;
+ $conf['basedir'] = '/';
+ $conf['useheading'] = 0;
+ $conf['userewrite'] = 0;
+ $conf['useslash'] = 0;
+ $conf['canonical'] = 0;
+
+ $p = new Doku_Renderer_xhtml();
+ $p->locallink('test', $caption);
+
+ $expect = '<a href="#test" title="'.$page.' &crarr;" class="wikilink1">'.$caption.'</a>';
+
+ $this->assertEqual($p->doc, $expect);
+ }
+}
diff --git a/_test/cases/inc/parserutils_set_metadata_during_rendering.test.php b/_test/cases/inc/parserutils_set_metadata_during_rendering.test.php
new file mode 100644
index 000000000..8319da298
--- /dev/null
+++ b/_test/cases/inc/parserutils_set_metadata_during_rendering.test.php
@@ -0,0 +1,93 @@
+<?php
+
+require_once DOKU_INC.'inc/init.php';
+
+class parserutils_set_metadata_during_rendering_test extends UnitTestCase {
+ // the id used for this test case
+ private $id;
+ // if the test case is currently running
+ private $active = false;
+ // the original plugin controller
+ private $plugin_controller;
+
+ // the actual test
+ function test_p_set_metadata_during_rendering() {
+ global $EVENT_HANDLER;
+ $this->id = 'test:p_set_metadata_during_rendering';
+ $this->active = true;
+
+ // write the wiki page so it exists and needs to be rendered
+ saveWikiText($this->id, 'Test '.time(), 'Test data setup');
+
+ $EVENT_HANDLER->register_hook('PARSER_METADATA_RENDER', 'BEFORE', $this, 'helper_set_metadata', array('test_before_set' => 'test'));
+ $EVENT_HANDLER->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, 'helper_set_metadata', array('test_after_set' => 'test'));
+ $EVENT_HANDLER->register_hook('PARSER_HANDLER_DONE', 'BEFORE', $this, 'helper_inject_test_instruction');
+
+ // Change the global plugin controller so this test can be a fake syntax plugin
+ global $plugin_controller;
+ $this->plugin_controller = $plugin_controller;
+ $plugin_controller = $this;
+
+ // the actual rendering, all hooks should be executed here
+ $newMeta = p_get_metadata($this->id);
+
+ // restore the plugin controller
+ $plugin_controller = $this->plugin_controller;
+
+ // assert that all three calls to p_set_metadata have been successful
+ $this->assertEqual($newMeta['test_before_set'], 'test');
+ $this->assertEqual($newMeta['test_after_set'], 'test');
+ $this->assertEqual($newMeta['test_during_rendering'], 'test');
+
+ // clean up
+ $this->active = false;
+
+ // make sure the saved metadata is the one that has been rendered
+ $this->assertEqual($newMeta, p_get_metadata($this->id));
+
+ saveWikiText($this->id, '', 'Test data remove');
+ }
+
+ // helper for the action plugin part of the test, tries executing p_set_metadata during rendering
+ function helper_set_metadata($event, $meta) {
+ if ($this->active) {
+ p_set_metadata($this->id, $meta, false, true);
+ $key = array_pop(array_keys($meta));
+ $this->assertTrue(is_string($meta[$key])); // ensure we really have a key
+ // ensure that the metadata property hasn't been set previously
+ $this->assertNotEqual($meta[$key], p_get_metadata($this->id, $key));
+ }
+ }
+
+ // helper for injecting an instruction for this test case
+ function helper_inject_test_instruction($event) {
+ if ($this->active)
+ $event->data->calls[] = array('plugin', array('parserutils_test', array()));
+ }
+
+ // fake syntax plugin rendering method that tries calling p_set_metadata during the actual rendering process
+ function render($format, &$renderer, $data) {
+ if ($this->active) {
+ $key = 'test_during_rendering';
+ p_set_metadata($this->id, array($key => 'test'), false, true);
+ // ensure that the metadata property hasn't been set previously
+ $this->assertNotEqual($key, p_get_metadata($this->id, $key));
+ }
+ }
+
+ // wrapper function for the fake plugin controller
+ function getList($type='',$all=false){
+ return $this->plugin_controller->getList();
+ }
+
+ // wrapper function for the fake plugin controller, return $this for the fake syntax of this test
+ function &load($type,$name,$new=false,$disabled=false){
+ if ($name == 'parserutils_test') {
+ return $this;
+ } else {
+ return $this->plugin_controller->load($type, $name, $new, $disabled);
+ }
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/_test/cases/inc/safefn.test.php b/_test/cases/inc/safefn.test.php
new file mode 100644
index 000000000..1227e5578
--- /dev/null
+++ b/_test/cases/inc/safefn.test.php
@@ -0,0 +1,48 @@
+<?php
+// use no mbstring help here
+if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
+require_once DOKU_INC.'inc/utf8.php';
+require_once DOKU_INC.'inc/SafeFN.class.php';
+
+class safeFN_test extends UnitTestCase {
+
+
+ function test1(){
+ // we test multiple cases here - format: string, repl, additional, test
+ $tests = array();
+ $tests[] = array('äa.txt', '%5g]a.txt');
+ $tests[] = array('ä.', '%5g].');
+ $tests[] = array('asciistring','asciistring');
+ $tests[] = array('ascii-_/.string','ascii-_/.string');
+ $tests[] = array('AName','%x%1a]ame');
+ $tests[] = array('A Name','%x%0%1a]ame');
+ $tests[] = array('Another...Name','%x]nother...%1a]ame');
+ $tests[] = array('Aß∂ƒName','%x%5b%6oy%aa%1a]ame');
+ $tests[] = array('A%ß-∂_.ƒName','%x%%5b]-%6oy]_.%aa%1a]ame');
+ $tests[] = array('A%%ß-∂_.ƒName','%x%%%5b]-%6oy]_.%aa%1a]ame');
+ $tests[] = array('데이터도 함께 복원됩니다. 강력한','%zf4%13dg%15ao%zhg%0%164o%yig%0%11at%138w%zk9%zag%zb8].%0%xyt%10cl%164c]');
+ $tests[] = array('совместимая','%td%ta%sy%t8%t1%td%te%t4%t8%sw%tr]');
+ $tests[] = array('нехватка_файлового_пространства_на_сервере_p0-squid.some.domain.1270211897.txt.gz','%t9%t1%th%sy%sw%te%t6%sw]_%tg%sw%t5%t7%ta%sy%ta%sz%ta]_%tb%tc%ta%td%te%tc%sw%t9%td%te%sy%sw]_%t9%sw]_%td%t1%tc%sy%t1%tc%t1]_p0-squid.some.domain.1270211897.txt.gz');
+
+ $tests[] = array('name[1]','name[1]');
+ $tests[] = array('Name[1]','%1a]ame[1]');
+ $tests[] = array('Name[A]','%1a]ame[%x]]');
+
+ foreach($tests as $test){
+ list($utf8,$safe) = $test;
+ $this->assertEqual(SafeFN::encode($utf8),$safe);
+ $this->assertEqual(SafeFN::decode($safe),$utf8);
+ }
+ }
+
+ function test2(){
+ $tests[] = array('совместимая','%td%ta%sy%t8%t1%td%te%t4%t8%sw%tr');
+
+ foreach($tests as $test){
+ list($utf8,$safe) = $test;
+ $this->assertEqual(SafeFN::decode($safe),$utf8);
+ }
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/search/data/ns1/ns3/page3.txt b/_test/cases/inc/search/data/ns1/ns3/page3.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/_test/cases/inc/search/data/ns1/ns3/page3.txt
diff --git a/_test/cases/inc/search/data/ns1/page1.txt b/_test/cases/inc/search/data/ns1/page1.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/_test/cases/inc/search/data/ns1/page1.txt
diff --git a/_test/cases/inc/search/data/ns1/page2.txt b/_test/cases/inc/search/data/ns1/page2.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/_test/cases/inc/search/data/ns1/page2.txt
diff --git a/_test/cases/inc/search/data/ns2/nopage.ext b/_test/cases/inc/search/data/ns2/nopage.ext
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/_test/cases/inc/search/data/ns2/nopage.ext
diff --git a/_test/cases/inc/search/data/ns2/page1.txt b/_test/cases/inc/search/data/ns2/page1.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/_test/cases/inc/search/data/ns2/page1.txt
diff --git a/_test/cases/inc/search/search.test.php b/_test/cases/inc/search/search.test.php
new file mode 100644
index 000000000..a6f15e9b6
--- /dev/null
+++ b/_test/cases/inc/search/search.test.php
@@ -0,0 +1,102 @@
+<?php
+require_once DOKU_INC.'inc/search.php';
+
+class search_test extends UnitTestCase {
+ function strip_index_data($entry) {
+ $n_entry = array();
+ foreach(array('id', 'type', 'level', 'open') as $k) {
+ $n_entry[$k] = $entry[$k];
+ }
+ return $n_entry;
+ }
+
+ function test_search_index(){
+ $data = array();
+ search($data, dirname(__FILE__) . '/data', 'search_index',
+ array('ns' => 'ns2'));
+ $this->assertEqual(array_map(array($this, 'strip_index_data'), $data),
+ array(
+ array(
+ 'id' => 'ns1',
+ 'type' => 'd',
+ 'level' => 1,
+ 'open' => false
+ ), array(
+ 'id' => 'ns2',
+ 'type' => 'd',
+ 'level' => 1,
+ 'open' => true
+ ), array(
+ 'id' => 'ns2:page1',
+ 'type' => 'f',
+ 'level' => 2,
+ 'open' => true,
+ ), ));
+ $data = array();
+ search($data, dirname(__FILE__) . '/data', 'search_index',
+ array('ns' => 'ns1/ns3'));
+ $this->assertEqual(array_map(array($this, 'strip_index_data'), $data),
+ array(
+ array(
+ 'id' => 'ns1',
+ 'type' => 'd',
+ 'level' => 1,
+ 'open' => true,
+ ),
+ array(
+ 'id' => 'ns1:ns3',
+ 'type' => 'd',
+ 'level' => 2,
+ 'open' => true,
+ ),
+ array(
+ 'id' => 'ns1:ns3:page3',
+ 'type' => 'f',
+ 'level' => 3,
+ 'open' => true,
+ ),
+ array(
+ 'id' => 'ns1:page1',
+ 'type' => 'f',
+ 'level' => 2,
+ 'open' => true,
+ ),
+ array(
+ 'id' => 'ns1:page2',
+ 'type' => 'f',
+ 'level' => 2,
+ 'open' => true,
+ ),
+ array(
+ 'id' => 'ns2',
+ 'type' => 'd',
+ 'level' => 1,
+ 'open' => false,
+ ), ));
+ $data = array();
+ search($data, dirname(__FILE__) . '/data', 'search_index',
+ array('ns' => 'ns1/ns3', 'nofiles' => true));
+ $this->assertEqual(array_map(array($this, 'strip_index_data'), $data),
+ array(
+ array(
+ 'id' => 'ns1',
+ 'type' => 'd',
+ 'level' => 1,
+ 'open' => true,
+ ),
+ array(
+ 'id' => 'ns1:ns3',
+ 'type' => 'd',
+ 'level' => 2,
+ 'open' => true,
+ ),
+ array(
+ 'id' => 'ns2',
+ 'type' => 'd',
+ 'level' => 1,
+ 'open' => false,
+ ), ));
+
+ }
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/utf8_correctidx.test.php b/_test/cases/inc/utf8_correctidx.test.php
new file mode 100644
index 000000000..20f6ba3a3
--- /dev/null
+++ b/_test/cases/inc/utf8_correctidx.test.php
@@ -0,0 +1,78 @@
+<?php
+// use no mbstring help here
+if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
+require_once DOKU_INC.'inc/utf8.php';
+
+class utf8_correctidx_test extends UnitTestCase {
+
+
+ function test_singlebyte(){
+ // we test multiple cases here - format: in, offset, length, out
+ $tests = array();
+
+ // single byte, should return current index
+ $tests[] = array('aaживπά우리をあöä',0,false,0);
+ $tests[] = array('aaживπά우리をあöä',1,false,1);
+ $tests[] = array('aaживπά우리をあöä',1,true,1);
+
+ foreach($tests as $test){
+ $this->assertEqual(utf8_correctIdx($test[0],$test[1],$test[2]),$test[3]);
+ }
+ }
+
+ function test_twobyte(){
+ // we test multiple cases here - format: in, offset, length, out
+ $tests = array();
+
+ // two byte, should move to boundary, expect even number
+ $tests[] = array('aaживπά우리をあöä',2,false,2);
+ $tests[] = array('aaживπά우리をあöä',3,false,2);
+ $tests[] = array('aaживπά우리をあöä',4,false,4);
+
+ $tests[] = array('aaживπά우리をあöä',2,true,2);
+ $tests[] = array('aaживπά우리をあöä',3,true,4);
+ $tests[] = array('aaживπά우리をあöä',4,true,4);
+
+ foreach($tests as $test){
+ $this->assertEqual(utf8_correctIdx($test[0],$test[1],$test[2]),$test[3]);
+ }
+ }
+
+ function test_threebyte(){
+ // we test multiple cases here - format: in, offset, length, out
+ $tests = array();
+
+ // three byte, should move to boundary 10 or 13
+ $tests[] = array('aaживπά우리をあöä',10,false,10);
+ $tests[] = array('aaживπά우리をあöä',11,false,10);
+ $tests[] = array('aaживπά우리をあöä',12,false,10);
+ $tests[] = array('aaживπά우리をあöä',13,false,13);
+
+ $tests[] = array('aaживπά우리をあöä',10,true,10);
+ $tests[] = array('aaживπά우리をあöä',11,true,13);
+ $tests[] = array('aaживπά우리をあöä',12,true,13);
+ $tests[] = array('aaживπά우리をあöä',13,true,13);
+
+ foreach($tests as $test){
+ $this->assertEqual(utf8_correctIdx($test[0],$test[1],$test[2]),$test[3]);
+ }
+ }
+
+ function test_bounds(){
+ // we test multiple cases here - format: in, offset, length, out
+ $tests = array();
+
+ // bounds checking
+ $tests[] = array('aaживπά우리をあöä',-2,false,0);
+ $tests[] = array('aaживπά우리をあöä',128,false,29);
+
+ $tests[] = array('aaживπά우리をあöä',-2,true,0);
+ $tests[] = array('aaживπά우리をあöä',128,true,29);
+
+ foreach($tests as $test){
+ $this->assertEqual(utf8_correctIdx($test[0],$test[1],$test[2]),$test[3]);
+ }
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/utf8_html.test.php b/_test/cases/inc/utf8_html.test.php
new file mode 100644
index 000000000..3e6d35bc7
--- /dev/null
+++ b/_test/cases/inc/utf8_html.test.php
@@ -0,0 +1,72 @@
+<?php
+
+require_once DOKU_INC.'inc/utf8.php';
+
+// use no mbstring help here
+if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
+
+class utf8_html_test extends UnitTestCase {
+
+ function test_from_1byte(){
+ $in = 'a';
+ $out = 'a';
+ $this->assertEqual(utf8_tohtml($in),$out);
+ }
+
+ function test_from_2byte(){
+ $in = "\xc3\xbc";
+ $out = '&#252;';
+ $this->assertEqual(utf8_tohtml($in),$out);
+ }
+
+ function test_from_3byte(){
+ $in = "\xe2\x99\x8a";
+ $out = '&#x264a;';
+ $this->assertEqual(utf8_tohtml($in),$out);
+ }
+
+ function test_from_4byte(){
+ $in = "\xf4\x80\x80\x81";
+ $out = '&#x100001;';
+ $this->assertEqual(utf8_tohtml($in),$out);
+ }
+
+ function test_to_1byte(){
+ $out = 'a';
+ $in = 'a';
+ $this->assertEqual(utf8_unhtml($in),$out);
+ }
+
+ function test_to_2byte(){
+ $out = "\xc3\xbc";
+ $in = '&#252;';
+ $this->assertEqual(utf8_unhtml($in),$out);
+ }
+
+ function test_to_3byte(){
+ $out = "\xe2\x99\x8a";
+ $in = '&#x264a;';
+ $this->assertEqual(utf8_unhtml($in),$out);
+ }
+
+ function test_to_4byte(){
+ $out = "\xf4\x80\x80\x81";
+ $in = '&#x100001;';
+ $this->assertEqual(utf8_unhtml($in),$out);
+ }
+
+ function test_without_entities(){
+ $out = '&amp;#38;&amp;#38;';
+ $in = '&amp;#38;&#38;amp;#38;';
+ $this->assertEqual(utf8_unhtml($in),$out);
+ }
+
+ function test_with_entities(){
+ $out = '&#38;&amp;#38;';
+ $in = '&amp;#38;&#38;amp;#38;';
+ $this->assertEqual(utf8_unhtml($in,HTML_ENTITIES),$out);
+ }
+
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/utf8_kanaromaji.txt b/_test/cases/inc/utf8_kanaromaji.txt
new file mode 100644
index 000000000..d6bf51e95
--- /dev/null
+++ b/_test/cases/inc/utf8_kanaromaji.txt
@@ -0,0 +1,22893 @@
+いつか;itsuka
+いつか;itsuka
+いつつ;itsutsu
+いつでも;itsudemo
+いつのまにか;itsunomanika
+いつまでも;itsumademo
+いつも;itsumo
+いてん;iten
+いと;ito
+いとこ;itoko
+いとこ;itoko
+いとま;itoma
+いど;ido
+いど;ido
+いどう;idou
+いない;inai
+いなか;inaka
+いにしえ;inishie
+いぬ;inu
+いね;ine
+いねむり;inemuri
+いのち;inochi
+いのる;inoru
+いはん;ihan
+いばる;ibaru
+いふく;ifuku
+いま;ima
+いま;ima
+いまに;imani
+いまにも;imanimo
+いみ;imi
+いもうと;imouto
+いや;iya
+いやがる;iyagaru
+いよいよ;iyoiyo
+いらい;irai
+いらい;irai
+いらいら;iraira
+いらっしゃる;irassharu
+いりぐち;iriguchi
+いりょう;iryou
+いる;iru
+いる;iru
+いる;iru
+いる;iru
+いれもの;iremono
+いれる;ireru
+いろ;iro
+いろいろ;iroiro
+いわ;iwa
+いわい;iwai
+いわう;iwau
+いわば;iwaba
+いわゆる;iwayuru
+いん;in
+いん;in
+いんさつ;insatsu
+いんしょう;inshou
+いんたい;intai
+いんよう;in_you
+いんりょく;inryoku
+うえ;ue
+うえき;ueki
+うえした;ueshita
+うえる;ueru
+うえる;ueru
+うお;uo
+うかがう;ukagau
+うかぶ;ukabu
+うかべる;ukaberu
+うがい;ugai
+うく;uku
+うけたまわる;uketamawaru
+うけつけ;uketsuke
+うけとり;uketori
+うけとる;uketoru
+うけもつ;ukemotsu
+うける;ukeru
+うごかす;ugokasu
+うごく;ugoku
+うさぎ;usagi
+うし;ushi
+うしなう;ushinau
+うじ;uji
+うすい;usui
+うすぐらい;usugurai
+うすめる;usumeru
+うずめる;uzumeru
+うそ;uso
+うた;uta
+うたう;utau
+うたがう;utagau
+うち;uchi
+うちあわせ;uchiawase
+うちあわせる;uchiawaseru
+うちけす;uchikesu
+うちゅう;uchuu
+うっかり;ukkari
+うったえる;uttaeru
+うつ;utsu
+うつ;utsu
+うつ;utsu
+うつくしい;utsukushii
+うつす;utsusu
+うつす;utsusu
+うつす;utsusu
+うつる;utsuru
+うつる;utsuru
+うつる;utsuru
+うつわ;utsuwa
+うで;ude
+うどん;udon
+うなずく;unazuku
+うなる;unaru
+うばう;ubau
+うま;uma
+うまい;umai
+うまれ;umare
+うまれる;umareru
+うみ;umi
+うむ;umu
+うめ;ume
+うやまう;uyamau
+うら;ura
+うら;ura
+うらがえす;uragaesu
+うらぎる;uragiru
+うらぐち;uraguchi
+うらなう;uranau
+うらみ;urami
+うらむ;uramu
+うらやましい;urayamashii
+うらやむ;urayamu
+うりあげ;uriage
+うりきれ;urikire
+うりきれる;urikireru
+うりば;uriba
+うる;uru
+うる;uru
+うるさい;urusai
+うれしい;ureshii
+うれゆき;ureyuki
+うれる;ureru
+うろうろ;urouro
+うわぎ;uwagi
+うわさ;uwasa
+うわて;uwate
+うわる;uwaru
+うん;un
+うんが;unga
+うんてん;unten
+うんどう;undou
+え;e
+え;e
+え;e
+え;e
+えいえん;eien
+えいが;eiga
+えいきゅう;eikyuu
+えいきょう;eikyou
+えいぎょう;eigyou
+えいご;eigo
+えいせい;eisei
+えいぶん;eibun
+えいよう;eiyou
+えいわ;eiwa
+ええ;ee
+ええと;eeto
+えがお;egao
+えがく;egaku
+えき;eki
+えき;eki
+えきたい;ekitai
+えさ;esa
+えだ;eda
+えのぐ;enogu
+えらい;erai
+えらぶ;erabu
+えん;en
+えん;en
+えん;en
+えん;en
+えん;en
+えんかい;enkai
+えんき;enki
+えんぎ;engi
+えんげい;engei
+えんげき;engeki
+えんしゅう;enshuu
+えんしゅう;enshuu
+えんじょ;enjo
+えんぜつ;enzetsu
+えんそう;ensou
+えんそく;ensoku
+えんちょう;enchou
+えんとつ;entotsu
+えんりょ;enryo
+お;o
+おい;oi
+おいかける;oikakeru
+おいこす;oikosu
+おいしい;oishii
+おいつく;oitsuku
+おいでになる;oideninaru
+おう;ou
+おう;ou
+おうえん;ouen
+おうさま;ousama
+おうしょく;oushoku
+おうじ;ouji
+おうじょ;oujo
+おうじる;oujiru
+おうずる;ouzuru
+おうせつ;ousetsu
+おうたい;outai
+おうだん;oudan
+おうふく;oufuku
+おうべい;oubei
+おうよう;ouyou
+おえる;oeru
+おおい;ooi
+おおいに;ooini
+おおう;oou
+おおきい;ookii
+おおごと;oogoto
+おおざっぱ;oozappa
+おおどおり;oodoori
+おおや;ooya
+おおよそ;ooyoso
+おか;oka
+おかあさん;okaasan
+おかげ;okage
+おかげさまで;okagesamade
+おかしい;okashii
+おかず;okazu
+おかまいなく;okamainaku
+おかわり;okawari
+おがむ;ogamu
+おき;oki
+おきる;okiru
+おぎなう;oginau
+おく;oku
+おく;oku
+おく;oku
+おくがい;okugai
+おくさん;okusan
+おくじょう;okujou
+おくりがな;okurigana
+おくりもの;okurimono
+おくる;okuru
+おくる;okuru
+おくれる;okureru
+おこさん;okosan
+おこす;okosu
+おこたる;okotaru
+おこなう;okonau
+おこる;okoru
+おさ;osa
+おさえる;osaeru
+おさきに;osakini
+おさない;osanai
+おさめる;osameru
+おさめる;osameru
+おさめる;osameru
+おしい;oshii
+おしいれ;oshiire
+おしえる;oshieru
+おしゃべり;oshaberi
+おしゃれ;oshare
+おじ;oji
+おじいさん;ojiisan
+おじぎ;ojigi
+おじさん;ojisan
+おじゃまします;ojamashimasu
+おじょうさん;ojousan
+おす;osu
+おせん;osen
+おそい;osoi
+おそらく;osoraku
+おそれる;osoreru
+おそろしい;osoroshii
+おそわる;osowaru
+おだいじに;odaijini
+おだやか;odayaka
+おちつく;ochitsuku
+おちる;ochiru
+おっしゃる;ossharu
+おっと;otto
+おてあらい;otearai
+おてつだいさん;otetsudaisan
+おと;oto
+おとうと;otouto
+おとうさん;otousan
+おとこ;otoko
+おとこのひと;otokonohito
+おとしもの;otoshimono
+おとす;otosu
+おととい;ototoi
+おととし;ototoshi
+おとな;otona
+おとなしい;otonashii
+おとめ;otome
+おとる;otoru
+おどかす;odokasu
+おどり;odori
+おどる;odoru
+おどろかす;odorokasu
+おどろく;odoroku
+おなか;onaka
+おなご;onago
+おなじ;onaji
+おに;oni
+おにいさん;oniisan
+おねえさん;oneesan
+おねがいします;onegaishimasu
+おのおの;onoono
+おのおの;onoono
+おはよう;ohayou
+おば;oba
+おばあさん;obaasan
+おばさん;obasan
+おひる;ohiru
+おび;obi
+おぼえる;oboeru
+おぼれる;oboreru
+おまいり;omairi
+おまちどおさま;omachidoosama
+おまわりさん;omawarisan
+おめでとう;omedetou
+おも;omo
+おもい;omoi
+おもいがけない;omoigakenai
+おもいきり;omoikiri
+おもいこむ;omoikomu
+おもいだす;omoidasu
+おもいつく;omoitsuku
+おもいで;omoide
+おもう;omou
+おもしろい;omoshiroi
+おもたい;omotai
+おもちゃ;omocha
+おもて;omote
+おもなる;omonaru
+おもに;omoni
+おもやく;omoyaku
+おもわず;omowazu
+おや;oya
+おや;oya
+おやすみ;oyasumi
+おやつ;oyatsu
+おやゆび;oyayubi
+およぎ;oyogi
+およぐ;oyogu
+およそ;oyoso
+およぼす;oyobosu
+おりる;oriru
+おりる;oriru
+おる;oru
+おれる;oreru
+おろす;orosu
+おろす;orosu
+おわり;owari
+おわる;owaru
+おん;on
+おんがく;ongaku
+おんけい;onkei
+おんしつ;onshitsu
+おんせん;onsen
+おんたい;ontai
+おんだん;ondan
+おんちゅう;onchuu
+おんど;ondo
+おんな;onna
+おんなのこ;onnanoko
+おんなのひと;onnanohito
+か;ka
+か;ka
+か;ka
+か;ka
+か;ka
+か;ka
+かい;kai
+かい;kai
+かい;kai
+かいいん;kaiin
+かいかい;kaikai
+かいかん;kaikan
+かいが;kaiga
+かいがい;kaigai
+かいがん;kaigan
+かいぎ;kaigi
+かいけい;kaikei
+かいけつ;kaiketsu
+かいごう;kaigou
+かいさつ;kaisatsu
+かいさん;kaisan
+かいし;kaishi
+かいしゃ;kaisha
+かいしゃく;kaishaku
+かいじょう;kaijou
+かいすいよく;kaisuiyoku
+かいすう;kaisuu
+かいすうけん;kaisuuken
+かいせい;kaisei
+かいせい;kaisei
+かいせつ;kaisetsu
+かいぜん;kaizen
+かいぞう;kaizou
+かいだん;kaidan
+かいつう;kaitsuu
+かいてき;kaiteki
+かいてん;kaiten
+かいとう;kaitou
+かいとう;kaitou
+かいふく;kaifuku
+かいほう;kaihou
+かいほう;kaihou
+かいもの;kaimono
+かいよう;kaiyou
+かいわ;kaiwa
+かう;kau
+かう;kau
+かえす;kaesu
+かえす;kaesu
+かえって;kaette
+かえり;kaeri
+かえる;kaeru
+かえる;kaeru
+かえる;kaeru
+かえる;kaeru
+かえる;kaeru
+かえる;kaeru
+かお;kao
+かおく;kaoku
+かおり;kaori
+かかえる;kakaeru
+かかく;kakaku
+かかり;kakari
+かかる;kakaru
+かかわる;kakawaru
+かがく;kagaku
+かがく;kagaku
+かがみ;kagami
+かがやく;kagayaku
+かきとめ;kakitome
+かきとり;kakitori
+かきね;kakine
+かぎ;kagi
+かぎり;kagiri
+かぎる;kagiru
+かく;kaku
+かく;kaku
+かく;kaku
+かく;kaku
+かくう;kakuu
+かくご;kakugo
+かくじ;kakuji
+かくじつ;kakujitsu
+かくじゅう;kakujuu
+かくす;kakusu
+かくだい;kakudai
+かくち;kakuchi
+かくちょう;kakuchou
+かくど;kakudo
+かくにん;kakunin
+かくべつ;kakubetsu
+かくりつ;kakuritsu
+しびれる;shibireru
+しへい;shihei
+しほん;shihon
+しぼう;shibou
+しぼむ;shibomu
+しぼる;shiboru
+しま;shima
+しま;shima
+しまい;shimai
+しまう;shimau
+しまった;shimatta
+しまる;shimaru
+しみじみ;shimijimi
+しみん;shimin
+しめい;shimei
+しめきり;shimekiri
+しめきる;shimekiru
+しめす;shimesu
+しめた;shimeta
+しめる;shimeru
+しめる;shimeru
+しめる;shimeru
+しめる;shimeru
+しも;shimo
+しもべ;shimobe
+しゃかい;shakai
+しゃかいかがく;shakaikagaku
+しゃがむ;shagamu
+しゃこ;shako
+しゃしょう;shashou
+しゃしん;shashin
+しゃせい;shasei
+しゃせつ;shasetsu
+しゃっきん;shakkin
+しゃっくり;shakkuri
+しゃぶる;shaburu
+じょうはつ;jouhatsu
+じょうひん;jouhin
+じょうふ;joufu
+じょうほう;jouhou
+じょおう;joou
+じょきょうじゅ;jokyouju
+じょしゅ;joshu
+じょじょに;jojoni
+じょせい;josei
+じょゆう;joyuu
+じん;jin
+じんこう;jinkou
+じんこう;jinkou
+じんしゅ;jinshu
+じんじ;jinji
+じんじゃ;jinja
+じんせい;jinsei
+じんぞう;jinzou
+じんぶつ;jinbutsu
+じんぶんかがく;jinbunkagaku
+じんめい;jinmei
+じんもく;jinmoku
+じんるい;jinrui
+す;su
+す;su
+すいえい;suiei
+すいさん;suisan
+すいじ;suiji
+すいじゅん;suijun
+すいじょうき;suijouki
+すいせん;suisen
+すいそ;suiso
+すいちょく;suichoku
+すいてい;suitei
+すいてき;suiteki
+すいとう;suitou
+すいどう;suidou
+ちゅうがく;chuugaku
+ちゅうげん;chuugen
+ちゅうこ;chuuko
+ちゅうし;chuushi
+ちゅうし;chuushi
+ちゅうしゃ;chuusha
+ちゅうしゃ;chuusha
+ちゅうしょう;chuushou
+ちゅうしょく;chuushoku
+ちゅうしん;chuushin
+ちゅうじゅん;chuujun
+ちゅうせい;chuusei
+ちゅうせい;chuusei
+ちゅうと;chuuto
+ちゅうねん;chuunen
+ちゅうもく;chuumoku
+ちゅうもん;chuumon
+ちょう;chou
+ちょうか;chouka
+ちょうき;chouki
+ちょうこく;choukoku
+ちょうさ;chousa
+ちょうし;choushi
+ちょうしょ;chousho
+ちょうじょ;choujo
+ちょうじょう;choujou
+ちょうせい;chousei
+ちょうせつ;chousetsu
+ちょうたん;choutan
+ちょうだい;choudai
+ちょうてん;chouten
+ちょうど;choudo
+ちょうなん;chounan
+ちょうほうけい;chouhoukei
+ちょうみりょう;choumiryou
+ちょうめ;choume
+にんき;ninki
+にんぎょう;ningyou
+にんげん;ningen
+ぬう;nuu
+ぬく;nuku
+ぬぐ;nugu
+ぬける;nukeru
+ぬすむ;nusumu
+ぬの;nuno
+ぬらす;nurasu
+ぬる;nuru
+ぬるい;nurui
+ぬれる;nureru
+ね;ne
+ね;ne
+ねがい;negai
+ねがう;negau
+ねこ;neko
+ねじ;neji
+ねじる;nejiru
+ねず;nezu
+ねだん;nedan
+ねっしん;nesshin
+ねっする;nessuru
+ねったい;nettai
+ねっちゅう;necchuu
+ねつ;netsu
+ねぼう;nebou
+ねまき;nemaki
+ねまき;nemaki
+ねむい;nemui
+ねむる;nemuru
+ねらい;nerai
+ねらう;nerau
+ねる;neru
+ねんかん;nenkan
+ねんじゅう;nenjuu
+ねんせい;nensei
+ねんだい;nendai
+ねんど;nendo
+ほうそく;housoku
+ほうたい;houtai
+ほうちょう;houchou
+ほうていしき;houteishiki
+ほうふ;houfu
+ほうほう;houhou
+ほうめん;houmen
+ほうもん;houmon
+ほうりつ;houritsu
+ほうる;houru
+ほえる;hoeru
+ほお;hoo
+ほか;hoka
+ほかく;hokaku
+ほがらか;hogaraka
+ほけん;hoken
+ほこり;hokori
+ほこり;hokori
+ほこる;hokoru
+ほころびる;hokorobiru
+ほし;hoshi
+ほしい;hoshii
+ほしょう;hoshou
+ほす;hosu
+ほそい;hosoi
+ほそう;hosou
+ほぞん;hozon
+ほっきょく;hokkyoku
+ほとんど;hotondo
+ほど;hodo
+ほどう;hodou
+ほどく;hodoku
+ほのお;honoo
+ほほえむ;hohoemu
+ほぼ;hobo
+ほめる;homeru
+ほり;hori
+ほる;horu
+ほる;horu
+ほん;hon
+かならずしも;kanarazushimo
+かならずしもない;kanarazushimonai
+わけ;wake
+くげ;kuge
+ぶけ;buke
+へいみん;heimin
+いなか;inaka
+た;ta
+たとえば;tatoeba
+やま;yama
+わたなべ;watanabe
+かわ;kawa
+わたる;wataru
+いみ;imi
+つづき;tsuduki
+あきた;akita
+あきたけん;akitaken
+かいぬし;kainushi
+つかえる;tsukaeru
+そのうちに;sonouchini
+なくなる;nakunaru
+まいにち;mainichi
+あいだ;aida
+ねんかん;nenkan
+ある;aru
+しぬ;shinu
+たてる;tateru
+ひとびと;hitobito
+ゆうめい;yuumei
+にほんじゅう;nihonjuu
+はい;hai
+しょるい;shorui
+せつめい;setsumei
+こくせき;kokuseki
+うまれる;umareru
+ゆみ;yumi
+オーストラリア;oosutoraria
+スペイン;supein
+じゅうしょ;juusho
+しょくぎょう;shokugyou
+きょかしょう;kyokashou
+たいざい;taizai
+ため;tame
+にゅうがくする;nyuugakusuru
+クラブ;kurabu
+テニス;tenisu
+させる;saseru
+てがみ;tegami
+りょうしん;ryoushin
+どうぶつえん;doubutsuen
+もくようび;mokuyoubi
+おおよろこび;ooyorokobi
+はじめて;hajimete
+わたしたち;watashitachi
+いじょう;ijou
+ならぶ;narabu
+きせつ;kisetsu
+こたえる;kotaeru
+きりん;kirin
+くび;kubi
+しわ;shiwa
+ぞう;zou
+だらけ;darake
+とう;tou
+アフリカ;afurika
+インド;indo
+みみ;mimi
+あいきょう;aikyou
+くま;kuma
+ピーナッツ;piinattsu
+むしゃむしゃ;mushamusha
+えだ;eda
+さる;saru
+とびうつる;tobiutsuru
+ねむい;nemui
+め;me
+ゆっくり;yukkuri
+らくだ;rakuda
+いもうと;imouto
+おどろく;odoroku
+おり;ori
+こわい;kowai
+ちゃん;chan
+なく;naku
+ほえる;hoeru
+ライオン;raion
+かくれる;kakureru
+かぐ;kagu
+かぐ;kagu
+かけざん;kakezan
+かけつ;kaketsu
+かける;kakeru
+かける;kakeru
+かげ;kage
+かげつ;kagetsu
+かげん;kagen
+かこ;kako
+かこう;kakou
+かこう;kakou
+かこむ;kakomu
+かご;kago
+かさ;kasa
+かさい;kasai
+かさねる;kasaneru
+かざり;kazari
+かざる;kazaru
+かざん;kazan
+かし;kashi
+かし;kashi
+かしこい;kashikoi
+かしこまりました;kashikomarimashita
+かしだし;kashidashi
+かしつ;kashitsu
+かしま;kashima
+かしや;kashiya
+かしゅ;kashu
+かしょ;kasho
+かしょう;kashou
+かじ;kaji
+かじ;kaji
+かじつ;kajitsu
+かじょう;kajou
+かじる;kajiru
+かす;kasu
+かする;kasuru
+かず;kazu
+かせぐ;kasegu
+かせん;kasen
+かぜ;kaze
+かぜ;kaze
+かぜい;kazei
+かそく;kasoku
+かそくど;kasokudo
+かぞえる;kazoeru
+かぞく;kazoku
+かた;kata
+かた;kata
+かた;kata
+かたい;katai
+かたい;katai
+かたい;katai
+かたい;katai
+かたかな;katakana
+かたがた;katagata
+かたき;kataki
+かたち;katachi
+かたづく;kataduku
+かたづける;katadukeru
+かたな;katana
+かたぶく;katabuku
+かたまり;katamari
+かたまる;katamaru
+かたみち;katamichi
+かたよる;katayoru
+かたよる;katayoru
+かたる;kataru
+かち;kachi
+かち;kachi
+かっき;kakki
+かっこ;kakko
+かっこう;kakkou
+かってに;katteni
+かつ;katsu
+かつぐ;katsugu
+かつじ;katsuji
+かつどう;katsudou
+かつやく;katsuyaku
+かつよう;katsuyou
+かつりょく;katsuryoku
+かづけ;kaduke
+かてい;katei
+かてい;katei
+かてい;katei
+かてい;katei
+かど;kado
+かな;kana
+かない;kanai
+かなしい;kanashii
+かなしむ;kanashimu
+かなづかい;kanadukai
+かなづち;kanaduchi
+かならずしも;kanarazushimo
+かなり;kanari
+かね;kane
+かね;kane
+かねぐら;kanegura
+かねつ;kanetsu
+かねもち;kanemochi
+かねる;kaneru
+かのう;kanou
+かのじょ;kanojo
+かはんすう;kahansuu
+かばん;kaban
+かひん;kahin
+かび;kabi
+かびん;kabin
+かぶ;kabu
+かぶせる;kabuseru
+かぶる;kaburu
+かべ;kabe
+かま;kama
+かまいません;kamaimasen
+かみ;kami
+かみ;kami
+かみ;kami
+かみくず;kamikuzu
+かみさま;kamisama
+かみそり;kamisori
+かみのけ;kaminoke
+かむ;kamu
+かめ;kame
+かもく;kamoku
+かもしれない;kamoshirenai
+かもつ;kamotsu
+かゆ;kayu
+かゆい;kayui
+かよう;kayou
+かよう;kayou
+かよう;kayou
+から;kara
+からい;karai
+からかう;karakau
+からだ;karada
+からだ;karada
+からっぽ;karappo
+かりる;kariru
+かる;karu
+かるい;karui
+かるた;karuta
+かれ;kare
+かれら;karera
+かれる;kareru
+かわ;kawa
+かわ;kawa
+かわ;kawa
+かわいい;kawaii
+かわいがる;kawaigaru
+かわいそう;kawaisou
+かわいらしい;kawairashii
+かわかす;kawakasu
+かわく;kawaku
+かわく;kawaku
+かわせ;kawase
+かわら;kawara
+かわり;kawari
+かわる;kawaru
+かわる;kawaru
+かん;kan
+かん;kan
+かん;kan
+かん;kan
+かん;kan
+かん;kan
+かんかく;kankaku
+かんかく;kankaku
+かんがえ;kangae
+かんがえる;kangaeru
+かんき;kanki
+かんきゃく;kankyaku
+かんきょう;kankyou
+かんけい;kankei
+かんげい;kangei
+かんげき;kangeki
+かんこう;kankou
+かんごふ;kangofu
+かんさい;kansai
+かんさつ;kansatsu
+かんしゃ;kansha
+かんしょう;kanshou
+かんしん;kanshin
+かんしん;kanshin
+かんじ;kanji
+かんじ;kanji
+かんじゃ;kanja
+かんじょう;kanjou
+かんじょう;kanjou
+かんじる;kanjiru
+かんする;kansuru
+かんずる;kanzuru
+かんせい;kansei
+かんせつ;kansetsu
+かんぜん;kanzen
+かんそう;kansou
+かんそう;kansou
+かんそく;kansoku
+かんたい;kantai
+かんたん;kantan
+かんちがい;kanchigai
+かんちょう;kanchou
+かんづめ;kandume
+かんでんち;kandenchi
+かんとう;kantou
+かんとく;kantoku
+かんどう;kandou
+かんねん;kannen
+かんばん;kanban
+かんぱい;kanpai
+かんびょう;kanbyou
+かんり;kanri
+かんりょう;kanryou
+かんれん;kanren
+かんわ;kanwa
+がい;gai
+がい;gai
+がいこう;gaikou
+がいこく;gaikoku
+がいしゅつ;gaishutsu
+がいぶ;gaibu
+がいろん;gairon
+がか;gaka
+がく;gaku
+がくしゃ;gakusha
+がくしゅう;gakushuu
+がくじゅつ;gakujutsu
+がくせい;gakusei
+がくねん;gakunen
+がくぶ;gakubu
+がくもん;gakumon
+がくりょく;gakuryoku
+がち;gachi
+がっか;gakka
+がっかい;gakkai
+がっかり;gakkari
+がっき;gakki
+がっき;gakki
+がっきゅう;gakkyuu
+がっこう;gakkou
+がっぴ;gappi
+がまん;gaman
+がる;garu
+がわ;gawa
+がんきょう;gankyou
+がんじつ;ganjitsu
+がんばる;ganbaru
+き;ki
+き;ki
+き;ki
+き;ki
+きあつ;kiatsu
+きいろい;kiiroi
+きえる;kieru
+きおく;kioku
+きおん;kion
+きかい;kikai
+きかい;kikai
+きかえる;kikaeru
+きかん;kikan
+きかん;kikan
+きかんしゃ;kikansha
+ききん;kikin
+きぎょう;kigyou
+きく;kiku
+きく;kiku
+きぐ;kigu
+きけん;kiken
+きげん;kigen
+きげん;kigen
+きこう;kikou
+きこえる;kikoeru
+きごう;kigou
+きざし;kizashi
+きざむ;kizamu
+きし;kishi
+きしゃ;kisha
+きしゃ;kisha
+きしょう;kishou
+きじ;kiji
+きじ;kiji
+きじゅん;kijun
+きすう;kisuu
+きず;kizu
+きせつ;kisetsu
+きせる;kiseru
+きそ;kiso
+きそく;kisoku
+きた;kita
+きたい;kitai
+きたい;kitai
+きたく;kitaku
+きたない;kitanai
+きたる;kitaru
+きち;kichi
+きちょう;kichou
+きちんと;kichinto
+きっかけ;kikkake
+きっさ;kissa
+きって;kitte
+きっと;kitto
+きっぷ;kippu
+きつい;kitsui
+きづく;kiduku
+きにいる;kiniiru
+きにゅう;kinyuu
+きぬ;kinu
+きねん;kinen
+きのう;kinou
+きのう;kinou
+きのどく;kinodoku
+きはい;kihai
+きばん;kiban
+きびしい;kibishii
+きふ;kifu
+きぶん;kibun
+きほん;kihon
+きぼう;kibou
+きまり;kimari
+きまる;kimaru
+きみ;kimi
+きみ;kimi
+きみょう;kimyou
+きめる;kimeru
+きもち;kimochi
+きもの;kimono
+きゃく;kyaku
+きゃくせき;kyakuseki
+きゃくま;kyakuma
+きゅう;kyuu
+きゅう;kyuu
+きゅう;kyuu
+きゅう;kyuu
+きゅうか;kyuuka
+きゅうぎょう;kyuugyou
+きゅうけい;kyuukei
+きゅうげき;kyuugeki
+きゅうこう;kyuukou
+きゅうこう;kyuukou
+きゅうしゅう;kyuushuu
+きゅうじょ;kyuujo
+きゅうそく;kyuusoku
+きゅうそく;kyuusoku
+きゅうよ;kyuuyo
+きゅうよう;kyuuyou
+きゅうりょう;kyuuryou
+きょう;kyou
+きょう;kyou
+きょういく;kyouiku
+きょういん;kyouin
+きょうか;kyouka
+きょうかい;kyoukai
+きょうかい;kyoukai
+きょうかしょ;kyoukasho
+きょうきゅう;kyoukyuu
+きょうぎ;kyougi
+きょうさん;kyousan
+きょうし;kyoushi
+きょうしつ;kyoushitsu
+きょうしゅく;kyoushuku
+きょうじゅ;kyouju
+きょうそう;kyousou
+きょうだい;kyoudai
+きょうだい;kyoudai
+きょうちょう;kyouchou
+きょうつう;kyoutsuu
+きょうどう;kyoudou
+きょうふ;kyoufu
+きょうみ;kyoumi
+きょうよう;kyouyou
+きょうり;kyouri
+きょうりょく;kyouryoku
+きょうりょく;kyouryoku
+きょか;kyoka
+きょく;kyoku
+きょく;kyoku
+きょくせん;kyokusen
+きょだい;kyodai
+きょねん;kyonen
+きょり;kyori
+きよい;kiyoi
+きよう;kiyou
+きらい;kirai
+きらう;kirau
+きらく;kiraku
+きり;kiri
+きりつ;kiritsu
+きる;kiru
+きる;kiru
+きる;kiru
+きれい;kirei
+きれる;kireru
+きろく;kiroku
+きわ;kiwa
+きわた;kiwata
+きをつける;kiwotsukeru
+きんえん;kin_en
+きんがく;kingaku
+きんきん;kinkin
+きんぎょ;kingyo
+きんし;kinshi
+きんじょ;kinjo
+きんせん;kinsen
+きんぞく;kinzoku
+きんだい;kindai
+きんちょう;kinchou
+ああ;aa
+あい;ai
+あいかわらず;aikawarazu
+あいさつ;aisatsu
+あいじょう;aijou
+あいする;aisuru
+あいず;aizu
+あいだ;aida
+あいて;aite
+あいにく;ainiku
+あいまい;aimai
+あう;au
+あう;au
+あう;au
+あお;ao
+あおい;aoi
+あおじろい;aojiroi
+あか;aka
+あかい;akai
+あかがね;akagane
+あかちゃん;akachan
+あかり;akari
+あかるい;akarui
+あがる;agaru
+あき;aki
+あき;aki
+あき;aki
+あきうど;akiudo
+あきらか;akiraka
+あきらめる;akirameru
+あきる;akiru
+あきれる;akireru
+あく;aku
+あく;aku
+あく;aku
+あくしゅ;akushu
+あくび;akubi
+あくま;akuma
+あくまで;akumade
+あくる;akuru
+あけがた;akegata
+あける;akeru
+あける;akeru
+あげる;ageru
+あげる;ageru
+あこがれる;akogareru
+あさ;asa
+あさい;asai
+あさって;asatte
+あさねぼう;asanebou
+あざ;aza
+あし;ashi
+あしあと;ashiato
+あした;ashita
+あしもと;ashimoto
+あじ;aji
+あじわう;ajiwau
+あずかる;azukaru
+あずける;azukeru
+あずま;azuma
+あせ;ase
+あそこ;asoko
+あそび;asobi
+あたい;atai
+あたえる;ataeru
+あたし;atashi
+あたたかい;atatakai
+あたたまる;atatamaru
+あたためる;atatameru
+あたま;atama
+あたらしい;atarashii
+あたり;atari
+あたりまえ;atarimae
+あたる;ataru
+あだびと;adabito
+あちこち;achikochi
+あちら;achira
+あちらこちら;achirakochira
+あっこう;akkou
+あっしゅく;asshuku
+あっち;acchi
+あつい;atsui
+あつい;atsui
+あつい;atsui
+あつかう;atsukau
+あつかましい;atsukamashii
+あつまり;atsumari
+あつまる;atsumaru
+あつめる;atsumeru
+あてな;atena
+あてはまる;atehamaru
+あてはめる;atehameru
+あてる;ateru
+あと;ato
+あと;ato
+あな;ana
+あなた;anata
+あに;ani
+あね;ane
+あの;ano
+あばれる;abareru
+あびる;abiru
+あふれる;afureru
+あぶない;abunai
+あぶら;abura
+あぶる;aburu
+あまい;amai
+あまど;amado
+あまやかす;amayakasu
+あまり;amari
+あまる;amaru
+あみもの;amimono
+あむ;amu
+あめ;ame
+あめ;ame
+あやうい;ayaui
+あやしい;ayashii
+あやまり;ayamari
+あやまる;ayamaru
+あら;ara
+あらい;arai
+あらい;arai
+あらう;arau
+あらし;arashi
+あらすじ;arasuji
+あらそう;arasou
+あらた;arata
+あらためて;aratamete
+あらためる;aratameru
+あらゆる;arayuru
+あらわす;arawasu
+あらわす;arawasu
+あらわす;arawasu
+あらわれ;araware
+あらわれる;arawareru
+ありがたい;arigatai
+ありがとう;arigatou
+ある;aru
+ある;aru
+ある;aru
+あるいは;aruiha
+あるく;aruku
+あるじ;aruji
+あれ;are
+あれこれ;arekore
+あれる;areru
+あわ;awa
+あわせる;awaseru
+あわただしい;awatadashii
+あわてる;awateru
+あわれ;aware
+あん;an
+あんい;an_i
+あんがい;angai
+あんき;anki
+あんしん;anshin
+あんぜん;anzen
+あんてい;antei
+あんな;anna
+あんない;annai
+あんまり;anmari
+い;i
+いい;ii
+いいえ;iie
+いいだす;iidasu
+いいつける;iitsukeru
+いいん;iin
+いう;iu
+いえ;ie
+いえぬし;ienushi
+いか;ika
+いかが;ikaga
+いかずち;ikazuchi
+いかる;ikaru
+いがい;igai
+いがい;igai
+いがく;igaku
+いき;iki
+いき;iki
+いきいき;ikiiki
+いきおい;ikioi
+いきなり;ikinari
+いきもの;ikimono
+いきる;ikiru
+いぎ;igi
+いく;iku
+いく;iku
+いくさ;ikusa
+いくさ;ikusa
+いくじ;ikuji
+いくつ;ikutsu
+いくぶん;ikubun
+いくら;ikura
+いけ;ike
+いけない;ikenai
+いけばな;ikebana
+いけん;iken
+いこう;ikou
+いご;igo
+いさましい;isamashii
+いし;ishi
+いし;ishi
+いし;ishi
+いし;ishi
+いしき;ishiki
+いしゃ;isha
+いしょくじゅう;ishokujuu
+いじ;iji
+いじめる;ijimeru
+いじょう;ijou
+いじょう;ijou
+いじわる;ijiwaru
+いす;isu
+いずみ;izumi
+いずれ;izure
+いぜん;izen
+いそがしい;isogashii
+いそぐ;isogu
+いた;ita
+いたい;itai
+いたす;itasu
+いたずら;itazura
+いただきます;itadakimasu
+いただく;itadaku
+いたみ;itami
+いたむ;itamu
+いたる;itaru
+いだい;idai
+いだく;idaku
+いち;ichi
+いち;ichi
+いち;ichi
+いち;ichi
+いちいち;ichiichi
+いちおう;ichiou
+いちげん;ichigen
+いちじ;ichiji
+いちじつ;ichijitsu
+いちじょう;ichijou
+いちだんと;ichidanto
+いちど;ichido
+いちどに;ichidoni
+いちにん;ichinin
+いちば;ichiba
+いちばん;ichiban
+いちぶ;ichibu
+いちりゅう;ichiryuu
+いっか;ikka
+いっさくじつ;issakujitsu
+いっさくねん;issakunen
+いっしゅ;isshu
+いっしゅん;isshun
+いっしょ;issho
+いっしょう;isshou
+いっしょうけんめい;isshoukenmei
+いっせい;issei
+いっそう;issou
+いったい;ittai
+いったん;ittan
+いっち;icchi
+いっぱい;ippai
+いっぱん;ippan
+いっぽう;ippou
+いつ;itsu
+きんにく;kinniku
+きんゆう;kin_yuu
+きんよう;kin_you
+ぎいん;giin
+ぎかい;gikai
+ぎし;gishi
+ぎしき;gishiki
+ぎじゅつ;gijutsu
+ぎちょう;gichou
+ぎっしり;gisshiri
+ぎむ;gimu
+ぎもん;gimon
+ぎゃく;gyaku
+ぎゅうにゅう;gyuunyuu
+ぎょう;gyou
+ぎょうぎ;gyougi
+ぎょうじ;gyouji
+ぎょうれつ;gyouretsu
+ぎょぎょう;gyogyou
+ぎょく;gyoku
+ぎろん;giron
+ぎん;gin
+ぎんこう;ginkou
+く;ku
+くいき;kuiki
+くう;kuu
+くうき;kuuki
+くうこう;kuukou
+くうそう;kuusou
+くうちゅう;kuuchuu
+くぎ;kugi
+くぎる;kugiru
+くぐる;kuguru
+くさ;kusa
+くさい;kusai
+くさり;kusari
+くさる;kusaru
+くし;kushi
+くしゃみ;kushami
+くしん;kushin
+くじょう;kujou
+くすり;kusuri
+くすりゆび;kusuriyubi
+くず;kuzu
+くずす;kuzusu
+くずれる;kuzureru
+くせ;kuse
+くたびれる;kutabireru
+くだく;kudaku
+くだける;kudakeru
+くださる;kudasaru
+くだもの;kudamono
+くだらない;kudaranai
+くだり;kudari
+くだる;kudaru
+くち;kuchi
+くちびる;kuchibiru
+くちべに;kuchibeni
+くっつく;kuttsuku
+くっつける;kuttsukeru
+くつ;kutsu
+くつう;kutsuu
+くつした;kutsushita
+くとうてん;kutouten
+くどい;kudoi
+くに;kuni
+くにざかい;kunizakai
+くばる;kubaru
+くび;kubi
+くふう;kufuu
+くぶん;kubun
+くべつ;kubetsu
+くみ;kumi
+くみあい;kumiai
+くみあわせ;kumiawase
+くみたてる;kumitateru
+くむ;kumu
+くむ;kumu
+くむ;kumu
+くも;kumo
+くもり;kumori
+くもる;kumoru
+くやしい;kuyashii
+くやむ;kuyamu
+くらい;kurai
+くらい;kurai
+くらし;kurashi
+くらす;kurasu
+くらべる;kuraberu
+くりかえす;kurikaesu
+くるう;kuruu
+くるしい;kurushii
+くるしむ;kurushimu
+くるしめる;kurushimeru
+くるま;kuruma
+くるむ;kurumu
+くれ;kure
+くれぐれも;kureguremo
+くれる;kureru
+くれる;kureru
+くろ;kuro
+くろい;kuroi
+くろう;kurou
+くわえる;kuwaeru
+くわしい;kuwashii
+くわわる;kuwawaru
+くん;kun
+くんれん;kunren
+ぐあい;guai
+ぐうすう;guusuu
+ぐうぜん;guuzen
+ぐたい;gutai
+ぐっすり;gussuri
+ぐらい;gurai
+ぐん;gun
+ぐん;gun
+ぐんたい;guntai
+け;ke
+けい;kei
+けい;kei
+けい;kei
+けいい;keii
+けいえい;keiei
+けいかく;keikaku
+けいかん;keikan
+けいき;keiki
+けいけん;keiken
+けいこ;keiko
+けいこう;keikou
+けいこうとう;keikoutou
+けいこく;keikoku
+けいご;keigo
+けいさつ;keisatsu
+けいさん;keisan
+けいざい;keizai
+けいしき;keishiki
+けいじ;keiji
+けいじ;keiji
+けいぞく;keizoku
+けいと;keito
+けいとう;keitou
+けいど;keido
+けいば;keiba
+けいび;keibi
+けいやく;keiyaku
+けいゆ;keiyu
+けいようし;keiyoushi
+けいようどうし;keiyoudoushi
+けが;kega
+けがす;kegasu
+けがれる;kegareru
+けがわ;kegawa
+けさ;kesa
+けしき;keshiki
+けしょう;keshou
+けしゴム;keshigomu
+けす;kesu
+けずる;kezuru
+けた;keta
+けち;kechi
+けっか;kekka
+けっかん;kekkan
+けっきょく;kekkyoku
+けっこう;kekkou
+けっこん;kekkon
+けっさく;kessaku
+けっして;kesshite
+けっしん;kesshin
+けっせき;kesseki
+けってん;ketten
+けつあつ;ketsuatsu
+けつえき;ketsueki
+けつだん;ketsudan
+けつろん;ketsuron
+けむい;kemui
+けむり;kemuri
+ける;keru
+けれど;keredo
+けわしい;kewashii
+けん;ken
+けん;ken
+けんか;kenka
+けんかい;kenkai
+けんがく;kengaku
+けんきゅう;kenkyuu
+けんきょ;kenkyo
+けんこう;kenkou
+けんさ;kensa
+けんしゅう;kenshuu
+けんせつ;kensetsu
+けんそん;kenson
+けんちく;kenchiku
+けんちょう;kenchou
+けんとう;kentou
+けんとう;kentou
+けんびきょう;kenbikyou
+けんぶつ;kenbutsu
+けんぽう;kenpou
+けんめい;kenmei
+けんり;kenri
+げいじゅつ;geijutsu
+げいのう;geinou
+げか;geka
+げき;geki
+げき;geki
+げきじょう;gekijou
+げきぞう;gekizou
+げしゃ;gesha
+げしゅく;geshuku
+げじゅん;gejun
+げすい;gesui
+げた;geta
+げっきゅう;gekkyuu
+げつまつ;getsumatsu
+げつよう;getsuyou
+げん;gen
+げんいん;gen_in
+げんかい;genkai
+げんかん;genkan
+げんき;genki
+げんきん;genkin
+げんこう;genkou
+げんご;gengo
+げんさん;gensan
+げんざい;genzai
+げんし;genshi
+げんしょう;genshou
+げんじつ;genjitsu
+げんじゅう;genjuu
+げんじょう;genjou
+げんじょう;genjou
+げんだい;gendai
+げんど;gendo
+げんに;genni
+げんり;genri
+げんりょう;genryou
+こ;ko
+こ;ko
+こ;ko
+こい;koi
+こい;koi
+こいしい;koishii
+こいびと;koibito
+こう;kou
+こう;kou
+こういん;kouin
+こううん;kouun
+こうえん;kouen
+こうえん;kouen
+こうか;kouka
+こうか;kouka
+こうか;kouka
+こうかん;koukan
+こうがい;kougai
+こうがい;kougai
+こうきゅう;koukyuu
+こうきょう;koukyou
+こうぎ;kougi
+こうぎょう;kougyou
+こうくう;koukuu
+こうけい;koukei
+こうけん;kouken
+こうげい;kougei
+こうげき;kougeki
+こうこう;koukou
+こうこう;koukou
+こうこく;koukoku
+こうさ;kousa
+こうさい;kousai
+こうさてん;kousaten
+こうし;koushi
+こうしき;koushiki
+こうしゃ;kousha
+こうしゃ;kousha
+こうしゅう;koushuu
+こうじ;kouji
+こうじつ;koujitsu
+こうじょう;koujou
+こうすい;kousui
+こうせい;kousei
+こうせい;kousei
+こうせき;kouseki
+こうせん;kousen
+こうそう;kousou
+こうそく;kousoku
+こうぞう;kouzou
+こうたい;koutai
+こうち;kouchi
+こうちゃ;koucha
+こうつう;koutsuu
+こうつうきかん;koutsuukikan
+こうてい;koutei
+こうてい;koutei
+こうとう;koutou
+こうとうがっこう;koutougakkou
+こうど;koudo
+こうどう;koudou
+こうどう;koudou
+こうはい;kouhai
+こうばん;kouban
+こうひょう;kouhyou
+こうふく;koufuku
+こうぶつ;koubutsu
+こうへい;kouhei
+こうほ;kouho
+こうむ;koumu
+こうもく;koumoku
+こうよう;kouyou
+こうりゅう;kouryuu
+こうりょ;kouryo
+こうりょく;kouryoku
+こえ;koe
+こえる;koeru
+こえる;koeru
+こおり;koori
+こがす;kogasu
+こきゅう;kokyuu
+こきょう;kokyou
+こくおう;kokuou
+こくご;kokugo
+こくさい;kokusai
+こくせき;kokuseki
+こくばん;kokuban
+こくふく;kokufuku
+こくみん;kokumin
+こくもつ;kokumotsu
+こくりつ;kokuritsu
+こぐ;kogu
+こげる;kogeru
+ここ;koko
+ここのか;kokonoka
+ここのつ;kokonotsu
+こころ;kokoro
+こころあたり;kokoroatari
+こころえる;kokoroeru
+こごえる;kogoeru
+こごる;kogoru
+こし;koshi
+こしかけ;koshikake
+こしかける;koshikakeru
+こしょう;koshou
+こしょう;koshou
+こしらえる;koshiraeru
+こじん;kojin
+こす;kosu
+こす;kosu
+こたい;kotai
+こたえ;kotae
+こたえる;kotaeru
+こちら;kochira
+こちらこそ;kochirakoso
+こっか;kokka
+こっかい;kokkai
+こっせつ;kossetsu
+こっそり;kossori
+こつ;kotsu
+こづかい;kodukai
+こづつみ;kodutsumi
+こてん;koten
+こと;koto
+こと;koto
+ことし;kotoshi
+ことづける;kotodukeru
+ことなる;kotonaru
+ことば;kotoba
+ことばづかい;kotobadukai
+ことり;kotori
+ことわざ;kotowaza
+ことわる;kotowaru
+こども;kodomo
+こな;kona
+こないだ;konaida
+この;kono
+このあいだ;konoaida
+このごろ;konogoro
+このみ;konomi
+このむ;konomu
+こぼす;kobosu
+こぼれる;koboreru
+こまかい;komakai
+こまる;komaru
+こむ;komu
+こむ;komu
+こむぎ;komugi
+こめ;kome
+こや;koya
+こゆび;koyubi
+こらえる;koraeru
+これ;kore
+これら;korera
+ころがす;korogasu
+ころがる;korogaru
+ころす;korosu
+ころぶ;korobu
+こわい;kowai
+こわす;kowasu
+こわれる;kowareru
+こん;kon
+こんかい;konkai
+こんご;kongo
+こんごう;kongou
+こんざつ;konzatsu
+こんだて;kondate
+こんど;kondo
+こんな;konna
+こんなに;konnani
+こんなん;konnan
+こんにちは;konnichiha
+こんばんは;konbanha
+こんやく;kon_yaku
+こんらん;konran
+ご;go
+ご;go
+ご;go
+ご;go
+ごう;gou
+ごう;gou
+ごう;gou
+ごういん;gouin
+ごうか;gouka
+ごうかく;goukaku
+ごうぎ;gougi
+ごうけい;goukei
+ごうとう;goutou
+ごうどう;goudou
+ごうり;gouri
+ごうりゅう;gouryuu
+ごかい;gokai
+ごがく;gogaku
+ごく;goku
+ごくろうさま;gokurousama
+ごご;gogo
+ごじゅうおん;gojuuon
+ごぜん;gozen
+ごちそう;gochisou
+ごちそうさま;gochisousama
+ごと;goto
+ごはん;gohan
+ごぶさた;gobusata
+ごみ;gomi
+ごめん;gomen
+ごめんください;gomenkudasai
+ごめんなさい;gomennasai
+ごらく;goraku
+ごらん;goran
+さ;sa
+さあ;saa
+さい;sai
+さい;sai
+さい;sai
+さいきん;saikin
+さいこう;saikou
+さいご;saigo
+さいさん;saisan
+さいしゅう;saishuu
+さいしょ;saisho
+さいじつ;saijitsu
+さいそく;saisoku
+さいちゅう;saichuu
+さいてい;saitei
+さいてん;saiten
+さいなん;sainan
+さいのう;sainou
+さいばん;saiban
+さいふ;saifu
+さいほう;saihou
+さいわい;saiwai
+さか;saka
+さかい;sakai
+さかさ;sakasa
+さかさま;sakasama
+さかずき;sakazuki
+さかのぼる;sakanoboru
+さかば;sakaba
+さからう;sakarau
+さかり;sakari
+さかる;sakaru
+さかん;sakan
+さが;saga
+さがす;sagasu
+さがす;sagasu
+さがる;sagaru
+さき;saki
+さきおととい;sakiototoi
+さきほど;sakihodo
+さぎょう;sagyou
+さく;saku
+さく;saku
+さく;saku
+さくいん;sakuin
+さくしゃ;sakusha
+さくじょ;sakujo
+さくせい;sakusei
+さくひん;sakuhin
+さくぶつ;sakubutsu
+さくぶん;sakubun
+さくら;sakura
+さぐる;saguru
+さけ;sake
+さけぶ;sakebu
+さける;sakeru
+さげる;sageru
+ささえる;sasaeru
+ささやく;sasayaku
+ささる;sasaru
+さしあげる;sashiageru
+さしつかえ;sashitsukae
+さしひく;sashihiku
+さしみ;sashimi
+さじ;saji
+さす;sasu
+さす;sasu
+さす;sasu
+さす;sasu
+さす;sasu
+さすが;sasuga
+さそう;sasou
+さっか;sakka
+さっき;sakki
+さっきょく;sakkyoku
+さっさと;sassato
+さっそく;sassoku
+さっぱり;sappari
+さつ;satsu
+さつ;satsu
+さつえい;satsuei
+さて;sate
+さとう;satou
+さばく;sabaku
+さび;sabi
+さびしい;sabishii
+さびる;sabiru
+さべつ;sabetsu
+さほう;sahou
+さま;sama
+さまざま;samazama
+さます;samasu
+さます;samasu
+さまたげる;samatageru
+さむい;samui
+さめる;sameru
+さめる;sameru
+さゆう;sayuu
+さようなら;sayounara
+さら;sara
+さらいげつ;saraigetsu
+さらいしゅう;saraishuu
+さらいねん;sarainen
+さらに;sarani
+さる;saru
+さる;saru
+さわがしい;sawagashii
+さわぎ;sawagi
+さわやか;sawayaka
+さわる;sawaru
+さん;san
+さん;san
+さんか;sanka
+さんかく;sankaku
+さんぎょう;sangyou
+さんこう;sankou
+さんすう;sansuu
+さんせい;sansei
+さんせい;sansei
+さんそ;sanso
+さんち;sanchi
+さんぽ;sanpo
+さんりん;sanrin
+ざいがく;zaigaku
+ざいさん;zaisan
+ざいもく;zaimoku
+ざいりょう;zairyou
+ざしき;zashiki
+ざせき;zaseki
+ざっし;zasshi
+ざっと;zatto
+ざつおん;zatsuon
+ざぶとん;zabuton
+ざんねん;zannen
+し;shi
+し;shi
+し;shi
+しあい;shiai
+しあがる;shiagaru
+しあさって;shiasatte
+しあわせ;shiawase
+しいんと;shiinto
+しおからい;shiokarai
+しかい;shikai
+しかく;shikaku
+しかくい;shikakui
+しかし;shikashi
+しかた;shikata
+しかたがない;shikataganai
+しかも;shikamo
+しかる;shikaru
+しき;shiki
+しき;shiki
+しきち;shikichi
+しきゅう;shikyuu
+しきゅう;shikyuu
+しきりに;shikirini
+しく;shiku
+しけん;shiken
+しげき;shigeki
+しげる;shigeru
+しげん;shigen
+しごと;shigoto
+ししゃごにゅう;shishagonyuu
+ししゅつ;shishutsu
+しじ;shiji
+しじゅう;shijuu
+しじん;shijin
+しずか;shizuka
+しずまる;shizumaru
+しずむ;shizumu
+しせい;shisei
+しぜん;shizen
+しぜんかがく;shizenkagaku
+しそう;shisou
+しそん;shison
+した;shita
+した;shita
+したい;shitai
+したがう;shitagau
+したがき;shitagaki
+したがって;shitagatte
+したぎ;shitagi
+したく;shitaku
+したしい;shitashii
+したためる;shitatameru
+したまち;shitamachi
+しだい;shidai
+しち;shichi
+しっかり;shikkari
+しっき;shikki
+しっぱい;shippai
+しっぴつ;shippitsu
+しっぽ;shippo
+しつ;shitsu
+しつ;shitsu
+しつぎょう;shitsugyou
+しつこい;shitsukoi
+しつど;shitsudo
+しつぼう;shitsubou
+しつもん;shitsumon
+しつれい;shitsurei
+しつれいしました;shitsureishimashita
+しつれん;shitsuren
+してい;shitei
+してつ;shitetsu
+してん;shiten
+しどう;shidou
+しな;shina
+しなもの;shinamono
+しぬ;shinu
+しはい;shihai
+しはらい;shiharai
+しはらう;shiharau
+しばい;shibai
+しばしば;shibashiba
+しばふ;shibafu
+しばらく;shibaraku
+しばる;shibaru
+しゃべる;shaberu
+しゃらく;sharaku
+しゃりん;sharin
+しゅ;shu
+しゅう;shuu
+しゅう;shuu
+しゅう;shuu
+しゅうい;shuui
+しゅうかい;shuukai
+しゅうかく;shuukaku
+しゅうかん;shuukan
+しゅうかん;shuukan
+しゅうきょう;shuukyou
+しゅうきん;shuukin
+しゅうごう;shuugou
+しゅうしょく;shuushoku
+しゅうじ;shuuji
+しゅうせい;shuusei
+しゅうぜん;shuuzen
+しゅうだん;shuudan
+しゅうちゅう;shuuchuu
+しゅうてん;shuuten
+しゅうにゅう;shuunyuu
+しゅうにん;shuunin
+しゅうへん;shuuhen
+しゅうり;shuuri
+しゅうりょう;shuuryou
+しゅぎ;shugi
+しゅくしょう;shukushou
+しゅくじつ;shukujitsu
+しゅくだい;shukudai
+しゅくはく;shukuhaku
+しゅご;shugo
+しゅしょう;shushou
+しゅじゅつ;shujutsu
+しゅだん;shudan
+しゅちょう;shuchou
+しゅっきん;shukkin
+しゅっしん;shusshin
+しゅっせき;shusseki
+しゅっちょう;shucchou
+しゅっぱつ;shuppatsu
+しゅっぱん;shuppan
+しゅつじょう;shutsujou
+しゅと;shuto
+しゅふ;shufu
+しゅみ;shumi
+しゅやく;shuyaku
+しゅよう;shuyou
+しゅるい;shurui
+しゅんかん;shunkan
+しょ;sho
+しょい;shoi
+しょう;shou
+しょう;shou
+しょう;shou
+しょう;shou
+しょう;shou
+しょう;shou
+しょうか;shouka
+しょうかい;shoukai
+しょうがい;shougai
+しょうがくきん;shougakukin
+しょうがくせい;shougakusei
+しょうがっこう;shougakkou
+しょうがつ;shougatsu
+しょうきょくてき;shoukyokuteki
+しょうきん;shoukin
+しょうぎ;shougi
+しょうぎょう;shougyou
+しょうこう;shoukou
+しょうご;shougo
+しょうしゃ;shousha
+しょうしょう;shoushou
+しょうじ;shouji
+しょうじき;shoujiki
+しょうじょう;shoujou
+しょうじる;shoujiru
+しょうすう;shousuu
+しょうせつ;shousetsu
+しょうたい;shoutai
+しょうち;shouchi
+しょうてん;shouten
+しょうてん;shouten
+しょうとつ;shoutotsu
+しょうどく;shoudoku
+しょうにん;shounin
+しょうねん;shounen
+しょうはい;shouhai
+しょうばい;shoubai
+しょうひ;shouhi
+しょうひん;shouhin
+しょうひん;shouhin
+しょうぶ;shoubu
+しょうべん;shouben
+しょうぼう;shoubou
+しょうぼうしょ;shoubousho
+しょうみ;shoumi
+しょうめい;shoumei
+しょうめん;shoumen
+しょうゆ;shouyu
+しょうらい;shourai
+しょうりゃく;shouryaku
+しょきゅう;shokyuu
+しょく;shoku
+しょくえん;shokuen
+しょくぎょう;shokugyou
+しょくじ;shokuji
+しょくたく;shokutaku
+しょくどう;shokudou
+しょくにん;shokunin
+しょくば;shokuba
+しょくひん;shokuhin
+しょくぶつ;shokubutsu
+しょくもつ;shokumotsu
+しょくよく;shokuyoku
+しょくりょう;shokuryou
+しょさい;shosai
+しょしょ;shosho
+しょじゅん;shojun
+しょせき;shoseki
+しょっき;shokki
+しょてん;shoten
+しょどう;shodou
+しょほ;shoho
+しょめい;shomei
+しょもつ;shomotsu
+しょり;shori
+しょるい;shorui
+しよう;shiyou
+しらが;shiraga
+しらせ;shirase
+しらせる;shiraseru
+しらべる;shiraberu
+しり;shiri
+しりあい;shiriai
+しりぞく;shirizoku
+しりぞける;shirizokeru
+しりつ;shiritsu
+しりょう;shiryou
+しる;shiru
+しる;shiru
+しろ;shiro
+しろ;shiro
+しろ;shiro
+しろい;shiroi
+しろうと;shirouto
+しわ;shiwa
+しん;shin
+しん;shin
+しんかんせん;shinkansen
+しんがく;shingaku
+しんがり;shingari
+しんくう;shinkuu
+しんけい;shinkei
+しんけん;shinken
+しんこう;shinkou
+しんこく;shinkoku
+しんごう;shingou
+しんさつ;shinsatsu
+しんしん;shinshin
+しんじゅう;shinjuu
+しんじる;shinjiru
+しんずる;shinzuru
+しんせき;shinseki
+しんせつ;shinsetsu
+しんせん;shinsen
+しんぞう;shinzou
+しんだい;shindai
+しんだん;shindan
+しんちょう;shinchou
+しんにゅう;shinnyuu
+しんばん;shinban
+しんぱい;shinpai
+しんぶん;shinbun
+しんぽ;shinpo
+しんめんもく;shinmenmoku
+しんや;shin_ya
+しんゆう;shin_yuu
+しんよう;shin_you
+しんらい;shinrai
+しんり;shinri
+しんりん;shinrin
+しんるい;shinrui
+しんろ;shinro
+しんわ;shinwa
+じいん;jiin
+じえい;jiei
+じかた;jikata
+じかに;jikani
+じかん;jikan
+じかんわり;jikanwari
+じき;jiki
+じき;jiki
+じけん;jiken
+じこ;jiko
+じこく;jikoku
+じさつ;jisatsu
+じさん;jisan
+じしゃく;jishaku
+じしゅう;jishuu
+じしょ;jisho
+じしん;jishin
+じしん;jishin
+じしん;jishin
+じじつ;jijitsu
+じじょう;jijou
+じそく;jisoku
+じたい;jitai
+じたく;jitaku
+じだい;jidai
+じち;jichi
+じっかん;jikkan
+じっけん;jikken
+じっこう;jikkou
+じっさい;jissai
+じっし;jisshi
+じっしゅう;jisshuu
+じっせき;jisseki
+じっと;jitto
+じっぷん;jippun
+じつ;jitsu
+じつげん;jitsugen
+じつに;jitsuni
+じつは;jitsuha
+じつぶつ;jitsubutsu
+じつよう;jitsuyou
+じつりょく;jitsuryoku
+じつれい;jitsurei
+じてん;jiten
+じてんしゃ;jitensha
+じどう;jidou
+じどう;jidou
+じどうしゃ;jidousha
+じばん;jiban
+じびき;jibiki
+じぶん;jibun
+じまん;jiman
+じみ;jimi
+じむ;jimu
+じめん;jimen
+じゃくてん;jakuten
+じゃぐち;jaguchi
+じゃま;jama
+じゃんけん;janken
+じゅう;juu
+じゅうきょ;juukyo
+じゅうし;juushi
+じゅうしょ;juusho
+じゅうたい;juutai
+じゅうたい;juutai
+じゅうたく;juutaku
+じゅうたん;juutan
+じゅうだい;juudai
+じゅうてん;juuten
+じゅうみん;juumin
+じゅうよう;juuyou
+じゅうりょう;juuryou
+じゅうりょく;juuryoku
+じゅぎょう;jugyou
+じゅくご;jukugo
+じゅけん;juken
+じゅつご;jutsugo
+じゅみょう;jumyou
+じゅよう;juyou
+じゅわき;juwaki
+じゅん;jun
+じゅんかん;junkan
+じゅんさ;junsa
+じゅんじゅん;junjun
+じゅんじょ;junjo
+じゅんじょう;junjou
+じゅんすい;junsui
+じゅんちょう;junchou
+じゅんばん;junban
+じゆう;jiyuu
+じょ;jo
+じょう;jou
+じょう;jou
+じょうかく;joukaku
+じょうき;jouki
+じょうきゅう;joukyuu
+じょうきょう;joukyou
+じょうきょう;joukyou
+じょうぎ;jougi
+じょうけん;jouken
+じょうしき;joushiki
+じょうしゃ;jousha
+じょうじゅん;joujun
+じょうたい;joutai
+じょうたつ;joutatsu
+じょうだん;joudan
+じょうとう;joutou
+すいぶん;suibun
+すいへい;suihei
+すいへいせん;suiheisen
+すいみん;suimin
+すいめん;suimen
+すいよう;suiyou
+すう;suu
+すうがく;suugaku
+すうじ;suuji
+すえっこ;suekko
+すがた;sugata
+すき;suki
+すききらい;sukikirai
+すきずき;sukizuki
+すきとおる;sukitooru
+すきま;sukima
+すぎ;sugi
+すぎ;sugi
+すぎる;sugiru
+すくう;sukuu
+すくない;sukunai
+すくなくとも;sukunakutomo
+すぐ;sugu
+すぐれる;sugureru
+すこし;sukoshi
+すこしも;sukoshimo
+すごい;sugoi
+すごす;sugosu
+すじ;suji
+すすむ;susumu
+すすめる;susumeru
+すすめる;susumeru
+すず;suzu
+すずしい;suzushii
+すずむ;suzumu
+すっかり;sukkari
+すっきり;sukkiri
+すっと;sutto
+すっぱい;suppai
+すてき;suteki
+すてる;suteru
+すでに;sudeni
+すな;suna
+すなお;sunao
+すなわち;sunawachi
+すばらしい;subarashii
+すべて;subete
+すべる;suberu
+すまい;sumai
+すませる;sumaseru
+すまない;sumanai
+すみ;sumi
+すみ;sumi
+すみません;sumimasen
+すむ;sumu
+すむ;sumu
+すむ;sumu
+すめらぎ;sumeragi
+すもう;sumou
+すり;suri
+する;suru
+する;suru
+する;suru
+すると;suruto
+するどい;surudoi
+すれちがう;surechigau
+すわる;suwaru
+すんぽう;sunpou
+ず;zu
+ずいひつ;zuihitsu
+ずいぶん;zuibun
+ずうずうしい;zuuzuushii
+ずかん;zukan
+ずけい;zukei
+ずっと;zutto
+ずつう;zutsuu
+ずのう;zunou
+ずひょう;zuhyou
+ずらす;zurasu
+ずるい;zurui
+ずれる;zureru
+せい;sei
+せい;sei
+せい;sei
+せい;sei
+せいかく;seikaku
+せいかく;seikaku
+せいかつ;seikatsu
+せいき;seiki
+せいきゅう;seikyuu
+せいけつ;seiketsu
+せいげん;seigen
+せいこう;seikou
+せいさく;seisaku
+せいさん;seisan
+せいしき;seishiki
+せいしつ;seishitsu
+せいしょ;seisho
+せいしょうねん;seishounen
+せいしん;seishin
+せいじ;seiji
+せいじん;seijin
+せいすう;seisuu
+せいせき;seiseki
+せいぜい;seizei
+せいそう;seisou
+せいぞう;seizou
+せいぞん;seizon
+せいちょう;seichou
+せいと;seito
+せいとう;seitou
+せいど;seido
+せいねん;seinen
+せいねんがっぴ;seinengappi
+せいのう;seinou
+せいひん;seihin
+せいび;seibi
+せいふ;seifu
+せいぶつ;seibutsu
+せいぶん;seibun
+せいべつ;seibetsu
+せいほうけい;seihoukei
+せいめい;seimei
+せいもん;seimon
+せいよう;seiyou
+せいり;seiri
+せいりつ;seiritsu
+せいれき;seireki
+せかい;sekai
+せき;seki
+せき;seki
+せきたん;sekitan
+せきどう;sekidou
+せきにん;sekinin
+せきゆ;sekiyu
+せけん;seken
+せっかく;sekkaku
+せっきょくてき;sekkyokuteki
+せっきん;sekkin
+せっけい;sekkei
+せっけん;sekken
+せっする;sessuru
+せつ;setsu
+せつ;setsu
+せつぞく;setsuzoku
+せつび;setsubi
+せつめい;setsumei
+せつやく;setsuyaku
+せともの;setomono
+せなか;senaka
+せびろ;sebiro
+せまい;semai
+せまる;semaru
+せめ;seme
+せめる;semeru
+せめる;semeru
+せりふ;serifu
+せわ;sewa
+せん;sen
+せん;sen
+せん;sen
+せん;sen
+せんこう;senkou
+せんざい;senzai
+せんしゅ;senshu
+せんじつ;senjitsu
+せんす;sensu
+せんすい;sensui
+せんせい;sensei
+せんせい;sensei
+せんせんげつ;sensengetsu
+せんせんしゅう;sensenshuu
+せんそう;sensou
+せんぞ;senzo
+せんたく;sentaku
+せんたく;sentaku
+せんたん;sentan
+せんでん;senden
+せんとう;sentou
+せんぱい;senpai
+せんぷうき;senpuuki
+せんめん;senmen
+せんろ;senro
+ぜいかん;zeikan
+ぜいきん;zeikin
+ぜいたく;zeitaku
+ぜったい;zettai
+ぜつめつ;zetsumetsu
+ぜひ;zehi
+ぜひとも;zehitomo
+ぜん;zen
+ぜん;zen
+ぜんいん;zen_in
+ぜんこく;zenkoku
+ぜんご;zengo
+ぜんしゃ;zensha
+ぜんしゅう;zenshuu
+ぜんしん;zenshin
+ぜんしん;zenshin
+ぜんぜん;zenzen
+ぜんたい;zentai
+ぜんぱん;zenpan
+ぜんぶ;zenbu
+ぜんりょく;zenryoku
+そう;sou
+そう;sou
+そうい;soui
+そうおん;souon
+そうこ;souko
+そうご;sougo
+そうさ;sousa
+そうさく;sousaku
+そうしき;soushiki
+そうして;soushite
+そうじ;souji
+そうぞう;souzou
+そうぞうしい;souzoushii
+そうぞく;souzoku
+そうだん;soudan
+そうち;souchi
+そうとう;soutou
+そうべつ;soubetsu
+そうりだいじん;souridaijin
+そうりょう;souryou
+そくたつ;sokutatsu
+そくてい;sokutei
+そくど;sokudo
+そくりょう;sokuryou
+そくりょく;sokuryoku
+そこ;soko
+そこ;soko
+そこで;sokode
+そしき;soshiki
+そしつ;soshitsu
+そして;soshite
+そせん;sosen
+そそぐ;sosogu
+そそっかしい;sosokkashii
+そだつ;sodatsu
+そだてる;sodateru
+そちら;sochira
+そっくり;sokkuri
+そっちょく;socchoku
+そっと;sotto
+そつぎょう;sotsugyou
+そで;sode
+そと;soto
+そなえる;sonaeru
+その;sono
+そのうえ;sonoue
+そのうち;sonouchi
+そのため;sonotame
+そのほか;sonohoka
+そのまま;sonomama
+そば;soba
+そふ;sofu
+そぼ;sobo
+そぼく;soboku
+そまつ;somatsu
+それ;sore
+それから;sorekara
+それぞれ;sorezore
+それで;sorede
+それでは;soredeha
+それでも;soredemo
+それとも;soretomo
+それなら;sorenara
+それに;soreni
+それほど;sorehodo
+それる;soreru
+そろう;sorou
+そろえる;soroeru
+そろそろ;sorosoro
+そろばん;soroban
+そんがい;songai
+そんけい;sonkei
+そんざい;sonzai
+そんしつ;sonshitsu
+そんぞく;sonzoku
+そんちょう;sonchou
+そんとく;sontoku
+そんな;sonna
+ぞい;zoi
+ぞうか;zouka
+ぞうきん;zoukin
+ぞうげん;zougen
+ぞうせん;zousen
+ぞうだい;zoudai
+ぞうり;zouri
+ぞくする;zokusuru
+ぞくぞく;zokuzoku
+ぞんじる;zonjiru
+た;ta
+たい;tai
+たいいく;taiiku
+たいいん;taiin
+たいおん;taion
+たいかい;taikai
+たいきん;taikin
+たいくつ;taikutsu
+たいけい;taikei
+たいこ;taiko
+たいさく;taisaku
+たいざい;taizai
+たいし;taishi
+たいした;taishita
+たいして;taishite
+たいしょう;taishou
+たいしょう;taishou
+たいじゅう;taijuu
+たいする;taisuru
+たいせい;taisei
+たいせき;taiseki
+たいせつ;taisetsu
+たいせん;taisen
+たいそう;taisou
+たいてい;taitei
+たいど;taido
+たいはん;taihan
+たいふう;taifuu
+たいへん;taihen
+たいほ;taiho
+たいぼく;taiboku
+たいよう;taiyou
+たいら;taira
+たいりく;tairiku
+たいりつ;tairitsu
+たうえ;taue
+たえず;taezu
+たおす;taosu
+たおれる;taoreru
+たか;taka
+たかい;takai
+たかめる;takameru
+たから;takara
+たがい;tagai
+たがやす;tagayasu
+たき;taki
+たく;taku
+たく;taku
+たくさん;takusan
+たくわえる;takuwaeru
+たけ;take
+たしか;tashika
+たしか;tashika
+たしかめる;tashikameru
+たしょう;tashou
+たす;tasu
+たすかる;tasukaru
+たすける;tasukeru
+たずねる;tazuneru
+たずねる;tazuneru
+たたかい;tatakai
+たたかう;tatakau
+たたく;tataku
+たたむ;tatamu
+ただ;tada
+ただ;tada
+ただいま;tadaima
+ただし;tadashi
+ただしい;tadashii
+ただちに;tadachini
+たち;tachi
+たちあがる;tachiagaru
+たちどまる;tachidomaru
+たちば;tachiba
+たちまち;tachimachi
+たっする;tassuru
+たった;tatta
+たっぷり;tappuri
+たつ;tatsu
+たつ;tatsu
+たつ;tatsu
+たつ;tatsu
+たて;tate
+たてもの;tatemono
+たてる;tateru
+たてる;tateru
+たとえ;tatoe
+たとえば;tatoeba
+たとえる;tatoeru
+たな;tana
+たに;tani
+たのしい;tanoshii
+たのしみ;tanoshimi
+たのしむ;tanoshimu
+たのみ;tanomi
+たのむ;tanomu
+たのもしい;tanomoshii
+たば;taba
+たばこ;tabako
+たび;tabi
+たび;tabi
+たび;tabi
+たびたび;tabitabi
+たぶん;tabun
+たべる;taberu
+たま;tama
+たま;tama
+たまご;tamago
+たまたま;tamatama
+たまに;tamani
+たまらない;tamaranai
+たまる;tamaru
+ため;tame
+ためいき;tameiki
+ためし;tameshi
+ためし;tameshi
+ためす;tamesu
+ためらう;tamerau
+たより;tayori
+たよる;tayoru
+たりる;tariru
+たる;taru
+たれ;tare
+たん;tan
+たん;tan
+たんい;tan_i
+たんき;tanki
+たんこう;tankou
+たんご;tango
+たんしょ;tansho
+たんじゅん;tanjun
+たんじょう;tanjou
+たんす;tansu
+たんすい;tansui
+たんすう;tansuu
+たんとう;tantou
+たんなる;tannaru
+たんに;tanni
+たんぺん;tanpen
+だい;dai
+だい;dai
+だい;dai
+だいいち;daiichi
+だいがく;daigaku
+だいがくいん;daigakuin
+だいきん;daikin
+だいく;daiku
+だいしょう;daishou
+だいじょうぶ;daijoubu
+だいじん;daijin
+だいたい;daitai
+だいとうりょう;daitouryou
+だいどころ;daidokoro
+だいひょう;daihyou
+だいぶ;daibu
+だいぶぶん;daibubun
+だいめい;daimei
+だいめいし;daimeishi
+だいり;dairi
+だえん;daen
+だから;dakara
+だけど;dakedo
+だす;dasu
+だっせん;dassen
+だって;datte
+だとう;datou
+だます;damasu
+だまる;damaru
+だめ;dame
+だらけ;darake
+だらしない;darashinai
+だれか;dareka
+だん;dan
+だん;dan
+だんかい;dankai
+だんし;danshi
+だんすい;dansui
+だんせい;dansei
+だんたい;dantai
+だんだん;dandan
+だんち;danchi
+だんてい;dantei
+だんぼう;danbou
+ち;chi
+ち;chi
+ちい;chii
+ちいき;chiiki
+ちいさい;chiisai
+ちえ;chie
+ちか;chika
+ちかい;chikai
+ちかう;chikau
+ちかく;chikaku
+ちかごろ;chikagoro
+ちかすい;chikasui
+ちかづく;chikaduku
+ちかづける;chikadukeru
+ちかてつ;chikatetsu
+ちかよる;chikayoru
+ちから;chikara
+ちからづよい;chikaraduyoi
+ちがい;chigai
+ちがいない;chigainai
+ちがう;chigau
+ちきゅう;chikyuu
+ちぎる;chigiru
+ちく;chiku
+ちこく;chikoku
+ちしき;chishiki
+ちしつ;chishitsu
+ちじ;chiji
+ちじん;chijin
+ちず;chizu
+ちたい;chitai
+ちち;chichi
+ちちおや;chichioya
+ちちはは;chichihaha
+ちぢむ;chidimu
+ちぢめる;chidimeru
+ちぢれる;chidireru
+ちっとも;chittomo
+ちてん;chiten
+ちのう;chinou
+ちへいせん;chiheisen
+ちめい;chimei
+ちゃ;cha
+ちゃいろ;chairo
+ちゃく;chaku
+ちゃくちゃく;chakuchaku
+ちゃわん;chawan
+ちゃん;chan
+ちゃんと;chanto
+ちゅう;chuu
+ちゅう;chuu
+ちゅうい;chuui
+ちゅうおう;chuuou
+ちゅうかん;chuukan
+ちゅうかん;chuukan
+ちょきん;chokin
+ちょくご;chokugo
+ちょくせつ;chokusetsu
+ちょくせん;chokusen
+ちょくぜん;chokuzen
+ちょくつう;chokutsuu
+ちょくりゅう;chokuryuu
+ちょしゃ;chosha
+ちょぞう;chozou
+ちょっかく;chokkaku
+ちょっけい;chokkei
+ちょっと;chotto
+ちらかす;chirakasu
+ちらかる;chirakaru
+ちらす;chirasu
+ちり;chiri
+ちりがみ;chirigami
+ちる;chiru
+つい;tsui
+ついか;tsuika
+ついで;tsuide
+ついに;tsuini
+つう;tsuu
+つうか;tsuuka
+つうか;tsuuka
+つうがく;tsuugaku
+つうきん;tsuukin
+つうこう;tsuukou
+つうしん;tsuushin
+つうじる;tsuujiru
+つうち;tsuuchi
+つうちょう;tsuuchou
+つうやく;tsuuyaku
+つうよう;tsuuyou
+つうろ;tsuuro
+つかい;tsukai
+つかう;tsukau
+つかまえる;tsukamaeru
+つかまる;tsukamaru
+つかむ;tsukamu
+つかれ;tsukare
+つかれる;tsukareru
+つき;tsuki
+つき;tsuki
+つきあい;tsukiai
+つきあう;tsukiau
+つきあたり;tsukiatari
+つきあたる;tsukiataru
+つぎつぎ;tsugitsugi
+つく;tsuku
+つく;tsuku
+つく;tsuku
+つく;tsuku
+つく;tsuku
+つく;tsuku
+つくえ;tsukue
+つくる;tsukuru
+つくる;tsukuru
+つぐ;tsugu
+つけくわえる;tsukekuwaeru
+つける;tsukeru
+つける;tsukeru
+つける;tsukeru
+つける;tsukeru
+つける;tsukeru
+つごう;tsugou
+つたえる;tsutaeru
+つたわる;tsutawaru
+つち;tsuchi
+つちゅう;tsuchuu
+つっこむ;tsukkomu
+つつ;tsutsu
+つつみ;tsutsumi
+つづき;tsuduki
+つづく;tsuduku
+つづける;tsudukeru
+つとめ;tsutome
+つとめる;tsutomeru
+つとめる;tsutomeru
+つとめる;tsutomeru
+つな;tsuna
+つながり;tsunagari
+つながる;tsunagaru
+つなぐ;tsunagu
+つなげる;tsunageru
+つねに;tsuneni
+つばさ;tsubasa
+つぶ;tsubu
+つぶす;tsubusu
+つぶれる;tsubureru
+つま;tsuma
+つまずく;tsumazuku
+つまらない;tsumaranai
+つまり;tsumari
+つまる;tsumaru
+つみ;tsumi
+つむ;tsumu
+つめ;tsume
+つめたい;tsumetai
+つめる;tsumeru
+つもり;tsumori
+つもる;tsumoru
+つゆ;tsuyu
+つよい;tsuyoi
+つり;tsuri
+つりあう;tsuriau
+つる;tsuru
+つる;tsuru
+つるす;tsurusu
+つれ;tsure
+つれる;tsureru
+て;te
+てあらい;tearai
+てい;tei
+ていあん;teian
+ていいん;teiin
+ていか;teika
+ていか;teika
+ていき;teiki
+ていきけん;teikiken
+ていきゅうび;teikyuubi
+ていこう;teikou
+ていし;teishi
+ていし;teishi
+ていし;teishi
+ていしゃ;teisha
+ていしゅつ;teishutsu
+ていでん;teiden
+ていど;teido
+ていねい;teinei
+ていりゅうじょ;teiryuujo
+ていれ;teire
+てがみ;tegami
+てき;teki
+てきかく;tekikaku
+てきかく;tekikaku
+てきする;tekisuru
+てきせつ;tekisetsu
+てきとう;tekitou
+てきど;tekido
+てきよう;tekiyou
+てくび;tekubi
+てごろ;tegoro
+てじな;tejina
+てちょう;techou
+てっきょう;tekkyou
+てっきり;tekkiri
+てっこう;tekkou
+てっする;tessuru
+てってい;tettei
+てっぽう;teppou
+てつ;tetsu
+てつがく;tetsugaku
+てつだい;tetsudai
+てつだう;tetsudau
+てつづき;tetsuduki
+てつどう;tetsudou
+てつや;tetsuya
+てぬぐい;tenugui
+てぶくろ;tebukuro
+てま;tema
+てまえ;temae
+てら;tera
+てらす;terasu
+てる;teru
+てん;ten
+てん;ten
+てんいん;ten_in
+てんかい;tenkai
+てんき;tenki
+てんけい;tenkei
+てんこう;tenkou
+てんじょう;tenjou
+てんすう;tensuu
+てんてん;tenten
+てんてん;tenten
+てんねん;tennen
+てんらんかい;tenrankai
+で;de
+であい;deai
+であう;deau
+であう;deau
+でいり;deiri
+でいりぐち;deiriguchi
+でかける;dekakeru
+できあがり;dekiagari
+できあがる;dekiagaru
+できごと;dekigoto
+できる;dekiru
+できるだけ;dekirudake
+でぐち;deguchi
+でこぼこ;dekoboko
+ですから;desukara
+でたらめ;detarame
+では(でわ);deha(dewa)
+でむかえ;demukae
+でむかえる;demukaeru
+でも;demo
+でる;deru
+でんき;denki
+でんき;denki
+でんきゅう;denkyuu
+でんし;denshi
+でんしゃ;densha
+でんせん;densen
+でんせん;densen
+でんち;denchi
+でんちゅう;denchuu
+でんとう;dentou
+でんとう;dentou
+でんぱ;denpa
+でんぽう;denpou
+でんりゅう;denryuu
+でんりょく;denryoku
+でんわ;denwa
+と;to
+とい;toi
+といあわせ;toiawase
+とう;tou
+とう;tou
+とう;tou
+とうあん;touan
+とういつ;touitsu
+とうけい;toukei
+とうげ;touge
+とうざい;touzai
+とうしょ;tousho
+とうじ;touji
+とうじつ;toujitsu
+とうじょう;toujou
+とうだい;toudai
+とうちゃく;touchaku
+とうとう;toutou
+とうなん;tounan
+とうばん;touban
+とうひょう;touhyou
+とうぶん;toubun
+とうめい;toumei
+とうゆ;touyu
+とうよう;touyou
+とおい;tooi
+とおか;tooka
+とおく;tooku
+とおす;toosu
+とおり;toori
+とおりかかる;toorikakaru
+とおりすぎる;toorisugiru
+とおる;tooru
+とかい;tokai
+とかす;tokasu
+とがる;togaru
+とき;toki
+ときどき;tokidoki
+とく;toku
+とく;toku
+とくい;tokui
+とくしゅ;tokushu
+とくしょく;tokushoku
+とくちょう;tokuchou
+とくてい;tokutei
+とくばい;tokubai
+とくべつ;tokubetsu
+とけい;tokei
+とけこむ;tokekomu
+とける;tokeru
+とける;tokeru
+とこ;toko
+とこのま;tokonoma
+とこや;tokoya
+ところ;tokoro
+ところが;tokoroga
+ところで;tokorode
+とざん;tozan
+とし;toshi
+とし;toshi
+としつき;toshitsuki
+としょ;tosho
+としより;toshiyori
+としん;toshin
+とじょう;tojou
+とじる;tojiru
+とたん;totan
+とだな;todana
+とち;tochi
+とっきゅう;tokkyuu
+とっくに;tokkuni
+とつぜん;totsuzen
+とても;totemo
+ととのう;totonou
+とどく;todoku
+とどける;todokeru
+とどまる;todomaru
+とどまる;todomaru
+とどめる;todomeru
+とどめる;todomeru
+となり;tonari
+とにかく;tonikaku
+とばす;tobasu
+とばり;tobari
+とばり;tobari
+とびこむ;tobikomu
+とびだす;tobidasu
+とぶ;tobu
+とぶ;tobu
+とまる;tomaru
+とめる;tomeru
+とも;tomo
+ともかく;tomokaku
+ともしび;tomoshibi
+ともだち;tomodachi
+ともに;tomoni
+とら;tora
+とらえる;toraeru
+とり;tori
+とりあげる;toriageru
+とりいれる;toriireru
+とりかえる;torikaeru
+とりけす;torikesu
+とりだす;toridasu
+とりわけ;toriwake
+とる;toru
+とる;toru
+とる;toru
+とる;toru
+とれる;toreru
+とんでもない;tondemonai
+どう;dou
+どう;dou
+どういたしまして;douitashimashite
+どういつ;douitsu
+どうか;douka
+どうかく;doukaku
+どうぐ;dougu
+どうさ;dousa
+どうし;doushi
+どうして;doushite
+どうしても;doushitemo
+どうじ;douji
+どうせ;douse
+どうぞ;douzo
+どうぞよろしく;douzoyoroshiku
+どうとく;doutoku
+どうぶつ;doubutsu
+どうも;doumo
+どうよう;douyou
+どうよう;douyou
+どうりょう;douryou
+どうろ;douro
+どうわ;douwa
+どきどき;dokidoki
+どく;doku
+どくしょ;dokusho
+どくしん;dokushin
+どくとく;dokutoku
+どくりつ;dokuritsu
+どこ;doko
+どこか;dokoka
+どさん;dosan
+どちら;dochira
+どっと;dotto
+どなた;donata
+どなる;donaru
+どの;dono
+どよう;doyou
+どりょく;doryoku
+どれ;dore
+どれどれ;doredore
+どろ;doro
+どろぼう;dorobou
+どんどん;dondon
+どんな;donna
+どんなに;donnani
+どんぶり;donburi
+な;na
+ない;nai
+ないか;naika
+ないせん;naisen
+ないよう;naiyou
+なお;nao
+なおす;naosu
+なおす;naosu
+なおる;naoru
+なおる;naoru
+なか;naka
+なかなおり;nakanaori
+なかなか;nakanaka
+なかば;nakaba
+なかみ;nakami
+なかみ;nakami
+なかよし;nakayoshi
+ながい;nagai
+ながい;nagai
+ながす;nagasu
+ながびく;nagabiku
+ながめ;nagame
+ながめる;nagameru
+ながれ;nagare
+ながれる;nagareru
+なく;naku
+なく;naku
+なくす;nakusu
+なくす;nakusu
+なくなる;nakunaru
+なぐさめる;nagusameru
+なぐる;naguru
+なげる;nageru
+なさる;nasaru
+なし;nashi
+なす;nasu
+なぜ;naze
+なぜなら;nazenara
+なぞ;nazo
+なぞなぞ;nazonazo
+なっとく;nattoku
+なつ;natsu
+なつかしい;natsukashii
+なでる;naderu
+ななつ;nanatsu
+ななめ;naname
+なに;nani
+なにしろ;nanishiro
+なにぶん;nanibun
+なにも;nanimo
+なぬか;nanuka
+なべ;nabe
+なまいき;namaiki
+なまえ;namae
+なまける;namakeru
+なみ;nami
+なみき;namiki
+なみだ;namida
+なやむ;nayamu
+ならう;narau
+ならう;narau
+ならし;narashi
+ならす;narasu
+ならぶ;narabu
+ならべる;naraberu
+なる;naru
+なる;naru
+なる;naru
+なるべく;narubeku
+なるほど;naruhodo
+なれる;nareru
+なれる;nareru
+なわ;nawa
+なん;nan
+なんきょく;nankyoku
+なんて;nante
+なんで;nande
+なんでも;nandemo
+なんとか;nantoka
+なんとなく;nantonaku
+なんとも;nantomo
+なんべい;nanbei
+なんぼく;nanboku
+に;ni
+に;ni
+にあう;niau
+におい;nioi
+におう;niou
+にがい;nigai
+にがす;nigasu
+にがて;nigate
+にぎやか;nigiyaka
+にぎる;nigiru
+にく;niku
+にくい;nikui
+にくい;nikui
+にくむ;nikumu
+にくらしい;nikurashii
+にげる;nigeru
+にごる;nigoru
+にし;nishi
+にじ;niji
+にちじ;nichiji
+にちじょう;nichijou
+にちや;nichiya
+にちようひん;nichiyouhin
+にっか;nikka
+にっき;nikki
+にっこう;nikkou
+にっこり;nikkori
+にっちゅう;nicchuu
+にってい;nittei
+にっとう;nittou
+にっぽん;nippon
+ににん;ninin
+にぶい;nibui
+にもつ;nimotsu
+にゅういん;nyuuin
+にゅうがく;nyuugaku
+にゅうしゃ;nyuusha
+にゅうじょう;nyuujou
+にょうぼう;nyoubou
+にらむ;niramu
+にる;niru
+にる;niru
+にわ;niwa
+にわか;niwaka
+ねんれい;nenrei
+の;no
+のう;nou
+のうか;nouka
+のうぎょう;nougyou
+のうさんぶつ;nousanbutsu
+のうそん;nouson
+のうど;noudo
+のうみん;noumin
+のうやく;nouyaku
+のうりつ;nouritsu
+のうりょく;nouryoku
+のき;noki
+のこぎり;nokogiri
+のこす;nokosu
+のこらず;nokorazu
+のこり;nokori
+のこる;nokoru
+のせる;noseru
+のせる;noseru
+のぞく;nozoku
+のぞく;nozoku
+のぞみ;nozomi
+のぞむ;nozomu
+のど;nodo
+のばす;nobasu
+のばす;nobasu
+のびる;nobiru
+のびる;nobiru
+のべる;noberu
+のぼり;nobori
+のぼる;noboru
+のぼる;noboru
+のぼる;noboru
+のむ;nomu
+のり;nori
+のりかえ;norikae
+のりかえる;norikaeru
+のりこし;norikoshi
+のる;noru
+のる;noru
+のろのろ;noronoro
+のんき;nonki
+のんびり;nonbiri
+は;ha
+は;ha
+はい;hai
+はいいろ;haiiro
+はいく;haiku
+はいけん;haiken
+はいさら;haisara
+はいたつ;haitatsu
+はいゆう;haiyuu
+はう;hau
+はえる;haeru
+はか;haka
+はかせ;hakase
+はかり;hakari
+はかる;hakaru
+はかる;hakaru
+はかる;hakaru
+はがき;hagaki
+はがす;hagasu
+はきけ;hakike
+はきはき;hakihaki
+はく;haku
+はく;haku
+はく;haku
+はくしゅ;hakushu
+はくぶつかん;hakubutsukan
+はぐるま;haguruma
+はげしい;hageshii
+はこ;hako
+はこぶ;hakobu
+はさまる;hasamaru
+はさみ;hasami
+はさん;hasan
+はし;hashi
+はし;hashi
+はし;hashi
+はしら;hashira
+はしる;hashiru
+はじく;hajiku
+はじまり;hajimari
+はじまる;hajimaru
+はじめ;hajime
+はじめて;hajimete
+はじめまして;hajimemashite
+はじめる;hajimeru
+はす;hasu
+はず;hazu
+はずかしい;hazukashii
+はずす;hazusu
+はずれる;hazureru
+はた;hata
+はた;hata
+はたけ;hatake
+はたして;hatashite
+はたち;hatachi
+はたらき;hataraki
+はたらく;hataraku
+はだ;hada
+はだか;hadaka
+はだぎ;hadagi
+はち;hachi
+はち;hachi
+はっき;hakki
+はっきり;hakkiri
+はっけん;hakken
+はっこう;hakkou
+はっしゃ;hassha
+はっしゃ;hassha
+はっそう;hassou
+はったつ;hattatsu
+はってん;hatten
+はっぴょう;happyou
+はつ;hatsu
+はつ;hatsu
+はついく;hatsuiku
+はつおん;hatsuon
+はつか;hatsuka
+はつでん;hatsuden
+はつばい;hatsubai
+はつめい;hatsumei
+はで;hade
+はな;hana
+はな;hana
+はなし;hanashi
+はなしあい;hanashiai
+はなしあう;hanashiau
+はなしかける;hanashikakeru
+はなしちゅう;hanashichuu
+はなす;hanasu
+はなす;hanasu
+はなす;hanasu
+はなはだしい;hanahadashii
+はなばなしい;hanabanashii
+はなび;hanabi
+はなみ;hanami
+はなやか;hanayaka
+はなよめ;hanayome
+はなれる;hanareru
+はなれる;hanareru
+はね;hane
+はねる;haneru
+はは;haha
+ははおや;hahaoya
+はば;haba
+はぶく;habuku
+はへん;hahen
+はみがき;hamigaki
+はめる;hameru
+はやい;hayai
+はやい;hayai
+はやくち;hayakuchi
+はやし;hayashi
+はやり;hayari
+はやる;hayaru
+はら;hara
+はらいこむ;haraikomu
+はらいもどす;haraimodosu
+はらう;harau
+はり;hari
+はりがね;harigane
+はりきる;harikiru
+はる;haru
+はる;haru
+はる;haru
+はれ;hare
+はれる;hareru
+はん;han
+はんい;han_i
+はんえい;han_ei
+はんけい;hankei
+はんこ;hanko
+はんこう;hankou
+はんざい;hanzai
+はんじ;hanji
+はんせい;hansei
+はんたい;hantai
+はんだん;handan
+はんとう;hantou
+はんにん;hannin
+はんばい;hanbai
+はんぶん;hanbun
+ば;ba
+ばあい;baai
+ばい;bai
+ばいてん;baiten
+ばいばい;baibai
+ばか;baka
+ばからしい;bakarashii
+ばくだい;bakudai
+ばくはつ;bakuhatsu
+ばしょ;basho
+ばち;bachi
+ばっする;bassuru
+ばったり;battari
+ばね;bane
+ばめん;bamen
+ばん;ban
+ばん;ban
+ばん;ban
+ばんぐみ;bangumi
+ばんごう;bangou
+ばんざい;banzai
+ばんち;banchi
+ばんめ;banme
+ひ;hi
+ひ;hi
+ひ;hi
+ひ;hi
+ひえる;hieru
+ひかく;hikaku
+ひかくてき;hikakuteki
+ひかげ;hikage
+ひかり;hikari
+ひかる;hikaru
+ひがい;higai
+ひがえり;higaeri
+ひき;hiki
+ひきうける;hikiukeru
+ひきかえす;hikikaesu
+ひきざん;hikizan
+ひきだし;hikidashi
+ひきだす;hikidasu
+ひきとめる;hikitomeru
+ひきょう;hikyou
+ひきわけ;hikiwake
+ひく;hiku
+ひく;hiku
+ひくい;hikui
+ひけつ;hiketsu
+ひげ;hige
+ひげき;higeki
+ひこう;hikou
+ひこうじょう;hikoujou
+ひさしぶり;hisashiburi
+ひざ;hiza
+ひざし;hizashi
+ひじ;hiji
+ひじょう;hijou
+ひだり;hidari
+ひっかかる;hikkakaru
+ひっかける;hikkakeru
+ひっき;hikki
+ひっくりかえす;hikkurikaesu
+ひっくりかえる;hikkurikaeru
+ひっこし;hikkoshi
+ひっこす;hikkosu
+ひっこむ;hikkomu
+ひっし;hisshi
+ひっしゃ;hissha
+ひっぱる;hipparu
+ひつじ;hitsuji
+ひつじゅひん;hitsujuhin
+ひつよう;hitsuyou
+ひてい;hitei
+ひとごみ;hitogomi
+ひとさしゆび;hitosashiyubi
+ひとしい;hitoshii
+ひとすき;hitosuki
+ひとつ;hitotsu
+ひととおり;hitotoori
+ひとどおり;hitodoori
+ひとまず;hitomazu
+ひとみ;hitomi
+ひとやすみ;hitoyasumi
+ひとり;hitori
+ひとりごと;hitorigoto
+ひとりでに;hitorideni
+ひとりひとり;hitorihitori
+ひどい;hidoi
+ひにく;hiniku
+ひにち;hinichi
+ひねる;hineru
+ひのいり;hinoiri
+ひので;hinode
+ひはん;hihan
+ひひょう;hihyou
+ひび;hibi
+ひびき;hibiki
+ひびく;hibiku
+ひふ;hifu
+ひみつ;himitsu
+ひも;himo
+ひゃく;hyaku
+ひゃっかじてん;hyakkajiten
+ひゃっかじてん;hyakkajiten
+ひやす;hiyasu
+ひょうか;hyouka
+ひょうげん;hyougen
+ひょうご;hyougo
+ひょうし;hyoushi
+ひょうしき;hyoushiki
+ひょうじゅん;hyoujun
+ひょうじょう;hyoujou
+ひょうばん;hyouban
+ひょうほん;hyouhon
+ひょうめん;hyoumen
+ひょうろん;hyouron
+ひよう;hiyou
+ひらがな;hiragana
+ひらく;hiraku
+ひる;hiru
+ひるね;hirune
+ひろい;hiroi
+ひろう;hirou
+ひろがる;hirogaru
+ひろげる;hirogeru
+ひろさ;hirosa
+ひろば;hiroba
+ひろびろ;hirobiro
+ひろめる;hiromeru
+びじん;bijin
+びっくり;bikkuri
+びみょう;bimyou
+びょう;byou
+びょういん;byouin
+びょうき;byouki
+びょうどう;byoudou
+びよう;biyou
+びん;bin
+びんせん;binsen
+びんづめ;bindume
+ぴかぴか;pikapika
+ぴったり;pittari
+ふ;fu
+ふあん;fuan
+ふうけい;fuukei
+ふうせん;fuusen
+ふうぞく;fuuzoku
+ふうとう;fuutou
+ふうふ;fuufu
+ふうん;fuun
+ふえ;fue
+ふえる;fueru
+ふえる;fueru
+ふか;fuka
+ふかい;fukai
+ふかまる;fukamaru
+ふきそく;fukisoku
+ふきゅう;fukyuu
+ふきん;fukin
+ふく;fuku
+ふく;fuku
+ふく;fuku
+ふくざつ;fukuzatsu
+ふくし;fukushi
+ふくしゃ;fukusha
+ふくしゅう;fukushuu
+ふくすう;fukusuu
+ふくそう;fukusou
+ふくむ;fukumu
+ふくめる;fukumeru
+ふくらます;fukuramasu
+ふくらむ;fukuramu
+ふくろ;fukuro
+ふけつ;fuketsu
+ふける;fukeru
+ふける;fukeru
+ふこう;fukou
+ふごう;fugou
+ふさい;fusai
+ふさがる;fusagaru
+ふさぐ;fusagu
+ふざける;fuzakeru
+ふしぎ;fushigi
+ふじゆう;fujiyuu
+ふじん;fujin
+ふじん;fujin
+ふすま;fusuma
+ふせい;fusei
+ふせぐ;fusegu
+ふそく;fusoku
+ふぞく;fuzoku
+ふたご;futago
+ふたたび;futatabi
+ふたつ;futatsu
+ふだん;fudan
+ふつ;futsu
+ふつう;futsuu
+ふつう;futsuu
+ふつか;futsuka
+ふで;fude
+ふと;futo
+ふとい;futoi
+ふとう;futou
+ふとる;futoru
+ふとん;futon
+ふなびん;funabin
+ふね;fune
+ふね;fune
+ふびん;fubin
+ふぶき;fubuki
+ふへい;fuhei
+ふまん;fuman
+ふみ;fumi
+ふみきり;fumikiri
+ふむ;fumu
+ふもと;fumoto
+ふやす;fuyasu
+ふやす;fuyasu
+ふゆ;fuyu
+ふり;furi
+ふり;furi
+ふりがな;furigana
+ふりむく;furimuku
+ふりょう;furyou
+ふる;furu
+ふる;furu
+ふるい;furui
+ふるえる;furueru
+ふるまう;furumau
+ふれる;fureru
+ふろ;furo
+ふろしき;furoshiki
+ふん;fun
+ふんいき;fun_iki
+ふんか;funka
+ふんすい;funsui
+ぶ;bu
+ぶき;buki
+ぶさた;busata
+ぶし;bushi
+ぶしゅ;bushu
+ぶじ;buji
+ぶたい;butai
+ぶっか;bukka
+ぶっしつ;busshitsu
+ぶっそう;bussou
+ぶつ;butsu
+ぶつかる;butsukaru
+ぶつける;butsukeru
+ぶつぶつ;butsubutsu
+ぶつり;butsuri
+ぶひん;buhin
+ぶぶん;bubun
+ぶらさげる;burasageru
+ぶんか;bunka
+ぶんかい;bunkai
+ぶんがく;bungaku
+ぶんけん;bunken
+ぶんげい;bungei
+ぶんしょう;bunshou
+ぶんすう;bunsuu
+ぶんせき;bunseki
+ぶんたい;buntai
+ぶんたん;buntan
+ぶんぷ;bunpu
+ぶんぼうぐ;bunbougu
+ぶんぽう;bunpou
+ぶんみゃく;bunmyaku
+ぶんめい;bunmei
+ぶんや;bun_ya
+ぶんりょう;bunryou
+ぶんるい;bunrui
+へい;hei
+へいかい;heikai
+へいき;heiki
+へいこう;heikou
+へいじつ;heijitsu
+へいたい;heitai
+へいぼん;heibon
+へいや;heiya
+へいわ;heiwa
+へこむ;hekomu
+へそ;heso
+へた;heta
+へだたる;hedataru
+へだてる;hedateru
+へや;heya
+へらす;herasu
+へる;heru
+へる;heru
+へん;hen
+へん;hen
+へん;hen
+へん;hen
+へんか;henka
+へんこう;henkou
+へんしゅう;henshuu
+へんじ;henji
+べっそう;bessou
+べつ;betsu
+べつに;betsuni
+べつべつ;betsubetsu
+べんきょう;benkyou
+べんじょ;benjo
+べんとう;bentou
+べんり;benri
+ほう;hou
+ほう;hou
+ほうがく;hougaku
+ほうき;houki
+ほうげん;hougen
+ほうこう;houkou
+ほうこく;houkoku
+ほうしん;houshin
+ほうせき;houseki
+ほうそう;housou
+ほうそう;housou
+ほんとう;hontou
+ほんにん;honnin
+ほんの;honno
+ほんぶ;honbu
+ほんもの;honmono
+ほんやく;hon_yaku
+ほんらい;honrai
+ぼう;bou
+ぼう;bou
+ぼうえんきょう;bouenkyou
+ぼうけん;bouken
+ぼうさん;bousan
+ぼうし;boushi
+ぼうし;boushi
+ぼうだい;boudai
+ぼうはん;bouhan
+ぼうや;bouya
+ぼうりょく;bouryoku
+ぼくじょう;bokujou
+ぼくちく;bokuchiku
+ぼしゅう;boshuu
+ぼっちゃん;bocchan
+ぼろ;boro
+ぼん;bon
+ぼんち;bonchi
+まあ;maa
+まあまあ;maamaa
+まい;mai
+まいご;maigo
+まいすう;maisuu
+まいる;mairu
+まう;mau
+まかせる;makaseru
+まかなう;makanau
+まがる;magaru
+まき;maki
+まく;maku
+まく;maku
+まく;maku
+まくら;makura
+まけ;make
+まける;makeru
+まげる;mageru
+まご;mago
+まごまご;magomago
+まさか;masaka
+まさつ;masatsu
+まさに;masani
+まざる;mazaru
+まざる;mazaru
+まし;mashi
+まじる;majiru
+まじる;majiru
+ます;masu
+ますます;masumasu
+まず;mazu
+まずい;mazui
+まずしい;mazushii
+まぜる;mazeru
+まぜる;mazeru
+また;mata
+またぐ;matagu
+または;mataha
+まだ;mada
+まち;machi
+まちあいしつ;machiaishitsu
+まちあわせる;machiawaseru
+まちかど;machikado
+まちがい;machigai
+まちがう;machigau
+まちがえる;machigaeru
+まっか;makka
+まっくら;makkura
+まっくろ;makkuro
+まっさお;massao
+まっさき;massaki
+まっしろ;masshiro
+まっすぐ;massugu
+まったく;mattaku
+まつ;matsu
+まつ;matsu
+まつり;matsuri
+まつる;matsuru
+まとまる;matomaru
+まとめる;matomeru
+まど;mado
+まどぐち;madoguchi
+まなぶ;manabu
+まにあう;maniau
+まね;mane
+まねく;maneku
+まねる;maneru
+まぶしい;mabushii
+まぶた;mabuta
+まま;mama
+まめ;mame
+まもなく;mamonaku
+まもる;mamoru
+まよう;mayou
+まる;maru
+まるい;marui
+まるで;marude
+まれ;mare
+まわす;mawasu
+まわり;mawari
+まわりみち;mawarimichi
+まわる;mawaru
+まんいん;man_in
+まんが;manga
+まんぞく;manzoku
+まんてん;manten
+まんなか;mannaka
+まんねんひつ;mannenhitsu
+まんまえ;manmae
+まんまるい;manmarui
+み;mi
+み;mi
+みあげる;miageru
+みえる;mieru
+みおくり;miokuri
+みおくる;miokuru
+みおろす;miorosu
+みかけ;mikake
+みかずき;mikazuki
+みかた;mikata
+みかた;mikata
+みがく;migaku
+みぎ;migi
+みごと;migoto
+みさき;misaki
+みじかい;mijikai
+みじめ;mijime
+みず;mizu
+みずうみ;mizuumi
+みずから;mizukara
+みずぎ;mizugi
+みせや;miseya
+みせる;miseru
+みそ;miso
+みだし;midashi
+みち;michi
+みちじゅん;michijun
+みちる;michiru
+みっか;mikka
+みっつ;mittsu
+みっともない;mittomonai
+みつ;mitsu
+みつかる;mitsukaru
+みつける;mitsukeru
+みつめる;mitsumeru
+みどり;midori
+みな;mina
+みなおす;minaosu
+みなと;minato
+みなれる;minareru
+みにくい;minikui
+みのる;minoru
+みぶん;mibun
+みほん;mihon
+みまい;mimai
+みまう;mimau
+みまん;miman
+みみ;mimi
+みょう;myou
+みょうじ;myouji
+みらい;mirai
+みりょく;miryoku
+みる;miru
+みる;miru
+みんかん;minkan
+みんしゅ;minshu
+みんよう;min_you
+む;mu
+むいか;muika
+むかい;mukai
+むかう;mukau
+むかえ;mukae
+むかえる;mukaeru
+むかし;mukashi
+むき;muki
+むく;muku
+むく;muku
+むけ;muke
+むける;mukeru
+むげん;mugen
+むこう;mukou
+むし;mushi
+むし;mushi
+むしあつい;mushiatsui
+むしば;mushiba
+むしろ;mushiro
+むじ;muji
+むじゅん;mujun
+むす;musu
+むすう;musuu
+むすこ;musuko
+むすぶ;musubu
+むすめ;musume
+むずかしい;muzukashii
+むだ;muda
+むちゅう;muchuu
+むっつ;muttsu
+むね;mune
+むら;mura
+むらさき;murasaki
+むり;muri
+むりょう;muryou
+め;me
+め;me
+めい;mei
+めいかく;meikaku
+めいさく;meisaku
+めいし;meishi
+めいし;meishi
+めいしょ;meisho
+めいしん;meishin
+めいじる;meijiru
+めいじん;meijin
+めいずる;meizuru
+めいぶつ;meibutsu
+めいめい;meimei
+めいれい;meirei
+めいわく;meiwaku
+めうえ;meue
+めぐまれる;megumareru
+めぐる;meguru
+めざす;mezasu
+めざまし;mezamashi
+めし;meshi
+めしあがる;meshiagaru
+めした;meshita
+めじるし;mejirushi
+めずらしい;mezurashii
+めだつ;medatsu
+めちゃくちゃ;mechakucha
+めっきり;mekkiri
+めったに;mettani
+めでたい;medetai
+めまい;memai
+めやす;meyasu
+めん;men
+めんきょ;menkyo
+めんせき;menseki
+めんせつ;mensetsu
+めんぜい;menzei
+めんどう;mendou
+めんどうくさい;mendoukusai
+もう;mou
+もうかる;moukaru
+もうける;moukeru
+もうける;moukeru
+もうしあげる;moushiageru
+もうしこむ;moushikomu
+もうしわけ;moushiwake
+もうしわけない;moushiwakenai
+もうす;mousu
+もうふ;moufu
+もえる;moeru
+もくざい;mokuzai
+もくじ;mokuji
+もくてき;mokuteki
+もくひょう;mokuhyou
+もくよう;mokuyou
+もし;moshi
+もしかしたら;moshikashitara
+もしかすると;moshikasuruto
+もしも;moshimo
+もしもし;moshimoshi
+もじ;moji
+もたれる;motareru
+もち;mochi
+もちあげる;mochiageru
+もちいる;mochiiru
+もちろん;mochiron
+もったいない;mottainai
+もって;motte
+もっと;motto
+もっとも;mottomo
+もっとも;mottomo
+もつ;motsu
+もと;moto
+もとい;motoi
+もとづく;motoduku
+もとめる;motomeru
+もともと;motomoto
+もどす;modosu
+もどる;modoru
+もの;mono
+もの;mono
+ものおき;monooki
+ものおと;monooto
+ものがたり;monogatari
+ものがたる;monogataru
+ものごと;monogoto
+ものさし;monosashi
+ものすごい;monosugoi
+もむ;momu
+もも;momo
+もやす;moyasu
+もよう;moyou
+もよおし;moyooshi
+もらう;morau
+もり;mori
+もん;mon
+もんく;monku
+もんだい;mondai
+もんどう;mondou
+や;ya
+やおや;yaoya
+やかましい;yakamashii
+やかん;yakan
+やがて;yagate
+やぎょう;yagyou
+やく;yaku
+やく;yaku
+やくしゃ;yakusha
+やくしょ;yakusho
+やくす;yakusu
+やくそく;yakusoku
+やくだつ;yakudatsu
+やくにん;yakunin
+やくひん;yakuhin
+やくめ;yakume
+やくわり;yakuwari
+やける;yakeru
+やさい;yasai
+やさしい;yasashii
+やさしい;yasashii
+やしろ;yashiro
+やじるし;yajirushi
+やすい;yasui
+やすい;yasui
+やすみ;yasumi
+やすむ;yasumu
+やせる;yaseru
+やたらに;yatarani
+やちゅう;yachuu
+やちん;yachin
+やっかい;yakkai
+やっきょく;yakkyoku
+やっつ;yattsu
+やっつける;yattsukeru
+やっと;yatto
+やっぱり;yappari
+やとう;yatou
+やど;yado
+やね;yane
+やぶる;yaburu
+やぶれる;yabureru
+やま;yama
+やまい;yamai
+やむ;yamu
+やむ;yamu
+やむをえない;yamuwoenai
+やめる;yameru
+やや;yaya
+やる;yaru
+やわらかい;yawarakai
+やわらかい;yawarakai
+ゆ;yu
+ゆいいつ;yuiitsu
+ゆうえんち;yuuenchi
+ゆうかん;yuukan
+ゆうがた;yuugata
+ゆうき;yuuki
+ゆうこう;yuukou
+ゆうこう;yuukou
+ゆうしゅう;yuushuu
+ゆうしょう;yuushou
+ゆうじょう;yuujou
+ゆうじん;yuujin
+ゆうそう;yuusou
+ゆうだち;yuudachi
+ゆうのう;yuunou
+ゆうひ;yuuhi
+ゆうびん;yuubin
+ゆうべ;yuube
+ゆうめい;yuumei
+ゆうゆう;yuuyuu
+ゆうり;yuuri
+ゆうりょう;yuuryou
+ゆかい;yukai
+ゆかた;yukata
+ゆき;yuki
+ゆくえ;yukue
+ゆけつ;yuketsu
+ゆげ;yuge
+ゆしゅつ;yushutsu
+ゆずる;yuzuru
+ゆそう;yusou
+ゆたか;yutaka
+ゆだん;yudan
+ゆっくり;yukkuri
+ゆでる;yuderu
+ゆにゅう;yunyuu
+ゆのみ;yunomi
+ゆび;yubi
+ゆびわ;yubiwa
+ゆめ;yume
+ゆるい;yurui
+ゆるす;yurusu
+ゆれる;yureru
+よあけ;yoake
+よい;yoi
+よう;you
+よう;you
+ようい;youi
+ようい;youi
+ようか;youka
+ようがん;yougan
+ようき;youki
+ようき;youki
+ようきゅう;youkyuu
+ようご;yougo
+ようし;youshi
+ようじ;youji
+ようじ;youji
+ようじん;youjin
+ようす;yousu
+ようする;yousuru
+ようするに;yousuruni
+ようせき;youseki
+ようそ;youso
+ようち;youchi
+ようちえん;youchien
+ようてん;youten
+ようと;youto
+ようひんてん;youhinten
+ようび;youbi
+ようふく;youfuku
+ようぶん;youbun
+ようもう;youmou
+ようやく;youyaku
+ようりょう;youryou
+よき;yoki
+よく;yoku
+よくばり;yokubari
+よけい;yokei
+よこ;yoko
+よこぎる;yokogiru
+よこす;yokosu
+よさん;yosan
+よしゅう;yoshuu
+よす;yosu
+よせる;yoseru
+よそ;yoso
+よそく;yosoku
+よっか;yokka
+よっつ;yottsu
+よっぱらい;yopparai
+よつかど;yotsukado
+よてい;yotei
+よのなか;yononaka
+よび;yobi
+よびかける;yobikakeru
+よびだす;yobidasu
+よぶ;yobu
+よぶん;yobun
+よほう;yohou
+よぼう;yobou
+よみ;yomi
+よみがえる;yomigaeru
+よむ;yomu
+よめ;yome
+よやく;yoyaku
+よゆう;yoyuu
+より;yori
+よる;yoru
+よる;yoru
+よる;yoru
+よると;yoruto
+よろこび;yorokobi
+よろこぶ;yorokobu
+よろしい;yoroshii
+よろしく;yoroshiku
+よわい;yowai
+らい;rai
+らいにち;rainichi
+らく;raku
+らくだい;rakudai
+らん;ran
+らんぼう;ranbou
+りえき;rieki
+りか;rika
+りかい;rikai
+りがい;rigai
+りく;riku
+りこう;rikou
+りこん;rikon
+りそう;risou
+りっぱ;rippa
+りつ;ritsu
+りゃくす;ryakusu
+りゅう;ryuu
+りゅういき;ryuuiki
+りゅうがく;ryuugaku
+りゆう;riyuu
+りょう;ryou
+りょう;ryou
+りょう;ryou
+りょうがえ;ryougae
+りょうがわ;ryougawa
+りょうきん;ryoukin
+りょうし;ryoushi
+りょうしゅう;ryoushuu
+りょうじ;ryouji
+りょうり;ryouri
+りょかん;ryokan
+りょこう;ryokou
+りよう;riyou
+りん;rin
+りんじ;rinji
+るす;rusu
+るすばん;rusuban
+れい;rei
+れい;rei
+れいがい;reigai
+れいぎ;reigi
+れいせい;reisei
+れいぞうこ;reizouko
+れいてん;reiten
+れいとう;reitou
+れいぼう;reibou
+れきし;rekishi
+れっしゃ;ressha
+れっとう;rettou
+れつ;retsu
+れんが;renga
+れんごう;rengou
+れんしゅう;renshuu
+れんそう;rensou
+れんぞく;renzoku
+れんらく;renraku
+ろうか;rouka
+ろうじん;roujin
+ろうそく;rousoku
+ろうどう;roudou
+ろくおん;rokuon
+ろんじる;ronjiru
+ろんずる;ronzuru
+ろんそう;ronsou
+ろんぶん;ronbun
+わ;wa
+わえい;waei
+わかい;wakai
+わかす;wakasu
+わかる;wakaru
+わかれ;wakare
+わかれる;wakareru
+わかれる;wakareru
+わかわかしい;wakawakashii
+わが;waga
+わがまま;wagamama
+わき;waki
+わく;waku
+わく;waku
+わけ;wake
+わける;wakeru
+わざと;wazato
+わすれもの;wasuremono
+わすれる;wasureru
+わずか;wazuka
+わたす;watasu
+わたる;wataru
+わだい;wadai
+わびる;wabiru
+わふく;wafuku
+わらい;warai
+わらう;warau
+わりあい;wariai
+わりあいに;wariaini
+わりあて;wariate
+わりこむ;warikomu
+わりざん;warizan
+わりびき;waribiki
+わる;waru
+われる;wareru
+われわれ;wareware
+わん;wan
+わん;wan
+わん;wan
+アイスクリーム;aisukuriimu
+アイデア;aidea
+アイロン;airon
+アウト;auto
+アクセサリー;akusesarii
+アクセント;akusento
+アジア;ajia
+アナウンサー;anaunsaa
+アパート;apaato
+アフリカ;afurika
+アメリカ;amerika
+アルバイト;arubaito
+アルバム;arubamu
+アンテナ;antena
+イコール;ikooru
+イメージ;imeeji
+インク;inku
+インタビュー;intabyuu
+ウーマン;uuman
+ウール;uuru
+ウイスキー;uisukii
+ウェートレス;weetoresu
+エスカレーター;esukareetaa
+エチケット;echiketto
+エネルギー;enerugii
+エプロン;epuron
+エレベーター;erebeetaa
+エンジン;enjin
+オーケストラ;ookesutora
+オートバイ;ootobai
+オートメーション;ootomeeshon
+オイル;oiru
+オフィス;ofisu
+オルガン;orugan
+オレンジ;orenji
+カー;kaa
+カーテン;kaaten
+カード;kaado
+カーブ;kaabu
+カセット;kasetto
+カバー;kabaa
+カメラ;kamera
+カラー;karaa
+カレンダー;karendaa
+カロリー;karorii
+ガス;gasu
+ガソリン;gasorin
+ガソリンスタンド;gasorinsutando
+ガム;gamu
+ガラス;garasu
+キャプテン;kyaputen
+キャンパス;kyanpasu
+キャンプ;kyanpu
+キロ;kiro
+ギター;gitaa
+ギャング;gyangu
+クーラー;kuuraa
+クラス;kurasu
+クラブ;kurabu
+クリーニング;kuriiningu
+クリーム;kuriimu
+クリスマス;kurisumasu
+グラス;gurasu
+グラフ;gurafu
+グラム;guramu
+グランド;gurando
+グループ;guruupu
+ケーキ;keeki
+ケース;keesu
+ゲーム;geemu
+コース;koosu
+コーチ;koochi
+コート;kooto
+コード;koodo
+コーヒー;koohii
+コーラス;koorasu
+コック;kokku
+コップ;koppu
+コピー;kopii
+コミュニケーション;komyunikeeshon
+コレクション;korekushon
+コンクール;konkuuru
+コンクリート;konkuriito
+コンサート;konsaato
+コンセント;konsento
+コンピューター;konpyuutaa
+ゴム;gomu
+サークル;saakuru
+サービス;saabisu
+サイレン;sairen
+サイン;sain
+サラダ;sarada
+サラリーマン;sarariiman
+サンダル;sandaru
+サンドイッチ;sandoicchi
+サンプル;sanpuru
+シーズン;shiizun
+シーツ;shiitsu
+シャッター;shattaa
+シャツ;shatsu
+シャワー;shawaa
+ショップ;shoppu
+シリーズ;shiriizu
+ジーンズ;jiinzu
+ジェットき;jettoki
+ジャーナリスト;jaanarisuto
+ジャム;jamu
+ジュース;juusu
+スーツ;suutsu
+スーツケース;suutsukeesu
+スーパー;suupaa
+スープ;suupu
+スイッチ;suicchi
+スカート;sukaato
+スカーフ;sukaafu
+スキー;sukii
+スクール;sukuuru
+スケート;sukeeto
+スケジュール;sukejuuru
+スター;sutaa
+スタート;sutaato
+スタイル;sutairu
+スタンド;sutando
+スチュワーデス;suchuwaadesu
+ステージ;suteeji
+ステレオ;sutereo
+ストーブ;sutoobu
+ストッキング;sutokkingu
+ストップ;sutoppu
+スピーカー;supiikaa
+スピーチ;supiichi
+スピード;supiido
+スプーン;supuun
+スポーツ;supootsu
+スマート;sumaato
+スライド;suraido
+スリッパ;surippa
+ズボン;zubon
+セーター;seetaa
+セット;setto
+セメント;semento
+センター;sentaa
+センチ;senchi
+ゼミ;zemi
+ゼロ;zero
+ソファー;sofaa
+タイプ;taipu
+タイプライター;taipuraitaa
+タイヤ;taiya
+タオル;taoru
+タクシー;takushii
+ダイヤグラム;daiyaguramu
+ダイヤモンド;daiyamondo
+ダイヤル;daiyaru
+ダブる;daburu
+ダム;damu
+ダンス;dansu
+チーズ;chiizu
+チーム;chiimu
+チップ;chippu
+チャンス;chansu
+チョーク;chooku
+テーブル;teeburu
+テープ;teepu
+テープレコーダー;teepurekoodaa
+テーマ;teema
+テキスト;tekisuto
+テスト;tesuto
+テニス;tenisu
+テニスコート;tenisukooto
+テレビ;terebi
+テント;tento
+テンポ;tenpo
+デート;deeto
+デッサン;dessan
+デパート;depaato
+デモ;demo
+トイレ;toire
+トップ;toppu
+トラック;torakku
+トランプ;toranpu
+トレーニング;toreeningu
+トンネル;tonneru
+ドア;doa
+ドライブ;doraibu
+ドラマ;dorama
+ドレス;doresu
+ナイフ;naifu
+ナイロン;nairon
+ナンバー;nanbaa
+ニュース;nyuusu
+ネクタイ;nekutai
+ネックレス;nekkuresu
+ノート;nooto
+ノック;nokku
+ハイキング;haikingu
+ハンサム;hansamu
+ハンドバッグ;handobaggu
+ハンドル;handoru
+バイオリン;baiorin
+バケツ;baketsu
+バス;basu
+バター;bataa
+バック;bakku
+バッグ;baggu
+バランス;baransu
+バン;ban
+バンド;bando
+パーセント;paasento
+パーティー;paatii
+パイプ;paipu
+パイロット;pairotto
+パス;pasu
+パスポート;pasupooto
+パターン;pataan
+パンツ;pantsu
+ビール;biiru
+ビタミン;bitamin
+ビデオ;bideo
+ビニール;biniiru
+ビル;biru
+ピアノ;piano
+ピクニック;pikunikku
+ピストル;pisutoru
+ピン;pin
+ピンク;pinku
+ファスナー;fasunaa
+フィルム;firumu
+フォーク;fooku
+フライパン;furaipan
+フリー;furii
+ブラウス;burausu
+ブラシ;burashi
+ブレーキ;bureeki
+ブローチ;buroochi
+プール;puuru
+プラス;purasu
+プラスチック;purasuchikku
+プラットホーム;purattohoomu
+プラン;puran
+プリント;purinto
+プレゼント;purezento
+プロ;puro
+プログラム;puroguramu
+ヘリコプター;herikoputaa
+ベッド;beddo
+ベテラン;beteran
+ベル;beru
+ベルト;beruto
+ページ;peeji
+ペン;pen
+ペンキ;penki
+ペンチ;penchi
+ホーム;hoomu
+ホテル;hoteru
+ボーイ;booi
+ボート;booto
+ボーナス;boonasu
+ボール;booru
+ボールペン;boorupen
+ボタン;botan
+ポケット;poketto
+ポスター;posutaa
+ポスト;posuto
+マーケット;maaketto
+マイク;maiku
+マイナス;mainasu
+マスク;masuku
+マスター;masutaa
+マッチ;macchi
+マフラー;mafuraa
+ママ;mama
+マラソン;marason
+ミシン;mishin
+ミス;misu
+ミリ;miri
+ミルク;miruku
+メーター;meetaa
+メートル;meetoru
+メニュー;menyuu
+メモ;memo
+メンバー;menbaa
+モーター;mootaa
+モダン;modan
+モデル;moderu
+モノレール;monoreeru
+ユーモア;yuumoa
+ヨーロッパ;yooroppa
+ヨット;yotto
+ライター;raitaa
+ラケット;raketto
+ラジオ;rajio
+ラッシュアワー;rasshuawaa
+ランチ;ranchi
+リズム;rizumu
+リットル;rittoru
+リボン;ribon
+レインコート;reinkooto
+レクリエーション;rekurieeshon
+レコード;rekoodo
+レジャー;rejaa
+レストラン;resutoran
+レベル;reberu
+レポート;repooto
+レンズ;renzu
+ローマじ;roomaji
+ロケット;roketto
+ロッカー;rokkaa
+ロビー;robii
+ワイシャツ;waishatsu
+ワイン;wain
+ワンピース;wanpiisu
+だい;dai
+か;ka
+はやく;hayaku
+いく;iku
+わかる;wakaru
+へ(え);he(e)
+あつい;atsui
+ね;ne
+そう;sou
+れんしゅう;renshuu
+てん;ten
+か;ka
+みる;miru
+なん;nan
+を(お);wo(o)
+まだない;madanai
+いい;ii
+よ;yo
+ちょうしょく;choushoku
+おはようございます;ohayougozaimasu
+たべる;taberu
+パン;pan
+コーヒー;koohii
+のむ;nomu
+ビール;biiru
+りんご;ringo
+それでは(それでわ);soredeha(soredewa)
+たまご;tamago
+ぜいかん;zeikan
+カメラ;kamera
+もつ;motsu
+はい;hai
+ある;aru
+トランク;toranku
+なか;naka
+が;ga
+と;to
+ほん;hon
+ようふく;youfuku
+それ;sore
+だけ;dake
+さけ;sake
+けっこう;kekkou
+かいもの;kaimono
+デパート;depaato
+いっしょに;isshoni
+かう;kau
+くつした;kutsushita
+はいる;hairu
+ここ;koko
+でも;demo
+やめる;yameru
+しる;shiru
+タワー;tawaa
+から;kara
+どう;dou
+あるく;aruku
+えき;eki
+まで;made
+めぐろ;meguro
+しぶや;shibuya
+そこ;soko
+で;de
+とうきょう;toukyou
+それから;sorekara
+バス;basu
+すいぞくかん;suizokukan
+みせ;mise
+みやげ;miyage
+も;mo
+えいが;eiga
+きのう;kinou
+する;suru
+くる;kuru
+ともだち;tomodachi
+アメリカ;amerika
+めがね;megane
+わすれる;wasureru
+よく;yoku
+ちゅうかりょうり;chuukaryouri
+こんばん;konban
+だいすき;daisuki
+わたし;watashi
+さかな;sakana
+スープ;suupu
+とる;toru
+にく;niku
+はし;hashi
+いいえ;iie
+フォーク;fooku
+おねがいします;onegaishimasu
+ください;kudasai
+ありがとうございます;arigatougozaimasu
+とても;totemo
+テレビ;terebi
+すもう;sumou
+シーズン;shiizun
+よく;yoku
+ときどき;tokidoki
+ニュース;nyuusu
+ホーム・ドラマ;hoomu_dorama
+どちらも;dochiramo
+あさ;asa
+おきる;okiru
+じ;ji
+いち;ichi
+じゅう;juu
+おそい;osoi
+ねる;neru
+よる;yoru
+さん;san
+よなか;yonaka
+きょう;kyou
+それでも;soredemo
+バー;baa
+はたらく;hataraku
+たいへん;taihen
+こんにちは;konnichiha
+きっさてん;kissaten
+やまだ;yamada
+さん;san
+おかし;okashi
+ほんとう;hontou
+いま;ima
+ええ;ee
+ダイエット;daietto
+やくそく;yakusoku
+けさ;kesa
+フランス;furansu
+まえ;mae
+まつ;matsu
+どうしたのでしょう;doushitanodeshou
+こまる;komaru
+ドイツ;doitsu
+しょうかい;shoukai
+こばやし;kobayashi
+みちこ;michiko
+と;to
+すむ;sumu
+けっこん;kekkon
+ねん;nen
+いる;iru
+こども;kodomo
+ふたり;futari
+おとこのこ;otokonoko
+おんなのこ;onnanoko
+は(わ);ha(wa)
+ご;go
+さい;sai
+さいこん;saikon
+じつは(わ);jitsuha(wa)
+おぼっちゃん;obocchan
+にちようび;nichiyoubi
+ピクニック;pikunikku
+たなか;tanaka
+やまもと;yamamoto
+さそう;sasou
+かんがえ;kangae
+えのしま;enoshima
+サンドウイッチ;sandouicchi
+すし;sushi
+に;ni
+みかん;mikan
+ジュース;juusu
+ため;tame
+でんわをかける;denwawokakeru
+すぐ;sugu
+のみのいち;nominoichi
+その;sono
+はこ;hako
+みぎ;migi
+ひだり;hidari
+えん;en
+まん;man
+ごめんなさい;gomennasai
+ちょっと;chotto
+みせる;miseru
+ふるい;furui
+えど;edo
+もの;mono
+うら;ura
+ほんや;hon_ya
+せんそう;sensou
+へいわ;heiwa
+しょうしょう;shoushou
+にほん;nihon
+るす;rusu
+じぶん;jibun
+この;kono
+すすめる;susumeru
+つくる;tsukuru
+かんたん;kantan
+まいどありがとうございます;maidoarigatougozaimasu
+コンサート;konsaato
+だれ;dare
+ひと;hito
+しゃしん;shashin
+やまぐち;yamaguchi
+ふみこ;fumiko
+じょゆう;joyuu
+でわありません;dewaarimasen
+かしゅ;kashu
+うた;uta
+うたう;utau
+どんな;donna
+ジャズ;jazu
+こんど;kondo
+どようび;doyoubi
+が;ga
+つごう;tsugou
+わるい;warui
+もっと;motto
+より;yori
+むり;muri
+な;na
+つぎ;tsugi
+きかい;kikai
+きんえん;kin_en
+たばこや;tabakoya
+へん;hen
+とおい;tooi
+そんなに;sonnani
+みち;michi
+まがる;magaru
+おおきい;ookii
+かわ;kawa
+たすかる;tasukaru
+みっか;mikka
+すう;suu
+タバコ;tabako
+つらい;tsurai
+ぼく;boku
+ゆうびんきょく;yuubinkyoku
+うしろ;ushiro
+こうくう;koukuu
+はがき;hagaki
+ゆうびん;yuubin
+りょうきん;ryoukin
+イギリス;igirisu
+ギリシャ;girisha
+しらべる;shiraberu
+ひゃく;hyaku
+まい;mai
+しごと;shigoto
+うえ;ue
+げんき;genki
+むすこさん;musukosan
+ことし;kotoshi
+だいがく;daigaku
+そつぎょう;sotsugyou
+とうだい;toudai
+おめでとうございます;omedetougozaimasu
+つとめ;tsutome
+かいしゃ;kaisha
+かんけい;kankei
+しがつ;shigatsu
+じどうしゃ;jidousha
+にゅういんする;nyuuinsuru
+あう;au
+ごがつ;gogatsu
+おきのどくに;okinodokuni
+そのご;sonogo
+たいいんする;taiinsuru
+らいしゅう;raishuu
+あんしん;anshin
+アパート;apaato
+みつかる;mitsukaru
+せまい;semai
+けれども;keredomo
+ふん;fun
+おと;oto
+きこえる;kikoeru
+ぜんぜんない;zenzennai
+ようちえん;youchien
+かい;kai
+よん;yon
+ながめ;nagame
+から;kara
+ちょうど;choudo
+なにもない;nanimonai
+に;ni
+ビル;biru
+むかい;mukai
+きにいる;kiniiru
+やちん;yachin
+しょうせつ;shousetsu
+すいりしょうせつ;suirishousetsu
+しゅっぱん;shuppan
+はなし;hanashi
+しゅじんこう;shujinkou
+ファッション・モデル;fasshon_moderu
+スパイ;supai
+ページ;peeji
+おもう;omou
+ながい;nagai
+どのぐらい;donogurai
+もう;mou
+ちゅうごく;chuugoku
+らいねん;rainen
+ご;go
+むすこ;musuko
+かんこう;kankou
+おともする;otomosuru
+すこし;sukoshi
+それに;soreni
+ひま;hima
+げつようび;getsuyoubi
+しょくじ;shokuji
+ばん;ban
+まさこ;masako
+ひこうき;hikouki
+くうこう;kuukou
+ごぜん;gozen
+しあさって;shiasatte
+しち;shichi
+なりた;narita
+にっこう;nikkou
+びん;bin
+ひこうじょう;hikoujou
+むかえる;mukaeru
+エア・ターミナル;ea_taaminaru
+はこざき;hakozaki
+はやい;hayai
+リムジン・バス;rimujin_basu
+だいじょうぶ;daijoubu
+かならず;kanarazu
+わ;wa
+にもつ;nimotsu
+ちいさい;chiisai
+バッグ;baggu
+ふたつ;futatsu
+しんぱい;shinpai
+あに;ani
+でる;deru
+ところ;tokoro
+えいご;eigo
+あなた;anata
+かようび;kayoubi
+たんじょうび;tanjoubi
+どこか;dokoka
+おんがっかい;ongakkai
+しばい;shibai
+てんぷら;tenpura
+うえはら;uehara
+おしえる;oshieru
+ピアノ;piano
+きく;kiku
+なら;nara
+かぶき;kabuki
+それとも;soretomo
+ごさぶろう;gosaburou
+よつや;yotsuya
+かいだん;kaidan
+どっち;docchi
+の;no
+えんそう;ensou
+あたし;atashi
+きっぷ;kippu
+おく;oku
+たのむ;tanomu
+せんしゅう;senshuu
+なつ;natsu
+いろ;iro
+おひさしぶりです;ohisashiburidesu
+きれい;kirei
+こむぎ;komugi
+やける;yakeru
+おおしま;ooshima
+しま;shima
+せとないかい;setonaikai
+にし;nishi
+めいぶつ;meibutsu
+たいよう;taiyou
+つよい;tsuyoi
+ひかり;hikari
+いちにちじゅう;ichinichijuu
+しかない;shikanai
+ですから;desukara
+ひるね;hirune
+うみ;umi
+そして;soshite
+はん;han
+まいあさ;maiasa
+ろく;roku
+かいがん;kaigan
+だれもない;daremonai
+あさひ;asahi
+すいへいせん;suiheisen
+にっちゅう;nicchuu
+むら;mura
+かいるい;kairui
+しんせん;shinsen
+つる;tsuru
+うらやましい;urayamashii
+バーゲン;baagen
+てさげかばん;tesagekaban
+こうすい;kousui
+じん;jin
+タオル;taoru
+りょこう;ryokou
+みつこし;mitsukoshi
+がてら;gatera
+かね;kane
+あめ;ame
+ちかてつ;chikatetsu
+あおい;aoi
+あかい;akai
+かかる;kakaru
+ペア;pea
+しろい;shiroi
+め;me
+よこ;yoko
+やすい;yasui
+あね;ane
+しゅじん;shujin
+ガウン;gaun
+ご;go
+ふち;fuchi
+みず;mizu
+ぎんこう;ginkou
+よる;yoru
+ぜんぶ;zenbu
+ので;node
+おじ;oji
+かす;kasu
+かんさい;kansai
+しゅうまつ;shuumatsu
+しゅっぱつ;shuppatsu
+どうりょう;douryou
+こうそくどうろ;kousokudouro
+こくどう;kokudou
+はしる;hashiru
+キロ;kiro
+すすむ;susumu
+スピード;supiido
+せいげん;seigen
+はち;hachi
+トラック;torakku
+おいこす;oikosu
+いはん;ihan
+かかる;kakaru
+とき;toki
+はやい;hayai
+ほう;hou
+ゆうりょう;yuuryou
+あたり;atari
+しずおか;shizuoka
+つかまる;tsukamaru
+ばっきん;bakkin
+パト・カー;pato_kaa
+はらう;harau
+そのまま;sonomama
+たりる;tariru
+もどる;modoru
+よさん;yosan
+はちこう;hachikou
+いぬ;inu
+どうぞう;douzou
+いう;iu
+など;nado
+はなす;hanasu
+かんしん;kanshin
+うえの;ueno
+えいさぶろう;eisaburou
+かう;kau
+おくる;okuru
+ふどうさんや;fudousan_ya
+あおやま;aoyama
+さがす;sagasu
+なにか;nanika
+けん;ken
+にわ;niwa
+ダイニング;dainingu
+リビング;ribingu
+わかれる;wakareru
+いけばな;ikebana
+じょう;jou
+ちゃ;cha
+つま;tsuma
+ほしい;hoshii
+わしつ;washitsu
+ガレージ;gareeji
+くるま;kuruma
+だい;dai
+ひつよう;hitsuyou
+おおい;ooi
+きゃく;kyaku
+げつ;getsu
+しききん;shikikin
+ぶん;bun
+れいきん;reikin
+にゅうきょする;nyuukyosuru
+あきらめる;akirameru
+みょうじ;myouji
+しぜん;shizen
+あらわす;arawasu
+おなじ;onaji
+でんわちょう;denwachou
+すずき;suzuki
+しんせき;shinseki
+みんな;minna
+パンダ;panda
+えはがき;ehagaki
+かわり;kawari
+こんなに;konnani
+ずつ;zutsu
+いちにち;ichinichi
+たのしい;tanoshii
+むこう;mukou
+けんがく;kengaku
+こうじょう;koujou
+うごかす;ugokasu
+ようこそいらっしゃいました;youkosoirasshaimashita
+あんないする;annaisuru
+これから;korekara
+わたくしども;watakushidomo
+おもに;omoni
+せいひん;seihin
+でんき;denki
+あし;ashi
+きをつける;kiwotsukeru
+もと;moto
+そうこ;souko
+できあがる;dekiagaru
+できる;dekiru
+ねんだい;nendai
+じむしょ;jimusho
+せいぞう;seizou
+たてもの;tatemono
+しつもん;shitsumon
+すみません;sumimasen
+こういん;kouin
+ロボット;robotto
+コンピューター;konpyuutaa
+しつぎょうしゃ;shitsugyousha
+くみたてる;kumitateru
+アルゼンチン;aruzenchin
+おんな;onna
+さっきょくか;sakkyokuka
+オペラ;opera
+いそがしい;isogashii
+ことわる;kotowaru
+のに;noni
+ほか;hoka
+マージャン;maajan
+たのしみにする;tanoshiminisuru
+しょくご;shokugo
+びょうき;byouki
+あたたかい;atatakai
+ちょうし;choushi
+エス・エフ;esu_efu
+うちゅう;uchuu
+ちきゅう;chikyuu
+ぼうけん;bouken
+おこる;okoru
+ものがたり;monogatari
+てん;ten
+ロケット;roketto
+ほし;hoshi
+わくせい;wakusei
+しんりゃく;shinryaku
+はて;hate
+わるもの;warumono
+あんぜん;anzen
+かなた;kanata
+ヒーロー;hiiroo
+まもる;mamoru
+こい;koi
+さいご;saigo
+てきこく;tekikoku
+ハッピ・エンド;happi_endo
+きがする;kigasuru
+きょうみ;kyoumi
+ないよう;naiyou
+なんて;nante
+ホテル;hoteru
+でございます;degozaimasu
+よやく;yoyaku
+さま;sama
+ひとり;hitori
+おとな;otona
+めい;mei
+らいげつ;raigetsu
+はなれる;hanareru
+しょうご;shougo
+チェック・イン;chekku_in
+けど;kedo
+だって;datte
+フロア;furoa
+しかたがない;shikataganai
+こうざ;kouza
+たびたび;tabitabi
+ひらく;hiraku
+ふつう;futsuu
+カナダ;kanada
+ふつか;futsuka
+あずける;azukeru
+きこく;kikoku
+あそぶ;asobu
+ふえる;fueru
+ふゆ;fuyu
+りし;rishi
+よくじつ;yokujitsu
+からっぽ;karappo
+さいふ;saifu
+よてい;yotei
+しようりょう;shiyouryou
+がいこくじん;gaikokujin
+ねがい;negai
+い;i
+いかいよう;ikaiyou
+ちりょう;chiryou
+すいようび;suiyoubi
+おかけください;okakekudasai
+びょういん;byouin
+じんと;jinto
+だす;dasu
+ベッド;beddo
+おす;osu
+と;to
+ただ;tada
+たべすぎ;tabesugi
+たべもの;tabemono
+ひかえる;hikaeru
+いわい;iwai
+しょうしん;shoushin
+レストラン;resutoran
+カクテル・パーティー;kakuteru_paatii
+シャンペン;shanpen
+クラシック;kurashikku
+とくに;tokuni
+がっき;gakki
+オーボエ;ooboe
+しゅみ;shumi
+かつどう;katsudou
+きっかけ;kikkake
+こうとうがっこう;koutougakkou
+はじめる;hajimeru
+なかなかない;nakanakanai
+ふく;fuku
+カセット;kasetto
+さいきん;saikin
+もっぱら;moppara
+ラジオ;rajio
+つけっぱなし;tsukeppanashi
+あつまる;atsumaru
+かくしゅう;kakushuu
+なかま;nakama
+にん;nin
+いれる;ireru
+ひとりで;hitoride
+あき;aki
+おわる;owaru
+あしおと;ashioto
+みたい;mitai
+いわしぐも;iwashigumo
+うかぶ;ukabu
+そら;sora
+むなしい;munashii
+ゆうやけ;yuuyake
+よ;yo
+おちる;ochiru
+かなしい;kanashii
+かれは;kareha
+し;shi
+ためいき;tameiki
+ビオロン;bioron
+まったく;mattaku
+よう;you
+おわり;owari
+かがやく;kagayaku
+かき;kaki
+は;ha
+ひぐれ;higure
+あまりにも;amarinimo
+きもち;kimochi
+さびしい;sabishii
+いのち;inochi
+はかない;hakanai
+ロマンチック;romanchikku
+ふう;fuu
+よっぱらう;yopparau
+うる;uru
+しょうばい;shoubai
+しょくひん;shokuhin
+れいとう;reitou
+かとう;katou
+げんじつてき;genjitsuteki
+びじゅつかん;bijutsukan
+げんだい;gendai
+ところで;tokorode
+さっそく;sassoku
+え;e
+みどりいろ;midoriiro
+ひじょうに;hijouni
+ふしぎ;fushigi
+かお;kao
+あ;a
+ねこ;neko
+あたま;atama
+はな;hana
+だい;dai
+もり;mori
+ゆめ;yume
+タクシー;takushii
+どの;dono
+サントリー;santorii
+そば;soba
+く;ku
+みなと;minato
+くわしい;kuwashii
+こうしゅうでんわ;koushuudenwa
+こまかい;komakai
+たま;tama
+おりる;oriru
+あの;ano
+あみ;ami
+きょだい;kyodai
+ああ;aa
+ゴルフ;gorufu
+れんしゅうじょう;renshuujou
+サラリーマン;sarariiman
+ばしょ;basho
+おくじょう;okujou
+ひろい;hiroi
+スポーツ;supootsu
+やきゅう;yakyuu
+みまい;mimai
+にっせき;nisseki
+なんようび;nan_youbi
+きんようび;kin_youbi
+みょうごにち;myougonichi
+くだもの;kudamono
+はな;hana
+しゅじゅつ;shujutsu
+ちょう;chou
+きいろい;kiiroi
+ほん;hon
+うち;uchi
+おだいじに;odaijini
+わざわざ;wazawaza
+チュウリップ;chuurippu
+きがえる;kigaeru
+さあ;saa
+みずぎ;mizugi
+すいちゅうめがね;suichuumegane
+ぼうし;boushi
+つめたい;tsumetai
+わあ;waa
+いわ;iwa
+きょうそう;kyousou
+かつ;katsu
+あぶない;abunai
+おとなしい;otonashii
+アイス・クリーム;aisu_kuriimu
+あら;ara
+じゃ;ja
+すな;suna
+すわる;suwaru
+せなか;senaka
+たまらない;tamaranai
+ひやけ;hiyake
+きる;kiru
+バカンス;bakansu
+きょねん;kyonen
+まいとし;maitoshi
+けいゆ;keiyu
+シベリア;shiberia
+パリ;pari
+モスクワ;mosukuwa
+ウラジオストック;urajiosutokku
+のりかえる;norikaeru
+ふね;fune
+かんかく;kankaku
+たいくつ;taikutsu
+きめる;kimeru
+ごろ;goro
+しちがつ;shichigatsu
+はじめ;hajime
+れきし;rekishi
+なら;nara
+とおる;tooru
+まわり;mawari
+そう;sou
+てら;tera
+はたけ;hatake
+とうしょうだいじ;toushoudaiji
+ほうりゅうじ;houryuuji
+やくしじ;yakushiji
+しずか;shizuka
+とまる;tomaru
+いぜん;izen
+そのあと;sonoato
+かきとり;kakitori
+ひらがな;hiragana
+せんきょ;senkyo
+へん;hen
+ええと;eeto
+はた;hata
+スピーカー;supiikaa
+くりかえす;kurikaesu
+おおどおり;oodoori
+ど;do
+ながら;nagara
+りっこうほしゃ;rikkouhosha
+しかた;shikata
+やりかた;yarikata
+ちかづく;chikaduku
+でも;demo
+こんかい;konkai
+とちじ;tochiji
+こしょう;koshou
+でんきやさん;denkiyasan
+せんたくき;sentakuki
+いつつ;itsutsu
+とれる;toreru
+ねじ;neji
+そうじき;soujiki
+ついでに;tsuideni
+みっつ;mittsu
+かしら;kashira
+れいぞうこ;reizouko
+いったい;ittai
+ぬける;nukeru
+いらい;irai
+きぐ;kigu
+じゅう;juu
+たいしょく;taishoku
+ぶんかい;bunkai
+しんかんせん;shinkansen
+きゅうしゅう;kyuushuu
+まご;mago
+くらべる;kuraberu
+しゃない;shanai
+まど;mado
+おかげで;okagede
+さむい;samui
+すずしい;suzushii
+たしか;tashika
+むしあつい;mushiatsui
+れいぼう;reibou
+きょうと;kyouto
+ごこち;gokochi
+ねむる;nemuru
+よこはま;yokohama
+たら;tara
+おおさか;oosaka
+まいしゅう;maishuu
+へんじ;henji
+うけとる;uketoru
+ゆうべ;yuube
+ポスト;posuto
+とお;too
+とおか;tooka
+ところが;tokoroga
+ふうとう;fuutou
+きたく;kitaku
+ちゃんと;chanto
+はら;hara
+ばんち;banchi
+サービス;saabisu
+はいたつ;haitatsu
+せいかく;seikaku
+そくたつ;sokutatsu
+せんとう;sentou
+げしゅく;geshuku
+シャワー;shawaa
+ふべん;fuben
+まいばん;maiban
+ひろびろとする;hirobirotosuru
+ふかい;fukai
+ゆぶね;yubune
+すぎ;sugi
+すく;suku
+つかる;tsukaru
+まんいん;man_in
+せつび;setsubi
+あいだに;aidani
+げんかん;genkan
+だんじょ;danjo
+ても;temo
+はだか;hadaka
+べつべつ;betsubetsu
+はずかしい;hazukashii
+へいき;heiki
+きになる;kininaru
+ならう;narau
+こじん;kojin
+レッスン;ressun
+よむ;yomu
+じき;jiki
+それじゃ;soreja
+きじ;kiji
+こうぎょう;kougyou
+へえ;hee
+まじめ;majime
+ちち;chichi
+のうぎょう;nougyou
+ほうめん;houmen
+どんどん;dondon
+て;te
+あれ;are
+ロック;rokku
+えらぶ;erabu
+しんこんりょこう;shinkonryokou
+ひとつ;hitotsu
+しんじゅく;shinjuku
+ついたち;tsuitachi
+よろしく;yoroshiku
+いくらか;ikuraka
+カメラやさん;kamerayasan
+こがた;kogata
+ごらん;goran
+モデル;moderu
+ぜんじどう;zenjidou
+メーカー;meekaa
+ボディー;bodii
+かるい;karui
+えらびかた;erabikata
+について;nitsuite
+はなしあう;hanashiau
+ふさい;fusai
+コンクリート;konkuriito
+じしん;jishin
+おれ;ore
+じゅん;jun
+しき;shiki
+ていねん;teinen
+ぼんさい;bonsai
+すう;suu
+おうせつま;ousetsuma
+かんがえる;kangaeru
+しき;shiki
+しょくどう;shokudou
+しんしつ;shinshitsu
+ふろば;furoba
+モダン;modan
+じゅんび;junbi
+たち;tachi
+のる;noru
+ふじさん;fujisan
+って;tte
+くさる;kusaru
+じつぶつ;jitsubutsu
+ほど;hodo
+へん;hen
+いず;izu
+でかける;dekakeru
+はんとう;hantou
+くも;kumo
+ほうこう;houkou
+かぞく;kazoku
+そうしき;soushiki
+ちじん;chijin
+れいえん;reien
+はか;haka
+ぶんがくしゃ;bungakusha
+ぼち;bochi
+こそ;koso
+やはり;yahari
+いっしょう;isshou
+じゅういちがつ;juuichigatsu
+こうしつ;koushitsu
+とまる;tomaru
+はらじゅく;harajuku
+やまのてせん;yamanotesen
+よよぎ;yoyogi
+とくべつ;tokubetsu
+ばあい;baai
+てんのう;tennou
+へいか;heika
+おすまい;osumai
+こうきょ;koukyo
+ちよだく;chiyodaku
+れっしゃ;ressha
+こうごう;kougou
+なす;nasu
+おめにかかる;omenikakaru
+こくみん;kokumin
+りょう;ryou
+きゅうちゅうさんが;kyuuchuusanga
+しょうがつ;shougatsu
+すがた;sugata
+しょうぐん;shougun
+しろ;shiro
+まんなか;mannaka
+ジョギング;jogingu
+そんな;sonna
+おみあい;omiai
+おい;oi
+きしゃ;kisha
+けいざい;keizai
+だれか;dareka
+おいごさん;oigosan
+てんきん;tenkin
+ブラジル;burajiru
+しゃこうせい;shakousei
+じょうず;jouzu
+せったい;settai
+りそう;risou
+じょうけん;jouken
+こっかいぎいん;kokkaigiin
+ゆうじん;yuujin
+いたす;itasu
+のちほど;nochihodo
+れんらく;renraku
+かんじ;kanji
+しゃこうてき;shakouteki
+はきはき;hakihaki
+あう;au
+ごがく;gogaku
+し;shi
+ポルトガル;porutogaru
+かのじょ;kanojo
+せ;se
+にあう;niau
+ふとい;futoi
+ふりそで;furisode
+がまん;gaman
+スキー;sukii
+ウィーク・エンド;wiiku_endo
+あいつ;aitsu
+ひどいめにあう;hidoimeniau
+くん;kun
+じまん;jiman
+リフト;rifuto
+ふもと;fumoto
+べそをかく;besowokaku
+カーブ;kaabu
+ころぶ;korobu
+おきあがる;okiagaru
+おこす;okosu
+そのうえ;sonoue
+そのたんびに;sonotanbini
+はんにち;hannichi
+やまごや;yamagoya
+ゆき;yuki
+せっかく;sekkaku
+だいなし;dainashi
+ただいま;tadaima
+あっ;aっ
+おかえりなさい;okaerinasai
+おとす;otosu
+したく;shitaku
+つかれ;tsukare
+ゆうしょく;yuushoku
+うん;un
+いつでも;itsudemo
+かん;kan
+おまえ;omae
+ゆ;yu
+わかす;wakasu
+ひさしぶりに;hisashiburini
+からだ;karada
+じゅうぶん;juubun
+すいみん;suimin
+こんばんわ;konbanwa
+せんげつ;sengetsu
+ヨーロッパ;yooroppa
+しゃべり;shaberi
+ますます;masumasu
+うわさ;uwasa
+おもいちがい;omoichigai
+いっちょうら;icchoura
+じゅうにがつ;juunigatsu
+せびろ;sebiro
+ドア;doa
+ならす;narasu
+ベル;beru
+すてき;suteki
+ひやす;hiyasu
+おおそうじ;oosouji
+せちりょうり;sechiryouri
+ととのう;totonou
+おがむ;ogamu
+としこしそば;toshikoshisoba
+ねんし;nenshi
+ひので;hinode
+おおみそか;oomisoka
+すっかり;sukkari
+レヴェイヨン;reveiyon
+カンパイ;kanpai
+ごくろうさま;gokurousama
+キャンプ;kyanpu
+テント;tento
+すむ;sumu
+ばんめし;banmeshi
+まくら;makura
+かい;kai
+しにん;shinin
+つまり;tsumari
+ねかせる;nekaseru
+きらう;kirau
+むける;mukeru
+みなみ;minami
+しゃめん;shamen
+けんり;kenri
+ごんげん;gongen
+みち;michi
+やくみ;yakumi
+みりょく;miryoku
+ぎまい;gimai
+かじゅう;kajuu
+かちょう;kachou
+らしん;rashin
+せきぜん;sekizen
+せいせき;seiseki
+こうさい;kousai
+れっしゃ;ressha
+そうれつ;souretsu
+ぶんれつ;bunretsu
+れいがい;reigai
+とうほん;touhon
+ふっとう;futtou
+かっとう;kattou
+しょうり;shouri
+ぐうぞう;guuzou
+そうぐう;souguu
+いちぐう;ichiguu
+ぐち;guchi
+ぎょえん;gyoen
+えんせい;ensei
+えんてん;enten
+わんりょく;wanryoku
+がじょう;gajou
+はつが;hatsuga
+ゆうが;yuuga
+かくう;kakuu
+しゅくがかい;shukugakai
+がんこ;ganko
+こじん;kojin
+いっかげつ;ikkagetsu
+こうりょう;kouryou
+こうてつ;koutetsu
+ごうけんな;goukenna
+ほうし;houshi
+ねんぽう;nenpou
+てつぼう;tetsubou
+いっぱん;ippan
+うんぱん;unpan
+えんばん;enban
+しょうもう;shoumou
+びこう;bikou
+ぼうし;boushi
+いんぼう;inbou
+ばいかい;baikai
+がいねん;gainen
+ふんがい;fungai
+きせい;kisei
+こうげん;kougen
+げんせん;gensen
+しがんする;shigansuru
+ようぎ;yougi
+もぎ;mogi
+ぎょうこする;gyoukosuru
+きょうふ;kyoufu
+きぼう;kibou
+えんせん;ensen
+えんかん;enkan
+せんちょう;senchou
+ふじん;fujin
+ふよう;fuyou
+きそく;kisoku
+えいご;eigo
+えいが;eiga
+ちゅうおう;chuuou
+うまい;umai
+あじ;aji
+かもしれない;kamoshirenai
+マッチ;macchi
+みあたる;miataru
+え;e
+こんや;kon_ya
+とちゅう;tochuu
+みんしゅく;minshuku
+すきま;sukima
+セントラリ・ヒーティング;sentorari_hiitingu
+だて;date
+げんこう;genkou
+ひしょ;hisho
+べっそう;bessou
+もし;moshi
+やまなかこ;yamanakako
+コート;kooto
+ダイヤモンド;daiyamondo
+ハンド・バッグ;hando_baggu
+ミンク;minku
+ゆびわ;yubiwa
+わに;wani
+おがたこうりん;ogatakourin
+しゅう;shuu
+けんぶつ;kenbutsu
+しゅと;shuto
+すべて;subete
+すうねん;suunen
+ぜん;zen
+タヒチ;tahichi
+むすめ;musume
+かえす;kaesu
+しゃっきん;shakkin
+せんけつ;senketsu
+しんねんあけましておめでとうございます;shinnen_akemashiteomedetougozaimasu
+おせわになりました;osewaninarimashita
+さくねん;sakunen
+せわ;sewa
+ちゅう;chuu
+ほんねん;honnen
+いや;iya
+きもの;kimono
+じぎ;jigi
+けんきゅう;kenkyuu
+せいふ;seifu
+として;toshite
+りゅうがくせい;ryuugakusei
+がくせい;gakusei
+ウィーン;wiin
+オーストリア;oosutoria
+おもいだす;omoidasu
+ころ;koro
+なつかしい;natsukashii
+みおくる;miokuru
+かたかな;katakana
+おくれる;okureru
+こりごりです;korigoridesu
+めいろ;meiro
+ちか;chika
+つうろ;tsuuro
+ホーム;hoomu
+おおぜい;oozei
+エスカレーター;esukareetaa
+かいさつぐち;kaisatsuguchi
+でぐち;deguchi
+わたす;watasu
+いりぐち;iriguchi
+やっとのおもいで;yattonoomoide
+ひがし;higashi
+ひょうじばん;hyoujiban
+しきもう;shikimou
+おふくろ;ofukuro
+かたづける;katadukeru
+こんしゅう;konshuu
+たたむ;tatamu
+ふとん;futon
+いっぱい;ippai
+たたみ;tatami
+なんか;nanka
+さとう;satou
+したぎ;shitagi
+やさい;yasai
+ワイシャツ;waishatsu
+きたない;kitanai
+ナイフ;naifu
+ひからびる;hikarabiru
+アルバイト;arubaito
+くたくた;kutakuta
+さ;sa
+よゆう;yoyuu
+このまえ;konomae
+じょうきょう;joukyou
+きっきょう;kikkyou
+かぜ;kaze
+ひく;hiku
+くすり;kusuri
+きらい;kirai
+じゃあ;jaa
+いっさい;issai
+かんぽうやく;kanpouyaku
+こうせいぶっしつ;kouseibusshitsu
+しあつ;shiatsu
+はり;hari
+やくひん;yakuhin
+せっかき;sekkaki
+きがつく;kigatsuku
+ペット;petto
+がっこう;gakkou
+ビデオ;bideo
+ぶんか;bunka
+きんし;kinshi
+きんぺん;kinpen
+つうこう;tsuukou
+てんごく;tengoku
+ほこうしゃ;hokousha
+シーソー;shiisoo
+テーブル;teeburu
+ならべる;naraberu
+ブランコ;buranko
+づれ;dure
+くつ;kutsu
+はかす;hakasu
+あさくさ;asakusa
+ずっと;zutto
+まさか;masaka
+よう;you
+きちがい;kichigai
+きんじょ;kinjo
+くびわ;kubiwa
+にせ;nise
+びよういん;biyouin
+ほうせき;houseki
+おたく;otaku
+ぶんがく;bungaku
+わかい;wakai
+いっしょうけんめい;isshoukenmei
+げんじものがたり;genjimonogatari
+こてん;koten
+まくらのそうし;makuranosoushi
+まんが;manga
+かよう;kayou
+としょかん;toshokan
+おも;omo
+さくひん;sakuhin
+はたち;hatachi
+へいあん;heian
+ほぼ;hobo
+あんきする;ankisuru
+せいしょうなごん;seishounagon
+さっか;sakka
+じょりゅう;joryuu
+むらさきしきぶ;murasakishikibu
+ちょうてい;choutei
+だいひょうてき;daihyouteki
+おじゃましました;ojamashimashita
+ごちそうさまでした;gochisousamadeshita
+ばんごはん;bangohan
+どういたしまして;douitashimashite
+ごめんくださいませ;gomenkudasaimase
+きんかくじ;kinkakuji
+ひょうし;hyoushi
+いけ;ike
+きんいろ;kin_iro
+こころ;kokoro
+しずまる;shizumaru
+ふくげん;fukugen
+うつくしさ;utsukushisa
+おぼうさん;obousan
+かんぺき;kanpeki
+たえる;taeru
+ひ;hi
+もとめる;motomeru
+かじ;kaji
+もえる;moeru
+もくぞう;mokuzou
+び;bi
+みしまゆきお;mishimayukio
+あじわう;ajiwau
+かんこうきゃく;kankoukyaku
+じっさい;jissai
+ふうけい;fuukei
+ふんいき;fun_iki
+いんしょう;inshou
+がっかりする;gakkarisuru
+ごめんください;gomenkudasai
+あがる;agaru
+えんりょ;enryo
+おあがりください;oagarikudasai
+とつぎさき;totsugisaki
+はく;haku
+まいる;mairu
+よめ;yome
+こす;kosu
+ごぶさたしたおります;gobusatashitaorimasu
+さようでございます;sayoudegozaimasu
+ござる;gozaru
+たずねる;tazuneru
+とつぜん;totsuzen
+もうしわけありません;moushiwakearimasen
+きらく;kiraku
+じょうたい;joutai
+とこ;toko
+かねもち;kanemochi
+きげん;kigen
+ごらんのとおり;gorannotoori
+かへい;kahei
+かみ;kami
+さつ;satsu
+じょうぶ;joubu
+やぶれる;yabureru
+えがく;egaku
+じんぶつ;jinbutsu
+まちがえる;machigaeru
+けんぽう;kenpou
+しょうとくたいし;shoutokutaishi
+せいき;seiki
+なな;nana
+せいじか;seijika
+いとうひろぶみ;itouhirobumi
+いわくらともみ;iwakuratomomi
+めいじ;meiji
+ぶんかじん;bunkajin
+しそうか;shisouka
+ふくざわゆきち;fukuzawayukichi
+いしん;ishin
+おうべい;oubei
+せいよう;seiyou
+きょういくか;kyouikuka
+しょうわ;shouwa
+たいしょう;taishou
+にとべいなぞう;nitobeinazou
+きんだい;kindai
+なつめそうせき;natsumesouseki
+しつれい;shitsurei
+わがはい;wagahai
+しゃかい;shakai
+にんげん;ningen
+たいせん;taisen
+あつめる;atsumeru
+はなみ;hanami
+さくら;sakura
+まんかい;mankai
+ことわざ;kotowaza
+ちる;chiru
+しゅっちょう;shucchou
+ぜん;zen
+ござ;goza
+しく;shiku
+しんしゅう;shinshuu
+そふ;sofu
+すみ;sumi
+たんか;tanka
+よむ;yomu
+ままごと;mamagoto
+そぼ;sobo
+だんご;dango
+わらう;warau
+なみ;nami
+こくりつ;kokuritsu
+がくひ;gakuhi
+しゅうしょく;shuushoku
+らく;raku
+あずかる;azukaru
+ねえさん;neesan
+ちゅうがっこう;chuugakkou
+ねんせい;nensei
+み;mi
+きょうじゅ;kyouju
+だいがくせい;daigakusei
+たっしゃ;tassha
+こくさいてき;kokusaiteki
+こくご;kokugo
+さんすう;sansuu
+よほど;yohodo
+しょうがっこう;shougakkou
+しりつ;shiritsu
+ここのつ;kokonotsu
+みほん;mihon
+エヌ・エッチ・ケー;enu_ecchi_kee
+こうきょう;koukyou
+しゅるい;shurui
+チャンネル;channeru
+ばんぐみ;bangumi
+ほうそう;housou
+ほうふ;houfu
+みんかん;minkan
+げき;geki
+ほうえい;houei
+クイズ;kuizu
+なんでも;nandemo
+ごらく;goraku
+がいこくご;gaikokugo
+ギター;gitaa
+こうざ;kouza
+さいほう;saihou
+しゃみせん;shamisen
+はじまる;hajimaru
+フルート;furuuto
+しゃかいがく;shakaigaku
+すうがく;suugaku
+きょういく;kyouiku
+きぎょう;kigyou
+スポンサー;suponsaa
+いらいらする;irairasuru
+こうこく;koukoku
+ちゅうだん;chuudan
+トイレ;toire
+りよう;riyou
+おげんきで;ogenkide
+みじかい;mijikai
+とくしゅ;tokushu
+りかい;rikai
+こくさいれんごう;kokusairengou
+えんそく;ensoku
+べんとう;bentou
+おかず;okazu
+おにしめ;onishime
+とり;tori
+ゆでたまご;yudetamago
+くもり;kumori
+よほう;yohou
+おっしゃる;ossharu
+むすび;musubi
+いや;iya
+おもい;omoi
+リュック・サック;ryukku_sakku
+おやつ;oyatsu
+デザート;dezaato
+せんべい;senbei
+あまい;amai
+クッキー;kukkii
+チョコレート;chokoreeto
+おやすみなさい;oyasuminasai
+かいわ;kaiwa
+にちじょう;nichijou
+げいひんかん;geihinkan
+ひとごみ;hitogomi
+オランダ;oranda
+けいさつかん;keisatsukan
+じょおう;joou
+そうりだいじん;souridaijin
+こっかいぎじどう;kokkaigijidou
+むかう;mukau
+こんげつ;kongetsu
+ふけいかい;fukeikai
+しゅっせき;shusseki
+あかるい;akarui
+きびしい;kibishii
+りか;rika
+びだんし;bidanshi
+ファン;fan
+やさしい;yasashii
+きゅうに;kyuuni
+けい;kei
+しょうらい;shourai
+ねんごう;nengou
+こせきしょうほん;kosekishouhon
+せいれき;seireki
+たいしかん;taishikan
+ちゅういがき;chuuigaki
+めんどうくさい;mendoukusai
+やくする;yakusuru
+あたる;ataru
+がんねん;gannen
+たす;tasu
+とし;toshi
+ごぞんじです;gozonjidesu
+どなたか;donataka
+アップライト・ピアノ;appuraito_piano
+グランド・ピアノ;gurando_piano
+がいこくせい;gaikokusei
+こくさん;kokusan
+くろい;kuroi
+ちゃいろ;chairo
+がいかん;gaikan
+ひく;hiku
+ふかみ;fukami
+カタログ;katarogu
+おまわりさん;omawarisan
+ショッピングセンター;shoppingusentaa
+しんせつ;shinsetsu
+はは;haha
+まいご;maigo
+うんてんしゅ;untenshu
+こうば;kouba
+のうじょう;noujou
+ほっかいどう;hokkaidou
+うし;ushi
+うんてんする;untensuru
+くらす;kurasu
+すごす;sugosu
+トラクター;torakutaa
+ひゃくしょう;hyakushou
+オリンピック;orinpikku
+かたち;katachi
+けんちくか;kenchikuka
+しゅうがくりょこう;shuugakuryokou
+スタジアム;sutajiamu
+ちゅうがくせい;chuugakusei
+しょうしゃマン;shoushaman
+ついに;tsuini
+つうやく;tsuuyaku
+はいゆう;haiyuu
+かい;kai
+これら;korera
+しょうじき;shoujiki
+アシミル;ashimiru
+きそく;kisoku
+さつ;satsu
+ただしい;tadashii
+テキスト;tekisuto
+かんじ;kanji
+じ;ji
+かたあし;kataashi
+ぬき;nuki
+えとく;etoku
+り;ri
+ほ;ho
+つづける;tsudukeru
+こうはんりょ;kouhanryo
+さようなら;sayounara
+かまいません;kamaimasen
+あ;a
+ああ;aa
+あいだ;aida
+あう;au
+あがる;agaru
+あかんぼう;akanbou
+あさねぼう;asanebou
+あじ;aji
+あす;asu
+あそび;asobi
+あつまる;atsumaru
+あつめる;atsumeru
+あやまる;ayamaru
+アルバイト;arubaito
+あんしん;anshin
+あんぜん;anzen
+あんない;annai
+いか;ika
+いがい;igai
+いがく;igaku
+いきる;ikiru
+いくらても;ikuratemo
+いけん;iken
+いし;ishi
+いじょう;ijou
+いたす;itasu
+いちど;ichido
+いっしょうけんめい;isshoukenmei
+いと;ito
+いなか;inaka
+いのる;inoru
+いん;in
+うえる;ueru
+うけつけ;uketsuke
+うける;ukeru
+うごく;ugoku
+うつ;utsu
+うつす;utsusu
+うつる;utsuru
+うら;ura
+うりば;uriba
+うん;un
+うんてんしゅ;untenshu
+うんてん;unten
+エスカレーター;esukareetaa
+えだ;eda
+えらぶ;erabu
+えんりょ;enryo
+おいでになる;oideninaru
+おいわい;oiwai
+おうせつま;ousetsuma
+おおい;ooi
+おおきな;ookina
+オートバイ;ootobai
+オーバー;oobaa
+おき;oki
+おくじょう;okujou
+おくりもの;okurimono
+おくる;okuru
+おくれる;okureru
+おこす;okosu
+おこる;okoru
+おしいれ;oshiire
+おちる;ochiru
+おっしゃる;ossharu
+おと;oto
+おとす;otosu
+おどり;odori
+おどろく;odoroku
+おまつり;omatsuri
+おみまい;omimai
+おみやげ;omiyage
+おもいだす;omoidasu
+おもう;omou
+おもて;omote
+おりる;oriru
+おる;oru
+おれい;orei
+おれる;oreru
+おわり;owari
+か;ka
+カーテン;kaaten
+かい;kai
+かいがん;kaigan
+かいぎ;kaigi
+かいじょう;kaijou
+かいわ;kaiwa
+かえり;kaeri
+かがみ;kagami
+がくぶ;gakubu
+かざる;kazaru
+かじ;kaji
+ガソリン;gasorin
+ガソリンスタンド;gasorinsutando
+かたち;katachi
+かたづける;katadukeru
+かつ;katsu
+かなしい;kanashii
+かならず;kanarazu
+かねもち;kanemochi
+かのじょ;kanojo
+かべ;kabe
+かまう;kamau
+かみ;kami
+かむ;kamu
+かよう;kayou
+ガラス;garasu
+かれ;kare
+かれら;karera
+かわく;kawaku
+かわり;kawari
+かんがえる;kangaeru
+かんけい;kankei
+かんごふ;kangofu
+かんたん;kantan
+きかい;kikai
+きかい;kikai
+きけん;kiken
+きこえる;kikoeru
+ぎじゅつ;gijutsu
+きせつ;kisetsu
+きそく;kisoku
+きぬ;kinu
+きびしい;kibishii
+きまる;kimaru
+きめる;kimeru
+きもち;kimochi
+きもの;kimono
+きゃく;kyaku
+きゅう;kyuu
+きゅうこう;kyuukou
+きょういく;kyouiku
+きょうかい;kyoukai
+きょうそう;kyousou
+きょうみ;kyoumi
+きんじょ;kinjo
+ぐあい;guai
+くうこう;kuukou
+くさ;kusa
+くび;kubi
+くも;kumo
+くらべる;kuraberu
+くん;kun
+けいかん;keikan
+けいけん;keiken
+けいざい;keizai
+けいさつ;keisatsu
+げしゅく;geshuku
+けっして;kesshite
+けん;ken
+げんいん;gen_in
+けんきゅう;kenkyuu
+けんきゅうしつ;kenkyuushitsu
+けんぶつ;kenbutsu
+こ;ko
+ご;go
+こうがい;kougai
+こうぎ;kougi
+こうぎょう;kougyou
+こうとうがっこう;koutougakkou
+こうこうせい;koukousei
+こうじょう;koujou
+こうちょう;kouchou
+こうむいん;koumuin
+こころ;kokoro
+ございます;gozaimasu
+こしょう;koshou
+ごぞんじ;gozonji
+こたえ;kotae
+こっち;kocchi
+ことり;kotori
+こまかい;komakai
+こめ;kome
+ごらんになる;goranninaru
+こわす;kowasu
+こわれる;kowareru
+コンサート;konsaato
+こんど;kondo
+こんや;kon_ya
+さいきん;saikin
+さいご;saigo
+さいふ;saifu
+さがす;sagasu
+さがる;sagaru
+さしあげる;sashiageru
+さびしい;sabishii
+さま;sama
+さわぐ;sawagu
+さわる;sawaru
+サンダル;sandaru
+サンドイッチ;sandoicchi
+じ;ji
+しあい;shiai
+しかた;shikata
+しき;shiki
+しけん;shiken
+じしん;jishin
+したぎ;shitagi
+したく;shitaku
+しっぱい;shippai
+しつれい;shitsurei
+じてん;jiten
+しなもの;shinamono
+しま;shima
+じむしょ;jimusho
+しゃかい;shakai
+しゃちょう;shachou
+ジャム;jamu
+じゆう;jiyuu
+じゅうしょ;juusho
+じゅうどう;juudou
+しゅっせき;shusseki
+しゅっぱつ;shuppatsu
+しゅみ;shumi
+じゅんび;junbi
+しょうかい;shoukai
+しょうがつ;shougatsu
+しょうがっこう;shougakkou
+しょうせつ;shousetsu
+しょうたい;shoutai
+しょうち;shouchi
+しょうらい;shourai
+しょくじ;shokuji
+しょくりょうひん;shokuryouhin
+じょせい;josei
+しらせる;shiraseru
+しらべる;shiraberu
+じんじゃ;jinja
+しんせつ;shinsetsu
+しんぱい;shinpai
+しんぶんしゃ;shinbunsha
+すいえい;suiei
+すいどう;suidou
+すうがく;suugaku
+スーツケース;suutsukeesu
+すぎる;sugiru
+すっかり;sukkari
+ステレオ;sutereo
+すてる;suteru
+すな;suna
+すみ;sumi
+すむ;sumu
+すると;suruto
+せい;sei
+せいじ;seiji
+せいよう;seiyou
+せき;seki
+せつめい;setsumei
+せなか;senaka
+せわ;sewa
+せんそう;sensou
+せんぱい;senpai
+せんもん;senmon
+そう;sou
+そうだん;soudan
+そだてる;sodateru
+そつぎょう;sotsugyou
+そふ;sofu
+そぼ;sobo
+それに;soreni
+そんな;sonna
+だい;dai
+たいいん;taiin
+だいがくせい;daigakusei
+だいじ;daiji
+タイプ;taipu
+たいふう;taifuu
+たおれる;taoreru
+たしか;tashika
+たす;tasu
+だす;dasu
+たずねる;tazuneru
+ただしい;tadashii
+たたみ;tatami
+たてる;tateru
+たてる;tateru
+たとえば;tatoeba
+たな;tana
+たのしむ;tanoshimu
+たりる;tariru
+だんせい;dansei
+だんぼう;danbou
+ち;chi
+ちいさな;chiisana
+ちから;chikara
+ちゃん;chan
+ちゅうがっこう;chuugakkou
+ちゅうしゃ;chuusha
+ちゅうしゃじょう;chuushajou
+ちり;chiri
+ついて;tsuite
+つかまえる;tsukamaeru
+つき;tsuki
+つごう;tsugou
+つたえる;tsutaeru
+つづける;tsudukeru
+つつむ;tsutsumu
+つま;tsuma
+つる;tsuru
+ていねい;teinei
+テキスト;tekisuto
+てきとう;tekitou
+テニスコート;tenisukooto
+てぶくろ;tebukuro
+てら;tera
+てん;ten
+てんいん;ten_in
+てんきよほう;tenkiyohou
+でんとう;dentou
+でんぽう;denpou
+てんらんかい;tenrankai
+どうぐ;dougu
+とうとう;toutou
+どうぶつえん;doubutsuen
+とおく;tooku
+とおり;toori
+とおる;tooru
+とき;toki
+とくに;tokuni
+とくべつ;tokubetsu
+とし;toshi
+とちゅう;tochuu
+とっきゅう;tokkyuu
+どっち;docchi
+とどける;todokeru
+とまる;tomaru
+とめる;tomeru
+とりかえる;torikaeru
+どろぼう;dorobou
+ながら;nagara
+なく;naku
+なくす;nakusu
+なげる;nageru
+なるほど;naruhodo
+なれる;nareru
+にがい;nigai
+にくい;nikui
+にっき;nikki
+にゅういん;nyuuin
+にゅうがく;nyuugaku
+ぬすむ;nusumu
+ねむい;nemui
+ねむる;nemuru
+のりかえる;norikaeru
+のりもの;norimono
+は;ha
+ばあい;baai
+ばい;bai
+はいしゃ;haisha
+ばかり;bakari
+はこぶ;hakobu
+はじめる;hajimeru
+はずかしい;hazukashii
+はなみ;hanami
+はらう;harau
+ばんぐみ;bangumi
+ひ;hi
+ひえる;hieru
+ひきだし;hikidashi
+ひこうじょう;hikoujou
+ひさしぶり;hisashiburi
+びじゅつかん;bijutsukan
+びっくりする;bikkurisuru
+ひっこす;hikkosu
+ひつよう;hitsuyou
+ひらく;hiraku
+ビル;biru
+ひるま;hiruma
+ひるやすみ;hiruyasumi
+ひろう;hirou
+ふえる;fueru
+ふかい;fukai
+ふつう;futsuu
+ぶどう;budou
+ふとる;futoru
+ふとん;futon
+ふね;fune
+ふね;fune
+ふべん;fuben
+ふむ;fumu
+プレゼント;purezento
+ぶんか;bunka
+ぶんがく;bungaku
+ベル;beru
+へん;hen
+へんじ;henji
+ぼうえき;boueki
+ほうそう;housou
+ほし;hoshi
+ほんやく;hon_yaku
+まいる;mairu
+まける;makeru
+まちがえる;machigaeru
+まにあう;maniau
+まま;mama
+まわり;mawari
+まわる;mawaru
+まんが;manga
+まんなか;mannaka
+みずうみ;mizuumi
+みつかる;mitsukaru
+みつける;mitsukeru
+みどり;midori
+みな;mina
+みなと;minato
+むかえる;mukaeru
+むし;mushi
+むすこ;musuko
+むすめ;musume
+むら;mura
+むり;muri
+め;me
+めしあがる;meshiagaru
+もうしあげる;moushiageru
+もうすぐ;mousugu
+もし;moshi
+もどる;modoru
+もめん;momen
+やく;yaku
+やくにたつ;yakunitatsu
+やくそく;yakusoku
+やける;yakeru
+やさしい;yasashii
+やすい;yasui
+やはり;yahari
+やわらかい;yawarakai
+ゆ;yu
+ゆうはん;yuuhan
+ゆしゅつ;yushutsu
+ゆび;yubi
+ゆびわ;yubiwa
+ゆめ;yume
+ゆれる;yureru
+よう;you
+ようい;youi
+よごれる;yogoreru
+よしゅう;yoshuu
+よてい;yotei
+よやく;yoyaku
+よる;yoru
+によると;niyoruto
+よろこぶ;yorokobu
+よわい;yowai
+りゆう;riyuu
+りよう;riyou
+りょうほう;ryouhou
+りょかん;ryokan
+るす;rusu
+れきし;rekishi
+れんらく;renraku
+わかす;wakasu
+わかれる;wakareru
+わく;waku
+わけ;wake
+わらう;warau
+わりあい;wariai
+われる;wareru
+ああ;aa
+あう;au
+あおい;aoi
+あかい;akai
+あかるい;akarui
+あき;aki
+あける;akeru
+あさ;asa
+あさごはん;asagohan
+あし;ashi
+あそぶ;asobu
+あたたかい;atatakai
+あたま;atama
+あつい;atsui
+あつい;atsui
+あつい;atsui
+あに;ani
+あね;ane
+あの;ano
+あのう;anou
+アパート;apaato
+あぶない;abunai
+あまい;amai
+あまり;amari
+あめ;ame
+あらう;arau
+ある;aru
+あるく;aruku
+あれ;are
+いい;ii
+よい;yoi
+いいえ;iie
+いう;iu
+いく;iku
+ゆく;yuku
+いけ;ike
+いそがしい;isogashii
+いち;ichi
+いちにち;ichinichi
+いつか;itsuka
+いつつ;itsutsu
+いま;ima
+いみ;imi
+いもうと;imouto
+いや;iya
+いりぐち;iriguchi
+いる;iru
+いる;iru
+いれる;ireru
+いろ;iro
+うえ;ue
+うしろ;ushiro
+うすい;usui
+うた;uta
+うたう;utau
+うまれる;umareru
+うみ;umi
+うる;uru
+うわぎ;uwagi
+え;e
+えいが;eiga
+えいがかん;eigakan
+えいご;eigo
+ええ;ee
+えき;eki
+エレベーター;erebeetaa
+えん;en
+えんぴつ;enpitsu
+お;o
+おおきい;ookii
+おおぜい;oozei
+おかし;okashi
+おかね;okane
+おきる;okiru
+おさけ;osake
+おさら;osara
+おじ;oji
+おじ;oji
+おしえる;oshieru
+おす;osu
+おそい;osoi
+おちゃ;ocha
+おてあらい;otearai
+おとうと;otouto
+おとこ;otoko
+おとこのこ;otokonoko
+おとな;otona
+おなじ;onaji
+おば;oba
+おば;oba
+おべんとう;obentou
+おもい;omoi
+おりる;oriru
+おわる;owaru
+おんな;onna
+おんなのこ;onnanoko
+かい;kai
+かい;kai
+がいこくじん;gaikokujin
+かいしゃ;kaisha
+かいだん;kaidan
+かいもの;kaimono
+かう;kau
+かえす;kaesu
+かお;kao
+かかる;kakaru
+がくせい;gakusei
+かげつ;kagetsu
+かける;kakeru
+かける;kakeru
+かす;kasu
+かぜ;kaze
+かぞく;kazoku
+かたかな;katakana
+がつ;gatsu
+がっこう;gakkou
+かど;kado
+かばん;kaban
+かびん;kabin
+かみ;kami
+カメラ;kamera
+かようび;kayoubi
+からい;karai
+からだ;karada
+がる;garu
+かるい;karui
+カレンダー;karendaa
+かわ;kawa
+かわ;kawa
+がわ;gawa
+かんじ;kanji
+きいろい;kiiroi
+きく;kiku
+ギター;gitaa
+きたない;kitanai
+きって;kitte
+きっぷ;kippu
+きのう;kinou
+ぎゅうにく;gyuuniku
+きょう;kyou
+きょうしつ;kyoushitsu
+きょうだい;kyoudai
+きょねん;kyonen
+きらい;kirai
+きる;kiru
+きる;kiru
+キロ;kiro
+キロ;kiro
+ぎんこう;ginkou
+きんようび;kin_youbi
+く;ku
+くすり;kusuri
+くだもの;kudamono
+くつ;kutsu
+くつした;kutsushita
+くもる;kumoru
+くらい;kurai
+くらい;kurai
+ぐらい;gurai
+クラス;kurasu
+グラム;guramu
+くる;kuru
+くるま;kuruma
+くろい;kuroi
+けさ;kesa
+けす;kesu
+けっこん;kekkon
+げつようび;getsuyoubi
+げんかん;genkan
+げんき;genki
+こ;ko
+ご;go
+ご;go
+こえ;koe
+コート;kooto
+ここ;koko
+ここのつ;kokonotsu
+ごしゅじん;goshujin
+ごぜん;gozen
+こたえる;kotaeru
+コップ;koppu
+ことし;kotoshi
+こども;kodomo
+この;kono
+こまる;komaru
+ころ;koro
+ごろ;goro
+こんげつ;kongetsu
+こんしゅう;konshuu
+こんばん;konban
+さあ;saa
+さい;sai
+さかな;sakana
+さく;saku
+さくぶん;sakubun
+さす;sasu
+さつ;satsu
+さとう;satou
+さむい;samui
+さらいねん;sarainen
+さん;san
+さん;san
+し;shi
+じ;ji
+しお;shio
+じかん;jikan
+しごと;shigoto
+じしょ;jisho
+しずか;shizuka
+しち;shichi
+しつもん;shitsumon
+じどうしゃ;jidousha
+しぬ;shinu
+じびき;jibiki
+じぶん;jibun
+しまる;shimaru
+しめる;shimeru
+しめる;shimeru
+じゃ;ja
+じゃあ;jaa
+しゃしん;shashin
+シャツ;shatsu
+じゅう;juu
+しゅうかん;shuukan
+じゅぎょう;jugyou
+じょうず;jouzu
+しょくどう;shokudou
+しる;shiru
+しろい;shiroi
+じん;jin
+すいようび;suiyoubi
+すう;suu
+スカート;sukaato
+すぎ;sugi
+すぐに;suguni
+すこし;sukoshi
+すずしい;suzushii
+ずつ;zutsu
+ストーブ;sutoobu
+スプーン;supuun
+スポーツ;supootsu
+ズボン;zubon
+すむ;sumu
+スリッパ;surippa
+する;suru
+すわる;suwaru
+セーター;seetaa
+せびろ;sebiro
+せまい;semai
+ゼロ;zero
+せんげつ;sengetsu
+せんしゅう;senshuu
+ぜんぶ;zenbu
+そう;sou
+そうじ;souji
+そして;soshite
+そこ;soko
+その;sono
+そば;soba
+そら;sora
+それ;sore
+それから;sorekara
+だい;dai
+だいがく;daigaku
+たいしかん;taishikan
+だいじょうぶ;daijoubu
+たいへん;taihen
+たいへん;taihen
+たかい;takai
+タクシー;takushii
+だす;dasu
+たち;tachi
+たてもの;tatemono
+たのしい;tanoshii
+たのむ;tanomu
+たばこ;tabako
+たべもの;tabemono
+たべる;taberu
+たまご;tamago
+たんじょうび;tanjoubi
+ちいさい;chiisai
+ちがう;chigau
+ちかてつ;chikatetsu
+ちず;chizu
+ちち;chichi
+ちゃいろ;chairo
+ちゅう;chuu
+ついたち;tsuitachi
+つぎ;tsugi
+つくる;tsukuru
+つめたい;tsumetai
+つよい;tsuyoi
+て;te
+テープ;teepu
+テープレコーダー;teepurekoodaa
+テーブル;teeburu
+でかける;dekakeru
+てがみ;tegami
+でぐち;deguchi
+テスト;tesuto
+デパート;depaato
+でも;demo
+でる;deru
+テレビ;terebi
+でんき;denki
+と;to
+ど;do
+ドア;doa
+トイレ;toire
+どう;dou
+とお;too
+とおい;tooi
+とおか;tooka
+ときどき;tokidoki
+ところ;tokoro
+としょかん;toshokan
+とても;totemo
+どの;dono
+とぶ;tobu
+とまる;tomaru
+ともだち;tomodachi
+どようび;doyoubi
+とり;tori
+とりにく;toriniku
+とる;toru
+とる;toru
+どんな;donna
+ない;nai
+ナイフ;naifu
+ながい;nagai
+なく;naku
+なつ;natsu
+なつやすみ;natsuyasumi
+など;nado
+なのか;nanoka
+ならう;narau
+ならぶ;narabu
+ならべる;naraberu
+に;ni
+にく;niku
+にし;nishi
+にち;nichi
+にちようび;nichiyoubi
+にもつ;nimotsu
+ニュース;nyuusu
+にわ;niwa
+にん;nin
+ぬぐ;nugu
+ネクタイ;nekutai
+ねる;neru
+ねん;nen
+ノート;nooto
+のみもの;nomimono
+のむ;nomu
+は;ha
+パーティー;paatii
+はい;hai
+はい;hai
+はいざら;haizara
+はいる;hairu
+はがき;hagaki
+はく;haku
+はこ;hako
+はし;hashi
+はし;hashi
+はじまる;hajimaru
+はじめに;hajimeni
+はじめて;hajimete
+はしる;hashiru
+バス;basu
+バター;bataa
+はたち;hatachi
+はたらく;hataraku
+はち;hachi
+はつか;hatsuka
+はな;hana
+はな;hana
+はなし;hanashi
+はなす;hanasu
+はは;haha
+はやい;hayai
+はやい;hayai
+はる;haru
+はん;han
+ばん;ban
+ばん;ban
+パン;pan
+ハンカチ;hankachi
+ばんごう;bangou
+ばんごはん;bangohan
+ひがし;higashi
+ひき;hiki
+ひく;hiku
+ひく;hiku
+ひこうき;hikouki
+ひだり;hidari
+ひと;hito
+ひとつ;hitotsu
+ひとつき;hitotsuki
+ひゃく;hyaku
+びょういん;byouin
+びょうき;byouki
+ひらがな;hiragana
+ひる;hiru
+ひるごはん;hirugohan
+ひろい;hiroi
+フィルム;firumu
+ふうとう;fuutou
+プール;puuru
+フォーク;fooku
+ふく;fuku
+ふく;fuku
+ふたつ;futatsu
+ぶたにく;butaniku
+ふたり;futari
+ふつか;futsuka
+ふとい;futoi
+ふゆ;fuyu
+ふるい;furui
+ふん;fun
+パージ;paaji
+ベッド;beddo
+へん;hen
+ペン;pen
+ほう;hou
+ぼうし;boushi
+ボールペン;boorupen
+ほか;hoka
+ポケット;poketto
+ほしい;hoshii
+ほそい;hosoi
+ボタン;botan
+ホテル;hoteru
+ほん;hon
+ほん;hon
+ほんだな;hondana
+まい;mai
+まいあさ;maiasa
+まいげつ;maigetsu
+まいつき;maitsuki
+まいしゅう;maishuu
+まいにち;mainichi
+まいねん;mainen
+まいばん;maiban
+まえ;mae
+まがる;magaru
+まち;machi
+まつ;matsu
+マッチ;macchi
+まど;mado
+まるい;marui
+まるい;marui
+まん;man
+まんねんひつ;mannenhitsu
+みぎ;migi
+みじかい;mijikai
+みず;mizu
+みせ;mise
+みせる;miseru
+みち;michi
+みっか;mikka
+みっつ;mittsu
+みなさん;minasan
+みなみ;minami
+みみ;mimi
+みる;miru
+むいか;muika
+むこう;mukou
+むっつ;muttsu
+め;me
+メートル;meetoru
+めがね;megane
+もう;mou
+もう;mou
+もくようび;mokuyoubi
+もつ;motsu
+もっと;motto
+もの;mono
+もん;mon
+や;ya
+やおや;yaoya
+やさい;yasai
+やさしい;yasashii
+やすい;yasui
+やっつ;yattsu
+やま;yama
+ゆうびんきょく;yuubinkyoku
+ゆうべ;yuube
+ゆうめい;yuumei
+ゆき;yuki
+ゆっくり;yukkuri
+ようか;youka
+ようふく;youfuku
+よく;yoku
+よく;yoku
+よこ;yoko
+よっか;yokka
+よっつ;yottsu
+よぶ;yobu
+よむ;yomu
+よる;yoru
+らいしゅう;raishuu
+らいねん;rainen
+ラジオ;rajio
+りょこう;ryokou
+れい;rei
+れいぞうこ;reizouko
+レストラン;resutoran
+れんしゅう;renshuu
+ろく;roku
+ワイシャツ;waishatsu
+わかい;wakai
+わかる;wakaru
+わすれる;wasureru
+わたくし;watakushi
+わたる;wataru
+にせい;nisei
+みつご;mitsugo
+めがみ;megami
+ちしま;chishima
+さゆう;sayuu
+ふあん;fuan
+たしょう;tashou
+ちじん;chijin
+りようする;riyousuru
+いじょう;ijou
+へいわ;heiwa
+ゆらい;yurai
+るてん;ruten
+ほあん;hoan
+るす;rusu
+でんぱ;denpa
+まるた;maruta
+とまる;tomaru
+ひかく;hikaku
+むしゃ;musha
+えもん;emon
+じこ;jiko
+かにゅう;kanyuu
+こうい;koui
+よとう;yotou
+えど;edo
+うちゅう;uchuu
+ちえ;chie
+におうもん;nioumon
+いたり;itari
+しじけい;shijikei
+きゅうす;kyuusu
+のぎざか;nogizaka
+やすし;yasushi
+おける;okeru
+むた;muta
+ねぎ;negi
+くめ;kume
+いど;ido
+にいみ;niimi
+なら;nara
+ぬだ;nuda
+もうふ;moufu
+しつれい;shitsurei
+すんぽう;sunpou
+てんごく;tengoku
+おんち;onchi
+ちゅうごく;chuugoku
+ちゅうこく;chuukoku
+ちゅうてん;chuuten
+ちゅうかい;chuukai
+てんぽ;tenpo
+ほじょきん;hojokin
+ほき;hoki
+たいほ;taiho
+しゃちょう;shachou
+しゅちょう;shuchou
+つうちょう;tsuuchou
+ぼうちょう;bouchou
+ふよ;fuyo
+ふごう;fugou
+ふきん;fukin
+ぎり;giri
+かいぎ;kaigi
+れいぎ;reigi
+せいねん;seinen
+せいけつ;seiketsu
+せいし;seishi
+しんせい;shinsei
+ふぜい;fuzei
+ごにん;gonin
+ごじん;gojin
+かくご;kakugo
+にほんご;nihongo
+はくじん;hakujin
+いっぱく;ippaku
+せっぱく;seppaku
+はくしゅ;hakushu
+はくらいひん;hakuraihin
+はくちゅう;hakuchuu
+ほうちょう;houchou
+てっぽう;teppou
+すいほう;suihou
+かいほう;kaihou
+どうほう;douhou
+ほうしょく;houshoku
+じょうほ;jouho
+どじょう;dojou
+じょうぞう;jouzou
+かのう;kanou
+きかがく;kikagaku
+しゅっか;shukka
+こうか;kouka
+かせん;kasen
+かだん;kadan
+かもつ;kamotsu
+せいか;seika
+じんこう;jinkou
+せいこう;seikou
+せんこう;senkou
+こうこ;kouko
+こうちゃ;koucha
+こうもく;koumoku
+こうけん;kouken
+ぎこう;gikou
+しかいしゃ;shikaisha
+かし;kashi
+しいく;shiiku
+しこう;shikou
+しし;shishi
+きょうかん;kyoukan
+かんり;kanri
+かんしゃ;kansha
+かんちょう;kanchou
+けんやくする;ken_yakusuru
+ぼうけん;bouken
+けんさ;kensa
+けんどう;kendou
+まやく;mayaku
+けんま;kenma
+まじょ;majo
+しかん;shikan
+しゅっし;shusshi
+すんし;sunshi
+せいしん;seishin
+しんちょう;shinchou
+しんし;shinshi
+そせん;sosen
+そぜい;sozei
+そまつ;somatsu
+そし;soshi
+ていきゅう;teikyuu
+かいてい;kaitei
+してい;shitei
+てきせつ;tekisetsu
+てきち;tekichi
+せいてき;seiteki
+してき;shiteki
+いってき;itteki
+さんばい;sanbai
+ばいよう;baiyou
+ばいしょくする;baishokusuru
+ばいしょう;baishou
+はんてい;hantei
+どうはん;douhan
+こうぎ;kougi
+きこう;kikou
+こうにゅう;kounyuu
+はいすいこう;haisuikou
+ほうそうかい;housoukai
+すいそう;suisou
+かいそう;kaisou
+ゆしゅつ;yushutsu
+ゆらく;yuraku
+きょうゆ;kyouyu
+ゆちゃく;yuchaku
+しゅひつ;shuhitsu
+とくしゅ;tokushu
+しんじゅ;shinju
+きゅうしゅう;kyuushuu
+こうきゅう;koukyuu
+ちかん;chikan
+じょうち;jouchi
+どき;doki
+どりょく;doryoku
+えいえんの;eienno
+すいえい;suiei
+えいか;eika
+ふんすい;funsui
+ぎふん;gifun
+こふん;kofun
+ごふく;gofuku
+ごらく;goraku
+ごかい;gokai
+へんしゅう;henshuu
+へんけん;henken
+ふへん;fuhen
+ひょうはく;hyouhaku
+もくひょう;mokuhyou
+じあい;jiai
+じき;jiki
+じよう;jiyou
+しゅってい;shuttei
+かんてい;kantei
+こうてい;koutei
+つうか;tsuuka
+かちゅう;kachuu
+かふく;kafuku
+きすう;kisuu
+きふ;kifu
+きし;kishi
+こうどう;koudou
+こうかい;koukai
+ていこうする;teikousuru
+きょじん;kyojin
+きょひ;kyohi
+きょり;kyori
+かんそう;kansou
+かいそう;kaisou
+ようきゅう;youkyuu
+きゅうきゅうしゃ;kyuukyuusha
+やきゅう;yakyuu
+じゅうに;juuni
+にまんえん;niman_en
+りよう;riyou
+りえん;rien
+げり;geri
+かんりょう;kanryou
+りょうちょう;ryouchou
+りょうよう;ryouyou
+さいくつ;saikutsu
+やさい;yasai
+さいしょくする;saishokusuru
+せんしゃ;sensha
+せんてつ;sentetsu
+しんすい;shinsui
+しんせつな;shinsetsuna
+しんにゅう;shinnyuu
+しんすい;shinsui
+しんしつ;shinshitsu
+ぶんしょう;bunshou
+ひょうしょう;hyoushou
+しょうじ;shouji
+ほんしゅう;honshuu
+ろくだいしゅう;rokudaishuu
+おうしゅう;oushuu
+そうだい;soudai
+ふくそう;fukusou
+そうだん;soudan
+そうがい;sougai
+はんそく;hansoku
+そくりょう;sokuryou
+そくめん;sokumen
+こうたい;koutai
+たいよ;taiyo
+ゆうたい;yuutai
+おうへい;ouhei
+しっぺい;shippei
+ていえん;teien
+やえん;yaen
+しゅびょう;shubyou
+てんびょう;tenbyou
+あいびょう;aibyou
+かてい;katei
+てんかする;tenkasuru
+かどう;kadou
+そまつな;somatsuna
+ほうまつ;houmatsu
+まっさつ;massatsu
+ようし;youshi
+しどう;shidou
+しぼう;shibou
+かいきょう;kaikyou
+へんきょう;henkyou
+きょうげき;kyougeki
+てっきょう;tekkyou
+きょうせい;kyousei
+あいきょう;aikyou
+きろく;kiroku
+がんじつ;ganjitsu
+きかい;kikai
+たいくつ;taikutsu
+きょうりょく;kyouryoku
+きょうはくする;kyouhakusuru
+そうけい;soukei
+どうそう;dousou
+しょうか;shouka
+すいしょう;suishou
+にんじゃ;ninja
+ひにん;hinin
+ていそう;teisou
+ないてい;naitei
+あんしん;anshin
+あんない;annai
+ばっさい;bassai
+はばつ;habatsu
+ばくろ;bakuro
+ばくはつ;bakuhatsu
+ぼうし;boushi
+ぼくさつ;bokusatsu
+ぶれい;burei
+ぶたい;butai
+かちく;kachiku
+ちくでんち;chikudenchi
+しょうちょう;shouchou
+ちょうばつ;choubatsu
+ちょうしょく;choushoku
+まんちょう;manchou
+じどうしゃ;jidousha
+ろうどう;roudou
+かどう;kadou
+しどうする;shidousuru
+ふそく;fusoku
+そくしんする;sokushinsuru
+じが;jiga
+きが;kiga
+ふきゅう;fukyuu
+がくふ;gakufu
+はんれい;hanrei
+はんせん;hansen
+かへい;kahei
+へいがい;heigai
+ひはん;hihan
+ひくつな;hikutsuna
+ひめい;himei
+ほうごう;hougou
+こうほう;kouhou
+ほうゆう;houyuu
+ひょうそうする;hyousousuru
+どひょう;dohyou
+いかん;ikan
+いあん;ian
+じょうもん;joumon
+じょう;jou
+じょうしゃする;joushasuru
+かじょう;kajou
+じゅけんする;jukensuru
+じゅがく;jugaku
+じゅうじする;juujisuru
+そうじゅうする;soujuusuru
+じゅくちょう;jukuchou
+せいじゅく;seijuku
+ちゅうじゅん;chuujun
+じゅんし;junshi
+むじゅん;mujun
+じょじゅつ;jojutsu
+ぎじゅつ;gijutsu
+かいむ;kaimu
+かいきゅう;kaikyuu
+かいけい;kaikei
+かいが;kaiga
+えしゃく;eshaku
+えほん;ehon
+かいしん;kaishin
+きかい;kikai
+ほうかい;houkai
+じゅっかい;jukkai
+かんつうする;kantsuusuru
+こうかん;koukan
+しょうかんする;shoukansuru
+かんげんする;kangensuru
+じゅんかん;junkan
+しゅのう;shunou
+くのう;kunou
+のうずい;nouzui
+おうごん;ougon
+おうだんする;oudansuru
+けいこく;keikoku
+けいらん;keiran
+けんぎする;kengisuru
+ほけん;hoken
+けんちょう;kenchou
+けんしょう;kenshou
+しゅっきん;shukkin
+きんがしんねん;kingashinnen
+げんこう;genkou
+おうこう;oukou
+こうほ;kouho
+こうや;kouya
+きょうこう;kyoukou
+こんしんかい;konshinkai
+かいこん;kaikon
+こっし;kosshi
+こっけい;kokkei
+しんろう;shinrou
+がろう;garou
+くんこう;kunkou
+くんぷう;kunpuu
+へんきゃくする;henkyakusuru
+きゃくほん;kyakuhon
+こきょう;kokyou
+えいきょう;eikyou
+きょうかい;kyoukai
+きょうだい;kyoudai
+がまん;gaman
+まんが;manga
+せつめい;setsumei
+どうめい;doumei
+こくみん;kokumin
+あんみん;anmin
+てんねん;tennen
+かねんせい;kanensei
+かんれき;kanreki
+れきし;rekishi
+のうがっこう;nougakkou
+のうこう;noukou
+きんし;kinshi
+きんど;kindo
+かっそうろ;kassouro
+ろこつ;rokotsu
+しけい;shikei
+げんけい;genkei
+まさつ;masatsu
+そうほう;souhou
+そうえん;souen
+ちたい;chitai
+たいか;taika
+じたく;jitaku
+いたくする;itakusuru
+そうていする;souteisuru
+ていど;teido
+ていこく;teikoku
+ていけつする;teiketsusuru
+りょうてい;ryoutei
+ていし;teishi
+てっていする;tetteisuru
+てっかい;tekkai
+とこう;tokou
+とうとつな;toutotsuna
+さとう;satou
+そうこ;souko
+そうぞう;souzou
+みんよう;min_you
+どうようする;douyousuru
+じゅよう;juyou
+ようぶ;youbu
+ないよう;naiyou
+ようかい;youkai
+ゆうしゅう;yuushuu
+はいゆう;haiyuu
+しゅうき;shuuki
+かき;kaki
+たか;taka
+じぜん;jizen
+しゅうぜんする;shuuzensuru
+ぞう;zou
+そうぞう;souzou
+ぞうしょ;zousho
+しんぞう;shinzou
+しゅくはく;shukuhaku
+しゅくしょうする;shukushousuru
+りょうしょく;ryoushoku
+りゅうどう;ryuudou
+りゅうあん;ryuuan
+さんか;sanka
+ひさん;hisan
+せいど;seido
+せんすい;sensui
+せんろ;senro
+しんせつ;shinsetsu
+せっしゅ;sesshu
+しゃれい;sharei
+ほうしゃ;housha
+もほうする;mohousuru
+いっしょう;isshou
+じょうしょう;joushou
+しょうそう;shousou
+がんしょう;ganshou
+しょうぐん;shougun
+しょうがくきん;shougakukin
+ほしゅ;hoshu
+かんしゃ;kansha
+いかん;ikan
+こよう;koyou
+こもん;komon
+しがいせん;shigaisen
+しゆう;shiyuu
+そつぎょう;sotsugyou
+そっせん;sossen
+とうてい;toutei
+そっとうする;sottousuru
+せいげん;seigen
+きじょう;kijou
+しさい;shisai
+みつぼう;mitsubou
+きんじとう;kinjitou
+とうじょう;toujou
+あっぱく;appaku
+べいこく;beikoku
+べっそう;bessou
+しゅつぼつする;shutsubotsusuru
+こくびゃく;kokubyaku
+さんがつ;sangatsu
+さんかげつ;sankagetsu
+ほうぎょく;hougyoku
+にひゃく;nihyaku
+きょういき;kyouiki
+しゃじく;shajiku
+きちじつ;kichijitsu
+きく;kiku
+しょくもつ;shokumotsu
+どうみゃく;doumyaku
+ていねい;teinei
+ねったい;nettai
+いちにち;ichinichi
+にくしん;nikushin
+ろうにゃく;rounyaku
+とうにょうびょう;tounyoubyou
+こうおつへい;kouotsuhei
+りちぎ;richigi
+ばりき;bariki
+りくじょう;rikujou
+しゅっきんする;shukkinsuru
+たつじん;tatsujin
+しゅうわいする;shuuwaisuru
+ざせき;zaseki
+ぜいきん;zeikin
+ほぞん;hozon
+めつぼう;metsubou
+しだいに;shidaini
+しせい;shisei
+しほん;shihon
+しもん;shimon
+せっとう;settou
+しゃこう;shakou
+こうりょく;kouryoku
+こうがい;kougai
+こうさつ;kousatsu
+しょうかん;shoukan
+しょうわ;shouwa
+しょうめい;shoumei
+しょうせいする;shouseisuru
+しょうかいする;shoukaisuru
+こしょう;koshou
+しょうしょ;shousho
+ちょうか;chouka
+れいじょう;reijou
+れいきゃく;reikyaku
+れいじ;reiji
+でんれい;denrei
+こうれい;kourei
+りょうど;ryoudo
+さくぶん;sakubun
+さくねん;sakunen
+さくさん;sakusan
+さくしゅ;sakushu
+さぎ;sagi
+ぼち;bochi
+きぼ;kibo
+しぼ;shibo
+まくじょう;makujou
+ばくふ;bakufu
+かいまく;kaimaku
+ばくぜん;bakuzen
+ぎせい;gisei
+ふどうさん;fudousan
+くうふく;kuufuku
+ふくめん;fukumen
+りれき;rireki
+がんたん;gantan
+だいたん;daitan
+たんか;tanka
+どたんば;dotanba
+ちゅうしょく;chuushoku
+けいけん;keiken
+けいしょく;keishoku
+かけい;kakei
+けいろ;keiro
+きかいな;kikaina
+しょうぞうが;shouzouga
+しょうか;shouka
+しょうえん;shouen
+てっしょう;tesshou
+しんしゅく;shinshuku
+しんどう;shindou
+さんしん;sanshin
+こうしん;koushin
+くつじょく;kutsujoku
+けんすい;kensui
+すいみん;suimin
+ぼうすい;bousui
+こうくうゆうびん;koukuuyuubin
+さいほう;saihou
+きさい;kisai
+さいばいする;saibaisuru
+せんい;sen_i
+ふくし;fukushi
+ふくし;fukushi
+ぜんぷく;zenpuku
+そうかん;soukan
+かんちょう;kanchou
+ねんかん;nenkan
+らんようする;ran_yousuru
+かんさつ;kansatsu
+かんしょう;kanshou
+こうかん;koukan
+こうぎ;kougi
+こうざん;kouzan
+かくだい;kakudai
+せいじょう;seijou
+じょうみゃく;joumyaku
+そうぎ;sougi
+こどく;kodoku
+えんこ;enko
+すいか;suika
+せんいん;sen_in
+おんいん;on_in
+そんしつ;sonshitsu
+かんじょう;kanjou
+かんにん;kannin
+じんだい;jindai
+たいぐん;taigun
+ぐんかい;gunkai
+くんしゅ;kunshu
+しちょう;shichou
+しまい;shimai
+はいびょう;haibyou
+へきが;hekiga
+びょうへき;byouheki
+ふかひ;fukahi
+いちおくえん;ichiokuen
+きおく;kioku
+ようい;youi
+ほかくする;hokakusuru
+しゅうかく;shuukaku
+ほご;hogo
+もんぶだいじん;monbudaijin
+しもん;shimon
+いっつい;ittsui
+こうせい;kousei
+こうか;kouka
+ゆうびん;yuubin
+きょうあく;kyouaku
+どきょう;dokyou
+りりく;ririku
+こうこう;koukou
+こうぼ;koubo
+きょうじゅ;kyouju
+けいれつ;keiretsu
+けいそう;keisou
+しそん;shison
+ちゅうけん;chuuken
+けんめい;kenmei
+きんちょう;kinchou
+ふきつ;fukitsu
+きつもん;kitsumon
+けつろん;ketsuron
+かつれい;katsurei
+かんかつ;kankatsu
+そんがい;songai
+けいい;keii
+けいさつ;keisatsu
+きょうい;kyoui
+すいじん;suijin
+でいすい;deisui
+さいせき;saiseki
+ろうどく;roudoku
+るろう;rurou
+りょうしん;ryoushin
+えんりょ;enryo
+ほりょ;horyo
+ひふ;hifu
+ほさ;hosa
+だき;daki
+りんりがく;rinrigaku
+ごりん;gorin
+せきにん;sekinin
+にんしん;ninshin
+うんちん;unchin
+げんいん;gen_in
+こんいん;kon_in
+しゃおん;shaon
+たいし;taishi
+かんり;kanri
+しゅくしゃ;shukusha
+しめい;shimei
+しへい;shihei
+ほじゅう;hojuu
+じゅうほう;juuhou
+だいとうりょう;daitouryou
+ふくつう;fukutsuu
+ぶよう;buyou
+しんじつ;shinjitsu
+きんしんする;kinshinsuru
+ちんあつ;chin_atsu
+ざんこく;zankoku
+こうぞう;kouzou
+へいよう;heiyou
+へい;hei
+かびん;kabin
+ちしき;chishiki
+しょくいん;shokuin
+そしき;soshiki
+しょっき;shokki
+いりょう;iryou
+とうほく;touhoku
+とうきょう;toukyou
+けんがく;kengaku
+けんきゅう;kenkyuu
+かいしゃ;kaisha
+あんないする;annaisuru
+でんわばんごう;denwabangou
+ばんごはん;bangohan
+だんせい;dansei
+じょせい;josei
+べんとう;bentou
+ちず;chizu
+だんち;danchi
+ちかてつ;chikatetsu
+としょかん;toshokan
+だいがく;daigaku
+だいじょうぶ;daijoubu
+がいこくじん;gaikokujin
+しぜん;shizen
+しがつ;shigatsu
+しちがつ;shichigatsu
+きゅうにん;kyuunin
+くじ;kuji
+じゅうろく;juuroku
+せんえん;sen_en
+いちまんえん;ichiman_en
+りょこう;ryokou
+かようび;kayoubi
+ぎゅうにゅう;gyuunyuu
+ぼんさい;bonsai
+すいようび;suiyoubi
+もくようび;mokuyoubi
+いっしょうけんめい;isshoukenmei
+ひじょう;hijou
+きんようび;kin_youbi
+ふじさん;fujisan
+にほん;nihon
+どようび;doyoubi
+えいわじてん;eiwajiten
+かんぜん;kanzen
+でんぽう;denpou
+げんき;genki
+かんじ;kanji
+じょうだん;joudan
+げんかん;genkan
+ひみつ;himitsu
+かいだん;kaidan
+じしん;jishin
+ひこうき;hikouki
+じしん;jishin
+きょねん;kyonen
+しょうてん;shouten
+けいおうだいがく;keioudaigaku
+ごぜん;gozen
+けんぶつ;kenbutsu
+ふきん;fukin
+きんえん;kin_en
+こんしゅう;konshuu
+こんど;kondo
+こうじょう;koujou
+こうこく;koukoku
+こうそくどうろ;kousokudouro
+きょうしつ;kyoushitsu
+えいぎょうちゅう;eigyouchuu
+しゃしん;shashin
+きゅうこう;kyuukou
+きゅうりょう;kyuuryou
+まいにち;mainichi
+らいねん;rainen
+しょうがっこう;shougakkou
+しょうばい;shoubai
+しつもん;shitsumon
+しょっけん;shokken
+せいしょ;seisho
+れいぞうこ;reizouko
+れんしゅう;renshuu
+らんぼう;ranbou
+さいふ;saifu
+せいよう;seiyou
+げきじょう;gekijou
+せいふ;seifu
+せんもんか;senmonka
+せんしゅ;senshu
+しゅうてん;shuuten
+せんきょ;senkyo
+せんそう;sensou
+しけん;shiken
+しっぱい;shippai
+たんじょうび;tanjoubi
+とくべつ;tokubetsu
+ゆうめい;yuumei
+やくそく;yakusoku
+ほんやく;hon_yaku
+たいふう;taifuu
+えきちょう;ekichou
+たいへん;taihen
+つごう;tsugou
+げいしゃ;geisha
+ようふく;youfuku
+やっきょく;yakkyoku
+ふとん;futon
+ぜんぶ;zenbu
+だいぶつ;daibutsu
+さんがく;sangaku
+いっかい;ikkai
+さんだい;sandai
+にまい;nimai
+にさつ;nisatsu
+せんだい;sendai
+じゅうにさい;juunisai
+かわいそう;kawaisou
+おきゃくさん;okyakusan
+めんどうな;mendouna
+めいじじだい;meijijidai
+にっこう;nikkou
+ほっかいどう;hokkaidou
+たいわん;taiwan
+えんぴつ;enpitsu
+とくほん;tokuhon
+かじ;kaji
+そふ;sofu
+そぼ;sobo
+じんじゃ;jinja
+びじん;bijin
+くろう;kurou
+おうじ;ouji
+だいいち;daiichi
+ごめん;gomen
+ざぜん;zazen
+ごらん;goran
+ほうそう;housou
+おんせん;onsen
+むり;muri
+かぐ;kagu
+もんぶしょう;monbushou
+おきのどく;okinodoku
+ほどう;hodou
+ちゅういする;chuuisuru
+もくてき;mokuteki
+いご;igo
+たにん;tanin
+てんきよほう;tenkiyohou
+げんざい;genzai
+ぼうえきかいしゃ;bouekikaisha
+かぞく;kazoku
+ごふんごびょう;gofungobyou
+していせき;shiteiseki
+きょういく;kyouiku
+はいけんする;haikensuru
+ぞくご;zokugo
+ぶし;bushi
+ろうじん;roujin
+けんこう;kenkou
+ちゅうかりょうり;chuukaryouri
+めいし;meishi
+きけん;kiken
+かんぱい;kanpai
+じゅっぽん;juppon
+びょういん;byouin
+しゃくはち;shakuhachi
+しちり;shichiri
+いちりん;ichirin
+どうじ;douji
+せいどう;seidou
+どうたい;doutai
+どうさつ;dousatsu
+すいとう;suitou
+とうゆ;touyu
+ちょうこう;choukou
+ちょうやくばん;chouyakuban
+ちょうせん;chousen
+ちょうぼう;choubou
+とうげんきょう;tougenkyou
+とうそう;tousou
+じょうぶつ;joubutsu
+ぜんせい;zensei
+はんじょう;hanjou
+ちゅうせい;chuusei
+じょうない;jounai
+さいばん;saiban
+しぼう;shibou
+もうじゃ;mouja
+ほんもう;honmou
+ぼうねんかい;bounenkai
+たぼう;tabou
+ほうそうもう;housoumou
+もうもく;moumoku
+ちしきそう;chishikisou
+ぜんそう;zensou
+なかそね;nakasone
+ぞうか;zouka
+ぞうしん;zoushin
+きそうする;kisousuru
+ぞうてい;zoutei
+きょうさんしゅぎ;kyousanshugi
+きょうけい;kyoukei
+きょうきゅうする;kyoukyuusuru
+くよう;kuyou
+くうこう;kuukou
+こうずい;kouzui
+けんにん;kennin
+けんじょう;kenjou
+けんぎ;kengi
+きげん;kigen
+れんばい;renbai
+れんぷ;renpu
+しょうがつ;shougatsu
+せいぎ;seigi
+せっしょう;sesshou
+せいばつ;seibatsu
+ほしょう;hoshou
+びょうしょう;byoushou
+いっかつする;ikkatsusuru
+かっしょく;kasshoku
+かっすい;kassui
+えっけん;ekken
+こご;kogo
+こはん;kohan
+こたん;kotan
+きょじゅう;kyojuu
+そうい;soui
+いだい;idai
+けいい;keii
+かんこく;kankoku
+きしゃ;kisha
+ちき;chiki
+きげん;kigen
+せいき;seiki
+きちゅう;kichuu
+おうひ;ouhi
+しんぱいする;shinpaisuru
+きゅうはん;kyuuhan
+はんかん;hankan
+たんもの;tanmono
+てっぱん;teppan
+けいじばん;keijiban
+はんばい;hanbai
+しゅっぱんしゃ;shuppansha
+はんしん;hanshin
+へんじ;henji
+かめん;kamen
+じむ;jimu
+むさん;musan
+じゅうどう;juudou
+にゅうわ;nyuuwa
+ごふん;gofun
+じぶん;jibun
+ふんまつ;funmatsu
+ふんぎ;fungi
+ふんいき;fun_iki
+びんぼう;binbou
+ひんぷ;hinpu
+はんぷ;hanpu
+こっき;kokki
+しょうぎ;shougi
+きほん;kihon
+がっき;gakki
+せんがく;sengaku
+きんせん;kinsen
+じっせん;jissen
+さんばし;sanbashi
+たいぎょう;taigyou
+ぼたい;botai
+ちあん;chian
+げんしてき;genshiteki
+しんかんせん;shinkansen
+かんちょう;kanchou
+しゅうかん;shuukan
+かんがん;kangan
+かんよう;kan_you
+ごけん;goken
+ふけい;fukei
+けいば;keiba
+きょうそう;kyousou
+がいきょう;gaikyou
+しゅくふく;shukufuku
+しゅうぎ;shuugi
+こっき;kokki
+せいめい;seimei
+ひゃくしょう;hyakushou
+しょうぶん;shoubun
+せいざ;seiza
+みょうじょう;myoujou
+でんち;denchi
+しこうする;shikousuru
+ふせ;fuse
+ひにょう;hinyou
+ぶんぴつ;bunpitsu
+ひつよう;hitsuyou
+しゅくふ;shukufu
+ていしゅく;teishuku
+かんとく;kantoku
+せいじゃく;seijaku
+せきせい;sekisei
+ふくいん;fukuin
+あんき;anki
+かいがん;kaigan
+こうかい;koukai
+ばいか;baika
+ぶじょく;bujoku
+びんそくな;binsokuna
+はんえい;han_ei
+ぼうえい;bouei
+ぼうせき;bouseki
+ぼうず;bouzu
+ぼっちゃん;bocchan
+ぼうがい;bougai
+ぼうせん;bousen
+かんぼうちょう;kanbouchou
+ほうめん;houmen
+ほうし;houshi
+ほうもんする;houmonsuru
+かんげき;kangeki
+ふせつ;fusetsu
+かち;kachi
+ほうちする;houchisuru
+せいしょく;seishoku
+しょくぶつえん;shokubutsuen
+ちょくめん;chokumen
+しょうじき;shoujiki
+とうけつ;touketsu
+れんきんじゅつ;renkinjutsu
+ちんれつ;chinretsu
+ちゅうしゃ;chuusha
+でんちゅう;denchuu
+ちゅうしゃじょう;chuushajou
+ちゅうきする;chuukisuru
+しゅじん;shujin
+じゅうしょ;juusho
+おうふく;oufuku
+いしょう;ishou
+しゃしょう;shashou
+しょくどう;shokudou
+じゆう;jiyuu
+せきゆ;sekiyu
+ちゅうしょう;chuushou
+しゅうしゅ;shuushu
+かくじ;kakuji
+せいかく;seikaku
+ないかく;naikaku
+おきゃくさん;okyakusan
+りょかく;ryokaku
+みゃくらく;myakuraku
+らくご;rakugo
+らくのう;rakunou
+りゃくご;ryakugo
+ぜんがく;zengaku
+しゃふつ;shafutsu
+けいさつしょ;keisatsusho
+ざんしょ;zansho
+しょこく;shokoku
+ちょしゃ;chosha
+ちょゆう;choyuu
+じょうちょ;joucho
+きょうと;kyouto
+たいよう;taiyou
+けいよう;keiyou
+だいちょう;daichou
+ねっとう;nettou
+しょうがい;shougai
+こうてつ;koutetsu
+ちつじょ;chitsujo
+はくぶつかん;hakubutsukan
+とばく;tobaku
+はっか;hakka
+そくばく;sokubaku
+ぼき;boki
+しょうてんがい;shoutengai
+かいどう;kaidou
+しょうがい;shougai
+けいひ;keihi
+けいこ;keiko
+かさく;kasaku
+ふうとう;fuutou
+ほうけん;houken
+えつらんしつ;etsuranshitsu
+まんえつ;man_etsu
+えいびん;eibin
+だつぜい;datsuzei
+だいこん;daikon
+かいこん;kaikon
+むげん;mugen
+がんきゅう;gankyuu
+かいげん;kaigen
+ぎんこう;ginkou
+てったい;tettai
+してん;shiten
+しよう;shiyou
+したい;shitai
+ぎのう;ginou
+きろ;kiro
+しょうねん;shounen
+こうしょう;koushou
+しょうろく;shouroku
+はんせい;hansei
+ごびょう;gobyou
+きみょう;kimyou
+ぶあい;buai
+ふ;fu
+れっとうかん;rettoukan
+でし;deshi
+きょうだい;kyoudai
+ひにく;hiniku
+ひがい;higai
+ひがん;higan
+ひろう;hirou
+はさん;hasan
+ろうば;rouba
+はいく;haiku
+せんぱい;senpai
+はいすいかん;haisuikan
+ひかん;hikan
+もんぴ;monpi
+ゆうざい;yuuzai
+じない;jinai
+しじ;shiji
+じじゅう;jijuu
+しじん;shijin
+しょうたい;shoutai
+れっとう;rettou
+とうふ;toufu
+だいず;daizu
+てんねんとう;tennentou
+せんとう;sentou
+とうろく;touroku
+とざん;tozan
+せんとう;sentou
+おんど;ondo
+ずつう;zutsuu
+ほうねん;hounen
+せいちょうな;seichouna
+たんき;tanki
+ようもう;youmou
+ようそう;yousou
+きゅうよう;kyuuyou
+ようぎょう;yougyou
+はっしょうち;hasshouchi
+しょうさい;shousai
+しんせん;shinsen
+にちょうめ;nichoume
+ちょうにん;chounin
+ちょうてん;chouten
+ちょきん;chokin
+でんとう;dentou
+ていせい;teisei
+だとうする;datousuru
+しゅしゃ;shusha
+しゅみ;shumi
+さいしん;saishin
+さつえい;satsuei
+ちく;chiku
+せんく;senku
+おうしゅう;oushuu
+おうだ;ouda
+すうじく;suujiku
+ちょうせいする;chouseisuru
+しょうちょく;shouchoku
+そがい;sogai
+しんらい;shinrai
+しょうちくばい;shouchikubai
+そしょう;soshou
+ろうおう;rouou
+ていあん;teian
+ていぼう;teibou
+よくぼう;yokubou
+よくしつ;yokushitsu
+ゆうこく;yuukoku
+よゆう;yoyuu
+せきじつ;sekijitsu
+こんじゃく;konjaku
+こせき;koseki
+せきはい;sekihai
+さくご;sakugo
+しゃっきん;shakkin
+そち;sochi
+ほうかつ;houkatsu
+べんぜつ;benzetsu
+じてん;jiten
+きゅうけい;kyuukei
+よやく;yoyaku
+よきん;yokin
+じょぶん;jobun
+じょがい;jogai
+そうじ;souji
+じょじし;jojishi
+じょこう;jokou
+とそう;tosou
+とちゅう;tochuu
+よはく;yohaku
+しゅざいする;shuzaisuru
+ざいさん;zaisan
+てんさい;tensai
+へいてん;heiten
+しきしゃ;shikisha
+こうき;kouki
+かいぐん;kaigun
+ろくしょう;rokushou
+ぶしょう;bushou
+しょうじょう;shoujou
+ふしん;fushin
+せいてん;seiten
+かんじょう;kanjou
+ちょうし;choushi
+ちょうぞう;chouzou
+えんしゅう;enshuu
+がいとうしゃ;gaitousha
+だんがい;dangai
+かくしん;kakushin
+じこくひょう;jikokuhyou
+けいざい;keizai
+しょさい;shosai
+せいしょう;seishou
+せんざい;senzai
+だいく;daiku
+ばいう;baiu
+こうあん;kouan
+けんぽう;kenpou
+かんさい;kansai
+とんカツ;tonkatsu
+めいわく;meiwaku
+ばいしん;baishin
+ばいしゅう;baishuu
+どくりつ;dokuritsu
+はいし;haishi
+とち;tochi
+てんのう;tennou
+えんじょ;enjo
+ごけい;gokei
+はけん;haken
+にゅういん;nyuuin
+みょうにち;myounichi
+けしょうしつ;keshoushitsu
+ふうふ;fuufu
+しゅしょう;shushou
+いるい;irui
+ばんざい;banzai
+しそう;shisou
+じんそく;jinsoku
+へいきん;heikin
+じどう;jidou
+かいしゃく;kaishaku
+もんく;monku
+きゅうじつ;kyuujitsu
+しやくしょ;shiyakusho
+ぼしゅう;boshuu
+ばっきん;bakkin
+ちい;chii
+ちょくせつ;chokusetsu
+せけん;seken
+はんだん;handan
+じむようひん;jimuyouhin
+はんとう;hantou
+しゅんかん;shunkan
+しんこうする;shinkousuru
+けいしき;keishiki
+しゅうきょう;shuukyou
+ちょうさ;chousa
+こうちょうかい;kouchoukai
+ちょうそん;chouson
+ちゅうけい;chuukei
+だいじん;daijin
+だかい;dakai
+えんき;enki
+えんぜつ;enzetsu
+ふっこう;fukkou
+げんめい;genmei
+はんい;han_i
+しゅうりょう;shuuryou
+けっしょう;kesshou
+こくばん;kokuban
+きょうみ;kyoumi
+ふっきゅう;fukkyuu
+ふたん;futan
+さくげん;sakugen
+ごうとう;goutou
+じさつ;jisatsu
+ぎょぎょう;gyogyou
+しゅうのう;shuunou
+じゅりつ;juritsu
+ぎょうせい;gyousei
+はんにん;hannin
+けんせつ;kensetsu
+けんちく;kenchiku
+ひりょう;hiryou
+じげん;jigen
+じしん;jishin
+はってん;hatten
+げか;geka
+しょとく;shotoku
+けいき;keiki
+じゅうよう;juuyou
+ひょうろんか;hyouronka
+いらい;irai
+ひてい;hitei
+じじつ;jijitsu
+めいじいしん;meijiishin
+かいかく;kaikaku
+こうきょ;koukyo
+せっしょう;sesshou
+きそ;kiso
+せんでん;senden
+まんかい;mankai
+ようちえん;youchien
+こうきゅう;koukyuu
+しょくたくえん;shokutakuen
+こうげき;kougeki
+りえき;rieki
+ついきゅう;tsuikyuu
+ひよう;hiyou
+かいたく;kaitaku
+けいたい;keitai
+きしょう;kishou
+こんらん;konran
+じょうやく;jouyaku
+じけん;jiken
+いこう;ikou
+かいとう;kaitou
+けいやく;keiyaku
+きそ;kiso
+きょか;kyoka
+とうぎ;tougi
+しんさつ;shinsatsu
+しゅるい;shurui
+きけん;kiken
+せんぷうき;senpuuki
+にほんしゅ;nihonshu
+しりつ;shiritsu
+すうがく;suugaku
+しゅさい;shusai
+ていか;teika
+きんゆう;kin_yuu
+しき;shiki
+ようさん;yousan
+よさん;yosan
+そうさく;sousaku
+とうちゃく;touchaku
+れんぽう;renpou
+こんなん;konnan
+しんりん;shinrin
+とっぱ;toppa
+おせん;osen
+るいぞう;ruizou
+とうひょう;touhyou
+のうりつ;nouritsu
+ぜんしょう;zenshou
+さいがい;saigai
+さいかい;saikai
+あいけん;aiken
+きんぎょばち;kingyobachi
+せっきょく;sekkyoku
+ぜったい;zettai
+しゅうしょく;shuushoku
+たいど;taido
+りゅうがく;ryuugaku
+おうしゅう;oushuu
+きせつ;kisetsu
+ベース;beesu
+へきえき;hekieki
+ぺこぺこ;pekopeko
+ベスト;besuto
+ベストセラー;besutoseraa
+へだたる;hedataru
+へり;heri
+へりくだる;herikudaru
+へる;heru
+べんかい;benkai
+へんかく;henkaku
+へんかん;henkan
+べんぎ;bengi
+へんけん;henken
+べんご;bengo
+へんさい;hensai
+べんしょう;benshou
+へんせん;hensen
+へんとう;hentou
+へんどう;hendou
+べんろん;benron
+ほ;ho
+ほいく;hoiku
+ボイコット;boikotto
+ポイント;pointo
+ほうあん;houan
+ぼうえい;bouei
+ぼうか;bouka
+ほうかい;houkai
+ぼうがい;bougai
+ほうがく;hougaku
+ほうけん;houken
+ほうさく;housaku
+ほうさく;housaku
+ほうし;houshi
+ほうしき;houshiki
+ほうしゃ;housha
+ほうしゃのう;houshanou
+ほうしゅう;houshuu
+ほうしゅつ;houshutsu
+ほうじる;houjiru
+ほうずる;houzuru
+ぼうせき;bouseki
+ぼうぜん;bouzen
+ほうち;houchi
+ぼうちょう;bouchou
+ほうてい;houtei
+ほうどう;houdou
+ぼうとう;boutou
+いもうと;imouto
+さんにん;sannin
+けいざい;keizai
+がくぶ;gakubu
+けいざいがくぶ;keizaigakubu
+さんねんせい;sannensei
+せんもん;senmon
+し;shi
+ろしあご;roshiago
+アジア;ajia
+いちねんせい;ichinensei
+こうこうせい;koukousei
+らいねん;rainen
+にゅうがく;nyuugaku
+にゅうがくする;nyuugakusuru
+あさごはん;asagohan
+たべる;taberu
+コーヒー;koohii
+すきだ;sukida
+きらいだ;kiraida
+こうちゃ;koucha
+ひるごはん;hirugohan
+しょくどう;shokudou
+ばんごはん;bangohan
+どようび;doyoubi
+よる;yoru
+ときどき;tokidoki
+くる;kuru
+はなしあう;hanashiau
+にちようび;nichiyoubi
+テレビ;terebi
+みる;miru
+ラジオ;rajio
+きく;kiku
+しゅうまつ;shuumatsu
+くがつ;kugatsu
+あさ;asa
+ばん;ban
+いちじはん;ichijihan
+だいさんか;daisanka
+まいあさ;maiasa
+そんな;sonna
+いかなる;ikanaru
+おおきな;ookina
+ちいさな;chiisana
+おえる;oeru
+おみやげ;omiyage
+にほんてきだ;nihontekida
+ほしい;hoshii
+とくちょう;tokuchou
+みんげい;mingei
+ほうふだ;houfuda
+ちかどう;chikadou
+そのまま;sonomama
+ちか;chika
+よう;you
+かていようひん;kateiyouhin
+ふじん;fujin
+いっぱいだ;ippaida
+そこ;soko
+とおりぬける;toorinukeru
+エスカレーター;esukareetaa
+アクセサリー;akusesarii
+ハンドバッグ;handobaggu
+ハンカチ;hankachi
+ベルト;beruto
+そうしんぐ;soushingu
+やくひん;yakuhin
+けしょうひん;keshouhin
+うりば;uriba
+しんじゅ;shinju
+ネックレス;nekkuresu
+そのかわりに;sonokawarini
+じょうひんだ;jouhinda
+すてきだ;sutekida
+きぬ;kinu
+スカーフ;sukaafu
+あか;aka
+きいろ;kiiro
+みどりいろ;midoriiro
+デザイン;dezain
+つつむ;tsutsumu
+に、さんぷん;ni_sanpun
+ブルー;buruu
+おれんじいろ;orenjiiro
+リボン;ribon
+むすぶ;musubu
+はこ;hako
+スカート;sukaato
+ブラウス;burausu
+スーツ;suutsu
+コート;kooto
+パンタロン;pantaron
+サイズ;saizu
+ようふく;youfuku
+きじ;kiji
+さんかい;sankai
+しんし;shinshi
+したぎ;shitagi
+きもの;kimono
+おび;obi
+め;me
+うつる;utsuru
+えんぴつ;enpitsu
+けしごむ;keshigomu
+がくようひん;gakuyouhin
+まんねんひつ;mannenhitsu
+ボールペン;boorupen
+じむようひん;jimuyouhin
+カメラ;kamera
+ちゅうがくせい;chuugakusei
+こんざつ;konzatsu
+こんざつする;konzatsusuru
+ほうせき;houseki
+ききんぞく;kikinzoku
+かく;kaku
+しんるい;shinrui
+おおよろこびだ;ooyorokobida
+とうほく;touhoku
+とうほくちほう;touhokuchihou
+こけしにんぎょう;kokeshiningyou
+かわいらしい;kawairashii
+にする;nisuru
+しょさい;shosai
+かざる;kazaru
+もってくる;mottekuru
+こけし;kokeshi
+でございます;degozaimasu
+ございません;gozaimasen
+すこしおまちください;sukoshiomachikudasai
+コーヒースタンド;koohiisutando
+ひとつ;hitotsu
+ふたつ;futatsu
+みっつ;mittsu
+よっつ;yottsu
+いつつ;itsutsu
+むっつ;muttsu
+やっつ;yattsu
+ここのつ;kokonotsu
+とお;too
+ひき;hiki
+ほん;hon
+けん;ken
+だい;dai
+き;ki
+はい;hai
+つう;tsuu
+こ;ko
+わ;wa
+とう;tou
+そう;sou
+せき;seki
+りょう;ryou
+ちゃく;chaku
+そく;soku
+いつか;itsuka
+にじゅうくにち;nijuukunichi
+てんのう;tennou
+みっか;mikka
+けんぽう;kenpou
+きねん;kinen
+きねんする;kinensuru
+きねんび;kinenbi
+こうきゅうび;koukyuubi
+いのうえ;inoue
+やくしょ;yakusho
+はなや;hanaya
+よる;yoru
+しろ;shiro
+カーネーション;kaaneeshon
+おかしや;okashiya
+チョコレート;chokoreeto
+ひとはこ;hitohako
+とうよこせん;touyokosen
+でんえんちょうふ;den_enchoufu
+みちじゅん;michijun
+みせる;miseru
+みち;michi
+たずねる;tazuneru
+でぐち;deguchi
+みつける;mitsukeru
+あまり;amari
+あし;ashi
+まつ;matsu
+みごとだ;migotoda
+うわる;uwaru
+いりぐち;iriguchi
+もん;mon
+こえ;koe
+こえをかける;koewokakeru
+とつぜん;totsuzen
+いぬ;inu
+げんかん;genkan
+ほえる;hoeru
+とびら;tobira
+あんしん;anshin
+あんしんする;anshinsuru
+ねこ;neko
+とり;tori
+ことり;kotori
+かう;kau
+わらう;warau
+しょくぶつ;shokubutsu
+うえる;ueru
+そだてる;sodateru
+くつ;kutsu
+ぬぐ;nugu
+むすこ;musuko
+むすめ;musume
+おじょうさん;ojousan
+とし;toshi
+うえの;ueno
+どうぶつえん;doubutsuen
+パンダ;panda
+ちょうきてきだ;choukitekida
+こっかけいかくけいざい;kokkakeikakukeizai
+すすめる;susumeru
+きき;kiki
+インフレ;infure
+じつげん;jitsugen
+じつげんする;jitsugensuru
+おいでになる;oideninaru
+こうさくきかい;kousakukikai
+ぼうせききかい;bousekikikai
+ちんぎん;chingin
+おはなしをうかがう;ohanashiwoukagau
+おたずねする;otazunesuru
+つごう;tsugou
+つごうをつける;tsugouwotsukeru
+けいひんちたい;keihinchitai
+じそく;jisoku
+はやさ;hayasa
+げしゃ;gesha
+げしゃする;geshasuru
+おんなのこ;onnanoko
+ひとりむすめ;hitorimusume
+だいきらいだ;daikiraida
+おとこのこ;otokonoko
+あきらめる;akirameru
+こぼす;kobosu
+おば;oba
+けんきゅうじょ;kenkyuujo
+けんきゅういん;kenkyuuin
+ばかりする;bakarisuru
+わ;wa
+の;no
+すると;suruto
+しんゆう;shin_yuu
+だいじ;daiji
+だいじだ;daijida
+ふこう;fukou
+ふこうだ;fukouda
+み;mi
+むらかみ;murakami
+やまがたけん;yamagataken
+まずしい;mazushii
+ちょうなん;chounan
+ぶっしつてきだ;busshitsutekida
+せいさく;seisaku
+こうふく;koufuku
+けってん;ketten
+こうせいしょう;kouseishou
+こうえい;kouei
+りんじ;rinji
+ぎゃくてん;gyakuten
+しさつ;shisatsu
+ぼくし;bokushi
+あくま;akuma
+よういな;youina
+いいんかい;iinkai
+てんじょう;tenjou
+はちじょう;hachijou
+どくせん;dokusen
+かいさつぐち;kaisatsuguchi
+しつれん;shitsuren
+かんごふ;kangofu
+せんこう;senkou
+てつがく;tetsugaku
+かんげい;kangei
+いっせき;isseki
+はいけい;haikei
+かんじゃ;kanja
+そんちょう;sonchou
+じごく;jigoku
+せいれい;seirei
+えんかい;enkai
+こうし;koushi
+ほうしん;houshin
+はくぼく;hakuboku
+ちんもく;chinmoku
+しゅりょう;shuryou
+どれい;dorei
+もうけん;mouken
+いんさつ;insatsu
+がんせき;ganseki
+だんぼう;danbou
+かんぷう;kanpuu
+せきたん;sekitan
+しっけ;shikke
+しんとう;shintou
+かくじつ;kakujitsu
+きぎょう;kigyou
+さんせい;sansei
+せいめい;seimei
+しゃっかん;shakkan
+しじ;shiji
+しっこう;shikkou
+しょぶん;shobun
+しょうにん;shounin
+しょぞく;shozoku
+たいしゅう;taishuu
+はんちょう;hanchou
+すいせん;suisen
+ゆうかい;yuukai
+うよく;uyoku
+れんぞく;renzoku
+けいこう;keikou
+はけん;haken
+しょうかせん;shoukasen
+しょうだく;shoudaku
+はいせき;haiseki
+すてき;suteki
+しゅうげき;shuugeki
+ゆいごん;yuigon
+たんてい;tantei
+こうてい;koutei
+じゅんび;junbi
+しゅうり;shuuri
+さらいねん;sarainen
+くんれん;kunren
+きこく;kikoku
+へいたい;heitai
+ゆうじん;yuujin
+いみん;imin
+だとう;datou
+しんこう;shinkou
+しゅうじん;shuujin
+げいのうかい;geinoukai
+げた;geta
+むだ;muda
+えきたい;ekitai
+じゃくにくきょうしょく;jakunikukyoushoku
+びしょう;bishou
+こくじ;kokuji
+べいこく;beikoku
+ばくしゅ;bakushu
+げんきん;genkin
+りゅうさん;ryuusan
+ひょうざん;hyouzan
+ゆうき;yuuki
+だいいっかん;daiikkan
+こうたんさい;koutansai
+とくがわじだい;tokugawajidai
+ばいしゅん;baishun
+ゆうじょ;yuujo
+しんそう;shinsou
+ごくひ;gokuhi
+きぞく;kizoku
+けっぱく;keppaku
+びおん;bion
+きゅうそく;kyuusoku
+じんけん;jinken
+とうみん;toumin
+どうがん;dougan
+けっきょじん;kekkyojin
+いんりょく;inryoku
+かんこんそうさい;kankonsousai
+こうふん;koufun
+いちょう;ichou
+かいかつ;kaikatsu
+ひめい;himei
+きょくせつ;kyokusetsu
+しゅうい;shuui
+いじょう;ijou
+さべつ;sabetsu
+こうひょう;kouhyou
+よか;yoka
+たいこく;taikoku
+とうあ;toua
+ししょう;shishou
+おくじょうおくをかする;okujouokuwokasuru
+へん;hen
+けいひんせん;keihinsen
+せいかん;seikan
+とにかく;tonikaku
+せきはん;sekihan
+こうはん;kouhan
+らっかんしゅぎ;rakkanshugi
+べんぎしゅぎ;bengishugi
+きょうらくしゅぎ;kyourakushugi
+ゆいぶつろん;yuibutsuron
+つや;tsuya
+にほんとう;nihontou
+せんじょうのたん;senjounotan
+どくしょきょう;dokushokyou
+じもく;jimoku
+さっそく;sassoku
+そうそう;sousou
+そうそう;sousou
+げこ;geko
+じょうご;jougo
+はくちょう;hakuchou
+こうよう;kouyou
+ばか;baka
+いんしょく;inshoku
+なんぼく;nanboku
+うんすい;unsui
+じすい;jisui
+じょさいない;josainai
+こうけつあつ;kouketsuatsu
+ぎし;gishi
+じじょうじばく;jijoujibaku
+かくせいざい;kakuseizai
+ほうおう;houou
+じゅんぽうすと;junpousuto
+ひぎょう;higyou
+ふくだけ;fukudake
+きどうにのる;kidouninoru
+かいぞくばん;kaizokuban
+そんざいりゆう;sonzairiyuu
+こうごうへいか;kougouheika
+がじょう;gajou
+きじゅ;kiju
+はいけい;haikei
+だんがんれっしゃ;danganressha
+すいでん;suiden
+きょうみしんしんする;kyoumishinshinsuru
+せっしょく;sesshoku
+きしょう;kishou
+てんこ;tenko
+ふりょく;furyoku
+しゅういつな;shuuitsuna
+ほうせき;houseki
+いあつてきな;iatsutekina
+めんか;menka
+たいこばん;taikoban
+あくしゅ;akushu
+あくしゅう;akushuu
+ちょうでん;chouden
+はんしょう;hanshou
+まてんろう;matenrou
+めいよきょうじゅ;meiyokyouju
+けっさく;kessaku
+じゅうい;juui
+たんれん;tanren
+じさつみすい;jisatsumisui
+かいはくしょく;kaihakushoku
+ごうゆうする;gouyuusuru
+ふうりん;fuurin
+ちょうちょうふじん;chouchoufujin
+ちち;chichi
+たんたん;tantan
+りゅうりゅう;ryuuryuu
+だくおん;dakuon
+せんりゅう;senryuu
+しつるい;shitsurui
+ろうきゅう;roukyuu
+とろ;toro
+さっきん;sakkin
+しこん;shikon
+らくらい;rakurai
+こうおつへいてい;kouotsuheitei
+いちもうだじん;ichimoudajin
+きんにくろうどう;kinnikuroudou
+いっしょくそくはつ;isshokusokuhatsu
+ひけん;hiken
+けつるい;ketsurui
+きょうさいか;kyousaika
+しちや;shichiya
+たいすい;taisui
+かんこつだったいする;kankotsudattaisuru
+しっこく;shikkoku
+すいとう;suitou
+かんさんしんくかん;kansanshinkukan
+よくよう;yokuyou
+ろうでん;rouden
+ほくとしちせい;hokutoshichisei
+かっこう;kakkou
+こんたん;kontan
+らんそう;ransou
+えん;en
+げいいんばしょく;geiinbashoku
+しゆうをけっする;shiyuuwokessuru
+とうき;touki
+とうすい;tousui
+かんとうしょう;kantoushou
+ぎしんあんき;gishin_anki
+ここう;kokou
+しっぷうじんらいてき;shippuujinraiteki
+りゅうず;ryuuzu
+ばいしゃくけっこん;baishakukekkon
+とうほんせいそう;touhonseisou
+きかん;kikan
+けいこうでんとう;keikoudentou
+ウーロンちゃ;uuroncha
+めんぼく;menboku
+ようき;youki
+いんき;inki
+やくどし;yakudoshi
+かん;kan
+らんがい;rangai
+ひょうり;hyouri
+ゆうよ;yuuyo
+へいこう;heikou
+けんしん;kenshin
+ちんみ;chinmi
+きょぎ;kyogi
+さこく;sakoku
+だんぺん;danpen
+ひんど;hindo
+そうにゅう;sounyuu
+りょうぼ;ryoubo
+しとう;shitou
+じゅんかい;junkai
+そうしょく;soushoku
+せいぎょ;seigyo
+ゆせい;yusei
+もうそう;mousou
+もうらする;mourasuru
+ふにん;funin
+のうこう;noukou
+こうそく;kousoku
+こんきょ;konkyo
+とくしょく;tokushoku
+ゆうぜん;yuuzen
+びょうとう;byoutou
+ひじゅん;hijun
+じゃっかん;jakkan
+しゃだん;shadan
+じょうはつ;jouhatsu
+へいぼん;heibon
+きょくたん;kyokutan
+ねんど;nendo
+せんかい;senkai
+おんわ;onwa
+きんこう;kinkou
+ひんかく;hinkaku
+ちょうえつ;chouetsu
+しっそ;shisso
+じゅうたい;juutai
+びしゅう;bishuu
+こちょう;kochou
+しゅつじん;shutsujin
+すうはい;suuhai
+りんじん;rinjin
+せんせい;sensei
+とうすい;tousui
+ほうよう;houyou
+かくねん;kakunen
+がっしゅく;gasshuku
+けんびきょう;kenbikyou
+かいじょう;kaijou
+こうそ;kouso
+てんぷ;tenpu
+ばんそう;bansou
+じゅんきん;junkin
+きょうかん;kyoukan
+そうどう;soudou
+ごうもん;goumon
+まいぼつ;maibotsu
+せんたく;sentaku
+いっち;icchi
+きがん;kigan
+とうめい;toumei
+けんない;kennai
+かんよう;kan_you
+もはん;mohan
+じゅんしょく;junshoku
+しゃめん;shamen
+ちじょく;chijoku
+しょうこ;shouko
+けいだい;keidai
+きんぱつ;kinpatsu
+ついらく;tsuiraku
+ざんてい;zantei
+ぎゃくさつ;gyakusatsu
+ぶんせき;bunseki
+げっぷ;geppu
+きゅうだん;kyuudan
+せいぼ;seibo
+ついとう;tsuitou
+じしゃく;jishaku
+そぞう;sozou
+なっとう;nattou
+しんまい;shinmai
+こんちゅう;konchuu
+しさ;shisa
+じんぐう;jinguu
+さんがく;sangaku
+ていそう;teisou
+げんしろ;genshiro
+かえん;kaen
+ついせき;tsuiseki
+だらく;daraku
+ようす;yousu
+にょうぼう;nyoubou
+ちょうなん;chounan
+ちくら;chikura
+ぶようじん;buyoujin
+びょうどう;byoudou
+さぎょう;sagyou
+すいとう;suitou
+しょうに;shouni
+ぞうに;zouni
+うもう;umou
+ひょうし;hyoushi
+だんじき;danjiki
+きゅうでん;kyuuden
+かいぼう;kaibou
+いしょく;ishoku
+こんきゅう;konkyuu
+へんせん;hensen
+よくじつ;yokujitsu
+むちゅう;muchuu
+きゅうどう;kyuudou
+ばつぐん;batsugun
+じんぎ;jingi
+ぜんじ;zenji
+じんもん;jinmon
+そうしつ;soushitsu
+かし;kashi
+げんそう;gensou
+かんわ;kanwa
+えきびょう;ekibyou
+なんか;nanka
+ちっそく;chissoku
+しゃめん;shamen
+しょうれいきん;shoureikin
+かんぼつ;kanbotsu
+ちくいち;chikuichi
+きとく;kitoku
+どんぶつ;donbutsu
+やばん;yaban
+ちゅうてつ;chuutetsu
+しゅんさい;shunsai
+がんちく;ganchiku
+ひやく;hiyaku
+ゆうげん;yuugen
+かっせん;kassen
+ひろうえん;hirouen
+あいしょう;aishou
+じゅうまんえん;juuman_en
+ゆうぎ;yuugi
+はあく;haaku
+ざんこく;zankoku
+じしゅく;jishuku
+じょうじゅ;jouju
+むほん;muhon
+さいしょう;saishou
+おせちりょうり;osechiryouri
+あいそ;aiso
+しゅじゅう;shujuu
+たんざく;tanzaku
+せんぼう;senbou
+ねんぐ;nengu
+きょうしゃ;kyousha
+いっさい;issai
+すき;suki
+くでん;kuden
+きんじょう;kinjou
+ちょうもん;choumon
+だいみょう;daimyou
+げし;geshi
+ていさい;teisai
+こんりゅう;konryuu
+ひょうろう;hyourou
+くないちょう;kunaichou
+ゆさん;yusan
+ぞうお;zouo
+だいおんじょう;daionjou
+そうしょう;soushou
+したく;shitaku
+うむ;umu
+しゃくどう;shakudou
+らいさん;raisan
+じゅみょう;jumyou
+そうさい;sousai
+りょうし;ryoushi
+ふってい;futtei
+ばちあたり;bachiatari
+ぶぎょう;bugyou
+けねん;kenen
+やくびょうがみ;yakubyougami
+こんせき;konseki
+かんおうかい;kan_oukai
+かんきゅう;kankyuu
+いっし;isshi
+さきゅう;sakyuu
+すいじょう;suijou
+かんぱん;kanpan
+すいそう;suisou
+しゅうじゃく;shuujaku
+しんおう;shin_ou
+ごうしゃ;gousha
+はっと;hatto
+しりょう;shiryou
+ちん;chin
+こうたい;koutai
+しょうぞく;shouzoku
+じょせい;josei
+しんぼく;shinboku
+きんけい;kinkei
+こうかく;koukaku
+はんざつ;hanzatsu
+こくう;kokuu
+ごてん;goten
+かんきゃく;kankyaku
+けいてき;keiteki
+ぎょうてんする;gyoutensuru
+すいじゃく;suijaku
+きんせん;kinsen
+はいはん;haihan
+どしゃほうかい;doshahoukai
+さんか;sanka
+れいげん;reigen
+ちょうえき;choueki
+くおん;kuon
+さいご;saigo
+こうし;koushi
+けびょう;kebyou
+いんきょ;inkyo
+てんにょ;tennyo
+ゆいしょ;yuisho
+いいだくだく;iidakudaku
+しんしんこうじゃく;shinshinkoujaku
+ばっし;basshi
+いっこん;ikkon
+なや;naya
+たいぼく;taiboku
+なんど;nando
+ひってき;hitteki
+とつめんきょう;totsumenkyou
+おうめんきょう;oumenkyou
+けんし;kenshi
+とうは;touha
+りゅうき;ryuuki
+せいりょうざい;seiryouzai
+どんてん;donten
+ぎょうてん;gyouten
+はいちゃく;haichaku
+じゅんぽう;junpou
+せんぷくする;senpukusuru
+えんぶん;enbun
+かほう;kahou
+しゅうてい;shuutei
+ぼうげん;bougen
+へんれいする;henreisuru
+ちゅうとんする;chuutonsuru
+ちょうてい;choutei
+いんとく;intoku
+しんりょく;shinryoku
+ふうき;fuuki
+くどく;kudoku
+せいきょ;seikyo
+しぎん;shigin
+いっこく;ikkoku
+いっしゃく;isshaku
+いっきん;ikkin
+じじん;jijin
+しんく;shinku
+せきせつ;sekisetsu
+きゅうじ;kyuuji
+こうずか;kouzuka
+げんち;genchi
+くとうてん;kutouten
+しんか;shinka
+しょうよう;shouyou
+いちないしじゅう;ichinaishijuu
+じゅんぼく;junboku
+せつれつ;setsuretsu
+はんも;hanmo
+らくいんきょ;rakuinkyo
+ちゅうしん;chuushin
+いかく;ikaku
+たんせい;tansei
+しょみん;shomin
+だんしゃく;danshaku
+ちゅうよう;chuuyou
+しょうにん;shounin
+えま;ema
+くり;kuri
+ごりやく;goriyaku
+ごんぎょう;gongyou
+せっしょうかい;sesshoukai
+きえ;kie
+ぼんのう;bonnou
+しゅくごう;shukugou
+ろくやおん;rokuyaon
+けごんぎょう;kegongyou
+げだつ;gedatsu
+えしん;eshin
+にそう;nisou
+しゅぎょう;shugyou
+なむあみだぶつ;namuamidabutsu
+おしょう;oshou
+にょらい;nyorai
+あんぎゃ;angya
+しゅじょう;shujou
+えはつ;ehatsu
+ほっしん;hosshin
+せっしゅ;sesshu
+こうぼうだいし;kouboudaishi
+かくりつ;kakuritsu
+がくれき;gakureki
+かけ;kake
+かけ;kake
+かけ;kake
+がけ;gake
+かけあし;kakeashi
+かけい;kakei
+かけっこ;kakekko
+かける;kakeru
+かける;kakeru
+かこう;kakou
+かごう;kagou
+かさばる;kasabaru
+かさむ;kasamu
+かじょうがき;kajougaki
+かしら;kashira
+かすか;kasuka
+かすむ;kasumu
+かする;kasuru
+かせい;kasei
+かせき;kaseki
+かせん;kasen
+かせん;kasen
+かそ;kaso
+かた;kata
+かだい;kadai
+がたい;gatai
+かたこと;katakoto
+かたづけ;kataduke
+かたむける;katamukeru
+かためる;katameru
+かたわら;katawara
+かだん;kadan
+かちく;kachiku
+かつ;katsu
+かっき;kakki
+がっくり;gakkuri
+がっしょう;gasshou
+がっしり;gasshiri
+がっち;gacchi
+がっちり;gacchiri
+かつて;katsute
+かって;katte
+カット;katto
+かっぱつ;kappatsu
+カップ;kappu
+がっぺい;gappei
+カテゴリー;kategorii
+かなう;kanau
+かなえる;kanaeru
+かなづち;kanaduchi
+かなわない;kanawanai
+かにゅう;kanyuu
+かねて;kanete
+かばう;kabau
+かぶしき;kabushiki
+かぶれる;kabureru
+かふん;kafun
+かへい;kahei
+かまえる;kamaeru
+かみ;kami
+かみつ;kamitsu
+かみきる;kamikiru
+カムバック;kamubakku
+カメラマン;kameraman
+かゆ;kayu
+からだつき;karadatsuki
+からむ;karamu
+かり;kari
+かり;kari
+かりに;karini
+カルテ;karute
+カレー;karee
+ガレージ;gareeji
+かろう;karou
+かろうじて;karoujite
+かわす;kawasu
+かわるがわる;kawarugawaru
+かん;kan
+かん;kan
+かん;kan
+がん;gan
+かんい;kan_i
+かんがい;kangai
+がんか;ganka
+がんきゅう;gankyuu
+がんぐ;gangu
+かんけつ;kanketsu
+かんげん;kangen
+かんご;kango
+かんご;kango
+がんこ;ganko
+かんこう;kankou
+かんこう;kankou
+かんこく;kankoku
+かんさん;kansan
+かんし;kanshi
+かんしゅう;kanshuu
+かんしゅう;kanshuu
+がんしょ;gansho
+かんしょう;kanshou
+がんじょう;ganjou
+かんしょく;kanshoku
+かんじん;kanjin
+かんじん;kanjin
+かんせい;kansei
+かんぜい;kanzei
+がんせき;ganseki
+かんせん;kansen
+かんせん;kansen
+かんそ;kanso
+かんてん;kanten
+かんど;kando
+カンニング;kanningu
+がんねん;gannen
+かんぶ;kanbu
+かんぺき;kanpeki
+かんべん;kanben
+かんむりょう;kanmuryou
+かんゆう;kan_yuu
+かんよ;kan_yo
+かんよう;kan_you
+がんらい;ganrai
+かんらん;kanran
+かんりょう;kanryou
+かんれい;kanrei
+かんれき;kanreki
+かんろく;kanroku
+かんわ;kanwa
+ぎあん;gian
+きがい;kigai
+きかく;kikaku
+きかく;kikaku
+きかざる;kikazaru
+きがね;kigane
+きがる;kigaru
+きかん;kikan
+きかん;kikan
+きき;kiki
+ききとり;kikitori
+ききめ;kikime
+ききょう;kikyou
+ぎきょく;gikyoku
+ききん;kikin
+きげき;kigeki
+ぎけつ;giketsu
+きけん;kiken
+きげん;kigen
+きこう;kikou
+きこん;kikon
+きざ;kiza
+きさい;kisai
+きざし;kizashi
+きしつ;kishitsu
+きじつ;kijitsu
+きしむ;kishimu
+ぎじどう;gijidou
+きじゅつ;kijutsu
+きしょう;kishou
+きずく;kizuku
+きずつく;kizutsuku
+きずつける;kizutsukeru
+きせい;kisei
+ぎせい;gisei
+きせん;kisen
+きぞう;kizou
+ぎぞう;gizou
+きぞく;kizoku
+ぎだい;gidai
+きたえる;kitaeru
+きだて;kidate
+あ;a
+あいそう;aisou
+あいだがら;aidagara
+あいま;aima
+あえて;aete
+あおぐ;aogu
+あか;aka
+あかじ;akaji
+あかす;akasu
+あからむ;akaramu
+あがり;agari
+あきらめ;akirame
+あく;aku
+アクセル;akuseru
+あくどい;akudoi
+あご;ago
+あこがれ;akogare
+あさ;asa
+あざ;aza
+あさましい;asamashii
+あざむく;azamuku
+あざやか;azayaka
+あざわらう;azawarau
+あしからず;ashikarazu
+あじわい;ajiwai
+あせる;aseru
+あせる;aseru
+あたい;atai
+あたいする;ataisuru
+あたり;atari
+あっか;akka
+あつかい;atsukai
+あっけない;akkenai
+あっさり;assari
+あっせん;assen
+あっとう;attou
+あっぱく;appaku
+アップ;appu
+あつらえる;atsuraeru
+あつりょく;atsuryoku
+あて;ate
+あて;ate
+あてじ;ateji
+あてる;ateru
+あとつぎ;atotsugi
+あとまわし;atomawashi
+あぶらえ;aburae
+アプローチ;apuroochi
+あべこべ;abekobe
+あまえる;amaeru
+あまぐ;amagu
+あまくち;amakuchi
+アマチュア;amachua
+あみ;ami
+あやつる;ayatsuru
+あやぶむ;ayabumu
+あやふや;ayafuya
+あやまち;ayamachi
+あやまる;ayamaru
+あゆみ;ayumi
+あゆむ;ayumu
+あらかじめ;arakajime
+あらす;arasu
+あらそい;arasoi
+あらたまる;aratamaru
+あらっぽい;arappoi
+アラブ;arabu
+あられ;arare
+ありさま;arisama
+ありのまま;arinomama
+ありふれる;arifureru
+アルカリ;arukari
+アルコール;arukooru
+アルミ;arumi
+アワー;awaa
+あわす;awasu
+あわせ;awase
+アンケート;ankeeto
+アンコール;ankooru
+あんさつ;ansatsu
+あんざん;anzan
+あんじ;anji
+あんじる;anjiru
+あんせい;ansei
+あんのじょう;annojou
+い;i
+い;i
+いいかげん;iikagen
+いいわけ;iiwake
+いいん;iin
+イェス;yesu
+いえで;iede
+いかす;ikasu
+いかに;ikani
+いかにも;ikanimo
+いかり;ikari
+いき;iki
+いぎ;igi
+いきがい;ikigai
+いきちがい;ikichigai
+いきごむ;ikigomu
+いくせい;ikusei
+いくた;ikuta
+いける;ikeru
+いけん;iken
+いこう;ikou
+いこう;ikou
+いざ;iza
+いじ;iji
+いじゅう;ijuu
+いしょう;ishou
+いじる;ijiru
+いせい;isei
+いせき;iseki
+いぜん;izen
+いぞん;izon
+いたく;itaku
+いただき;itadaki
+いたって;itatte
+いためる;itameru
+いためる;itameru
+いたわる;itawaru
+いち;ichi
+いちがいに;ichigaini
+いちじるしい;ichijirushii
+いちどう;ichidou
+いちぶぶん;ichibubun
+いちべつ;ichibetsu
+いちめん;ichimen
+いちもく;ichimoku
+いちよう;ichiyou
+いちりつ;ichiritsu
+いちれん;ichiren
+いっかつ;ikkatsu
+いっき;ikki
+いっきょに;ikkyoni
+いっけん;ikken
+いっさい;issai
+いっしん;isshin
+いっそ;isso
+いったい;ittai
+いっぺん;ippen
+いと;ito
+いどう;idou
+いとなむ;itonamu
+いどむ;idomu
+いなびかり;inabikari
+いのり;inori
+いびき;ibiki
+いまさら;imasara
+いまだ;imada
+いみん;imin
+いやいや;iyaiya
+いやしい;iyashii
+いやに;iyani
+いやらしい;iyarashii
+いよく;iyoku
+いりょう;iryou
+いりょく;iryoku
+いるい;irui
+いろん;iron
+いんかん;inkan
+いんき;inki
+いんきょ;inkyo
+インターチェンジ;intaachenji
+インターナショナル;intaanashonaru
+インターフォン;intaafon
+インテリ;interi
+インフォメーション;infomeeshon
+インフレ;infure
+うかる;ukaru
+うけいれ;ukeire
+うけいれる;ukeireru
+うけつぐ;uketsugu
+うけつける;uketsukeru
+うけとめる;uketomeru
+うけみ;ukemi
+うけもち;ukemochi
+うごき;ugoki
+うず;uzu
+うずめる;uzumeru
+うそつき;usotsuki
+うたたね;utatane
+うちあける;uchiakeru
+うちきる;uchikiru
+うちけし;uchikeshi
+うちこむ;uchikomu
+うちわ;uchiwa
+うちわけ;uchiwake
+うつし;utsushi
+うったえ;uttae
+うっとうしい;uttoushii
+うつむく;utsumuku
+うつろ;utsuro
+うつわ;utsuwa
+うでまえ;udemae
+うてん;uten
+うながす;unagasu
+うぬぼれ;unubore
+うまれつき;umaretsuki
+うまる;umaru
+うむ;umu
+うめこむ;umekomu
+うめぼし;umeboshi
+うらがえし;uragaeshi
+うりだし;uridashi
+うりだす;uridasu
+うるおう;uruou
+うわき;uwaki
+うわまわる;uwamawaru
+うわる;uwaru
+うんえい;un_ei
+うんざり;unzari
+うんそう;unsou
+うんちん;unchin
+うんぬん;unnun
+うんぱん;unpan
+うんめい;unmei
+うんゆ;un_yu
+うんよう;un_you
+え;e
+エアメール;eameeru
+えい;ei
+えいじ;eiji
+えいしゃ;eisha
+えいせい;eisei
+えいぞう;eizou
+えいゆう;eiyuu
+えき;eki
+えつらん;etsuran
+えもの;emono
+えり;eri
+エレガント;ereganto
+えん;en
+えんかつ;enkatsu
+えんがわ;engawa
+えんがん;engan
+えんきょく;enkyoku
+えんしゅつ;enshutsu
+エンジニア;enjinia
+えんじる;enjiru
+えんずる;enzuru
+えんせん;ensen
+えんだん;endan
+えんぽう;enpou
+えんまん;enman
+お;o
+おいこむ;oikomu
+おいだす;oidasu
+おいて;oite
+おいる;oiru
+おう;ou
+おうきゅう;oukyuu
+おうごん;ougon
+おうしん;oushin
+おうぼ;oubo
+おおい;ooi
+おおかた;ookata
+おおがら;oogara
+オーケー;ookee
+おおげさ;oogesa
+おおすじ;oosuji
+おおぞら;oozora
+オートマチック;ootomachikku
+オープン;oopun
+オーバー;oobaa
+おおはば;oohaba
+おおまかな;oomakana
+おおみず;oomizu
+おおやけ;ooyake
+おかす;okasu
+おかす;okasu
+おくびょう;okubyou
+おくらす;okurasu
+おくれ;okure
+おごそか;ogosoka
+おこない;okonai
+おごる;ogoru
+おさまる;osamaru
+おさまる;osamaru
+おさまる;osamaru
+おさん;osan
+おしえ;oshie
+おしきる;oshikiru
+おしこむ;oshikomu
+おしむ;oshimu
+おしよせる;oshiyoseru
+おす;osu
+おせじ;oseji
+おそう;osou
+おそくとも;osokutomo
+おそれ;osore
+おそれいる;osoreiru
+おだてる;odateru
+おちこむ;ochikomu
+おちつき;ochitsuki
+おちば;ochiba
+おつ;otsu
+おつかい;otsukai
+おっかない;okkanai
+おてあげ;oteage
+おどおど;odoodo
+おどす;odosu
+おとずれる;otozureru
+おとも;otomo
+おとろえる;otoroeru
+おどろき;odoroki
+おないどし;onaidoshi
+おのずから;onozukara
+おびえる;obieru
+おびただしい;obitadashii
+おびやかす;obiyakasu
+おびる;obiru
+おふくろ;ofukuro
+おぼえ;oboe
+おまけ;omake
+おみや;omiya
+おむつ;omutsu
+おもいつき;omoitsuki
+おもむき;omomuki
+おもむく;omomuku
+おもんじる;omonjiru
+おもんずる;omonzuru
+おやじ;oyaji
+および;oyobi
+およぶ;oyobu
+おり;ori
+おり;ori
+オリエンテーション;orienteeshon
+おりかえす;orikaesu
+おりもの;orimono
+おる;oru
+おれ;ore
+おろか;oroka
+おろそか;orosoka
+おんぶ;onbu
+オンライン;onrain
+おんわ;onwa
+が;ga
+が;ga
+カーペット;kaapetto
+かい;kai
+かい;kai
+がい;gai
+かいあく;kaiaku
+かいうん;kaiun
+がいか;gaika
+かいかく;kaikaku
+かいがら;kaigara
+がいかん;gaikan
+かいきゅう;kaikyuu
+かいきょう;kaikyou
+かいけん;kaiken
+かいご;kaigo
+かいさい;kaisai
+かいしゅう;kaishuu
+かいしゅう;kaishuu
+かいじゅう;kaijuu
+かいじょ;kaijo
+がいしょう;gaishou
+がいする;gaisuru
+がいせつ;gaisetsu
+かいそう;kaisou
+かいそう;kaisou
+かいたく;kaitaku
+かいだん;kaidan
+かいてい;kaitei
+かいてい;kaitei
+ガイド;gaido
+かいどう;kaidou
+がいとう;gaitou
+がいとう;gaitou
+ガイドブック;gaidobukku
+かいにゅう;kainyuu
+がいねん;gainen
+かいはつ;kaihatsu
+かいばつ;kaibatsu
+かいほう;kaihou
+かいぼう;kaibou
+がいらい;gairai
+かいらん;kairan
+がいりゃく;gairyaku
+かいりゅう;kairyuu
+かいりょう;kairyou
+かいろ;kairo
+かいろ;kairo
+かえりみる;kaerimiru
+かえりみる;kaerimiru
+かおつき;kaotsuki
+かがい;kagai
+かかげる;kakageru
+かかと;kakato
+かきとる;kakitoru
+かきまわす;kakimawasu
+かく;kaku
+かく;kaku
+かく;kaku
+かく;kaku
+かく;kaku
+かく;kaku
+がくげい;gakugei
+かくさ;kakusa
+かくさん;kakusan
+がくし;gakushi
+かくしゅ;kakushu
+かくしゅう;kakushuu
+かくしん;kakushin
+かくしん;kakushin
+がくせつ;gakusetsu
+かくてい;kakutei
+カクテル;kakuteru
+かくとく;kakutoku
+がくふ;gakufu
+かくほ;kakuho
+かくめい;kakumei
+きたる;kitaru
+きちっと;kichitto
+きちょうめん;kichoumen
+きっかり;kikkari
+きっちり;kicchiri
+きっぱり;kippari
+きてい;kitei
+きてん;kiten
+きどう;kidou
+ぎのう;ginou
+きはん;kihan
+きひん;kihin
+きふう;kifuu
+きふく;kifuku
+きぼ;kibo
+きまぐれ;kimagure
+きまじめ;kimajime
+きまつ;kimatsu
+きまりわるい;kimariwarui
+きめい;kimei
+きやく;kiyaku
+きゃくしょく;kyakushoku
+ぎゃくてん;gyakuten
+きゃくほん;kyakuhon
+きゃしゃ;kyasha
+きゃっかん;kyakkan
+キャッチ;kyacchi
+キャリア;kyaria
+きゅうえん;kyuuen
+きゅうがく;kyuugaku
+きゅうきょく;kyuukyoku
+きゅうくつ;kyuukutsu
+きゅうこん;kyuukon
+きゅうさい;kyuusai
+きゅうじ;kyuuji
+きゅうしょく;kyuushoku
+きゅうせん;kyuusen
+きゅうでん;kyuuden
+きゅうち;kyuuchi
+きゅうぼう;kyuubou
+きゅうりょう;kyuuryou
+きよ;kiyo
+きょう;kyou
+きょう;kyou
+きょうい;kyoui
+きょうか;kyouka
+きょうかい;kyoukai
+きょうがく;kyougaku
+きょうかん;kyoukan
+きょうぎ;kyougi
+きょうぐう;kyouguu
+きょうくん;kyoukun
+きょうこう;kyoukou
+きょうこう;kyoukou
+きょうざい;kyouzai
+きょうさく;kyousaku
+ぎょうしゃ;gyousha
+きょうじゅ;kyouju
+きょうしゅう;kyoushuu
+きょうしゅう;kyoushuu
+きょうしょく;kyoushoku
+きょうじる;kyoujiru
+きょうせい;kyousei
+ぎょうせい;gyousei
+ぎょうせき;gyouseki
+きょうぞん;kyouzon
+きょうちょう;kyouchou
+きょうてい;kyoutei
+きょうど;kyoudo
+きょうはく;kyouhaku
+ぎょうむ;gyoumu
+きょうめい;kyoumei
+きょうり;kyouri
+きょうれつ;kyouretsu
+きょうわ;kyouwa
+きょくげん;kyokugen
+きょくたん;kyokutan
+きょじゅう;kyojuu
+きょぜつ;kyozetsu
+ぎょせん;gyosen
+ぎょそん;gyoson
+きょひ;kyohi
+きょよう;kyoyou
+きよらか;kiyoraka
+きらびやか;kirabiyaka
+きり;kiri
+きり;kiri
+ぎり;giri
+きりかえ;kirikae
+きりゅう;kiryuu
+きれめ;kireme
+ぎわく;giwaku
+きわめて;kiwamete
+きん;kin
+きんがん;kingan
+きんきゅう;kinkyuu
+きんこう;kinkou
+きんこう;kinkou
+きんし;kinshi
+きんじる;kinjiru
+きんべん;kinben
+ぎんみ;ginmi
+きんむ;kinmu
+きんもつ;kinmotsu
+きんろう;kinrou
+く;ku
+く;ku
+クイズ;kuizu
+くいちがう;kuichigau
+くうかん;kuukan
+くうふく;kuufuku
+くかく;kukaku
+くかん;kukan
+くき;kuki
+くぎり;kugiri
+くぐる;kuguru
+くじ;kuji
+くじびき;kujibiki
+くすぐったい;kusuguttai
+ぐち;guchi
+くちずさむ;kuchizusamu
+くちばし;kuchibashi
+くちる;kuchiru
+くつがえす;kutsugaesu
+くっきり;kukkiri
+くっせつ;kussetsu
+ぐっと;gutto
+くびかざり;kubikazari
+くびわ;kubiwa
+くみこむ;kumikomu
+くみあわせる;kumiawaseru
+くら;kura
+グレー;guree
+クレーン;kureen
+くろうと;kurouto
+くろじ;kuroji
+ぐん;gun
+ぐんかん;gunkan
+ぐんじ;gunji
+くんしゅ;kunshu
+ぐんしゅう;gunshuu
+ぐんしゅう;gunshuu
+ぐんび;gunbi
+ぐんぷく;gunpuku
+けい;kei
+けい;kei
+げい;gei
+けいい;keii
+けいか;keika
+けいかい;keikai
+けいかい;keikai
+けいき;keiki
+けいき;keiki
+けいぐ;keigu
+けいげん;keigen
+けいさい;keisai
+けいしゃ;keisha
+けいせい;keisei
+けいせい;keisei
+けいそつ;keisotsu
+けいたい;keitai
+けいたい;keitai
+けいばつ;keibatsu
+けいひ;keihi
+けいぶ;keibu
+けいべつ;keibetsu
+けいれき;keireki
+けいろ;keiro
+ケース;keesu
+けがらわしい;kegarawashii
+げきだん;gekidan
+げきれい;gekirei
+ゲスト;gesuto
+けだもの;kedamono
+けつ;ketsu
+けつい;ketsui
+けっかく;kekkaku
+けっかん;kekkan
+けつぎ;ketsugi
+けっこう;kekkou
+けつごう;ketsugou
+けっさん;kessan
+げっしゃ;gessha
+けっしょう;kesshou
+けっしょう;kesshou
+けっせい;kessei
+けっそく;kessoku
+げっそり;gessori
+けつだん;ketsudan
+げっぷ;geppu
+けつぼう;ketsubou
+けとばす;ketobasu
+けなす;kenasu
+けむたい;kemutai
+けむる;kemuru
+けもの;kemono
+けらい;kerai
+げり;geri
+けん;ken
+けん;ken
+けんい;ken_i
+けんぎょう;kengyou
+げんけい;genkei
+げんけい;genkei
+けんげん;kengen
+げんこう;genkou
+けんざい;kenzai
+げんさく;gensaku
+けんじ;kenji
+げんし;genshi
+げんしゅ;genshu
+げんしょ;gensho
+けんしょう;kenshou
+げんしょう;genshou
+けんぜん;kenzen
+げんそ;genso
+げんぞう;genzou
+げんそく;gensoku
+けんち;kenchi
+げんち;genchi
+げんてい;gentei
+げんてん;genten
+げんてん;genten
+げんばく;genbaku
+げんぶん;genbun
+げんみつ;genmitsu
+けんめい;kenmei
+けんやく;ken_yaku
+げんゆ;gen_yu
+けんよう;ken_you
+けんりょく;kenryoku
+げんろん;genron
+こ;ko
+ごい;goi
+こいする;koisuru
+こう;kou
+こう;kou
+こうい;koui
+こうい;koui
+ごうい;goui
+こうえん;kouen
+こうかい;koukai
+こうかい;koukai
+こうがく;kougaku
+こうぎ;kougi
+ごうぎ;gougi
+こうきょ;koukyo
+こうきょう;koukyou
+こうぎょう;kougyou
+こうぎょう;kougyou
+こうげん;kougen
+こうご;kougo
+こうこうと;koukouto
+こうこがく;koukogaku
+こうさく;kousaku
+こうさく;kousaku
+こうざん;kouzan
+こうしゅう;koushuu
+こうじゅつ;koujutsu
+こうじょ;koujo
+こうしょう;koushou
+こうしょう;koushou
+こうじょう;koujou
+こうしん;koushin
+こうしんりょう;koushinryou
+こうすい;kousui
+こうずい;kouzui
+ごうせい;gousei
+こうぜん;kouzen
+こうそう;kousou
+こうそう;kousou
+こうそく;kousoku
+こうたい;koutai
+こうたく;koutaku
+こうだん;koudan
+こうちょう;kouchou
+こうとう;koutou
+こうどく;koudoku
+こうどく;koudoku
+こうにゅう;kounyuu
+こうにん;kounin
+こうねつひ;kounetsuhi
+こうはい;kouhai
+こうばい;koubai
+こうひょう;kouhyou
+こうふ;koufu
+こうふく;koufuku
+こうふん;koufun
+こうぼ;koubo
+こうみょう;koumyou
+こうよう;kouyou
+こうり;kouri
+こうりつ;kouritsu
+こうりつ;kouritsu
+ごえい;goei
+コーナー;koonaa
+こがら;kogara
+こぎって;kogitte
+ごく;goku
+こくさん;kokusan
+こくてい;kokutei
+こくはく;kokuhaku
+こくぼう;kokubou
+こくゆう;kokuyuu
+ごくらく;gokuraku
+こくれん;kokuren
+こげちゃ;kogecha
+ごげん;gogen
+ここ;koko
+ここち;kokochi
+こころえ;kokoroe
+こころがけ;kokorogake
+こころがける;kokorogakeru
+こころざし;kokorozashi
+こころざす;kokorozasu
+こころづよい;kokoroduyoi
+こころぼそい;kokorobosoi
+こころみ;kokoromi
+こころみる;kokoromiru
+こころよい;kokoroyoi
+ごさ;gosa
+ございます;gozaimasu
+こじ;koji
+こじれる;kojireru
+こじん;kojin
+こす;kosu
+こずえ;kozue
+こせい;kosei
+こせき;koseki
+こぜに;kozeni
+こだい;kodai
+こたつ;kotatsu
+こだわる;kodawaru
+こちょう;kochou
+こつ;kotsu
+こっけい;kokkei
+こっこう;kokkou
+こっとうひん;kottouhin
+こてい;kotei
+ことがら;kotogara
+こどく;kodoku
+ことごとく;kotogotoku
+ことづけ;kotoduke
+ことに;kotoni
+ことによると;kotoniyoruto
+こなごな;konagona
+このましい;konomashii
+ごばん;goban
+こべつ;kobetsu
+ごまかす;gomakasu
+こまやか;komayaka
+コマーシャル;komaasharu
+こめる;komeru
+コメント;komento
+こもる;komoru
+こゆう;koyuu
+こよみ;koyomi
+こらす;korasu
+ごらんなさい;gorannasai
+こりつ;koritsu
+こりる;koriru
+こる;koru
+こんき;konki
+こんきょ;konkyo
+こんけつ;konketsu
+コンタクト;kontakuto
+こんちゅう;konchuu
+こんてい;kontei
+コンテスト;kontesuto
+こんどう;kondou
+コントラスト;kontorasuto
+コントロール;kontorooru
+コンパス;konpasu
+こんぽん;konpon
+さ;sa
+ざい;zai
+さいかい;saikai
+さいがい;saigai
+さいきん;saikin
+さいく;saiku
+さいくつ;saikutsu
+サイクル;saikuru
+さいけつ;saiketsu
+さいけん;saiken
+さいげん;saigen
+ざいげん;zaigen
+ざいこ;zaiko
+さいさん;saisan
+さいしゅう;saishuu
+サイズ;saizu
+さいせい;saisei
+ざいせい;zaisei
+さいぜん;saizen
+さいたく;saitaku
+さいばい;saibai
+さいはつ;saihatsu
+さいぼう;saibou
+さいよう;saiyou
+さえぎる;saegiru
+さえずる;saezuru
+さえる;saeru
+さお;sao
+さかえる;sakaeru
+さがく;sagaku
+さかずき;sakazuki
+さかだち;sakadachi
+さきに;sakini
+さぎ;sagi
+さく;saku
+さく;saku
+さく;saku
+さくげん;sakugen
+さくご;sakugo
+さくせん;sakusen
+さけび;sakebi
+さける;sakeru
+ささげる;sasageru
+さしかかる;sashikakaru
+さしず;sashizu
+さしだす;sashidasu
+さしつかえる;sashitsukaeru
+さしひき;sashihiki
+さずける;sazukeru
+さする;sasuru
+さぞ;sazo
+さだまる;sadamaru
+さだめる;sadameru
+ざだんかい;zadankai
+ざつ;zatsu
+ざっか;zakka
+さつじん;satsujin
+さっする;sassuru
+ざつだん;zatsudan
+さっと;satto
+さっぱりする;sapparisuru
+さとる;satoru
+さなか;sanaka
+さばく;sabaku
+ざひょう;zahyou
+さほど;sahodo
+サボる;saboru
+さま;sama
+さむけ;samuke
+さむらい;samurai
+さも;samo
+さよう;sayou
+さらう;sarau
+さわる;sawaru
+さん;san
+さんか;sanka
+さんがく;sangaku
+さんぎいん;sangiin
+さんきゅう;sankyuu
+サンキュー;sankyuu
+ざんきん;zankin
+さんご;sango
+ざんこく;zankoku
+さんしゅつ;sanshutsu
+さんしょう;sanshou
+さんじょう;sanjou
+ざんだか;zandaka
+サンタクロース;santakuroosu
+さんばし;sanbashi
+さんび;sanbi
+さんぷく;sanpuku
+さんふじんか;sanfujinka
+さんぶつ;sanbutsu
+さんみゃく;sanmyaku
+し;shi
+し;shi
+し;shi
+じ;ji
+しあがり;shiagari
+しあげ;shiage
+しあげる;shiageru
+しいく;shiiku
+しいて;shiite
+シート;shiito
+ジーパン;jiipan
+しいれる;shiireru
+しいる;shiiru
+しお;shio
+しか;shika
+じが;jiga
+しかく;shikaku
+しかく;shikaku
+じかく;jikaku
+しかけ;shikake
+しかける;shikakeru
+しかしながら;shikashinagara
+しき;shiki
+じき;jiki
+じき;jiki
+しきさい;shikisai
+しきじょう;shikijou
+しきたり;shikitari
+じぎょう;jigyou
+しきる;shikiru
+しきん;shikin
+じく;jiku
+しくじる;shikujiru
+しくみ;shikumi
+しけい;shikei
+しける;shikeru
+じこ;jiko
+しこう;shikou
+しこう;shikou
+しこう;shikou
+しこう;shikou
+じこう;jikou
+じこくひょう;jikokuhyou
+じごく;jigoku
+じさ;jisa
+じざい;jizai
+しさつ;shisatsu
+しさん;shisan
+しじ;shiji
+じしゅ;jishu
+じしゅ;jishu
+ししゅう;shishuu
+しじょう;shijou
+じしょく;jishoku
+しずく;shizuku
+システム;shisutemu
+しずめる;shizumeru
+しせつ;shisetsu
+じぜん;jizen
+しそく;shisoku
+じぞく;jizoku
+じそんしん;jisonshin
+じたい;jitai
+じたい;jitai
+したう;shitau
+したごころ;shitagokoro
+したじ;shitaji
+したしむ;shitashimu
+したしらべ;shitashirabe
+したてる;shitateru
+したどり;shitadori
+したび;shitabi
+じつ;jitsu
+じっか;jikka
+しっかく;shikkaku
+しつぎ;shitsugi
+しっきゃく;shikkyaku
+じつぎょうか;jitsugyouka
+シック;shikku
+じっくり;jikkuri
+しつけ;shitsuke
+しつける;shitsukeru
+じっせん;jissen
+しっそ;shisso
+じったい;jittai
+しっちょう;shicchou
+しっと;shitto
+じっぴ;jippi
+してき;shiteki
+してん;shiten
+じてん;jiten
+しとやか;shitoyaka
+しなびる;shinabiru
+シナリオ;shinario
+しなやか;shinayaka
+しにょう;shinyou
+じぬし;jinushi
+しのぐ;shinogu
+しば;shiba
+しはつ;shihatsu
+じびか;jibika
+しぶつ;shibutsu
+しぶとい;shibutoi
+しほう;shihou
+しぼう;shibou
+しぼう;shibou
+しまつ;shimatsu
+しみる;shimiru
+しめい;shimei
+じもと;jimoto
+しや;shiya
+じゃく;jaku
+しゃこう;shakou
+ジャズ;jazu
+しゃぜつ;shazetsu
+しゃたく;shataku
+じゃっかん;jakkan
+しゃみせん;shamisen
+しゃめん;shamen
+じゃり;jari
+しゃれる;shareru
+ジャンパー;janpaa
+ジャンプ;janpu
+ジャンボ;janbo
+ジャンル;janru
+しゅ;shu
+しゅ;shu
+しゆう;shiyuu
+しゅう;shuu
+しゅう;shuu
+じゅう;juu
+しゅうえき;shuueki
+しゅうがく;shuugaku
+しゅうき;shuuki
+しゅうぎいん;shuugiin
+しゅうぎょう;shuugyou
+じゅうぎょういん;juugyouin
+しゅうけい;shuukei
+しゅうげき;shuugeki
+しゅうし;shuushi
+しゅうし;shuushi
+しゅうし;shuushi
+じゅうじ;juuji
+しゅうじつ;shuujitsu
+じゅうじつ;juujitsu
+しゅうしゅう;shuushuu
+しゅうしょく;shuushoku
+じゅうじろ;juujiro
+しゅうじゃく;shuujaku
+しゅうちゃく;shuuchaku
+じゅうなん;juunan
+じゅうふく;juufuku
+しゅうよう;shuuyou
+じゅうらい;juurai
+しゅうりょう;shuuryou
+しゅえい;shuei
+しゅえん;shuen
+しゅかん;shukan
+しゅぎょう;shugyou
+じゅく;juku
+しゅくが;shukuga
+しゅくめい;shukumei
+しゅげい;shugei
+しゅけん;shuken
+しゅさい;shusai
+しゅざい;shuzai
+しゅし;shushi
+しゅじゅ;shuju
+しゅしょく;shushoku
+しゅじんこう;shujinkou
+しゅたい;shutai
+しゅだい;shudai
+しゅつえん;shutsuen
+しゅっけつ;shukketsu
+しゅつげん;shutsugen
+しゅっさん;shussan
+しゅっしゃ;shussha
+しゅっしょう;shusshou
+しゅっせい;shussei
+しゅっせ;shusse
+しゅつだい;shutsudai
+しゅつどう;shutsudou
+しゅっぴ;shuppi
+しゅっぴん;shuppin
+しゅどう;shudou
+しゅにん;shunin
+しゅのう;shunou
+しゅび;shubi
+じんかく;jinkaku
+しんぎ;shingi
+しんこう;shinkou
+しんこう;shinkou
+しんこう;shinkou
+しんこく;shinkoku
+しんこん;shinkon
+しんさ;shinsa
+じんざい;jinzai
+しんし;shinshi
+しんじつ;shinjitsu
+しんじゃ;shinja
+しんじゅ;shinju
+しんしゅつ;shinshutsu
+しんじん;shinjin
+しんせい;shinsei
+しんぜん;shinzen
+しんそう;shinsou
+じんそく;jinsoku
+じんたい;jintai
+しんちく;shinchiku
+しんじゅう;shinjuu
+しんてい;shintei
+しんてん;shinten
+しんでん;shinden
+しんど;shindo
+しんどう;shindou
+しんにゅうせい;shinnyuusei
+しんにん;shinnin
+しんぴ;shinpi
+しんぼう;shinbou
+じんみん;jinmin
+しんり;shinri
+しんりゃく;shinryaku
+しんりょう;shinryou
+すい;sui
+すいげん;suigen
+すいしん;suishin
+すいせん;suisen
+すいそう;suisou
+すいそく;suisoku
+すいでん;suiden
+すいり;suiri
+すうし;suushi
+すうはい;suuhai
+すえつける;suetsukeru
+すえる;sueru
+すがすがしい;sugasugashii
+すくい;sukui
+すくう;sukuu
+すこやか;sukoyaka
+すすぐ;susugu
+すすみ;susumi
+すそ;suso
+スタジオ;sutajio
+スチーム;suchiimu
+ストライキ;sutoraiki
+スト;suto
+ストレス;sutoresu
+ストロー;sutoroo
+ストロボ;sutorobo
+すばしこい;subashikoi
+すばやい;subayai
+ずばり;zubari
+スプリング;supuringu
+スペース;supeesu
+ずぶぬれ;zubunure
+スポーツカー;supootsukaa
+すます;sumasu
+すます;sumasu
+すます;sumasu
+すみやか;sumiyaka
+スラックス;surakkusu
+ずらっと;zuratto
+する;suru
+ずるずる;zuruzuru
+ずれ;zure
+すれちがい;surechigai
+すれる;sureru
+すんなり;sunnari
+せい;sei
+せいいく;seiiku
+せいいく;seiiku
+せいか;seika
+せいかい;seikai
+せいき;seiki
+せいぎ;seigi
+せいけい;seikei
+せいけん;seiken
+せいこう;seikou
+せいざ;seiza
+せいさい;seisai
+せいさく;seisaku
+せいさん;seisan
+せいし;seishi
+せいし;seishi
+せいじつ;seijitsu
+せいじゅく;seijuku
+せいしゅん;seishun
+せいじゅん;seijun
+せいしょ;seisho
+せいじょう;seijou
+せいする;seisuru
+せいぜん;seizen
+せいそう;seisou
+せいだい;seidai
+せいだく;seidaku
+せいてい;seitei
+せいてき;seiteki
+せいてつ;seitetsu
+せいてん;seiten
+せいとう;seitou
+せいねん;seinen
+せいふく;seifuku
+せいふく;seifuku
+せいほう;seihou
+せいみつ;seimitsu
+ぜいむしょ;zeimusho
+せいめい;seimei
+せいめい;seimei
+せいやく;seiyaku
+せいり;seiri
+せいりょく;seiryoku
+せいれつ;seiretsu
+セール;seeru
+せかす;sekasu
+せがれ;segare
+せきむ;sekimu
+セクション;sekushon
+せじ;seji
+せたい;setai
+ぜせい;zesei
+せだい;sedai
+せつ;setsu
+せっかい;sekkai
+セックス;sekkusu
+せつじつ;setsujitsu
+せっしょく;sesshoku
+せつぞくし;setsuzokushi
+せっち;secchi
+せっちゅう;secchuu
+せってい;settei
+せっとく;settoku
+せつない;setsunai
+ぜっぱん;zeppan
+せつりつ;setsuritsu
+せめ;seme
+ゼリー;zerii
+セレモニー;seremonii
+せん;sen
+ぜん;zen
+ぜん;zen
+せんい;sen_i
+ぜんかい;zenkai
+せんきょ;senkyo
+せんきょう;senkyou
+せんげん;sengen
+せんこう;senkou
+せんこう;senkou
+せんさい;sensai
+せんしゅう;senshuu
+せんじゅつ;senjutsu
+センス;sensu
+せんすい;sensui
+ぜんせい;zensei
+せんだい;sendai
+せんだって;sendatte
+せんちゃく;senchaku
+ぜんてい;zentei
+せんてんてき;sententeki
+ぜんと;zento
+せんとう;sentou
+せんにゅう;sennyuu
+せんぱく;senpaku
+ぜんめつ;zenmetsu
+せんよう;sen_you
+せんりょう;senryou
+ぜんりょう;zenryou
+せんりょく;senryoku
+ぜんれい;zenrei
+そう;sou
+そう;sou
+そう;sou
+そう;sou
+ぞう;zou
+そうおう;souou
+そうかい;soukai
+そうかん;soukan
+ぞうき;zouki
+そうきゅう;soukyuu
+さっきゅう;sakkyuu
+ぞうきょう;zoukyou
+そうきん;soukin
+そうこう;soukou
+そうごう;sougou
+そうさ;sousa
+そうさく;sousaku
+そうじゅう;soujuu
+ぞうしょう;zoushou
+そうしょく;soushoku
+ぞうしん;zoushin
+そうぞう;souzou
+そうたい;soutai
+そうだい;soudai
+そうどう;soudou
+そうなん;sounan
+そうば;souba
+そうび;soubi
+そうりつ;souritsu
+そえる;soeru
+ソース;soosu
+そくざに;sokuzani
+そくしん;sokushin
+そくする;sokusuru
+そくばく;sokubaku
+そくめん;sokumen
+そこなう;sokonau
+そこら;sokora
+そざい;sozai
+そし;soshi
+そしょう;soshou
+そだち;sodachi
+そち;sochi
+ソックス;sokkusu
+そっけない;sokkenai
+そっぽ;soppo
+そなえつける;sonaetsukeru
+そなわる;sonawaru
+そなわる;sonawaru
+そびえる;sobieru
+ソフト;sofuto
+そぼく;soboku
+そむく;somuku
+そまる;somaru
+そめる;someru
+そらす;sorasu
+そり;sori
+そる;soru
+それゆえ;soreyue
+ソロ;soro
+そろい;soroi
+ぞんざい;zonzai
+そんしつ;sonshitsu
+そんぞく;sonzoku
+ダース;daasu
+たい;tai
+たい;tai
+たいおう;taiou
+たいか;taika
+たいか;taika
+たいがい;taigai
+たいかく;taikaku
+たいがく;taigaku
+たいきん;taikin
+たいぐう;taiguu
+たいけつ;taiketsu
+たいけん;taiken
+たいこう;taikou
+たいじ;taiji
+たいしゅう;taishuu
+たいしょ;taisho
+たいしょく;taishoku
+だいする;daisuru
+たいせい;taisei
+たいだん;taidan
+だいたん;daitan
+たいとう;taitou
+タイトル;taitoru
+だいなし;dainashi
+たいのう;tainou
+たいひ;taihi
+タイピスト;taipisuto
+たいぶ;taibu
+だいべん;daiben
+だいべん;daiben
+たいぼう;taibou
+だいほん;daihon
+タイマー;taimaa
+たいまん;taiman
+タイミング;taimingu
+タイム;taimu
+タイムリー;taimurii
+たいめん;taimen
+だいよう;daiyou
+たいりょく;tairyoku
+タイル;tairu
+たいわ;taiwa
+ダウン;daun
+たえる;taeru
+たえる;taeru
+たえる;taeru
+たえる;taeru
+だかい;dakai
+たかまる;takamaru
+たきび;takibi
+だきょう;dakyou
+たくましい;takumashii
+たくみ;takumi
+たけ;take
+だけ;dake
+だげき;dageki
+だけつ;daketsu
+ださく;dasaku
+たしざん;tashizan
+たすうけつ;tasuuketsu
+たすけ;tasuke
+たずさわる;tazusawaru
+ただよう;tadayou
+たちさる;tachisaru
+たちよる;tachiyoru
+たつ;tatsu
+だっこ;dakko
+たっしゃ;tassha
+だっしゅつ;dasshutsu
+だっする;dassuru
+たっせい;tassei
+だったい;dattai
+だったら;dattara
+たて;tate
+たてかえる;tatekaeru
+たてまえ;tatemae
+たてまつる;tatematsuru
+だと;dato
+たどうし;tadoushi
+たとえ;tatoe
+たどりつく;tadoritsuku
+たどる;tadoru
+たばねる;tabaneru
+だぶだぶ;dabudabu
+ダブル;daburu
+たほう;tahou
+たぼう;tabou
+たまう;tamau
+たましい;tamashii
+たまり;tamari
+たまわる;tamawaru
+たもつ;tamotsu
+たやすい;tayasui
+たよう;tayou
+だるい;darui
+たるみ;tarumi
+たるむ;tarumu
+たれる;tareru
+タレント;tarento
+タワー;tawaa
+たん;tan
+たんいつ;tan_itsu
+たんか;tanka
+たんか;tanka
+たんき;tanki
+だんけつ;danketsu
+たんけん;tanken
+だんげん;dangen
+たんしゅく;tanshuku
+だんぜん;danzen
+たんそ;tanso
+たんだい;tandai
+たんちょう;tanchou
+たんどく;tandoku
+だんな;danna
+たんぱ;tanpa
+たんぱくしつ;tanpakushitsu
+ダンプ;danpu
+だんめん;danmen
+だんりょく;danryoku
+ちあん;chian
+チームワーク;chiimuwaaku
+チェンジ;chenji
+ちがえる;chigaeru
+ちくさん;chikusan
+ちくしょう;chikushou
+ちくせき;chikuseki
+ちけい;chikei
+ちせい;chisei
+ちち;chichi
+ちぢまる;chidimaru
+ちつじょ;chitsujo
+ちっそく;chissoku
+ちてき;chiteki
+チャイム;chaimu
+ちゃくしゅ;chakushu
+ちゃくしょく;chakushoku
+ちゃくせき;chakuseki
+ちゃくもく;chakumoku
+ちゃくりく;chakuriku
+ちゃっこう;chakkou
+ちゃのま;chanoma
+ちゃのゆ;chanoyu
+ちやほや;chiyahoya
+チャンネル;channeru
+ちゅうがえり;chuugaeri
+ちゅうけい;chuukei
+ちゅうこく;chuukoku
+ちゅうしょう;chuushou
+ちゅうすう;chuusuu
+ちゅうせん;chuusen
+ちゅうだん;chuudan
+ちゅうどく;chuudoku
+ちゅうふく;chuufuku
+ちゅうりつ;chuuritsu
+ちゅうわ;chuuwa
+ちょ;cho
+ちょう;chou
+ちょう;chou
+ちょう;chou
+ちょういん;chouin
+ちょうかく;choukaku
+ちょうかん;choukan
+ちょうこう;choukou
+ちょうしゅう;choushuu
+しゅほう;shuhou
+じゅもく;jumoku
+じゅりつ;juritsu
+じゅんきゅう;junkyuu
+じゅんじる;junjiru
+しょ;sho
+しよう;shiyou
+しよう;shiyou
+しょう;shou
+しょう;shou
+じょう;jou
+じょう;jou
+じょう;jou
+じょうい;joui
+じょうえん;jouen
+じょうか;jouka
+しょうがい;shougai
+しょうきょ;shoukyo
+じょうくう;joukuu
+しょうげき;shougeki
+しょうげん;shougen
+しょうこ;shouko
+しょうごう;shougou
+しょうさい;shousai
+じょうし;joushi
+じょうしょう;joushou
+しょうしん;shoushin
+しょうする;shousuru
+じょうせい;jousei
+しょうそく;shousoku
+しょうたい;shoutai
+しょうだく;shoudaku
+じょうちょ;joucho
+じょうしょ;jousho
+しょうちょう;shouchou
+しょうにか;shounika
+しようにん;shiyounin
+じょうねつ;jounetsu
+じょうほ;jouho
+しょうめい;shoumei
+じょうやく;jouyaku
+しょうり;shouri
+じょうりく;jouriku
+じょうりゅう;jouryuu
+しょうれい;shourei
+ショー;shoo
+じょがい;jogai
+しょくいん;shokuin
+しょくみんち;shokuminchi
+しょくむ;shokumu
+しょくん;shokun
+じょげん;jogen
+じょこう;jokou
+しょざい;shozai
+しょじ;shoji
+じょし;joshi
+じょし;joshi
+しょぞく;shozoku
+しょち;shochi
+ショック;shokku
+しょっちゅう;shocchuu
+しょてい;shotei
+じょどうし;jodoushi
+しょとく;shotoku
+しょばつ;shobatsu
+しょはん;shohan
+しょひょう;shohyou
+しょぶん;shobun
+しょみん;shomin
+しょむ;shomu
+しょゆう;shoyuu
+しらべ;shirabe
+じりつ;jiritsu
+しるす;shirusu
+しれい;shirei
+しん;shin
+じん;jin
+しんか;shinka
+はたす;hatasu
+はちみつ;hachimitsu
+パチンコ;pachinko
+ばつ;batsu
+はついく;hatsuiku
+はつが;hatsuga
+はっくつ;hakkutsu
+はつげん;hatsugen
+バッジ;bajji
+はっせい;hassei
+バッテリー;batterii
+バット;batto
+はつびょう;hatsubyou
+はつみみ;hatsumimi
+はて;hate
+はてる;hateru
+ばてる;bateru
+パトカー;patokaa
+はなはだ;hanahada
+はなばなしい;hanabanashii
+はなびら;hanabira
+はなやか;hanayaka
+パパ;papa
+はばむ;habamu
+はま;hama
+はまべ;hamabe
+はまる;hamaru
+はやす;hayasu
+はやめる;hayameru
+はらだち;haradachi
+はらっぱ;harappa
+はらはら;harahara
+ばらまく;baramaku
+はりがみ;harigami
+はるか;haruka
+はれつ;haretsu
+はれる;hareru
+はん;han
+はん;han
+はん;han
+はんえい;han_ei
+はんが;hanga
+ハンガー;hangaa
+はんかん;hankan
+はんきょう;hankyou
+パンク;panku
+はんげき;hangeki
+はんけつ;hanketsu
+はんしゃ;hansha
+はんじょう;hanjou
+はんしょく;hanshoku
+はんする;hansuru
+はんてい;hantei
+ばんにん;bannin
+ばんねん;bannen
+はんのう;hannou
+ばんのう;bannou
+はんぱ;hanpa
+はんぱつ;hanpatsu
+はんらん;hanran
+はんらん;hanran
+ひ;hi
+ひ;hi
+び;bi
+ひいては;hiiteha
+ビールス;biirusu
+ひかえしつ;hikaeshitsu
+ひかえる;hikaeru
+ひかん;hikan
+ひきあげる;hikiageru
+ひきいる;hikiiru
+ひきおこす;hikiokosu
+ひきさげる;hikisageru
+ひきずる;hikizuru
+ひきとる;hikitoru
+ひけつ;hiketsu
+ひこう;hikou
+ひごろ;higoro
+ひさしい;hisashii
+ひさん;hisan
+ビジネス;bijinesu
+ひじゅう;hijuu
+びじゅつ;bijutsu
+ひしょ;hisho
+びしょう;bishou
+ちょうしんき;choushinki
+ちょうせん;chousen
+ちょうてい;choutei
+ちょうふく;choufuku
+ちょうへん;chouhen
+ちょうほう;chouhou
+ちょうり;chouri
+ちょうわ;chouwa
+ちょくちょく;chokuchoku
+ちょくめん;chokumen
+ちょしょ;chosho
+ちょちく;chochiku
+ちょっかん;chokkan
+ちょめい;chomei
+ちらっと;chiratto
+ちり;chiri
+ちりとり;chiritori
+ちりょう;chiryou
+ちんぎん;chingin
+ちんでん;chinden
+ちんぼつ;chinbotsu
+ちんもく;chinmoku
+ちんれつ;chinretsu
+つい;tsui
+ついきゅう;tsuikyuu
+ついせき;tsuiseki
+ついほう;tsuihou
+ついやす;tsuiyasu
+ついらく;tsuiraku
+つうかん;tsuukan
+つうじょう;tsuujou
+つうせつ;tsuusetsu
+つえ;tsue
+つかいみち;tsukaimichi
+つかえる;tsukaeru
+つかさどる;tsukasadoru
+つかのま;tsukanoma
+つきなみ;tsukinami
+つぎめ;tsugime
+つきる;tsukiru
+つぐ;tsugu
+つぐ;tsugu
+つくす;tsukusu
+つくづく;tsukuduku
+つくり;tsukuri
+つくり;tsukuri
+つくろう;tsukurou
+つけくわえる;tsukekuwaeru
+つげる;tsugeru
+つじつま;tsujitsuma
+つつ;tsutsu
+つつく;tsutsuku
+つっつく;tsuttsuku
+つつしむ;tsutsushimu
+つっぱる;tsupparu
+つとまる;tsutomaru
+つとめさき;tsutomesaki
+つとめて;tsutomete
+つなみ;tsunami
+つねる;tsuneru
+つの;tsuno
+つのる;tsunoru
+つば;tsuba
+つぶやく;tsubuyaku
+つぶら;tsubura
+つぶる;tsuburu
+つぼ;tsubo
+つぼみ;tsubomi
+つむ;tsumu
+つゆ;tsuyu
+つよまる;tsuyomaru
+つよめる;tsuyomeru
+つらなる;tsuranaru
+つらぬく;tsuranuku
+つらねる;tsuraneru
+つりがね;tsurigane
+つりかわ;tsurikawa
+てあて;teate
+ていぎ;teigi
+ていきょう;teikyou
+ていけい;teikei
+ていさい;teisai
+ていじ;teiji
+ティシュペーパー;tishupeepaa
+ていしょく;teishoku
+ていせい;teisei
+ていたい;teitai
+ていたく;teitaku
+ていねん;teinen
+ていぼう;teibou
+データ;deeta
+ておくれ;teokure
+でかい;dekai
+てがかり;tegakari
+てがける;tegakeru
+てかず;tekazu
+てがる;tegaru
+てきおう;tekiou
+てきぎ;tekigi
+てきせい;tekisei
+できもの;dekimono
+てぎわ;tegiwa
+でくわす;dekuwasu
+デザイン;dezain
+てじゅん;tejun
+てじょう;tejou
+てすう;tesuu
+デコレーション;dekoreeshon
+デザート;dezaato
+てぢか;tedika
+てっきり;tekkiri
+てっこう;tekkou
+デッサン;dessan
+てっする;tessuru
+てっぺん;teppen
+てつぼう;tetsubou
+でなおし;denaoshi
+てのひら;tenohira
+てはい;tehai
+てはず;tehazu
+てびき;tebiki
+てほん;tehon
+てまわし;temawashi
+てもと;temoto
+デモンストレーション;demonsutoreeshon
+てりかえす;terikaesu
+テレックス;terekkusu
+てわけ;tewake
+てん;ten
+でんえん;den_en
+てんか;tenka
+てんかい;tenkai
+てんかん;tenkan
+てんきょ;tenkyo
+てんきん;tenkin
+てんけん;tenken
+でんげん;dengen
+てんこう;tenkou
+てんごく;tengoku
+でんごん;dengon
+てんさい;tensai
+てんさい;tensai
+てんじ;tenji
+でんせつ;densetsu
+てんせん;tensen
+てんじる;tenjiru
+てんずる;tenzuru
+てんたい;tentai
+でんたつ;dentatsu
+てんち;tenchi
+てんで;tende
+てんにん;tennin
+てんぼう;tenbou
+でんらい;denrai
+てんらく;tenraku
+と;to
+ど;do
+といあわせる;toiawaseru
+とう;tou
+とう;tou
+とう;tou
+どう;dou
+どうい;doui
+どういん;douin
+どうかん;doukan
+とうき;touki
+とうぎ;tougi
+どうき;douki
+とうきゅう;toukyuu
+どうきゅう;doukyuu
+どうきょ;doukyo
+とうこう;toukou
+とうごう;tougou
+どうこう;doukou
+とうさん;tousan
+とうし;toushi
+どうし;doushi
+どうし;doushi
+どうじょう;doujou
+どうじょう;doujou
+とうせい;tousei
+とうせん;tousen
+とうぜん;touzen
+とうそう;tousou
+とうそつ;tousotsu
+とうたつ;toutatsu
+とうち;touchi
+どうちょう;douchou
+とうてい;toutei
+どうてき;douteki
+とうとい;toutoi
+とうとい;toutoi
+どうとう;doutou
+どうどう;doudou
+とうとぶ;toutobu
+どうにか;dounika
+とうにゅう;tounyuu
+どうにゅう;dounyuu
+とうにん;tounin
+どうふう;doufuu
+とうぼう;toubou
+とうみん;toumin
+どうめい;doumei
+どうやら;douyara
+どうよう;douyou
+どうりょく;douryoku
+とうろく;touroku
+とうろん;touron
+とおざかる;toozakaru
+とおまわり;toomawari
+トーン;toon
+とかく;tokaku
+とがめる;togameru
+ときおり;tokiori
+とぎれる;togireru
+とく;toku
+とぐ;togu
+とくぎ;tokugi
+どくさい;dokusai
+とくさん;tokusan
+どくじ;dokuji
+とくしゅう;tokushuu
+どくせん;dokusen
+どくそう;dokusou
+とくてん;tokuten
+とくは;tokuha
+とくゆう;tokuyuu
+とげ;toge
+とげる;togeru
+どころか;dokoroka
+としごろ;toshigoro
+とじまり;tojimari
+とじょう;tojou
+とじる;tojiru
+どだい;dodai
+とだえる;todaeru
+とっきょ;tokkyo
+とっけん;tokken
+とっさに;tossani
+とつじょ;totsujo
+とって;totte
+とっぱ;toppa
+どて;dote
+とどけ;todoke
+とどこおる;todokooru
+ととのえる;totonoeru
+とどめる;todomeru
+となえる;tonaeru
+とのさま;tonosama
+どひょう;dohyou
+とびら;tobira
+どぶ;dobu
+とほ;toho
+どぼく;doboku
+とぼける;tobokeru
+とぼしい;toboshii
+とみ;tomi
+とむ;tomu
+とも;tomo
+ともかせぎ;tomokasegi
+ともなう;tomonau
+ともばたらき;tomobataraki
+ドライ;dorai
+ドライクリーニング;doraikuriiningu
+ドライバー;doraibaa
+ドライブイン;doraibuin
+トラブル;toraburu
+トランジスター;toranjisutaa
+とりあえず;toriaezu
+とりあつかい;toriatsukai
+とりあつかう;toriatsukau
+とりい;torii
+とりかえ;torikae
+とりくむ;torikumu
+とりしまり;torishimari
+とりしまる;torishimaru
+とりしらべる;torishiraberu
+とりたてる;toritateru
+とりつぐ;toritsugu
+とりつける;toritsukeru
+とりのぞく;torinozoku
+とりひき;torihiki
+とりまく;torimaku
+とりまぜる;torimazeru
+とりもどす;torimodosu
+とりよせる;toriyoseru
+ドリル;doriru
+とりわけ;toriwake
+とろける;torokeru
+どんかん;donkan
+とんだ;tonda
+どわすれ;dowasure
+とんや;ton_ya
+ないかく;naikaku
+ないし;naishi
+ないしょ;naisho
+ないしん;naishin
+ないぞう;naizou
+ナイター;naitaa
+ないぶ;naibu
+ないらん;nairan
+ないりく;nairiku
+なえ;nae
+なおさら;naosara
+ながし;nagashi
+ながなが;naganaga
+なかほど;nakahodo
+なぎさ;nagisa
+なげく;nageku
+なげだす;nagedasu
+なこうど;nakoudo
+なごやか;nagoyaka
+なごり;nagori
+なさけ;nasake
+なさけない;nasakenai
+なさけぶかい;nasakebukai
+なじる;najiru
+なだかい;nadakai
+なだれ;nadare
+なつく;natsuku
+なづける;nadukeru
+なにげない;nanigenai
+なにとぞ;nanitozo
+なにより;naniyori
+ナプキン;napukin
+なふだ;nafuda
+なまぐさい;namagusai
+なまぬるい;namanurui
+なまみ;namami
+なまり;namari
+なみ;nami
+なめらか;nameraka
+なめる;nameru
+なやましい;nayamashii
+なやます;nayamasu
+なやみ;nayami
+ならす;narasu
+ならす;narasu
+ならびに;narabini
+なりたつ;naritatsu
+なるたけ;narutake
+なれ;nare
+なれなれしい;narenareshii
+なん;nan
+なんか;nanka
+ナンセンス;nansensu
+なんだか;nandaka
+なんだかんだ;nandakanda
+なんなり;nannari
+に;ni
+にかよう;nikayou
+にきび;nikibi
+にぎわう;nigiwau
+にくしみ;nikushimi
+にくしん;nikushin
+にくたい;nikutai
+にげだす;nigedasu
+にしび;nishibi
+にじむ;nijimu
+にせもの;nisemono
+にちや;nichiya
+にづくり;nidukuri
+になう;ninau
+にぶる;niburu
+にもかかわらず;nimokakawarazu
+ニュアンス;nyuansu
+ニュー;nyuu
+にゅうしゅ;nyuushu
+にゅうしょう;nyuushou
+にゅうよく;nyuuyoku
+にょう;nyou
+にんしき;ninshiki
+しんじょう;shinjou
+にんしん;ninshin
+にんむ;ninmu
+にんめい;ninmei
+ぬかす;nukasu
+ぬけだす;nukedasu
+ぬし;nushi
+ぬま;numa
+ね;ne
+ねいろ;neiro
+ねうち;neuchi
+ネガ;nega
+ねかせる;nekaseru
+ねじまわし;nejimawashi
+ねじれる;nejireru
+ねたむ;netamu
+ねだる;nedaru
+ねつい;netsui
+ねっとう;nettou
+ねつりょう;netsuryou
+ねばり;nebari
+ねばる;nebaru
+ねびき;nebiki
+ねまわし;nemawashi
+ねむたい;nemutai
+ねる;neru
+ねん;nen
+ねんが;nenga
+ねんかん;nenkan
+ねんがん;nengan
+ねんごう;nengou
+ねんしょう;nenshou
+ねんちょう;nenchou
+ねんりょう;nenryou
+ねんりん;nenrin
+ノイローゼ;noirooze
+のう;nou
+のうこう;noukou
+のうじょう;noujou
+のうち;nouchi
+のうにゅう;nounyuu
+のがす;nogasu
+のがれる;nogareru
+のきなみ;nokinami
+のぞましい;nozomashii
+のぞむ;nozomu
+のっとる;nottoru
+のどか;nodoka
+ののしる;nonoshiru
+のべ;nobe
+のみこむ;nomikomu
+のりこむ;norikomu
+は;ha
+は;ha
+バー;baa
+はあく;haaku
+パート;paato
+はい;hai
+はい;hai
+はいき;haiki
+はいきゅう;haikyuu
+ばいきん;baikin
+はいぐうしゃ;haiguusha
+はいけい;haikei
+はいけい;haikei
+はいご;haigo
+はいし;haishi
+はいしゃく;haishaku
+はいじょ;haijo
+ばいしょう;baishou
+はいすい;haisui
+はいせん;haisen
+はいち;haichi
+はいふ;haifu
+はいぶん;haibun
+はいぼく;haiboku
+ばいりつ;bairitsu
+はいりょ;hairyo
+はいれつ;hairetsu
+はえる;haeru
+はかい;hakai
+はかどる;hakadoru
+はかない;hakanai
+ばかばかしい;bakabakashii
+はかる;hakaru
+はかる;hakaru
+はき;haki
+はぐ;hagu
+はくがい;hakugai
+はくじゃく;hakujaku
+はくじょう;hakujou
+ばくぜん;bakuzen
+ばくだん;bakudan
+ばくは;bakuha
+ばくろ;bakuro
+はげます;hagemasu
+はげむ;hagemu
+はげる;hageru
+ばける;bakeru
+はけん;haken
+はじ;haji
+はじく;hajiku
+パジャマ;pajama
+はじらう;hajirau
+はじる;hajiru
+はしわたし;hashiwatashi
+バス;basu
+はずむ;hazumu
+はそん;hason
+はたく;hataku
+はだし;hadashi
+ひずむ;hizumu
+ひそか;hisoka
+ひたす;hitasu
+ひたすら;hitasura
+ひだりきき;hidarikiki
+ひっかく;hikkaku
+ひっしゅう;hisshuu
+びっしょり;bisshori
+ひつぜん;hitsuzen
+ひってき;hitteki
+ひといき;hitoiki
+ひとかげ;hitokage
+ひとがら;hitogara
+ひとけ;hitoke
+ひところ;hitokoro
+ひとじち;hitojichi
+ひとすじ;hitosuji
+ひとめ;hitome
+ひどり;hidori
+ひな;hina
+ひなまつり;hinamatsuri
+ひなた;hinata
+ひなん;hinan
+ひなん;hinan
+ひのまる;hinomaru
+ひばな;hibana
+ひび;hibi
+ひめい;himei
+ひやかす;hiyakasu
+ひやけ;hiyake
+ひょう;hyou
+ひょうご;hyougo
+びょうしゃ;byousha
+ひょっと;hyotto
+びら;bira
+ひらたい;hiratai
+びり;biri
+ひりつ;hiritsu
+びりょう;biryou
+ひるめし;hirumeshi
+ひれい;hirei
+ひろう;hirou
+ひろまる;hiromaru
+びんかん;binkan
+ひんこん;hinkon
+ひんしつ;hinshitsu
+ひんじゃく;hinjaku
+ひんしゅ;hinshu
+ヒント;hinto
+ひんぱん;hinpan
+びんぼう;binbou
+ファイト;faito
+ファイル;fairu
+ファン;fan
+ふい;fui
+フィルタ;firuta
+ふう;fuu
+ふうさ;fuusa
+ふうしゃ;fuusha
+ふうしゅう;fuushuu
+ふうぞく;fuuzoku
+ブーツ;buutsu
+ふうど;fuudo
+ブーム;buumu
+フォーム;foomu
+ぶか;buka
+ふかけつ;fukaketsu
+ぶかぶか;bukabuka
+ふかめる;fukameru
+ふきつ;fukitsu
+ふきょう;fukyou
+ふきん;fukin
+ふく;fuku
+ふくごう;fukugou
+ふくし;fukushi
+ふくめん;fukumen
+ふくれる;fukureru
+ふけいき;fukeiki
+ふける;fukeru
+ふける;fukeru
+ふごう;fugou
+ふこく;fukoku
+ブザー;buzaa
+ふさい;fusai
+ふざい;fuzai
+ふさわしい;fusawashii
+ふじゅん;fujun
+ふしょう;fushou
+ぶじょく;bujoku
+ふしん;fushin
+ふしん;fushin
+ぶそう;busou
+ふだ;fuda
+ふたん;futan
+ふちょう;fuchou
+ふっかつ;fukkatsu
+ぶつぎ;butsugi
+ふっきゅう;fukkyuu
+ふっこう;fukkou
+ぶっし;busshi
+ぶつぞう;butsuzou
+ぶったい;buttai
+ふっとう;futtou
+ふとう;futou
+ふどうさん;fudousan
+ぶなん;bunan
+ふにん;funin
+ふはい;fuhai
+ふひょう;fuhyou
+ふふく;fufuku
+ふへん;fuhen
+ふまえる;fumaeru
+ふみこむ;fumikomu
+ふめい;fumei
+ぶもん;bumon
+ふよう;fuyou
+ふらふら;furafura
+ぶらぶら;burabura
+ふり;furi
+ふりかえる;furikaeru
+ふりだし;furidashi
+ふりょう;furyou
+ふりょく;furyoku
+ぶりょく;buryoku
+ブル;buru
+ふるわせる;furuwaseru
+ぶれい;burei
+ふろく;furoku
+フロント;furonto
+ふんがい;fungai
+ぶんかざい;bunkazai
+ぶんぎょう;bungyou
+ぶんご;bungo
+ぶんさん;bunsan
+ぶんし;bunshi
+ふんしつ;funshitsu
+ふんしゅつ;funshutsu
+ぶんしょ;bunsho
+ふんそう;funsou
+ふんだん;fundan
+ぶんたん;buntan
+ふんとう;funtou
+ぶんぱい;bunpai
+ぶんぼ;bunbo
+ふんまつ;funmatsu
+ぶんり;bunri
+ぶんれつ;bunretsu
+ペア;pea
+へいき;heiki
+へいこう;heikou
+へいこう;heikou
+へいさ;heisa
+へいし;heishi
+へいじょう;heijou
+へいほう;heihou
+へいれつ;heiretsu
+ぼうどう;boudou
+ほうび;houbi
+ぼうふう;boufuu
+ほうむる;houmuru
+ほうりこむ;hourikomu
+ほうりだす;houridasu
+ぼうりょく;bouryoku
+ほうわ;houwa
+ホース;hoosu
+ポーズ;poozu
+ホール;hooru
+ほおん;hoon
+ほかく;hokaku
+ほかん;hokan
+ほきゅう;hokyuu
+ほきょう;hokyou
+ぼきん;bokin
+ぼくし;bokushi
+ほげい;hogei
+ぼける;bokeru
+ほけん;hoken
+ほご;hogo
+ぼこう;bokou
+ぼこく;bokoku
+ほこる;hokoru
+ほころびる;hokorobiru
+ほし;hoshi
+ポジション;pojishon
+ほしもの;hoshimono
+ほしゅ;hoshu
+ほじゅう;hojuu
+ほじょ;hojo
+ほしょう;hoshou
+ほしょう;hoshou
+ほそう;hosou
+ほそく;hosoku
+ぼち;bochi
+ほっさ;hossa
+ぼっしゅう;bosshuu
+ほっそく;hossoku
+ほっと;hotto
+ポット;potto
+ほっぺた;hoppeta
+ぼつぼつ;botsubotsu
+ぼつらく;botsuraku
+ほどける;hodokeru
+ほどこす;hodokosu
+ほとり;hotori
+ぼやく;boyaku
+ぼやける;boyakeru
+ほよう;hoyou
+ほりょ;horyo
+ボルト;boruto
+ほろびる;horobiru
+ほろぼす;horobosu
+ほんかく;honkaku
+ほんかん;honkan
+ほんき;honki
+ほんごく;hongoku
+ほんしつ;honshitsu
+ほんたい;hontai
+ほんね;honne
+ほんのう;honnou
+ほんば;honba
+ポンプ;ponpu
+ほんぶん;honbun
+ほんみょう;honmyou
+マーク;maaku
+マイ;mai
+マイクロフォン;maikurofon
+まいぞう;maizou
+まう;mau
+まうえ;maue
+まえうり;maeuri
+まえおき;maeoki
+まえもって;maemotte
+まかす;makasu
+まかす;makasu
+まかなう;makanau
+まぎらわしい;magirawashii
+まぎれる;magireru
+まく;maku
+まごころ;magokoro
+まごつく;magotsuku
+まこと;makoto
+まことに;makotoni
+まさしく;masashiku
+まさる;masaru
+まし;mashi
+まじえる;majieru
+ました;mashita
+まして;mashite
+まじわる;majiwaru
+ますい;masui
+マスコミ;masukomi
+また;mata
+またがる;matagaru
+まちあわせ;machiawase
+まちどおしい;machidooshii
+まちのぞむ;machinozomu
+まちまち;machimachi
+まつ;matsu
+まっき;makki
+マッサージ;massaaji
+まっぷたつ;mapputatsu
+まと;mato
+まとまり;matomari
+まとめ;matome
+まぬがれる;manugareru
+まねき;maneki
+まばたき;mabataki
+まひ;mahi
+まみれ;mamire
+まゆ;mayu
+まり;mari
+まるごと;marugoto
+まるっきり;marukkiri
+まるまる;marumaru
+まるめる;marumeru
+まんげつ;mangetsu
+まんじょう;manjou
+まんまえ;manmae
+まんまるい;manmarui
+まんまるい;manmarui
+み;mi
+みあい;miai
+みあわせる;miawaseru
+みおとす;miotosu
+みかい;mikai
+みかく;mikaku
+みかける;mikakeru
+みき;miki
+みぐるしい;migurushii
+みこみ;mikomi
+みこん;mikon
+みじゅく;mijuku
+みじん;mijin
+ミス;misu
+みずけ;mizuke
+ミスプリント;misupurinto
+みすぼらしい;misuborashii
+ミセス;misesu
+みせびらかす;misebirakasu
+みせもの;misemono
+みぞ;mizo
+みたす;mitasu
+みだす;midasu
+みだれる;midareru
+みち;michi
+みぢか;midika
+みちびく;michibiku
+みっしゅう;misshuu
+みっせつ;missetsu
+みつど;mitsudo
+みつもり;mitsumori
+みてい;mitei
+みとおし;mitooshi
+みなす;minasu
+みなもと;minamoto
+みならう;minarau
+みなり;minari
+みね;mine
+みのうえ;minoue
+みのがす;minogasu
+みのまわり;minomawari
+みはからう;mihakarau
+みはらし;miharashi
+みぶり;miburi
+みゃく;myaku
+ミュージック;myuujikku
+みれん;miren
+みわたす;miwatasu
+みんしゅく;minshuku
+みんぞく;minzoku
+みんぞく;minzoku
+むいみ;muimi
+ムード;muudo
+むくち;mukuchi
+むこ;muko
+むこう;mukou
+むごん;mugon
+むじゃき;mujaki
+むしる;mushiru
+むすび;musubi
+むすびつき;musubitsuki
+むすびつく;musubitsuku
+むすびつける;musubitsukeru
+むせん;musen
+むだづかい;mudadukai
+むだん;mudan
+むち;muchi
+むちゃ;mucha
+むちゃくちゃ;muchakucha
+むなしい;munashii
+むねん;munen
+むのう;munou
+むやみに;muyamini
+むよう;muyou
+むら;mura
+むらがる;muragaru
+むろん;muron
+めいさん;meisan
+めいしょう;meishou
+めいちゅう;meichuu
+めいはく;meihaku
+めいぼ;meibo
+めいよ;meiyo
+めいりょう;meiryou
+めいろう;meirou
+メーカー;meekaa
+めかた;mekata
+めぐみ;megumi
+めぐむ;megumu
+めくる;mekuru
+めざましい;mezamashii
+めざめる;mezameru
+めす;mesu
+めす;mesu
+めつき;metsuki
+メッセージ;messeeji
+めつぼう;metsubou
+メディア;media
+めど;medo
+めもり;memori
+メロディー;merodii
+めんかい;menkai
+めんじょ;menjo
+めんする;mensuru
+めんぼく;menboku
+めんもく;menmoku
+もう;mou
+もうける;moukeru
+もうしいれる;moushiireru
+もうしこみ;moushikomi
+もうしで;moushide
+もうしでる;moushideru
+もうしぶん;moushibun
+もうてん;mouten
+もうれつ;mouretsu
+モーテル;mooteru
+もがく;mogaku
+もくろく;mokuroku
+もくろみ;mokuromi
+もけい;mokei
+もさく;mosaku
+もしかして;moshikashite
+もしくは;moshikuha
+もたらす;motarasu
+もちきり;mochikiri
+もっか;mokka
+もっぱら;moppara
+もてなす;motenasu
+もてる;moteru
+モニター;monitaa
+もの;mono
+ものずき;monozuki
+ものたりない;monotarinai
+もはや;mohaya
+もはん;mohan
+もほう;mohou
+もめる;momeru
+もも;momo
+もも;momo
+もよおす;moyoosu
+もらす;morasu
+もりあがる;moriagaru
+もる;moru
+もれる;moreru
+もろい;moroi
+もろに;moroni
+や;ya
+やがい;yagai
+やく;yaku
+やぐ;yagu
+やくしょく;yakushoku
+やくば;yakuba
+やけに;yakeni
+やしき;yashiki
+やしなう;yashinau
+やしん;yashin
+やすっぽい;yasuppoi
+やすめる;yasumeru
+やせい;yasei
+やつ;yatsu
+やとう;yatou
+やみ;yami
+やむ;yamu
+ややこしい;yayakoshii
+やりとおす;yaritoosu
+やりとげる;yaritogeru
+やわらげる;yawarageru
+ヤング;yangu
+ゆ;yu
+ゆう;yuu
+ゆうい;yuui
+ゆううつ;yuuutsu
+ゆうえき;yuueki
+ゆうえつ;yuuetsu
+ゆうかん;yuukan
+ゆうき;yuuki
+ゆうぐれ;yuugure
+ゆうし;yuushi
+ゆうする;yuusuru
+ゆうせい;yuusei
+ゆうせん;yuusen
+ゆうどう;yuudou
+ゆうずう;yuuzuu
+ゆうび;yuubi
+ゆうぼう;yuubou
+ゆうぼく;yuuboku
+ゆうやけ;yuuyake
+ゆうりょく;yuuryoku
+ゆうれい;yuurei
+ゆうわく;yuuwaku
+ゆえ;yue
+ゆがむ;yugamu
+ゆさぶる;yusaburu
+ゆすぐ;yusugu
+ゆとり;yutori
+ユニーク;yuniiku
+ユニフォーム;yunifoomu
+ゆびさす;yubisasu
+ゆみ;yumi
+ゆらぐ;yuragu
+ゆるむ;yurumu
+ゆるめる;yurumeru
+ゆるやか;yuruyaka
+よ;yo
+よう;you
+よういん;youin
+ようえき;youeki
+ようけん;youken
+ようご;yougo
+ようし;youshi
+ようしき;youshiki
+ようする;yousuru
+ようせい;yousei
+ようそう;yousou
+ようひん;youhin
+ようふう;youfuu
+ようほう;youhou
+ようぼう;youbou
+よか;yoka
+よかん;yokan
+よきょう;yokyou
+よきん;yokin
+よく;yoku
+よくあつ;yokuatsu
+よくしつ;yokushitsu
+よくせい;yokusei
+よくふかい;yokufukai
+よくぼう;yokubou
+よける;yokeru
+よげん;yogen
+よこづな;yokoduna
+よごれ;yogore
+よし;yoshi
+よし;yoshi
+よしあし;yoshiashi
+よそう;yosou
+よそみ;yosomi
+よち;yochi
+よって;yotte
+よとう;yotou
+よびとめる;yobitomeru
+よふかし;yofukashi
+よふけ;yofuke
+よほど;yohodo
+よみあげる;yomiageru
+より;yori
+よりかかる;yorikakaru
+よろん;yoron
+せろん;seron
+よわまる;yowamaru
+よわめる;yowameru
+よわる;yowaru
+らいじょう;raijou
+ライス;raisu
+らくのう;rakunou
+らっか;rakka
+らっかん;rakkan
+ラベル;raberu
+ランプ;ranpu
+らんよう;ran_you
+リード;riido
+りくつ;rikutsu
+りし;rishi
+りじゅん;rijun
+りせい;risei
+りそく;risoku
+りったい;rittai
+りっぽう;rippou
+りっぽう;rippou
+りてん;riten
+りゃくだつ;ryakudatsu
+りゃくご;ryakugo
+りゅうつう;ryuutsuu
+りょういき;ryouiki
+りょうかい;ryoukai
+りょうかい;ryoukai
+りょうきょく;ryoukyoku
+りょうこう;ryoukou
+りょうしき;ryoushiki
+りょうしつ;ryoushitsu
+りょうしょう;ryoushou
+りょうしん;ryoushin
+りょうち;ryouchi
+りょうど;ryoudo
+りょうりつ;ryouritsu
+りょかく;ryokaku
+りょけん;ryoken
+りれき;rireki
+りろん;riron
+りんぎょう;ringyou
+るい;rui
+るいすい;ruisui
+るいじ;ruiji
+ルーズ;ruuzu
+ルール;ruuru
+れいこく;reikoku
+れいぞう;reizou
+れいたん;reitan
+レース;reesu
+レギュラー;regyuraa
+レッスン;ressun
+レディー;redii
+レバー;rebaa
+れんあい;ren_ai
+れんきゅう;renkyuu
+レンジ;renji
+れんじつ;renjitsu
+れんたい;rentai
+レンタカー;rentakaa
+れんちゅう;renchuu
+レントゲン;rentogen
+れんぽう;renpou
+れんめい;renmei
+ろうすい;rousui
+ろうどく;roudoku
+ろうひ;rouhi
+ろうりょく;rouryoku
+ロープウエイ;roopuuei
+ロープ;roopu
+ろくな;rokuna
+ろこつ;rokotsu
+ロマンチック;romanchikku
+ろんぎ;rongi
+ろんり;ronri
+わく;waku
+わくせい;wakusei
+わざ;waza
+わざわざ;wazawaza
+わずらわしい;wazurawashii
+わたりどり;wataridori
+ワット;watto
+わび;wabi
+わぶん;wabun
+わら;wara
+わり;wari
+わりあて;wariate
+わりこむ;warikomu
+わるもの;warumono
+われ;ware
+いない;inai
+けいかくです;keikakudesu
+たがる;tagaru
+とちがう;tochigau
+として;toshite
+やをない;yawonai
+あがる;agaru
+あいだ;aida
+あじ;aji
+あかりがきえている;akarigakieteiru
+あきる;akiru
+あまい;amai
+あんぜん;anzen
+あらゆる;arayuru
+あさい;asai
+あつい;atsui
+あつまり;atsumari
+あつまる;atsumaru
+あつめる;atsumeru
+あやまる;ayamaru
+AよりBのほうがわかいです;AyoriBnohougawakaidesu
+ばんぐみ;bangumi
+バター;bataa
+ベル;beru
+びっくり;bikkuri
+びしょうじょ;bishoujo
+ボタン;botan
+ぶどうしゅ;budoushu
+ぶん;bun
+ぶんれい;bunrei
+ちゃんと;chanto
+ち;chi
+ちかぢか;chikadika
+ちから;chikara
+ちょうし;choushi
+ちゅうがっこう;chuugakkou
+ちゅういする;chuuisuru
+だけど;dakedo
+だんぼう;danbou
+だれにでも;darenidemo
+だろう;darou
+だす;dasu
+だす;dasu
+でんとう;dentou
+でている;deteiru
+どんなでも;donnademo
+どんなに;donnani
+どのくらい;donokurai
+どりょく;doryoku
+どうぶつえん;doubutsuen
+どうどう;doudou
+どうしたの;doushitano
+どうやって;douyatte
+えだ;eda
+えいがかん;eigakan
+えらぶ;erabu
+ふで;fude
+ふえる;fueru
+ふかい;fukai
+ふく;fuku
+ふね;fune
+ふとい;futoi
+ふつか;futsuka
+ふつう;futsuu
+ふつうの;futsuuno
+ふうとう;fuutou
+がいこくじん;gaikokujin
+ガソリンスタンド;gasorinsutando
+ごい;goi
+ごめんください;gomenkudasai
+はく;haku
+はなし;hanashi
+はらい;harai
+はしる;hashiru
+はたらく;hataraku
+はつか;hatsuka
+へる;heru
+ひえる;hieru
+ひがし;higashi
+ひきだし;hikidashi
+ひろば;hiroba
+ひろい;hiroi
+ひるま;hiruma
+ひるすぎ;hirusugi
+ひつよう;hitsuyou
+ほか;hoka
+ほしい;hoshii
+ほそい;hosoi
+いちじかんご;ichijikango
+いがい;igai
+いいんだけど;iindakedo
+いまでも;imademo
+いみ;imi
+いのり;inori
+いれる;ireru
+いろいろあるね;iroiroarune
+いし;ishi
+いそいで;isoide
+いっしょう;isshou
+いっしゅうかん;isshuukan
+いたむ;itamu
+いたす;itasu
+いつか;itsuka
+いつか;itsuka
+いやでも;iyademo
+じゃ、このつぎ;ja_konotsugi
+じしん;jishin
+じしん;jishin
+じしょをひく;jishowohiku
+じゆう;jiyuu
+じゆうじかん;jiyuujikan
+じょうず;jouzu
+じょうずに;jouzuni
+じゅんばん;junban
+じゅんび;junbi
+じゅうよっか;juuyokka
+カーテン;kaaten
+かどうか;kadouka
+かがみ;kagami
+かい;kai
+かいわ;kaiwa
+かっこ;kakko
+かまいません;kamaimasen
+かまわない;kamawanai
+かならず;kanarazu
+かんがえる;kangaeru
+かんごふ;kangofu
+かんじる;kanjiru
+からだ;karada
+からい;karai
+かす;kasu
+かたち;katachi
+かつ;katsu
+かうことにする;kaukotonisuru
+かわく;kawaku
+かわる;kawaru
+かよう;kayou
+かざる;kazaru
+かぜ;kaze
+かぜ;kaze
+けんきゅう;kenkyuu
+けんきゅうしつ;kenkyuushitsu
+けんめい;kenmei
+けしごむ;keshigomu
+けっして;kesshite
+きびしい;kibishii
+きけん;kiken
+きんえん;kin_en
+きたない;kitanai
+きわめる;kiwameru
+コギャル;kogyaru
+こくでん;kokuden
+こくご;kokugo
+こまる;komaru
+ころぶ;korobu
+こし;koshi
+こしょう;koshou
+こたえ;kotae
+こうちょう;kouchou
+こうえい;kouei
+こうぎ;kougi
+こういう;kouiu
+こうとうがっこう;koutougakkou
+くらべる;kuraberu
+くらい;kurai
+きょく;kyoku
+きょう;kyou
+きょうかしょ;kyoukasho
+きょうしつ;kyoushitsu
+きゅうに;kyuuni
+まちあわせ;machiawase
+まちがい;machigai
+まいる;mairu
+まなぶ;manabu
+まねき;maneki
+まにあう;maniau
+まるい;marui
+めがねをかける;meganewokakeru
+めがさめる;megasameru
+めいれい;meirei
+めざめる;mezameru
+みにいく;miniiku
+みたい;mitai
+もじ;moji
+もつ;motsu
+もうすぐです;mousugudesu
+むかい;mukai
+むこう;mukou
+むり;muri
+むりに;murini
+なのか;nanoka
+ならべる;naraberu
+ならぶ;narabu
+ならう;narau
+ねむれない;nemurenai
+にがい;nigai
+にじゅうよっか;nijuuyokka
+にかい;nikai
+にんじん;ninjin
+にし;nishi
+ので;node
+のに;noni
+にゅうがく;nyuugaku
+おこす;okosu
+おくれる;okureru
+おくりもの;okurimono
+おくりさき;okurisaki
+おくる;okuru
+おみやげ;omiyage
+おもい;omoi
+おもいだす;omoidasu
+おもいで;omoide
+おもう;omou
+おなじ;onaji
+おおい;ooi
+オートバイ;ootobai
+おれい;orei
+おさきにしつれいします;osakinishitsureishimasu
+おしいれ;oshiire
+パソコン;pasokon
+らくな;rakuna
+らしい;rashii
+れい;rei
+れいぼう;reibou
+りゆう;riyuu
+りょう;ryou
+さびしい;sabishii
+さがる;sagaru
+さがす;sagasu
+さがす;sagasu
+さいご;saigo
+さいきん;saikin
+さいてい;saitei
+さいやく;saiyaku
+さく;saku
+さくぶん;sakubun
+さんかく;sankaku
+さしあげる;sashiageru
+せいかい;seikai
+せいかく;seikaku
+せいせき;seiseki
+せき;seki
+せなか;senaka
+しゃしんか;shashinka
+しゃしんをとる;shashinwotoru
+しあい;shiai
+しばふ;shibafu
+しばらくです;shibarakudesu
+しか;shika
+しま;shima
+しまる;shimaru
+しも;shimo
+しなもの;shinamono
+しんぱい;shinpai
+しらべる;shiraberu
+しる;shiru
+したく;shitaku
+しつもん;shitsumon
+しょくどう;shokudou
+しょうがっこう;shougakkou
+しょうじょ;shoujo
+しょうじょう;shoujou
+しょうたい;shoutai
+しゅっきん;shukkin
+しゅくだいをだす;shukudaiwodasu
+しゅみ;shumi
+しゅうり;shuuri
+それに;soreni
+そつぎょうしき;sotsugyoushiki
+そうじ;souji
+すべりやすい;suberiyasui
+すぐ;sugu
+すいどう;suidou
+すいえい;suiei
+すいか;suika
+すっかり;sukkari
+すむ;sumu
+すわる;suwaru
+すずしい;suzushii
+たちいりきんし;tachiirikinshi
+たいふう;taifuu
+たいいん;taiin
+たてる;tateru
+たとえば;tatoeba
+たずねる;tazuneru
+たずねる;tazuneru
+てまえ;temae
+てんらんかい;tenrankai
+てつだい;tetsudai
+とぶ;tobu
+という;toiu
+といわれた;toiwareta
+ところ;tokoro
+ところで;tokorode
+ところです;tokorodesu
+とく;toku
+とくに;tokuni
+とまる;tomaru
+とにかく;tonikaku
+とおか;tooka
+とおる;tooru
+とりあえず;toriaezu
+とうとう;toutou
+ついたち;tsuitachi
+つくる;tsukuru
+つまらない;tsumaranai
+つめたい;tsumetai
+つれてくる;tsuretekuru
+つよい;tsuyoi
+うける;ukeru
+うる;uru
+うすい;usui
+うつす;utsusu
+うつす;utsusu
+わかれる;wakareru
+わけ;wake
+われる;wareru
+わる;waru
+わたる;wataru
+やりかた;yarikata
+やせている;yaseteiru
+よごれる;yogoreru
+よほう;yohou
+よこ;yoko
+よく;yoku
+よく;yoku
+よくじつ;yokujitsu
+よんかい;yonkai
+よる;yoru
+よしゅう;yoshuu
+よてい;yotei
+よう;you
+ようだ;youda
+ようふく;youfuku
+ようか;youka
+ようになりました;youninarimashita
+ようす;yousu
+よわい;yowai
+ゆれる;yureru
+ゆうえんち;yuuenchi
+ユーロー;yuuroo
+ぜんぶ;zenbu
+ぜんぶで;zenbude
+ずっと;zutto
+だいいっか;daiikka
+にほんご;nihongo
+べんきょうする;benkyousuru
+だいがく;daigaku
+ある;aru
+たてもの;tatemono
+おおきい;ookii
+そして;soshite
+りっぱだ;rippada
+がくせい;gakusei
+かず;kazu
+おおい;ooi
+なかむら;nakamura
+にほんじん;nihonjin
+たち;tachi
+まいにち;mainichi
+おしえる;oshieru
+きょうしつ;kyoushitsu
+はなす;hanasu
+にほんにっぽん;nihonnippon
+がっか;gakka
+にほんがっか;nihongakka
+ちいさい;chiisai
+きれいだ;kireida
+いく;iku
+バス;basu
+きょう;kyou
+ごぜん;gozen
+ごぜんちゅう;gozenchuu
+じゅぎょう;jugyou
+しゅっせき;shusseki
+しゅっせきする;shussekisuru
+としょかん;toshokan
+ほん;hon
+よむ;yomu
+しずかだ;shizukada
+こんばん;konban
+たんご;tango
+それから;sorekara
+さくぶん;sakubun
+そのあと;sonoato
+ともだち;tomodachi
+てがみ;tegami
+たのしい;tanoshii
+さん;san
+おがわ;ogawa
+だいにか;dainika
+かぞく;kazoku
+ごにん;gonin
+ちち;chichi
+がいむしょう;gaimushou
+はは;haha
+えいご;eigo
+とても;totemo
+いそがしい;isogashii
+にわ;niwa
+ひろい;hiroi
+ばら;bara
+など;nado
+はな;hana
+さく;saku
+きょうだい;kyoudai
+あに;ani
+おきる;okiru
+パン;pan
+をでる;woderu
+こうぎ;kougi
+はじまる;hajimaru
+ぶんがく;bungaku
+ぜんぜんない;zenzennai
+たいくつ;taikutsu
+たいくつする;taikutsusuru
+れきし;rekishi
+げつようび;getsuyoubi
+すいようび;suiyoubi
+やさしい;yasashii
+どいつご;doitsugo
+じょうずだ;jouzuda
+わかる;wakaru
+しつもん;shitsumon
+しつもんする;shitsumonsuru
+こたえる;kotaeru
+しんせつだ;shinsetsuda
+おわる;owaru
+ほかのひ;hokanohi
+こうがい;kougai
+あまりない;amarinai
+べんりだ;benrida
+へいじつ;heijitsu
+かじ;kaji
+かいもの;kaimono
+りょうりする;ryourisuru
+つくる;tsukuru
+さら;sara
+あらう;arau
+そうじ;souji
+そうじする;soujisuru
+ねる;neru
+そうです;soudesu
+かようび;kayoubi
+もくようび;mokuyoubi
+きんようび;kin_youbi
+だいよんか;daiyonka
+けんぶつ;kenbutsu
+けんぶつする;kenbutsusuru
+どいつみんしゅきょうわこく;doitsuminshukyouwakoku
+しゅと;shuto
+かんこうきゃく;kankoukyaku
+ここ;koko
+ひろば;hiroba
+ひらた;hirata
+つうやく;tsuuyaku
+つうやくする;tsuuyakusuru
+あたり;atari
+あるく;aruku
+あれ;are
+ホテル;hoteru
+ね;ne
+それに;soreni
+ひゃくめえてる;hyakumeeteru
+さあ;saa
+しる;shiru
+ひだり;hidari
+デパート;depaato
+みぎ;migi
+しちょうしゃ;shichousha
+この;kono
+だいぶぶん;daibubun
+てれびとう;terebitou
+うえ;ue
+のぼる;noboru
+エレベーター;erebeetaa
+めいしょ;meisho
+はいる;hairu
+こくでん;kokuden
+えき;eki
+ふたり;futari
+どいつじん;doitsujin
+おちゃ;ocha
+ちゃ;cha
+だいすきだ;daisukida
+ご;go
+しょくぎょう;shokugyou
+ぎし;gishi
+よく;yoku
+はたらく;hataraku
+あね;ane
+おとうと;otouto
+ほんとうに;hontouni
+たいへんだ;taihenda
+かんしん;kanshin
+かんしんする;kanshinsuru
+どおり;doori
+おりる;oriru
+おとうとさん;otoutosan
+おいしゃさん;oishasan
+だいごか;daigoka
+ほんや;hon_ya
+たなか;tanaka
+がくしゃ;gakusha
+ことし;kotoshi
+しがつ;shigatsu
+ヨーロッパ;yooroppa
+けんきゅう;kenkyuu
+けんきゅうする;kenkyuusuru
+すごす;sugosu
+でかける;dekakeru
+かう;kau
+さがす;sagasu
+その;sono
+とき;toki
+そのとき;sonotoki
+しりあい;shiriai
+あう;au
+こんにちは;konnichiha
+ひさしぶりです;hisashiburidesu
+このまえから;konomaekara
+みせ;mise
+うる;uru
+よ;yo
+ぶんか;bunka
+かんけい;kankei
+びじゅつ;bijutsu
+じしょ;jisho
+もつ;motsu
+ああ;aa
+いっさつ;issatsu
+でも;demo
+ないよう;naiyou
+いいよい;iiyoi
+へん;hen
+すこし;sukoshi
+さんぽする;sanposuru
+ありがとう;arigatou
+ありがとうございます;arigatougozaimasu
+おうち;ouchi
+とおい;tooi
+かよう;kayou
+やく;yaku
+いちじかん;ichijikan
+かかる;kakaru
+おうふく;oufuku
+おうふくする;oufukusuru
+ふべんだ;fubenda
+りょう;ryou
+すむ;sumu
+げしゅく;geshuku
+げしゅくする;geshukusuru
+しゅじん;shujin
+たいがいぼうえきしょう;taigaibouekishou
+しごと;shigoto
+する;suru
+ひと;hito
+きのう;kinou
+についての;nitsuiteno
+ゆっくり;yukkuri
+さようなら;sayounara
+せいかつする;seikatsusuru
+といっしょに;toisshoni
+だいろっか;dairokka
+とうきょう;toukyou
+だいい;daii
+めんせき;menseki
+せまい;semai
+とち;tochi
+ひとびと;hitobito
+しんじゅく;shinjuku
+としん;toshin
+こうそう;kousou
+けんちく;kenchiku
+きんだいてきだ;kindaitekida
+さいきん;saikin
+たつ;tatsu
+かい;kai
+にかいだて;nikaidate
+ふるい;furui
+あさくさ;asakusa
+せんそうじ;sensouji
+でんとうてきだ;dentoutekida
+じいん;jiin
+とくに;tokuni
+ゆうめいだ;yuumeida
+こうきょ;koukyo
+いちぶ;ichibu
+れきしてきだ;rekishitekida
+とかい;tokai
+ぎんざ;ginza
+にぎやかだ;nigiyakada
+ところ;tokoro
+せんもんてん;senmonten
+つぎつぎに;tsugitsugini
+ならぶ;narabu
+じゅうたく;juutaku
+がい;gai
+じゅうたくがい;juutakugai
+ふえる;fueru
+せいかくだ;seikakuda
+ちほう;chihou
+しゅうへん;shuuhen
+でていく;deteiku
+へる;heru
+ひるま;hiruma
+けん;ken
+かいしゃ;kaisha
+つとめにん;tsutomenin
+つうきん;tsuukin
+つうがく;tsuugaku
+ながい;nagai
+らっしゅのじかん;rasshunojikan
+こうつうきかん;koutsuukikan
+こうそくどうろ;kousokudouro
+てん;ten
+かいけつ;kaiketsu
+かいけつする;kaiketsusuru
+こんご;kongo
+はってん;hatten
+はってんする;hattensuru
+のために;notameni
+じゅうようだ;juuyouda
+へいほう;heihou
+キロ;kiro
+おしえました;oshiemashita
+いろいろだ;iroiroda
+じゅっかいだて;jukkaidate
+いっかい;ikkai
+おおく;ooku
+になっている;ninatteiru
+いちがつ;ichigatsu
+にがつ;nigatsu
+さんがつ;sangatsu
+ごがつ;gogatsu
+ろくがつ;rokugatsu
+しちがつ;shichigatsu
+はちがつ;hachigatsu
+じゅうがつ;juugatsu
+じゅういちがつ;juuichigatsu
+じゅうにがつ;juunigatsu
+れい;rei
+ひゃく;hyaku
+まん;man
+しき;shiki
+いちねん;ichinen
+なつ;natsu
+あき;aki
+ふゆ;fuyu
+へんか;henka
+へんかする;henkasuru
+はっきりする;hakkirisuru
+かんしん;kanshin
+よほう;yohou
+てんきよほう;tenkiyohou
+はじめ;hajime
+あいさつする;aisatsusuru
+えいきょう;eikyou
+あたえる;ataeru
+つよい;tsuyoi
+かぜ;kaze
+ふく;fuku
+おだやかだ;odayakada
+あたたかい;atatakai
+いろ;iro
+さくら;sakura
+によって;niyotte
+ちがう;chigau
+じょうじゅん;joujun
+ばいう;baiu
+きせつ;kisetsu
+ちゅうじゅん;chuujun
+あめ;ame
+きおん;kion
+さがる;sagaru
+かなり;kanari
+すずしい;suzushii
+あつい;atsui
+あがる;agaru
+しっけ;shikke
+よわい;yowai
+むしあつい;mushiatsui
+うみ;umi
+やま;yama
+ほっかいどう;hokkaidou
+しんしゅう;shinshuu
+りょこう;ryokou
+りょこうする;ryokousuru
+おわり;owari
+たいふう;taifuu
+はげしい;hageshii
+さる;saru
+ほんかくてきだ;honkakutekida
+いちねんちゅう;ichinenchuu
+さわやかだ;sawayakada
+あおい;aoi
+そら;sora
+げじゅん;gejun
+ひえる;hieru
+つめたい;tsumetai
+さむい;samui
+にほんかい;nihonkai
+がわ;gawa
+ゆき;yuki
+きゅうしゅう;kyuushuu
+かごしま;kagoshima
+テキスト;tekisuto
+らいしゅう;raishuu
+テスト;tesuto
+くらい;kurai
+なんねん;nannen
+なんじ;nanji
+なんにん;nannin
+なんにち;nannichi
+なんようび;nan_youbi
+なんど;nando
+なんかい;nankai
+なんさつ;nansatsu
+なんまい;nanmai
+なんばん;nanban
+どの;dono
+どんな;donna
+どう;dou
+よてい;yotei
+よていする;yoteisuru
+おげんきですか;ogenkidesuka
+げんきだ;genkida
+ところで;tokorode
+べつにありません;betsuniarimasen
+きょうと;kyouto
+つれていく;tsureteiku
+くわしい;kuwashii
+しんかんせん;shinkansen
+はくぶつかん;hakubutsukan
+けんがく;kengaku
+けんがくする;kengakusuru
+おおさか;oosaka
+ぶんらく;bunraku
+しゅっぱつ;shuppatsu
+しゅっぱつする;shuppatsusuru
+ふん;fun
+ごう;gou
+ひかり;hikari
+はやい;hayai
+おじ;oji
+とまる;tomaru
+おもう;omou
+そう;sou
+ねがう;negau
+おねがいします;onegaishimasu
+もどる;modoru
+くるま;kuruma
+ひえいざん;hieizan
+うんてん;unten
+うんてんする;untensuru
+へただ;hetada
+けっこうだ;kekkouda
+まだない;madanai
+ちず;chizu
+でる;deru
+かいさつぐち;kaisatsuguchi
+まちがえる;machigaeru
+すみませんが;sumimasenga
+きっぷ;kippu
+あんない;annai
+あんないする;annaisuru
+かす;kasu
+ちゅうしん;chuushin
+きょうみぶかい;kyoumibukai
+こんど;kondo
+きたい;kitai
+きたいする;kitaisuru
+おくれる;okureru
+ほか;hoka
+いちにちじゅう;ichinichijuu
+うまれる;umareru
+びじゅつかん;bijutsukan
+げいじゅつ;geijutsu
+がくもん;gakumon
+まち;machi
+として;toshite
+がわ;gawa
+ながれる;nagareru
+かん;kan
+きょういく;kyouiku
+ぎむきょういく;gimukyouiku
+うける;ukeru
+かもく;kamoku
+すうがく;suugaku
+がいこくご;gaikokugo
+いまりやき;imariyaki
+ひん;hin
+びじゅつひん;bijutsuhin
+ふかい;fukai
+げんだい;gendai
+せいじ;seiji
+きょうみ;kyoumi
+きじ;kiji
+かならず;kanarazu
+えいが;eiga
+えいがかん;eigakan
+とうろん;touron
+とうろんする;touronsuru
+そつぎょう;sotsugyou
+そつぎょうする;sotsugyousuru
+ご;go
+きぼう;kibou
+きぼうする;kibousuru
+いがい;igai
+はじめる;hajimeru
+ねっしんだ;nesshinda
+みじかい;mijikai
+きかん;kikan
+じょうたつする;joutatsusuru
+やくす;yakusu
+りゅうがく;ryuugaku
+りゅうがくする;ryuugakusuru
+きかい;kikai
+まもなく;mamonaku
+なれる;nareru
+なら;nara
+のう;nou
+かぶき;kabuki
+かんがえる;kangaeru
+こまる;komaru
+はんとし;hantoshi
+たいざい;taizai
+たいざいする;taizaisuru
+けいけん;keiken
+けいけんする;keikensuru
+きこく;kikoku
+きこくする;kikokusuru
+すずき;suzuki
+ふらんすご;furansugo
+ふらんすじん;furansujin
+すいすじん;suisujin
+たんじょうび;tanjoubi
+パーティー;paatii
+さい;sai
+になる;ninaru
+ふつう;futsuu
+かてい;katei
+おさない;osanai
+こども;kodomo
+いわう;iwau
+おとな;otona
+ばあい;baai
+とくべつだ;tokubetsuda
+きょねん;kyonen
+はんがりいじん;hangariijin
+ふんいき;fun_iki
+ちょくせつ;chokusetsu
+ふれる;fureru
+じぶん;jibun
+しょうたい;shoutai
+しょうたいする;shoutaisuru
+プレゼント;purezento
+じょうとうだ;joutouda
+ネクタイ;nekutai
+えらぶ;erabu
+よそう;yosou
+よそうする;yosousuru
+いじょう;ijou
+おどろく;odoroku
+それ;sore
+きにいる;kiniiru
+まよう;mayou
+てんいん;ten_in
+そうだん;soudan
+そうだんする;soudansuru
+さいご;saigo
+まい;mai
+さとう;satou
+きゅうだ;kyuuda
+やくそく;yakusoku
+やくそくする;yakusokusuru
+おそい;osoi
+それぞれ;sorezore
+おいわい;oiwai
+おいわいをのべる;oiwaiwonoberu
+のべる;noberu
+くわわる;kuwawaru
+にほんしゅ;nihonshu
+さかな;sakana
+やさい;yasai
+たまご;tamago
+さまざまだ;samazamada
+えんげき;engeki
+ゆかいだ;yukaida
+いけん;iken
+かならずしもない;kanarazushimonai
+しょくご;shokugo
+いもうとさん;imoutosan
+かずこ;kazuko
+ピアノ;piano
+ひく;hiku
+みんよう;min_you
+うたう;utau
+うた;uta
+てんけいてきだ;tenkeitekida
+きょく;kyoku
+いっきょく;ikkyoku
+ならう;narau
+ひとりで;hitoride
+ハンガリー;hangarii
+よろこぶ;yorokobu
+そのころ;sonokoro
+ころ;koro
+おもいがけない;omoigakenai
+こばやし;kobayashi
+ぐうぜんだ;guuzenda
+ほうもん;houmon
+ほうもんする;houmonsuru
+よなか;yonaka
+すぎ;sugi
+かえってくる;kaettekuru
+にとって;nitotte
+わすれがたい;wasuregatai
+ひとばん;hitoban
+まさお;masao
+お;o
+にさつ;nisatsu
+そう、そう;sou_sou
+さがし;sagashi
+やすい;yasui
+なかなかない;nakanakanai
+みつかる;mitsukaru
+いま;ima
+たがい;tagai
+たがいに;tagaini
+かわだ;kawada
+よつや;yotsuya
+かわり;kawari
+そのかわり;sonokawari
+さかなや;sakanaya
+やおや;yaoya
+むかい;mukai
+おすしや;osushiya
+くだもの;kudamono
+くさい;kusai
+におい;nioi
+にがてだ;nigateda
+だめだ;dameda
+ことわる;kotowaru
+つぎ;tsugi
+あおやま;aoyama
+ちかてつ;chikatetsu
+ばんごう;bangou
+ええと;eeto
+まつ;matsu
+ばん;ban
+かとう;katou
+こうしゅうでんわ;koushuudenwa
+でんわをかける;denwawokakeru
+ばしょ;basho
+すぐだ;suguda
+じゅっぷん;juppun
+かんじ;kanji
+かんじがいい;kanjigaii
+へやだい;heyadai
+こうきゅう;koukyuu
+これより;koreyori
+まずない;mazunai
+えん;en
+つらい;tsurai
+くるしい;kurushii
+かぐ;kagu
+りそうてきだ;risoutekida
+あの;ano
+きめる;kimeru
+かおいろ;kaoiro
+かおいろがわるい;kaoirogawarui
+あたま;atama
+きぶんがよい;kibungayoi
+きぶんがいい;kibungaii
+かぜ;kaze
+いけませんね;ikemasenne
+たいしたことはない;taishitakotohanai
+おだいじに;odaijini
+どういしまして;douishimashite
+りょうりや;ryouriya
+や;ya
+にほんりょうりや;nihonryouriya
+そのまえ;sonomae
+いちど;ichido
+おはなしする;ohanashisuru
+フランス;furansu
+びょうき;byouki
+かんきょう;kankyou
+あう;au
+ずつう;zutsuu
+きぶんがわるい;kibungawarui
+すぐ;sugu
+ぶ;bu
+いぎりすじん;igirisujin
+しんぱい;shinpai
+しんぱいする;shinpaisuru
+のみもの;nomimono
+かってくる;kattekuru
+かえり;kaeri
+とちゅう;tochuu
+オレンジ;orenji
+ジュース;juusu
+オレンジジュース;orenjijuusu
+えんりょ;enryo
+えんりょする;enryosuru
+りんご;ringo
+なし;nashi
+かわく;kawaku
+のどがかわく;nodogakawaku
+みず;mizu
+すっかり;sukkari
+こおり;koori
+まど;mado
+あける;akeru
+ほう;hou
+もうしわけありませんもうしわけありません;moushiwakearimasenmoushiwakearimasen
+ちっともない;chittomonai
+かまいません;kamaimasen
+どうせ;douse
+コンサート;konsaato
+おばさん;obasan
+げしゅくのおばさん;geshukunoobasan
+ゆうごはん;yuugohan
+たのむ;tanomu
+ていねいだ;teineida
+しんさつ;shinsatsu
+しんさつする;shinsatsusuru
+りゅうかん;ryuukan
+はやる;hayaru
+ちゅうしゃ;chuusha
+ちゅうしゃする;chuushasuru
+あんせい;ansei
+もういちど;mouichido
+ようす;yousu
+くすり;kusuri
+いちにち;ichinichi
+かい;kai
+のむ;nomu
+ひとばんじゅう;hitobanjuu
+あせ;ase
+あせをかく;asewokaku
+けさ;kesa
+もう;mou
+ずっと;zutto
+ひる;hiru
+かんだ;kanda
+じつに;jitsuni
+いっそう;issou
+もっとも;mottomo
+より;yori
+せんしゅう;senshuu
+あそぶ;asobu
+あそびにいく;asobiniiku
+たずねる;tazuneru
+さいふ;saifu
+わすれる;wasureru
+おかね;okane
+とる;toru
+でんわがかかる;denwagakakaru
+おそくなってしまった;osokunatteshimatta
+かえって;kaette
+ひつようだ;hitsuyouda
+しんぱいだ;shinpaida
+かんたんだ;kantanda
+ふくざつだ;fukuzatsuda
+わかりにくい;wakarinikui
+しらべる;shiraberu
+わりあい;wariai
+わりあいに;wariaini
+このまえ;konomae
+なかやま;nakayama
+しょくじ;shokuji
+じゅうきょ;juukyo
+やはり;yahari
+こんなんだ;konnanda
+わかい;wakai
+どくとくだ;dokutokuda
+いっぱんてきだ;ippantekida
+したしい;shitashii
+あいだ;aida
+さんかげつ;sankagetsu
+しぜんだ;shizenda
+ひょうげん;hyougen
+ひょうげんする;hyougensuru
+しかた;shikata
+しかたがない;shikataganai
+いっしょうけんめい;isshoukenmei
+どりょく;doryoku
+どりょくする;doryokusuru
+たとえば;tatoeba
+けいとうてきだ;keitoutekida
+あつめる;atsumeru
+ノート;nooto
+ノートする;nootosuru
+ほうほう;houhou
+こまかい;komakai
+そっちょくだ;socchokuda
+ざんねんだ;zannenda
+じょし;joshi
+クラス;kurasu
+がっこう;gakkou
+よにん;yonin
+さらに;sarani
+かんじ;kanji
+きょうじゅ;kyouju
+しゃかいがくしゃ;shakaigakusha
+いっしゅうかん;isshuukan
+ちしきじん;chishikijin
+きんろうしゃ;kinrousha
+はば;haba
+はばひろい;habahiroi
+かいそう;kaisou
+こうかん;koukan
+こうかんする;koukansuru
+こんしゅう;konshuu
+おとずれる;otozureru
+せいねん;seinen
+よか;yoka
+スポーツ;supootsu
+けんこう;kenkou
+まいしゅう;maishuu
+バドミントン;badominton
+たっきゅう;takkyuu
+すいえい;suiei
+すいえいぷうる;suieipuuru
+こてん;koten
+ジャズ;jazu
+ビート;biito
+ギター;gitaa
+つけくわえる;tsukekuwaeru
+ねっちゅうする;necchuusuru
+いう;iu
+ふそく;fusoku
+ふそくする;fusokusuru
+うんどうふそく;undoufusoku
+なりやすい;nariyasui
+うんどうじょう;undoujou
+トラック;torakku
+いち、にかい;ichi_nikai
+はしる;hashiru
+こうか;kouka
+しゅちょう;shuchou
+しゅちょうする;shuchousuru
+いっぱんのひとびと;ippannohitobito
+しせつ;shisetsu
+りょうきん;ryoukin
+りよう;riyou
+りようする;riyousuru
+りようできる;riyoudekiru
+じつじょう;jitsujou
+せつめい;setsumei
+せつめいする;setsumeisuru
+に、さんにん;ni_sannin
+ウインタースポーツ;uintaasupootsu
+やすみ;yasumi
+ふゆやすみ;fuyuyasumi
+スキー;sukii
+スケート;sukeeto
+にたいして;nitaishite
+はんたいする;hantaisuru
+しょうせつ;shousetsu
+し;shi
+しんじる;shinjiru
+あかるい;akarui
+けんこうだ;kenkouda
+くらい;kurai
+かなしい;kanashii
+さびしい;sabishii
+しじん;shijin
+とよぶ;toyobu
+どくしょ;dokusho
+テニス;tenisu
+じゆうだ;jiyuuda
+ぜいたくだ;zeitakuda
+むりだ;murida
+ふさわしい;fusawashii
+さいこう;saikou
+しゅうとく;shuutoku
+しゅうとくする;shuutokusuru
+しょうらい;shourai
+じつようてきだ;jitsuyoutekida
+かいわ;kaiwa
+やくにたつ;yakunitatsu
+さんせい;sansei
+さんせいする;sanseisuru
+たいせつだ;taisetsuda
+ちゅういする;chuuisuru
+ちゅういぶかい;chuuibukai
+ポーランド;poorando
+はじめて;hajimete
+もう(+Mengenangabe);mou(+Mengenangabe)
+いっかげつ;ikkagetsu
+べつの;betsuno
+ぶるがりあじん;burugariajin
+ドイツ;doitsu
+ながされる;nagasareru
+しゅうしょく;shuushoku
+しゅうしょくする;shuushokusuru
+ひさしぶりだ;hisashiburida
+よねんせい;yonensei
+とうじ;touji
+なかの;nakano
+ほうそうきょく;housoukyoku
+しけん;shiken
+しけんをうける;shikenwoukeru
+けっか;kekka
+おちる;ochiru
+とおり;toori
+しんぶんしゃ;shinbunsha
+ジャーナリスト;jaanarisuto
+とくはいん;tokuhain
+かつやく;katsuyaku
+かつやくする;katsuyakusuru
+りかい;rikai
+りかいする;rikaisuru
+たすける;tasukeru
+ぎんこう;ginkou
+ぎんこういん;ginkouin
+かくじつだ;kakujitsuda
+がいこうかん;gaikoukan
+たいしかん;taishikan
+きょうそう;kyousou
+きょうそうする;kyousousuru
+りつ;ritsu
+かいがい;kaigai
+ちゅうざい;chuuzai
+ちゅうざいする;chuuzaisuru
+しょうしゃ;shousha
+しょうしゃいん;shoushain
+ながい;nagai
+きょうし;kyoushi
+かわる;kawaru
+ぐたいてきだ;gutaitekida
+のうみん;noumin
+ふくしまけん;fukushimaken
+のうそん;nouson
+ろうどう;roudou
+ろうどうする;roudousuru
+くろう;kurou
+くろうする;kurousuru
+のうぎょう;nougyou
+じゅうじする;juujisuru
+いなか;inaka
+にあい;niai
+さわがしい;sawagashii
+はなれる;hanareru
+しぜん;shizen
+おくる;okuru
+きかい;kikai
+きかいか;kikaika
+すすむ;susumu
+らくだ;rakuda
+かいぜん;kaizen
+かいぜんする;kaizensuru
+けっしん;kesshin
+けっしんする;kesshinsuru
+やまだ;yamada
+せいじか;seijika
+かいしゃいん;kaishain
+ろうどうくみあい;roudoukumiai
+かつどう;katsudou
+かつどうする;katsudousuru
+しんぽてきだ;shinpotekida
+ろうどうしゃ;roudousha
+じょうけん;jouken
+せいこう;seikou
+せいこうする;seikousuru
+かんこう;kankou
+こくりつ;kokuritsu
+こくりつとしょかん;kokuritsutoshokan
+ひつよう;hitsuyou
+こうかんできる;koukandekiru
+アクセント;akusento
+かわむら;kawamura
+こうし;koushi
+える;eru
+ぶれひとげき;burehitogeki
+かのじょ;kanojo
+それん(=そびえとしゃかいしゅぎきょうわこくれんぽう);soren(=sobietoshakaishugikyouwakokurenpou)
+ぎきょく;gikyoku
+ブレヒトのぎきょく;burehitonogikyoku
+さくひん;sakuhin
+かんしょう;kanshou
+かんしょうする;kanshousuru
+しばい;shibai
+いんしょう;inshou
+しゃかい;shakai
+しゃかいてきだ;shakaitekida
+けいざいてきだ;keizaitekida
+あらゆる;arayuru
+ぶんや;bun_ya
+だんせい;dansei
+じょせい;josei
+けんり;kenri
+ぎむ;gimu
+げきだん;gekidan
+えんしゅつか;enshutsuka
+はいゆう;haiyuu
+かい;kai
+じょゆう;joyuu
+どうりょう;douryou
+のもとに;nomotoni
+さんか;sanka
+さんかする;sankasuru
+うらやましい;urayamashii
+れい;rei
+けっこん;kekkon
+けっこんする;kekkonsuru
+ふたん;futan
+ふたんする;futansuru
+おっと;otto
+しゃかいしゅぎ;shakaishugi
+しゃかいしゅぎこく;shakaishugikoku
+つま;tsuma
+つづける;tsudukeru
+めぐまれる;megumareru
+すてる;suteru
+しゅふ;shufu
+しきりに;shikirini
+おもいだす;omoidasu
+そうりつ;souritsu
+そうりつする;souritsusuru
+げきじょう;gekijou
+レパートリー;repaatorii
+にんき;ninki
+にんきのある;ninkinoaru
+すぐれる;sugureru
+すぐれた;sugureta
+えんぎ;engi
+かんきゃく;kankyaku
+さかんだ;sakanda
+はくしゅ;hakushu
+はくしゅする;hakushusuru
+はんのう;hannou
+はんのうする;hannousuru
+かんげき;kangeki
+かんげきする;kangekisuru
+まんいん;man_in
+てにいれる;teniireru
+にゅうじょうりょう;nyuujouryou
+ふくむ;fukumu
+すべて;subete
+こっか;kokka
+オペラ;opera
+しょうれい;shourei
+しょうれいする;shoureisuru
+ざいせいてきだ;zaiseitekida
+えんじょ;enjo
+えんじょする;enjosuru
+おしむ;oshimu
+ぶんかしょう;bunkashou
+からい;karai
+えいぶんがく;eibungaku
+ただ;tada
+いっぽう;ippou
+とくいだ;tokuida
+ところが;tokoroga
+うしろ;ushiro
+もと;moto
+ほか;hoka
+そと;soto
+ところ;tokoro
+てつだい;tetsudai
+じゅんび;junbi
+じゅんびする;junbisuru
+ほとんどない;hotondonai
+としうえ;toshiue
+よゆう;yoyuu
+ゆでたまご;yudetamago
+ミルク;miruku
+すます;sumasu
+かたづけ;kataduke
+コップ;koppu
+ナイフ;naifu
+フォーク;fooku
+スプーン;supuun
+おゆ;oyu
+しょっき;shokki
+とだな;todana
+バター;bataa
+れいぞうこ;reizouko
+いれる;ireru
+しょくたく;shokutaku
+ふく;fuku
+テーブルセンター;teeburusentaa
+かける;kakeru
+かびん;kabin
+いま;ima
+きもち;kimochi
+きもちがいい;kimochigaii
+たしょう;tashou
+よくじつ;yokujitsu
+ぜんぶ;zenbu
+にちようひん;nichiyouhin
+しょくりょうひん;shokuryouhin
+スーパーマーケット;suupaamaaketto
+きたく;kitaku
+きたくする;kitakusuru
+おもだ;omoda
+こしらえる;koshiraeru
+ひまだ;himada
+ごちそうする;gochisousuru
+たく;taku
+しゅるい;shurui
+おかず;okazu
+みそしる;misoshiru
+にく;niku
+ジャガイモ;jagaimo
+かわ;kawa
+むく;muku
+にんじん;ninjin
+キャベツ;kyabetsu
+きる;kiru
+ほおれんそう;hoorensou
+さとう;satou
+しお;shio
+こしょう;koshou
+あぶら;abura
+す;su
+ちょうみりょう;choumiryou
+おわん;owan
+はし;hashi
+ならべる;naraberu
+そろう;sorou
+ひととき;hitotoki
+すむ;sumu
+かたづける;katadukeru
+いやがる;iyagaru
+なべ;nabe
+フライパン;furaipan
+うえの;ueno
+ひきうける;hikiukeru
+でんき;denki
+でんきそうじき;denkisoujiki
+いえじゅう;iejuu
+したの;shitano
+せんたくする;sentakusuru
+せんたくもの;sentakumono
+ほす;hosu
+とりいれる;toriireru
+アイロン;airon
+アイロンをかける;aironwokakeru
+わける;wakeru
+ぜんたい;zentai
+かんげき;kangeki
+つたえる;tsutaeru
+タクシー;takushii
+さんもんおぺら;sanmon_opera
+じょうえん;jouen
+じょうえんする;jouensuru
+したがって;shitagatte
+かさねて;kasanete
+において;nioite
+にかんして;nikanshite
+にかんれんして;nikanrenshite
+をもって;womotte
+につれて;nitsurete
+にしたがって;nishitagatte
+におうじて;nioujite
+にならんで;ninarande
+たいした;taishita
+いわゆる;iwayuru
+さる;saru
+ぞう;zou
+くま;kuma
+おもしろそうだ;omoshirosouda
+いける;ikeru
+かこむ;kakomu
+おかし;okashi
+れこおどてん;rekoodoten
+クリスマス;kurisumasu
+ひこうき;hikouki
+か;ka
+せきにん;sekinin
+せきにんしゃ;sekininsha
+けいゆ;keiyu
+くうこう;kuukou
+こうくう;koukuu
+とぶ;tobu
+ちょっこう;chokkou
+ちょっこうする;chokkousuru
+じどうしゃ;jidousha
+むかえる;mukaeru
+むかえにいく;mukaeniiku
+むかえにくる;mukaenikuru
+こうくうけん;koukuuken
+りょけん;ryoken
+しょるい;shorui
+たしかめる;tashikameru
+ながめる;nagameru
+じさ;jisa
+ふしぎだ;fushigida
+しゅっこく;shukkoku
+しゅっこくする;shukkokusuru
+カウンター;kauntaa
+かかり;kakari
+かかりのひと;kakarinohito
+にもつ;nimotsu
+じゅうりょう;juuryou
+はかる;hakaru
+ちょうか;chouka
+ちょうかする;choukasuru
+はらう;harau
+てつづき;tetsuduki
+とうじょうけん;toujouken
+ぜいかん;zeikan
+てにもつ;tenimotsu
+けんさ;kensa
+けんさする;kensasuru
+まちあいしつ;machiaishitsu
+とおす;toosu
+めをとおす;mewotoosu
+きない;kinai
+せいけつだ;seiketsuda
+とうちゃく;touchaku
+とうちゃくする;touchakusuru
+のりかえる;norikaeru
+スチュアデス;suchuadesu
+たつ;tatsu
+ゆううつだ;yuuutsuda
+はっちゃく;hacchaku
+はっちゃくする;hacchakusuru
+おおがた;oogata
+じぇっとき;jettoki
+ら;ra
+たいりく;tairiku
+とびつづける;tobitsudukeru
+こうだいだ;koudaida
+こくど;kokudo
+みおろす;miorosu
+あらためる;aratameru
+あらためて;aratamete
+なりたくうこう;naritakuukou
+ちゃくりく;chakuriku
+ちゃくりくする;chakurikusuru
+にゅうこく;nyuukoku
+にゅうこくする;nyuukokusuru
+さしょう;sashou
+しらべ;shirabe
+ホール;hooru
+うけとる;uketoru
+でんぽう;denpou
+うつ;utsu
+でんぽうをうつ;denpouwoutsu
+かんけいしゃ;kankeisha
+しらせる;shiraseru
+しらせてある;shirasetearu
+でむかえる;demukaeru
+とない;tonai
+むかう;mukau
+ふりむく;furimuku
+あつまる;atsumaru
+なごや;nagoya
+ほいくしょ;hoikusho
+ようちえん;youchien
+しょうがっこう;shougakkou
+ちゅうがっこう;chuugakkou
+こうとうがっこう;koutougakkou
+しさつ;shisatsu
+しさつする;shisatsusuru
+まわる;mawaru
+せんもんか;senmonka
+きょういくしょう;kyouikushou
+げんざい;genzai
+はったつ;hattatsu
+はったつする;hattatsusuru
+はったつした;hattatsushita
+しほんしゅぎ;shihonshugi
+しょ;sho
+ちょうさ;chousa
+ちょうさする;chousasuru
+くにぐに;kuniguni
+くらべる;kuraberu
+にかんする;nikansuru
+こくみん;kokumin
+いっぱん;ippan
+しりつ;shiritsu
+ちゅうしょく;chuushoku
+ともに;tomoni
+あんないしゃ;annaisha
+おおの;oono
+し;shi
+りゆう;riyuu
+じじつ;jijitsu
+とくしゅだ;tokushuda
+じじょう;jijou
+せいど;seido
+すでに;sudeni
+ねんげつ;nengetsu
+すう;suu
+およぶ;oyobu
+ほうけんてきだ;houkentekida
+ほうけん;houken
+でんとう;dentou
+ねざす;nezasu
+ねつ;netsu
+にたいする;nitaisuru
+せっきょくてきだ;sekkyokutekida
+ひょうか;hyouka
+ひょうかする;hyoukasuru
+かたち;katachi
+あらわれる;arawareru
+せいき;seiki
+しゅうがく;shuugaku
+パーセント;paasento
+はなし;hanashi
+のぞく;nozoku
+アメリカ;amerika
+つぐ;tsugu
+についで;nitsuide
+こうとうきょういく;koutoukyouiku
+こえる;koeru
+とうけい;toukei
+せんしんてきだ;senshintekida
+しつ;shitsu
+かんれん;kanren
+かんれんする;kanrensuru
+にかんれんして;nikanrenshite
+かかえる;kakaeru
+かたる;kataru
+しみん;shimin
+きほんてきだ;kihontekida
+げんそく;gensoku
+もとづく;motoduku
+のうりょく;nouryoku
+おうじる;oujiru
+におうじて;nioujite
+びょうどうだ;byoudouda
+における;niokeru
+よさん;yosan
+だいがくせい;daigakusei
+そう;sou
+しゅっしん;shusshin
+じょしがくせい;joshigakusei
+むりょう;muryou
+こうりつ;kouritsu
+しゃ;sha
+レストラン;resutoran
+ちょうしょく;choushoku
+ゆうしょく;yuushoku
+えんそく;ensoku
+なかじま;nakajima
+しょぞく;shozoku
+しょぞくする;shozokusuru
+きょうしょくいん;kyoushokuin
+をはじめ;wohajime
+じむ;jimu
+じむいん;jimuin
+ひしょ;hisho
+だいたすう;daitasuu
+きょうこく;kyoukoku
+くたびれる;kutabireru
+きがつく;kigatsuku
+は;ha
+かお;kao
+みのまわりひん;minomawarihin
+かるい;karui
+てさげぶくろ;tesagebukuro
+くもる;kumoru
+しゅうごう;shuugou
+しゅうごうする;shuugousuru
+ほぼ;hobo
+ざせき;zaseki
+すわる;suwaru
+はっしゃ;hassha
+はっしゃする;hasshasuru
+いえなみ;ienami
+たえる;taeru
+さゆう;sayuu
+りょうがわ;ryougawa
+むぎ;mugi
+はたけ;hatake
+いちめん;ichimen
+ひろがる;hirogaru
+いちご;ichigo
+いちごばたけ;ichigobatake
+しゅうかく;shuukaku
+しゅうかくする;shuukakusuru
+じき;jiki
+こい;koi
+は;ha
+きる;kiru
+しゃがむ;shagamu
+み;mi
+つむ;tsumu
+かご;kago
+しゃべる;shaberu
+ねむい;nemui
+ねむる;nemuru
+いねむりする;inemurisuru
+だいにじせかいたいせん;dainijisekaitaisen
+ちょくぜん;chokuzen
+かいほう;kaihou
+かいほうする;kaihousuru
+ぐん;gun
+ナチ;nachi
+ぐんたい;guntai
+せんとう;sentou
+せんとうする;sentousuru
+せんし;senshi
+せんしする;senshisuru
+へいし;heishi
+とむらう;tomurau
+ひ;hi
+し;shi
+こっきょう;kokkyou
+こくせき;kokuseki
+しゅつにゅうこく;shutsunyuukoku
+いる;iru
+はし;hashi
+わたる;wataru
+もり;mori
+ほそい;hosoi
+ロマンチックだ;romanchikkuda
+ブルーベリー;buruuberii
+つかり;tsukari
+かんじる;kanjiru
+みずうみ;mizuumi
+かいすいぎ;kaisuigi
+しゃしん;shashin
+しゃしんする;shashinsuru
+ボール;booru
+なげる;nageru
+みおくる;miokuru
+そんなに;sonnani
+こっかい;kokkai
+ぎかい;gikai
+ひらく;hiraku
+いってい;ittei
+がく;gaku
+ぜいきん;zeikin
+だけ;dake
+せんきょ;senkyo
+せんきょする;senkyosuru
+せんきょけん;senkyoken
+おとこ;otoko
+おんな;onna
+しゅうぎいん;shuugiin
+さんぎいん;sangiin
+こうせい;kousei
+こうせいする;kouseisuru
+じょうやく;jouyaku
+みとめる;mitomeru
+そうりだいじん;souridaijin
+しめい;shimei
+しめいする;shimeisuru
+さいけつ;saiketsu
+さいけつする;saiketsusuru
+ぎいん;giin
+はんすう;hansuu
+さんぶんのに;sanbunnoni
+ぶん;bun
+けっせき;kesseki
+けっせきする;kessekisuru
+かいぎ;kaigi
+ほんかいぎ;honkaigi
+むこう;mukou
+きんきゅうだ;kinkyuuda
+りんじ;rinji
+ぎけつ;giketsu
+たすうけつ;tasuuketsu
+ほうしき;houshiki
+どうすう;dousuu
+ぎちょう;gichou
+けってい;kettei
+けっていする;ketteisuru
+による;niyoru
+ちょくせつせんきょ;chokusetsusenkyo
+ぎせき;giseki
+にんき;ninki
+ごとに;gotoni
+かいせん;kaisen
+かいせんする;kaisensuru
+ぜんこく;zenkoku
+せんきょく;senkyoku
+ふ;fu
+とうきょうと;toukyouto
+く;ku
+おおさかふ;oosakafu
+じゆうみんしゅとうじみんとう;jiyuuminshutoujimintou
+しゃかいとう;shakaitou
+きょうさんとう;kyousantou
+こうめいとう;koumeitou
+みんしゃとう;minshatou
+せいとう;seitou
+だいひょう;daihyou
+だいひょうする;daihyousuru
+あわてる;awateru
+ニュアンス;nyuansu
+ぶん;bun
+しゅうちゅうりょく;shuuchuuryoku
+どうけん;douken
+まえかわ;maekawa
+ふじん;fujin
+たのしみ;tanoshimi
+ちちおや;chichioya
+しぬ;shinu
+わかれる;wakareru
+しにわかれる;shiniwakareru
+したがう;shitagau
+かこ;kako
+じっさい;jissai
+そういう;souiu
+いっしょう;isshou
+がまん;gaman
+がまんする;gamansuru
+すみ;sumi
+なく;naku
+けっしてない;kesshitenai
+じんせい;jinsei
+どくりつ;dokuritsu
+どくりつする;dokuritsusuru
+にんげん;ningen
+あつかう;atsukau
+ぎのう;ginou
+けつい;ketsui
+けついする;ketsuisuru
+こんなん;konnan
+ほんやく;hon_yaku
+ほんやくする;hon_yakusuru
+アルバイト;arubaito
+アルバイトする;arubaitosuru
+もとめる;motomeru
+いろんな;ironna
+べんがく;bengaku
+がか;gaka
+ば;ba
+しりあう;shiriau
+はげます;hagemasu
+たすけあう;tasukeau
+くらす;kurasu
+いらい;irai
+しゅっぱん;shuppan
+しゅっぱんする;shuppansuru
+きょうりょく;kyouryoku
+きょうりょくする;kyouryokusuru
+おかげで;okagede
+おかげです;okagedesu
+ほしょう;hoshou
+ほしょうする;hoshousuru
+せんご;sengo
+しんしゅつする;shinshutsusuru
+けいこう;keikou
+たしかだ;tashikada
+めだつ;medatsu
+だいじん;daijin
+ぜんめんてきだ;zenmentekida
+のこす;nokosu
+れいがいてきだ;reigaitekida
+いぜん;izen
+いみ;imi
+まいつき;maitsuki
+おんがくかい;ongakukai
+そうい;soui
+めいじ;meiji
+けんきゅうしゃ;kenkyuusha
+あるいは;aruiha
+ひょうろんか;hyouronka
+さっか;sakka
+ろんぶん;ronbun
+きんべんだ;kinbenda
+れいぎ;reigi
+ただしい;tadashii
+れいぎただしい;reigitadashii
+ちつじょ;chitsujo
+まもる;mamoru
+かがくてきだ;kagakutekida
+ごうりてきだ;gouritekida
+しそう;shisou
+せいしん;seishin
+そんちょう;sonchou
+そんちょうする;sonchousuru
+しゅうきょうてきだ;shuukyoutekida
+かんてん;kanten
+かんさつ;kansatsu
+かんさつする;kansatsusuru
+たいしょう;taishou
+ろんじる;ronjiru
+いったい;ittai
+まさに;masani
+げんじつ;genjitsu
+ちゅうもく;chuumoku
+ちゅうもくする;chuumokusuru
+たんじゅんだ;tanjunda
+おうべいじん;oubeijin
+ときとして;tokitoshite
+きょくたんだ;kyokutanda
+むじゅん;mujun
+むじゅんする;mujunsuru
+たいしょうてきだ;taishoutekida
+めん;men
+どうじ;douji
+ルース・ベネディクト;ruusu_benedikuto
+きく;kiku
+かたな;katana
+こうどうする;koudousuru
+ぶんせき;bunseki
+ぶんせきする;bunsekisuru
+はあくする;haakusuru
+せいかく;seikaku
+ぶぶん;bubun
+いんしょうてきだ;inshoutekida
+すなわち;sunawachi
+にすると;nisuruto
+けんかする;kenkasuru
+おとなしい;otonashii
+いばる;ibaru
+あいて;aite
+ばかにする;bakanisuru
+がんこだ;gankoda
+じゅんのうせい;junnousei
+じゅうじゅんだ;juujunda
+たにん;tanin
+かんしょう;kanshou
+かんしょうする;kanshousuru
+はら;hara
+はらをたてる;harawotateru
+ちゅうじつだ;chuujitsuda
+かんようだ;kan_youda
+ふちゅうじつだ;fuchuujitsuda
+いじわるだ;ijiwaruda
+ゆうき;yuuki
+おくびょう;okubyou
+ほしゅてきだ;hoshutekida
+よろこんで;yorokonde
+うけいれる;ukeireru
+そうご;sougo
+まったく;mattaku
+はんする;hansuru
+こじん;kojin
+おおかれすくなかれ;ookaresukunakare
+けいせい;keisei
+けいせいする;keiseisuru
+こんきょ;konkyo
+いずれにしても;izurenishitemo
+こうぞう;kouzou
+きんだいか;kindaika
+きんだいかする;kindaikasuru
+かてい;katei
+むすびつく;musubitsuku
+ぜんじつ;zenjitsu
+かさねる;kasaneru
+かさねて;kasanete
+じしん;jishin
+ていあん;teian
+ていあんする;teiansuru
+がいらいご;gairaigo
+みみ;mimi
+みみにする;miminisuru
+のりもの;norimono
+こうこく;koukoku
+くわえる;kuwaeru
+とは;toha
+せいしつ;seishitsu
+もと;moto
+ぼこくご;bokokugo
+かんぜんだ;kanzenda
+さす;sasu
+なかば;nakaba
+ぽるとがるじん;porutogarujin
+おらんだじん;orandajin
+せっしょく;sesshoku
+せっしょくする;sesshokusuru
+ぶんめい;bunmei
+じぶつ;jibutsu
+もたらす;motarasu
+いご;igo
+おうべい;oubei
+かりいれる;kariireru
+いふく;ifuku
+いがく;igaku
+イタリア;itaria
+いたりあご;itariago
+こうぎょう;kougyou
+しょうぎょう;shougyou
+しゅうきょう;shuukyou
+はんい;han_i
+ぶんぷ;bunpu
+ぶんぷする;bunpusuru
+きんだい;kindai
+りょういき;ryouiki
+むける;mukeru
+いっち;icchi
+いっちする;icchisuru
+あめりかえいご;amerikaeigo
+あっとうてきだ;attoutekida
+びよういん;biyouin
+かみ;kami
+よごれる;yogoreru
+シャンプー;shanpuu
+ききかえす;kikikaesu
+ヘアー;heaa
+ほんらい;honrai
+うしなう;ushinau
+つうようする;tsuuyousuru
+おうかがいする;oukagaisuru
+しゅうにゅう;shuunyuu
+ぞうか;zouka
+ぞうかする;zoukasuru
+かんげい;kangei
+かんげいする;kangeisuru
+ひかんする;hikansuru
+たちば;tachiba
+うたがう;utagau
+きもちをわるくする;kimochiwowarukusuru
+とか;toka
+ですから;desukara
+えんりょぶかい;enryobukai
+じしん;jishin
+そだつ;sodatsu
+カーテン;kaaten
+まっしろだ;masshiroda
+つもる;tsumoru
+ふりつづく;furitsuduku
+に、さんねん;ni_sannen
+セントラル・ヒーティング;sentoraru_hiitingu
+だんぼう;danbou
+しゅっきん;shukkin
+しゅっきんする;shukkinsuru
+ねぼう;nebou
+ねぼうする;nebousuru
+せんめんじょ;senmenjo
+ひげをそる;higewosoru
+おおいそぎ;ooisogi
+ネクタイをしめる;nekutaiwoshimeru
+めんどうだ;mendouda
+ワイシャツ;waishatsu
+セーター;seetaa
+せびろ;sebiro
+うわぎ;uwagi
+ながぐつ;nagagutsu
+はく;haku
+まにあう;maniau
+あわてて;awatete
+おちつく;ochitsuku
+いやだ;iyada
+かみをとかす;kamiwotokasu
+けしょう;keshou
+けしょうする;keshousuru
+みじたく;mijitaku
+ととのえる;totonoeru
+きこえる;kikoeru
+ろうか;rouka
+にがわらい;nigawarai
+にがわらいする;nigawaraisuru
+こし;koshi
+て;te
+あてる;ateru
+いたそうだ;itasouda
+であう;deau
+よこぎる;yokogiru
+ゆうびんきょく;yuubinkyoku
+こおる;kooru
+ころぶ;korobu
+ズボン;zubon
+ちこく;chikoku
+ちこくする;chikokusuru
+れんらく;renraku
+れんらくする;renrakusuru
+むり;muri
+むりする;murisuru
+ちゅうこく;chuukoku
+ちゅうこくする;chuukokusuru
+どんどん;dondon
+いけない;ikenai
+きをつける;kiwotsukeru
+かさをさす;kasawosasu
+ろうじん;roujin
+すがた;sugata
+いがいだ;igaida
+いたむ;itamu
+たばこ;tabako
+すう;suu
+たばこをすう;tabakowosuu
+たいくつだ;taikutsuda
+おもいで;omoide
+しぜんかがく;shizenkagaku
+はなしかける;hanashikakeru
+ほうそう;housou
+ほうそうする;housousuru
+テレビほうそう;terebihousou
+かいし;kaishi
+かいしする;kaishisuru
+しょうわ;shouwa
+ばくはつてきだ;bakuhatsutekida
+いきおい;ikioi
+いいすぎ;iisugi
+そくど;sokudo
+ふきゅう;fukyuu
+ふきゅうする;fukyuusuru
+ばんめ;banme
+カラーテレビ;karaaterebi
+マスコミ;masukomi
+しゅだん;shudan
+はたす;hatasu
+やくわり;yakuwari
+やくわりをはたす;yakuwariwohatasu
+かわる;kawaru
+きゅうそくだ;kyuusokuda
+たかまる;takamaru
+こうしき;koushiki
+はっぴょう;happyou
+はっぴょうする;happyousuru
+せたい;setai
+ぶんかてきだ;bunkatekida
+およぼす;oyobosu
+むしする;mushisuru
+にっぽんほうそうきょうかい;nipponhousoukyoukai
+せんでん;senden
+せんでんする;sendensuru
+しゅうにゅうげん;shuunyuugen
+みんかん;minkan
+てれびきょく;terebikyoku
+ばんぐみ;bangumi
+とならんで;tonarande
+しちょうりつ;shichouritsu
+れんぞく;renzoku
+れんぞくする;renzokusuru
+ちゅうし;chuushi
+ちゅうしする;chuushisuru
+くりかえす;kurikaesu
+まれだ;mareda
+いち;ichi
+しめる;shimeru
+たいど;taido
+ていど;teido
+はんだん;handan
+はんだんする;handansuru
+うちのこ;uchinoko
+ふまん;fuman
+ごらく;goraku
+むだだ;mudada
+ついやす;tsuiyasu
+なげく;nageku
+ひなん;hinan
+ひなんする;hinansuru
+ねんれい;nenrei
+せいべつ;seibetsu
+ふだん;fudan
+へいきん;heikin
+へいきんする;heikinsuru
+へいきんして;heikinshite
+ひかく;hikaku
+ひかくする;hikakusuru
+ニュース;nyuusu
+かいせつ;kaisetsu
+かいせつする;kaisetsusuru
+ほうどう;houdou
+ほうどうする;houdousuru
+ドラマ;dorama
+けいおんがく;keiongaku
+クイズ;kuizu
+はなす;hanasu
+つけはなす;tsukehanasu
+けす;kesu
+めをやる;mewoyaru
+おきゃくさん;okyakusan
+きにする;kinisuru
+こうけい;koukei
+こしょう;koshou
+こしょうする;koshousuru
+ものたりない;monotarinai
+あつい;atsui
+めいわく;meiwaku
+めいわくをかける;meiwakuwokakeru
+からだ;karada
+からだじゅう;karadajuu
+かぜをひく;kazewohiku
+しない;shinai
+だんち;danchi
+ひっこす;hikkosu
+きんじょ;kinjo
+ごうかん;goukan
+きのどくだ;kinodokuda
+うわさ;uwasa
+うわさする;uwasasuru
+かおみしり;kaomishiri
+ぎゃくだ;gyakuda
+したしむ;shitashimu
+したしみやすい;shitashimiyasui
+かいだん;kaidan
+おもい;omoi
+かいものぶくろ;kaimonobukuro
+おうだん;oudan
+おうだんする;oudansuru
+ほどう;hodou
+おうだんほどう;oudanhodou
+としより;toshiyori
+あぶない;abunai
+そのたびに;sonotabini
+ありがたい;arigatai
+かいかつだ;kaikatsuda
+ちょうし;choushi
+じたく;jitaku
+まねく;maneku
+こころ;kokoro
+こころをうつ;kokorowoutsu
+いきいきと;ikiikito
+きがする;kigasuru
+せんそうちゅう;sensouchuu
+ひろしま;hiroshima
+げんばく;genbaku
+おとす;otosu
+こうかふこうか;koukafukouka
+さとがえり;satogaeri
+ばくだん;bakudan
+くさ;kusa
+はかい;hakai
+はかいする;hakaisuru
+なんとか;nantoka
+おそろしい;osoroshii
+きおく;kioku
+きおくする;kiokusuru
+くろい;kuroi
+やける;yakeru
+こげる;kogeru
+はだか;hadaka
+したい;shitai
+あちらこちら;achirakochira
+ころがる;korogaru
+よぶ;yobu
+ははおや;hahaoya
+さけぶ;sakebu
+きみわるい;kimiwarui
+ひびく;hibiku
+のはら;nohara
+やけのはら;yakenohara
+しょうそく;shousoku
+つかむ;tsukamu
+いっしゅん;isshun
+ざいさん;zaisan
+なくす;nakusu
+ひげき;higeki
+にどとふたたびない;nidotofutatabinai
+かたい;katai
+いきのこる;ikinokoru
+へいわ;heiwa
+いきる;ikiru
+いぎ;igi
+かく;kaku
+エネルギー;enerugii
+かくえねるぎい;kakuenerugii
+ころす;korosu
+しよう;shiyou
+しようする;shiyousuru
+ゆたかだ;yutakada
+しあわせだ;shiawaseda
+へいき;heiki
+せいぞう;seizou
+せいぞうする;seizousuru
+じっけん;jikken
+じっけんする;jikkensuru
+きんし;kinshi
+きんしする;kinshisuru
+もくてき;mokuteki
+がい;gai
+がいする;gaisuru
+こうけん;kouken
+こうけんする;koukensuru
+えらい;erai
+あさねぼう;asanebou
+あさねぼうする;asanebousuru
+めがさめる;megasameru
+おこす;okosu
+かぎる;kagiru
+にかぎって;nikagitte
+とまる;tomaru
+ドア;doa
+のせる;noseru
+しつれいだ;shitsureida
+おろす;orosu
+せかいてきだ;sekaitekida
+とどく;todoku
+へんだ;henda
+きがへんだ;kigahenda
+ぶり;buri
+あつさ;atsusa
+うごく;ugoku
+にっちゅう;nicchuu
+たいよう;taiyou
+ひかり;hikari
+とぼしい;toboshii
+てる;teru
+にっこう;nikkou
+にっこうよく;nikkouyoku
+しょうご;shougo
+よう;you
+ようがある;yougaaru
+ひとどおり;hitodoori
+まるで;marude
+きゅうか;kyuuka
+みなみ;minami
+ようい;youi
+よういする;youisuru
+ふるさと;furusato
+しま;shima
+とう;tou
+みなと;minato
+みなとまち;minatomachi
+あさい;asai
+およぎ;oyogi
+すいちゅう;suichuu
+ひっぱる;hipparu
+はな;hana
+しおからい;shiokarai
+おこる;okoru
+おおわらい;oowarai
+おおわらいする;oowaraisuru
+ゆめ;yume
+すなはま;sunahama
+すな;suna
+ほる;horu
+いし;ishi
+バレーボール;bareebooru
+かわらない;kawaranai
+ひがし;higashi
+もよう;moyou
+そらもよう;soramoyou
+あやしい;ayashii
+まっくろだ;makkuroda
+くも;kumo
+かみなり;kaminari
+おおつぶ;ootsubu
+かんし;kanshi
+かんしする;kanshisuru
+きがえる;kigaeru
+まとめる;matomeru
+らいう;raiu
+ふとい;futoi
+にげこむ;nigekomu
+かいがん;kaigan
+とおる;tooru
+とおりかかる;toorikakaru
+きけんだ;kikenda
+ますます;masumasu
+にし;nishi
+すこしずつ;sukoshizutsu
+はれあげる;hareageru
+すむ;sumu
+むしあつさ;mushiatsusa
+そうぞう;souzou
+そうぞうする;souzousuru
+てんこう;tenkou
+わすれものをする;wasuremonowosuru
+かばん;kaban
+もくひょう;mokuhyou
+とうぜんだ;touzenda
+うっかりする;ukkarisuru
+かねもち;kanemochi
+あきれる;akireru
+とにかく;tonikaku
+ごじぶん;gojibun
+じしん;jishin
+ことわざ;kotowaza
+よのなか;yononaka
+かじ;kaji
+おやじ;oyaji
+むしろ;mushiro
+どろぼう;dorobou
+じょうだん;joudan
+ともかく;tomokaku
+それはともかく;sorehatomokaku
+ぎじゅつ;gijutsu
+よこく;yokoku
+よこくする;yokokusuru
+よぼう;yobou
+よぼうする;yobousuru
+かんとうだいしんさい;kantoudaishinsai
+だいきぼだ;daikiboda
+さいがい;saigai
+たいけん;taiken
+たいけんする;taikensuru
+こわさ;kowasa
+ちんぼつ;chinbotsu
+ちんぼつする;chinbotsusuru
+ほろぶ;horobu
+テーマ;teema
+ベストセラー;besutoseraa
+ぽおらんどじん;poorandojin
+いよくてきだ;iyokutekida
+ゆれる;yureru
+ねまき;nemaki
+とびだす;tobidasu
+りょかん;ryokan
+あんぜんだ;anzenda
+ぐらぐらと;guragurato
+さすが;sasuga
+とっさに;tossani
+きんちょう;kinchou
+きんちょうする;kinchousuru
+ひなん;hinan
+ひなんする;hinansuru
+たちあがる;tachiagaru
+へいきだ;heikida
+だいじょうぶだ;daijoubuda
+くらい;kurai
+アパート;apaato
+たおれる;taoreru
+とうきょうじゅう;toukyoujuu
+ひ;hi
+たすかる;tasukaru
+そこ;soko
+はし;hashi
+さんみゃく;sanmyaku
+つらなる;tsuranaru
+かざん;kazan
+たえず;taezu
+けむり;kemuri
+げんいん;gen_in
+ふじさん;fujisan
+はこね;hakone
+おんせん;onsen
+うむ;umu
+うみだす;umidasu
+わけ;wake
+わけです;wakedesu
+あばれる;abareru
+くるう;kuruu
+あばれくるう;abarekuruu
+たほう;tahou
+おそれ;osore
+かんかく;kankaku
+あいじょう;aijou
+いだく;idaku
+しみじみと;shimijimito
+ゆめをみる;yumewomiru
+くろ;kuro
+なんかこく;nankakoku
+だいじしん;daijishin
+まどう;madou
+こわれる;kowareru
+たすけ;tasuke
+のむ;nomu
+まっくらだ;makkurada
+おく;oku
+わらいごえ;waraigoe
+さんぎょう;sangyou
+めざましい;mezamashii
+ほうめん;houmen
+ぼうえき;boueki
+ぼうえきかいしゃ;bouekikaisha
+あおき;aoki
+かわさき;kawasaki
+れっしゃ;ressha
+はやい;hayai
+ここち;kokochi
+のりごこちがいい;norigokochigaii
+のりごこちがわるい;norigokochigawarui
+ガラス;garasu
+とくべつ;tokubetsu
+しゃない;shanai
+にほんじゅう;nihonjuu
+かっき;kakki
+みちる;michiru
+しょうじきだ;shoujikida
+てっこうぎょう;tekkougyou
+ぞうせんぎょう;zousengyou
+せいさん;seisan
+せいさんする;seisansuru
+のびる;nobiru
+さん;san
+しげん;shigen
+せきゆ;sekiyu
+げんりょう;genryou
+ゆにゅう;yunyuu
+ゆにゅうする;yunyuusuru
+たよる;tayoru
+かこう;kakou
+かこうする;kakousuru
+ゆしゅつ;yushutsu
+ゆしゅつする;yushutsusuru
+れいがい;reigai
+ほら;hora
+けんせつ;kensetsu
+けんせつする;kensetsusuru
+けんせつちゅう;kensetsuchuu
+こうじょう;koujou
+ひろげる;hirogeru
+さっそく;sassoku
+だいこうじょう;daikoujou
+あんぜん;anzen
+せいけつ;seiketsu
+だいいちだ;daiichida
+このむ;konomu
+おくに;okuni
+きかいこうぎょう;kikaikougyou
+せんい;sen_i
+せんいこうぎょう;sen_ikougyou
+かがくこうぎょう;kagakukougyou
+すいじゅん;suijun
+りょう;ryou
+こうじょう;koujou
+こうじょうする;koujousuru
+こくえい;kokuei
+りえき;rieki
+そんみん;sonmin
+けんしんてきだ;kenshintekida
+ほね;hone
+ほねおる;honeoru
+ひょうばん;hyouban
+ひょうばんだ;hyoubanda
+もはん;mohan
+そんけい;sonkei
+そんけいする;sonkeisuru
+なかがよい;nakagayoi
+なかがわるい;nakagawarui
+かわ;kawa
+つる;tsuru
+らんぼうだ;ranbouda
+びんぼう;binbou
+びんぼうだ;binbouda
+しゃかいがく;shakaigaku
+とうほくだいがく;touhokudaigaku
+いがくぶ;igakubu
+ゆうじょう;yuujou
+まなぶ;manabu
+ちしき;chishiki
+まじめだ;majimeda
+しあわせ;shiawase
+しんけんだ;shinkenda
+ぎろん;giron
+ぎろんする;gironsuru
+げか;geka
+せんだい;sendai
+しゃかいか;shakaika
+じょうぶだ;joubuda
+ほえる;hoeru
+ほえっておく;hoetteoku
+けっかく;kekkaku
+びょうじょう;byoujou
+えいよう;eiyou
+えいようがある;eiyougaaru
+しょくもつ;shokumotsu
+じゅうぶんだ;juubunda
+せいよう;seiyou
+せいようする;seiyousuru
+しっそだ;shissoda
+かけい;kakei
+ふかのうだ;fukanouda
+つきあい;tsukiai
+びょういん;byouin
+にゅういん;nyuuin
+にゅういんする;nyuuinsuru
+もともと;motomoto
+げっきゅう;gekkyuu
+しゃかいほしょう;shakaihoshou
+ふじゅうぶんだ;fujuubunda
+ちょくせつだ;chokusetsuda
+だげき;dageki
+ちょきん;chokin
+ちょきんする;chokinsuru
+なめる;nameru
+ひよう;hiyou
+たいいん;taiin
+たいいんする;taiinsuru
+まかせる;makaseru
+のぞむ;nozomu
+へんじ;henji
+へんじする;henjisuru
+とどける;todokeru
+かんしゃ;kansha
+かんしゃする;kanshasuru
+おれい;orei
+おれいをいう;oreiwoiu
+さえ;sae
+すなおだ;sunaoda
+これこそ;korekoso
+きたない;kitanai
+そういうわけにはいかない;souiuwakenihaikanai
+ぼんやりと;bon_yarito
+おう;ou
+ひさしぶり;hisashiburi
+パートナー;paatonaa
+じっこう;jikkou
+じっこうする;jikkousuru
+ちかいうちに;chikaiuchini
+ゆいしょ;yuisho
+ゆいしょある;yuishoaru
+よやく;yoyaku
+よやくする;yoyakusuru
+おんなしゅじん;onnashujin
+おじぎ;ojigi
+おじぎする;ojigisuru
+もうける(1-dan);moukeru(1-dan)
+みょうごにち;myougonichi
+まことに;makotoni
+やけい;yakei
+テーブル;teeburu
+そつろん;sotsuron
+どだい;dodai
+さんこうしりょう;sankoushiryou
+ぺえじ;peeji
+みょうばん;myouban
+すべて;subete
+おしおきする;oshiokisuru
+おしおき;oshioki
+ゆるす;yurusu
+どうしよう;doushiyou
+なるほど;naruhodo
+てんいん;ten_in
+てんしゅ;tenshu
+てんちょう;tenchou
+かっこいい;kakkoii
+すてき;suteki
+だいじょうぶ;daijoubu
+ちくしょう;chikushou
+きさま;kisama
+おのれ;onore
+スケベ;sukebe
+ごちそうさまでした;gochisousamadeshita
+おじゃまします;ojamashimasu
+いらっしゃい;irasshai
+いらっしゃいませ;irasshaimase
+どうぞ、こちらへ;douzo_kochirahe
+どうぞおかけください;douzookakekudasai
+なんで;nande
+よく;yoku
+おきて;okite
+わかい;wakai
+おおかみ;ookami
+ずっと;zutto
+れい;rei
+かいとうようし;kaitouyoushi
+そうこう;soukou
+はしりがき;hashirigaki
+ざっそう;zassou
+そうしょ;sousho
+くさち;kusachi
+たすう;tasuu
+ためん;tamen
+おおすぎる;oosugiru
+たいし;taishi
+たいよう;taiyou
+ふとじ;futoji
+たいかく;taikaku
+ふうてい;fuutei
+からだつき;karadatsuki
+どだい;dodai
+たいふう;taifuu
+ちほう;chihou
+ちか;chika
+きじ;kiji
+ようすいち;yousuichi
+でんち;denchi
+ふるいけ;furuike
+ちしき;chishiki
+ちせい;chisei
+しりあい;shiriai
+ちくざい;chikuzai
+たけだ;takeda
+たけやぶ;takeyabu
+ちゃちゃ;chacha
+さか;saka
+ちゅうしょく;chuushoku
+ちゅうこうせい;chuukousei
+ひるま;hiruma
+せいちょう;seichou
+かいちょう;kaichou
+ながいき;nagaiki
+はくちょう;hakuchou
+やちょう;yachou
+とりい;torii
+ちょうしょく;choushoku
+あさひ;asahi
+ちょうてい;choutei
+つうこう;tsuukou
+つうきん;tsuukin
+おおどおり;oodoori
+してい;shitei
+でし;deshi
+きょうだい;kyoudai
+てんいん;ten_in
+よみせ;yomise
+たなだて;tanadate
+てんせん;tensen
+とくてん;tokuten
+じゅうてん;juuten
+でんきゅう;denkyuu
+でんりゅう;denryuu
+だいとう;daitou
+ぐんとう;guntou
+こがたな;kogatana
+とうみん;toumin
+とうき;touki
+ふゆしょうぐん;fuyushougun
+そうとう;soutou
+とうにん;tounin
+てあて;teate
+とうよう;touyou
+ちゅうとう;chuutou
+ひがしがわ;higashigawa
+かいとう;kaitou
+とうあん;touan
+くちごたえ;kuchigotae
+とうこつ;toukotsu
+きち;kichi
+きよ;kiyo
+よせなみ;yosenami
+たちよる;tachiyoru
+きそく;kisoku
+じょうぎ;jougi
+だいきぼ;daikibo
+ぎじゅつ;gijutsu
+ぎし;gishi
+えんぎ;engi
+しゅぎ;shugi
+ぎり;giri
+いぎ;igi
+ぎゃっこう;gyakkou
+ぎゃくせつ;gyakusetsu
+はんぎゃく;hangyaku
+えいきゅう;eikyuu
+くおん;kuon
+ひさしぶり;hisashiburi
+きゅうゆう;kyuuyuu
+きゅうは;kyuuha
+きゅうしき;kyuushiki
+きょじゅう;kyojuu
+じゅうきょ;juukyo
+いどころ;idokoro
+きょか;kyoka
+とっきょ;tokkyo
+てもと;temoto
+こっきょう;kokkyou
+けいだい;keidai
+きょうかいせん;kyoukaisen
+こうふん;koufun
+ふっこう;fukkou
+きょうみぶかい;kyoumibukai
+へいきん;heikin
+きんとう;kintou
+ふきんこう;fukinkou
+だんぼう;danbou
+だんりゅう;danryuu
+だんとう;dantou
+かちかん;kachikan
+ねびき;nebiki
+ちゅうさい;chuusai
+なこうど;nakoudo
+なかよく;nakayoku
+うちゅうせん;uchuusen
+ちゅうがえり;chuugaeri
+ちゅうのり;chuunori
+ちゅうじつ;chuujitsu
+ちゅうせい;chuusei
+ちゅうこく;chuukoku
+ちょしゃ;chosha
+ちょめい;chomei
+めいちょ;meicho
+かんちょう;kanchou
+ちょうれい;chourei
+かんきょうちょう;kankyouchou
+ちょうこう;choukou
+ぜんちょう;zenchou
+おくちょう;okuchou
+ちょうてん;chouten
+ちょうじょう;choujou
+ちょうだい;choudai
+ちょうりゅう;chouryuu
+しおみず;shiomizu
+しおどき;shiodoki
+ちんぎん;chingin
+うんちん;unchin
+やちん;yachin
+ずつう;zutsuu
+いたで;itade
+つうせつ;tsuusetsu
+はってん;hatten
+すいじょう;suijou
+まるおもり;maruomori
+ずいひつ;zuihitsu
+ずいこういん;zuikouin
+こつずい;kotsuzui
+のうずい;nouzui
+しんずい;shinzui
+すうじく;suujiku
+すうよう;suuyou
+ちゅうすう;chuusuu
+すうはい;suuhai
+すうこう;suukou
+すうけい;suukei
+すえおく;sueoku
+すえもの;suemono
+すえつけ;suetsuke
+すぎあや;sugiaya
+すぎがき;sugigaki
+すぎなみき;suginamiki
+うねだて;unedate
+にせ;nise
+うねおり;uneori
+あさせ;asase
+せと;seto
+せともの;setomono
+せつれつ;setsuretsu
+せっそく;sessoku
+せっとう;settou
+ひょうせつ;hyousetsu
+せっしゅ;sesshu
+せっしゅ;sesshu
+せっしょう;sesshou
+せっせい;sessei
+せんにん;sennin
+しゅせん;shusen
+すいせん;suisen
+さけ;sake
+みほん;mihon
+みほんいち;mihon_ichi
+てんじ;tenji
+てんじする;tenjisuru
+かいじょう;kaijou
+さいしん;saishin
+でんきこうぎょう;denkikougyou
+でんし;denshi
+でんしこうぎょう;denshikougyou
+せいひん;seihin
+かがくぎじゅつ;kagakugijutsu
+こうりゅう;kouryuu
+ふかまる;fukamaru
+ひとことでいえば;hitokotodeieba
+いとなむ;itonamu
+しょとく;shotoku
+こくみんしょとく;kokuminshotoku
+りんぎょう;ringyou
+ちくさんぎょう;chikusangyou
+すいさんぎょう;suisangyou
+だいじ;daiji
+こうぎょう;kougyou
+せいぞうぎょう;seizougyou
+けんせつぎょう;kensetsugyou
+うんゆ;un_yu
+つうしん;tsuushin
+うんゆつうしんぎょう;un_yutsuushingyou
+きんゆう;kin_yuu
+ほけん;hoken
+きんゆうほけんぎょう;kin_yuuhokengyou
+こうむ;koumu
+じゆうぎょう;jiyuugyou
+さあびすぎょう;saabisugyou
+ひじゅう;hijuu
+とうぶん;toubun
+よち;yochi
+のうさんぶつ;nousanbutsu
+いぞん;izon
+いぞんする;izonsuru
+けいこうぎょう;keikougyou
+じゅうかがくこうぎょう;juukagakukougyou
+じゅうしする;juushisuru
+にともなう;nitomonau
+ぶもん;bumon
+こよう;koyou
+せんぜん;senzen
+かくしん;kakushin
+ぎじゅつかくしん;gijutsukakushin
+せいみつだ;seimitsuda
+せいのう;seinou
+きょうか;kyouka
+きょうかする;kyoukasuru
+たんちょうだ;tanchouda
+にくたいてきだ;nikutaitekida
+じゅうろうどう;juuroudou
+つねに;tsuneni
+じゅくれん;jukuren
+じゅくれんする;jukurensuru
+のうりつ;nouritsu
+おもんじる;omonjiru
+ちゅうねん;chuunen
+くんれん;kunren
+くんれんする;kunrensuru
+せいふ;seifu
+けいえい;keiei
+けいえいする;keieisuru
+けいえいしゃ;keieisha
+ようきゅう;youkyuu
+ようきゅうする;youkyuusuru
+しつぎょう;shitsugyou
+しつぎょうする;shitsugyousuru
+ふきょう;fukyou
+しりょう;shiryou
+くせ;kuse
+むちゅうだ;muchuuda
+かぞえる;kazoeru
+めいわくだ;meiwakuda
+よう;you
+センチメンタルだ;senchimentaruda
+さわる;sawaru
+くちにあう;kuchiniau
+じゅんじょ;junjo
+ぎょうぎ;gyougi
+おと;oto
+おとをたてる;otowotateru
+とうなん;tounan
+じけん;jiken
+すじ;suji
+すいせん;suisen
+すいせんする;suisensuru
+いちりゅう;ichiryuu
+しゅうい;shuui
+せつび;setsubi
+サービス;saabisu
+このつぎ;konotsugi
+まんぞく;manzoku
+まんぞくする;manzokusuru
+うけつけ;uketsuke
+がいじん;gaijin
+くび;kubi
+かしげる;kashigeru
+じこく;jikoku
+みぶん;mibun
+あきらかだ;akirakada
+ほんにん;honnin
+しはい;shihai
+しはいする;shihaisuru
+しはいにん;shihainin
+きそく;kisoku
+おこる;okoru
+しんよう;shin_you
+しんようする;shin_yousuru
+にかかわる;nikakawaru
+まざまざと;mazamazato
+あせる;aseru
+ひきだし;hikidashi
+ようふくだんす;youfukudansu
+みあたる;miataru
+いんさつ;insatsu
+いんさつする;insatsusuru
+いんさつぶつ;insatsubutsu
+しなもの;shinamono
+さいわい;saiwai
+げんきん;genkin
+みにつける;minitsukeru
+さいなん;sainan
+まぬがれる;manugareru
+もうしわけない;moushiwakenai
+げんどう;gendou
+あやしい;ayashii
+みかける;mikakeru
+けいさつ;keisatsu
+フロント;furonto
+てはいする;tehaisuru
+ぬすむ;nusumu
+かち;kachi
+けいかん;keikan
+やってくる;yattekuru
+ひがい;higai
+じょうきょう;joukyou
+はんにん;hannin
+つかまえる;tsukamaeru
+はっけん;hakken
+はっけんする;hakkensuru
+よくあさ;yokuasa
+しんらい;shinrai
+しんらいする;shinraisuru
+きょうちょう;kyouchou
+きょうちょうする;kyouchousuru
+しょち;shochi
+しゃ;sha
+きんがく;kingaku
+せいきゅう;seikyuu
+せいきゅうする;seikyuusuru
+かくにん;kakunin
+かくにんする;kakuninsuru
+かんじょう;kanjou
+かんじょうする;kanjousuru
+さしひく;sashihiku
+さ;sa
+さがく;sagaku
+はらいもどす;haraimodosu
+さわぐ;sawagu
+あやまる;ayamaru
+せっかく;sekkaku
+ようやく;youyaku
+じこにあう;jikoniau
+ぶつかる;butsukaru
+はこぶ;hakobu
+はこびこむ;hakobikomu
+ぶつける;butsukeru
+みまう;mimau
+うつる;utsuru
+つい;tsui
+べッド;beddo
+ねかす;nekasu
+つうしんしゃ;tsuushinsha
+げんこう;genkou
+しきゅう;shikyuu
+そくたつ;sokutatsu
+こうくうびん;koukuubin
+めいれい;meirei
+めいれいする;meireisuru
+ほうしん;houshin
+まとまる;matomaru
+おもわす;omowasu
+ひにち;hinichi
+せわ;sewa
+せわする;sewasuru
+つきじ;tsukiji
+いちば;ichiba
+うおいちば;uoichiba
+そうちょう;souchou
+そうとう;soutou
+ふるえる;furueru
+しょうかい;shoukai
+しょうかいする;shoukaisuru
+いけだ;ikeda
+ちかづく;chikaduku
+いせい;isei
+いせいのいい;iseinoii
+かけごえ;kakegoe
+ライトバン;raitoban
+やかましい;yakamashii
+そうおん;souon
+まわり;mawari
+ばめん;bamen
+あっとうする;attousuru
+ぎょこう;gyokou
+りく;riku
+りくにあげる;rikuniageru
+たいりょう;tairyou
+おろしぎょうしゃ;oroshigyousha
+なま;nama
+しんせんだ;shinsenda
+あじ;aji
+しょうひん;shouhin
+しいれる;shiireru
+はかり;hakari
+めかた;mekata
+はかる;hakaru
+おおごえ;oogoe
+どなる;donaru
+おおぜい;oozei
+ふむ;fumu
+よこ;yoko
+インタビュー;intabyuu
+ちゅうおうせん;chuuousen
+こうえんじ;kouenji
+まがる;magaru
+おおどおり;oodoori
+まっすぐだ;massuguda
+かど;kado
+おれる;oreru
+うおまる;uomaru
+かんばん;kanban
+おじさん;ojisan
+ざしき;zashiki
+あがる;agaru
+さしみ;sashimi
+ほがらかだ;hogarakada
+ふうふ;fuufu
+うちとける;uchitokeru
+ゆずる;yuzuru
+しょうばい;shoubai
+くしん;kushin
+くしんする;kushinsuru
+くさる;kusaru
+いじょうだ;ijouda
+ぶっかだか;bukkadaka
+せつやく;setsuyaku
+せつやくする;setsuyakusuru
+みつもる;mitsumoru
+こめ;kome
+しょくりょう;shokuryou
+せいさんしゃ;seisansha
+りょうし;ryoushi
+さんち;sanchi
+ねだんをつける;nedanwotsukeru
+しょうひ;shouhi
+しょうひする;shouhisuru
+しょうひしゃ;shouhisha
+ばい;bai
+もうける;moukeru
+わずかだ;wazukada
+きびしい;kibishii
+ちゅうもんする;chuumonsuru
+ひとで;hitode
+たりる;tariru
+はいたつ;haitatsu
+はいたつする;haitatsusuru
+つぶれる;tsubureru
+ふあん;fuan
+ふあんだ;fuanda
+なかま;nakama
+いっか;ikka
+もうしこむ;moushikomu
+つうち;tsuuchi
+つうちする;tsuuchisuru
+ふさい;fusai
+ちゃん;chan
+こうふん;koufun
+こうふんする;koufunsuru
+きれ;kire
+くん;kun
+だまる;damaru
+えどじだい;edojidai
+ほうこく;houkoku
+ほうこくする;houkokusuru
+かべ;kabe
+なやむ;nayamu
+ゆるす;yurusu
+こうかい;koukai
+こうかいする;koukaisuru
+ゆうじん;yuujin
+げきれい;gekirei
+げきれいする;gekireisuru
+しどう;shidou
+しどうする;shidousuru
+こうふくだ;koufukuda
+けんい;ken_i
+はやし;hayashi
+やくば;yakuba
+てら;tera
+きろく;kiroku
+きろくする;kirokusuru
+じかに;jikani
+せっする;sessuru
+すすめる;susumeru
+ひょうじゅん;hyoujun
+ひょうじゅんご;hyoujungo
+ようじん;youjin
+ようじんする;youjinsuru
+ひょうめんてきだ;hyoumentekida
+さっする;sassuru
+こうさい;kousai
+こうさいする;kousaisuru
+ながのけん;naganoken
+むら;mura
+そんちょう;sonchou
+いらい;irai
+いらいする;iraisuru
+くばる;kubaru
+きをくばる;kiwokubaru
+きょり;kyori
+ほうげん;hougen
+あっさり;assari
+あいにく;ainiku
+るす;rusu
+さらいげつ;saraigetsu
+したく;shitaku
+したくする;shitakusuru
+いし;ishi
+しゅうしゅう;shuushuu
+しゅうしゅうする;shuushuusuru
+せいり;seiri
+せいりする;seirisuru
+しゅうちゅう;shuuchuu
+しゅうちゅうする;shuuchuusuru
+うえだ;ueda
+だいり;dairi
+あべ;abe
+ちゃんと;chanto
+おせじ;oseji
+とめる;tomeru
+じゅうしょく;juushoku
+ぎもん;gimon
+しじゅう;shijuu
+きげん;kigen
+きげんする;kigensuru
+のうか;nouka
+みこん;mikon
+じしゅてきだ;jishutekida
+だんたい;dantai
+まつり;matsuri
+しょうぼう;shoubou
+ようすい;yousui
+こうじ;kouji
+こうきょう;koukyou
+じぎょう;jigyou
+きょうどう;kyoudou
+そしき;soshiki
+そしきする;soshikisuru
+にんむ;ninmu
+だんじょ;danjo
+あい;ai
+ちかう;chikau
+しょうめい;shoumei
+しょうめいする;shoumeisuru
+しょうこ;shouko
+あきまつり;akimatsuri
+ほし;hoshi
+ほしぞら;hoshizora
+まぶしい;mabushii
+かがやく;kagayaku
+むし;mushi
+なく;naku
+あざやかだ;azayakada
+え;e
+じめん;jimen
+かげ;kage
+かんどう;kandou
+かんどうする;kandousuru
+おそう;osou
+しげき;shigeki
+しげきする;shigekisuru
+ごかい;gokai
+ごかいする;gokaisuru
+だいひょうだん;daihyoudan
+だんちょう;danchou
+にちじょう;nichijou
+ごうにいってはごうにしたがえ;gouniittehagounishitagae
+じょうようしゃ;jouyousha
+だんけつ;danketsu
+だんけつする;danketsusuru
+しんいち;shin_ichi
+ごぶさたする;gobusatasuru
+あいかわらず;aikawarazu
+ぐあい;guai
+ぐあいがわるい;guaigawarui
+い;i
+しんけい;shinkei
+しょうか;shouka
+しょうかする;shoukasuru
+きかん;kikan
+くれぐれも;kureguremo
+くれぐれもきをつける;kureguremokiwotsukeru
+そうごう;sougou
+そうごうする;sougousuru
+しんだん;shindan
+しんだんする;shindansuru
+たいかく;taikaku
+しんぞう;shinzou
+けつえき;ketsueki
+ふとる;futoru
+おそらく;osoraku
+さいしゅうてきだ;saishuutekida
+さて;sate
+けっさく;kessaku
+てあたり;teatari
+しだい;shidai
+てあたりしだい;teatarishidai
+てつや;tetsuya
+てつやする;tetsuyasuru
+ちから;chikara
+みにつく;minitsuku
+せんこう;senkou
+せんこうする;senkousuru
+いとこ;itoko
+ゲーテ;geete
+ちゅうりゅう;chuuryuu
+やしなう;yashinau
+きじゅん;kijun
+かだいだ;kadaida
+きそ;kiso
+しんじつ;shinjitsu
+かい;kai
+はがき;hagaki
+がくしゅう;gakushuu
+がくしゅうする;gakushuusuru
+つまる;tsumaru
+だす;dasu
+しまだ;shimada
+さいそく;saisoku
+さいそくする;saisokusuru
+スピード;supiido
+せいげん;seigen
+せいげんする;seigensuru
+いはん;ihan
+いはんする;ihansuru
+ばっきん;bakkin
+じまん;jiman
+じまんする;jimansuru
+かげん;kagen
+かげんする;kagensuru
+いいかげんにする;iikagennisuru
+しまつ;shimatsu
+しまつする;shimatsusuru
+おう;ou
+しまつにおえない;shimatsunioenai
+きつい;kitsui
+しきん;shikin
+さそう;sasou
+はりきる(5-dan);harikiru(5-dan)
+たいしょう;taishou
+よろしくつたえる(1-dan);yoroshikutsutaeru(1-dan)
+はるお;haruo
+たいようがぽかぽか(と)てる;taiyougapokapoka(to)teru
+けはい;kehai
+はだ;hada
+ほっとする;hottosuru
+つきひ;tsukihi
+ぐったり;guttari
+わた;wata
+さらさら;sarasara
+ぶるぶるふるえる;buruburufurueru
+むかう;mukau
+けろりとなおる;keroritonaoru
+さむがり;samugari
+のびのび(と)くらす;nobinobi(to)kurasu
+きんきょう(M);kinkyou(M)
+きぶんがさっぱりする;kibungasapparisuru
+ちる;chiru
+しゃっきり(と)する;shakkiri(to)suru
+はくし;hakushi
+いらいらする;irairasuru
+あと;ato
+やまなか;yamanaka
+くふう;kufuu
+くふうする;kufuusuru
+ゆういぎだ;yuuigida
+かさなる;kasanaru
+ふらふら(と);furafura(to)
+めまい;memai
+めまいがする;memaigasuru
+かんり;kanri
+かんりする;kanrisuru
+きそくてきだ;kisokutekida
+きく;kiku
+たいそう;taisou
+ひごろ(M);higoro(M)
+なまける(1-dan);namakeru(1-dan)
+せい;sei
+いき;iki
+きれる(1-dan);kireru(1-dan)
+いきがきれる;ikigakireru
+ハーハー(と);haahaa(to)
+こきゅう;kokyuu
+こきゅうする;kokyuusuru
+りくじょうきょうぎ;rikujoukyougi
+きょうぎ;kyougi
+せんしゅ;senshu
+たけし;takeshi
+クラブ;kurabu
+いいん;iin
+じなん;jinan
+みつお;mitsuo
+ちょうじょ;choujo
+れいこ;reiko
+おうえん;ouen
+おうえんする;ouensuru
+ゲーム;geemu
+ほねやすめ;honeyasume
+しあい;shiai
+ぐるりと;gururito
+まわす;mawasu
+たかこ;takako
+チーム;chiimu
+くむ;kumu
+まける;makeru
+かつ;katsu
+ケーキ;keeki
+きゃあきゃあ(と);kyaakyaa(to)
+はしゃぐ;hashagu
+どっと;dotto
+まあまあ;maamaa
+せんしゅけん;senshuken
+たいかい;taikai
+せんしゅけんたいかい;senshukentaikai
+けっしょう;kesshou
+じゅん;jun
+せん;sen
+しょうぶ;shoubu
+しょうぶする;shoubusuru
+にこにこ;nikoniko
+にこにこする;nikonikosuru
+のぞく;nozoku
+なあ;naa
+かってだ;katteda
+くじ;kuji
+ひく;hiku
+くじをひく;kujiwohiku
+おろおろ(と);orooro(to)
+おろおろ(と)する;orooro(to)suru
+こうぎ;kougi
+こうぎする;kougisuru
+オリンピック;orinpikku
+しゅつじょう;shutsujou
+しゅつじょうする;shutsujousuru
+きょうそう;kyousou
+さっぱり;sappari
+はめ;hame
+おちいる(5-dan);ochiiru(5-dan)
+はめにおちいる;hameniochiiru
+どっしり;dosshiri
+どうり(M);douri(M)
+がやがや;gayagaya
+けっきょく(M);kekkyoku(M)
+けいひん;keihin
+けいひんがつく;keihingatsuku
+どうてん;douten
+えんちょう;enchou
+えんちょうする;enchousuru
+ひきわける;hikiwakeru
+ひきわけ;hikiwake
+ぷんぷん;punpun
+ずるい;zurui
+くう;kuu
+くってかかる;kuttekakaru
+そうべつかい;soubetsukai
+じょうきゅう;joukyuu
+はずむ;hazumu
+はなしがはずむ;hanashigahazumu
+ふける(1-dan);fukeru(1-dan)
+てをかす;tewokasu
+ちかごろ(M);chikagoro(M)
+けんとう;kentou
+けんとうする;kentousuru
+べん;ben
+わかれ;wakare
+わかれをおしむ;wakarewooshimu
+せんげつ;sengetsu
+すえ;sue
+のうぎょうせいさんきょうどうくみあい;nougyouseisankyoudoukumiai
+のうはんき;nouhanki
+おす;osu
+おしかける(1-dan);oshikakeru(1-dan)
+きほん;kihon
+こうえん;kouen
+こうえんする;kouensuru
+そう;sou
+しゅうぎょう;shuugyou
+しゅうぎょうする;shuugyousuru
+わずか;wazuka
+とどまる;todomaru
+げきげんする;gekigensuru
+そうねん;sounen
+ちたい;chitai
+しんしゅつ;shinshutsu
+きぎょう;kigyou
+だいきぎょう;daikigyou
+さぎょう;sagyou
+のうさぎょう;nousagyou
+かたにかかる;katanikakaru
+まめ;mame
+こくもつ;kokumotsu
+じきゅう;jikyuu
+じきゅうする;jikyuusuru
+こくない;kokunai
+じゅよう;juyou
+うわまわる;uwamawaru
+あまる;amaru
+だいず;daizu
+けつぼう;ketsubou
+けつぼうする;ketsubousuru
+まかなう;makanau
+じょうたい;joutai
+しょくりょう;shokuryou
+きょうきゅう;kyoukyuu
+きょうきゅうする;kyoukyuusuru
+ふくろ;fukuro
+いぶくろ;ibukuro
+あずける;azukeru
+こうど;koudo
+せいちょう;seichou
+せいちょうする;seichousuru
+トラクター;torakutaa
+はいっている;haitteiru
+しゅうやく;shuuyaku
+しゅうやくする;shuuyakusuru
+か;ka
+こうにゅう;kounyuu
+こうにゅうする;kounyuusuru
+きかん;kikan
+うったえる(1-dan);uttaeru(1-dan)
+こうしょう;koushou
+しゅうり;shuuri
+しゅうりする;shuurisuru
+ぶひん;buhin
+とりかえる(1-dan);torikaeru(1-dan)
+たいしゅう;taishuu
+せいじてきだ;seijitekida
+いしき;ishiki
+いんしょうをうける;inshouwoukeru
+こうがい;kougai
+きょうつうする;kyoutsuusuru
+じゅうだいだ;juudaida
+ます;masu
+ひりょう;hiryou
+かがくひりょう;kagakuhiryou
+かいはつ;kaihatsu
+かいはつする;kaihatsusuru
+のうやく;nouyaku
+もちいる(1-dan);mochiiru(1-dan)
+ちゅうどく;chuudoku
+ちゅうどくする;chuudokusuru
+しぼう;shibou
+しぼうする;shibousuru
+はっせい;hassei
+はっせいする;hasseisuru
+ぎせい;gisei
+いっぽうてきだ;ippoutekida
+かたよる;katayoru
+かたよった;katayotta
+ほご;hogo
+ほごする;hogosuru
+せいさく;seisaku
+あんてい;antei
+あんていする;anteisuru
+さんぶつ;sanbutsu
+かかく;kakaku
+かくりつ;kakuritsu
+かくりつする;kakuritsusuru
+おかわりありませんか;okawariarimasenka
+かけがえのない;kakegaenonai
+こじんきょうじゅ;kojinkyouju
+どうきゅう;doukyuu
+たより;tayori
+とも(Suffix);tomo(Suffix)
+はなす;hanasu
+みっせつだ;missetsuda
+しゅし;shushi
+はんきょう;hankyou
+たにざきじゅんいちろう;tanizakijun_ichirou
+かわばたやすなり;kawabatayasunari
+び;bi
+エキゾチシズム;ekizochishizumu
+コピー;kopii
+たずさわる;tazusawaru
+すうじ;suuji
+ことずける(1-dan);kotozukeru(1-dan)
+まえもって;maemotte
+ざんしょ;zansho
+いのる;inoru
+やまもと;yamamoto
+ふみこ;fumiko
+ただいま;tadaima
+ませ;mase
+つかまる;tsukamaru
+ごめんなさい;gomennasai
+ゼミ;zemi
+れんちゅう;renchuu
+かくめい;kakumei
+てんらんかい;tenrankai
+じゃ;ja
+いってたろう;ittetarou
+なにしろ;nanishiro
+せんむ;senmu
+えんかい;enkai
+おうせつま;ousetsuma
+わざわざ;wazawaza
+おこしになる;okoshininaru
+きょうしゅくだ;kyoushukuda
+ぎょうむ;gyoumu
+じゅんちょうだ;junchouda
+らいねんど;rainendo
+ゆうし;yuushi
+ゆうしする;yuushisuru
+たちいる(1-dan);tachiiru(1-dan)
+ほんじつ;honjitsu
+ようけん;youken
+せき;seki
+ぼうし;boushi
+たとえば;tatoeba
+しけん;shiken
+おとめ;otome
+めいれい;meirei
+おい;oi
+おいて;oite
+しんか;shinka
+しんうん;shin_un
+すすむ;susumu
+つい;tsui
+そそぐ;sosogu
+いっかげつ;ikkagetsu
+さゆう;sayuu
+みぎて;migite
+あまぐも;amagumo
+はるさめ;harusame
+ごひゃくえん;gohyakuen
+まるい;marui
+おうじ;ouji
+おうじょ;oujo
+おとをだす;otowodasu
+ほんね;honne
+したごころ;shitagokoro
+げひんな;gehinna
+したごころ;shitagokoro
+ください;kudasai
+へたな;hetana
+かざん;kazan
+かようび;kayoubi
+ひばな;hibana
+はなび;hanabi
+こっか;kokka
+はなみ;hanami
+かいぼたん;kaibotan
+がくせい;gakusei
+がっこう;gakkou
+まなぶ;manabu
+きたい;kitai
+きゅうじつ;kyuujitsu
+ひるやすみ;hiruyasumi
+たまご;tamago
+きんいろ;kin_iro
+おかね;okane
+きゅうかい;kyuukai
+くうしゃ;kuusha
+からて;karate
+おおぞら;oozora
+あける;akeru
+しがつ;shigatsu
+まいつき;maitsuki
+つきろけっと;tsukiroketto
+げつようび;getsuyoubi
+ばんけん;banken
+こいぬ;koinu
+いぬごや;inugoya
+いっけん;ikken
+せんけん;senken
+みほん;mihon
+みる;miru
+みせる;miseru
+ごにん;gonin
+いつか;itsuka
+くちだし;kuchidashi
+ちゅうがっこう;chuugakkou
+ぼこう;bokou
+こうちょう;kouchou
+さほう;sahou
+ひだりあし;hidariashi
+さんにん;sannin
+みっか;mikka
+さんすい;sansui
+かざん;kazan
+こやま;koyama
+しがつ;shigatsu
+よっか;yokka
+だんし;danshi
+じょし;joshi
+おんなのこ;onnanoko
+いっしまとわね;isshimatowane
+いとぐるま;itoguruma
+きいと;kiito
+こくじ;kokuji
+ろおまじ;roomaji
+じもく;jimoku
+みみたぶ;mimitabu
+しちにん;shichinin
+なのか;nanoka
+すいしゃ;suisha
+じょうず;jouzu
+てほん;tehon
+じゅうにん;juunin
+とおか;tooka
+しゅっか;shukka
+ひとで;hitode
+だす;dasu
+でる;deru
+じょちゅう;jochuu
+おんなのひと;onnanohito
+こびと;kobito
+こがね;kogane
+じょうげ;jouge
+しんりん;shinrin
+あおもり;aomori
+どいつじん;doitsujin
+ひゃくにん;hyakunin
+ひとびと;hitobito
+すいようび;suiyoubi
+みずがめ;mizugame
+ただしい;tadashii
+いけばな;ikebana
+うまれる;umareru
+せいねん;seinen
+あおぞら;aozora
+あおもの;aomono
+ぼくせき;bokuseki
+こいし;koishi
+いしきり;ishikiri
+せきどう;sekidou
+あからめる;akarameru
+せんじつ;senjitsu
+せんせんげつ;sensengetsu
+かんてん;kanten
+ひぼしの;hiboshino
+ほしくさ;hoshikusa
+おがわ;ogawa
+かわかみ;kawakami
+そうそう;sousou
+はやみみ;hayamimi
+てばやい;tebayai
+そうげん;sougen
+くさき;kusaki
+そうほん;souhon
+いっそく;issoku
+てあし;teashi
+たりる;tariru
+たす;tasu
+そんかい;sonkai
+そんちょう;sonchou
+むらびと;murabito
+たいきん;taikin
+おおきさ;ookisa
+だんせい;dansei
+ちょうなん;chounan
+おとこのひと;otokonohito
+おおおとこ;oootoko
+ちくりん;chikurin
+しない;shinai
+たけのつえ;takenotsue
+にちゅう;nichuu
+いちにちじゅう;ichinichijuu
+がいちゅう;gaichuu
+むしば;mushiba
+ちょうない;chounai
+したまち;shitamachi
+てんもんがく;tenmongaku
+あまのがわ;amanogawa
+すいでん;suiden
+ほんだ;honda
+どぼく;doboku
+どじん;dojin
+ふたり;futari
+ふつか;futsuka
+いちじつ;ichijitsu
+ついたち;tsuitachi
+みっか;mikka
+にゅうこく;nyuukoku
+はいる;hairu
+いれる;ireru
+ねんきん;nenkin
+はくし;hakushi
+しろい;shiroi
+はちにん;hachinin
+ようか;youka
+やっつ;yattsu
+ひゃくにん;hyakunin
+ぶんがく;bungaku
+ふみ;fumi
+ほんじつ;honjitsu
+もと;moto
+めいが;meiga
+だいみょう;daimyou
+もくようび;mokuyoubi
+きぎ;kigi
+いちもく;ichimoku
+めうえ;meue
+めした;meshita
+いっせき;isseki
+ゆうひ;yuuhi
+たなばた;tanabata
+じりつ;jiritsu
+たてる;tateru
+たいりょく;tairyoku
+むりょく;muryoku
+りんがく;ringaku
+こばやし;kobayashi
+ろくにん;rokunin
+むいか;muika
+いんりょく;inryoku
+ひきだし;hikidashi
+うもう;umou
+しらは;shiraha
+はねだ;haneda
+ふううん;fuuun
+あんうん;an_un
+あまぐも;amagumo
+らくえん;rakuen
+はなぞの;hanazono
+そくたつ;sokutatsu
+そくど;sokudo
+はやめる;hayameru
+すみやか;sumiyaka
+こうよう;kouyou
+おうごん;ougon
+きいろ;kiiro
+なにごと;nanigoto
+なんにち;nannichi
+りっか;rikka
+なつもの;natsumono
+かじ;kaji
+けらい;kerai
+やぬし;yanushi
+しりょう;shiryou
+りょうきん;ryoukin
+かしゅ;kashu
+たんか;tanka
+うたう;utau
+がか;gaka
+あう;au
+かいぎ;kaigi
+こんかい;konkai
+ぜんかい;zenkai
+いいまわし;iimawashi
+まわす;mawasu
+まわる;mawaru
+たいかい;taikai
+うちうみ;uchiumi
+かいが;kaiga
+えはがき;ehagaki
+くちえ;kuchie
+がいらいご;gairaigo
+ほかに;hokani
+はずす;hazusu
+さんかく;sankaku
+まちかど;machikado
+たのしい;tanoshii
+ぶんらく;bunraku
+かつどう;katsudou
+ちゅうかん;chuukan
+にんげん;ningen
+まもなく;mamonaku
+がんやく;gan_yaku
+まるい;marui
+こばやしまる;kobayashimaru
+がんせき;ganseki
+いわや;iwaya
+がんめん;ganmen
+かおいろ;kaoiro
+しらんかお;shirankao
+きこく;kikoku
+きせん;kisen
+きゅうどう;kyuudou
+ゆみや;yumiya
+ぎゅうにく;gyuuniku
+うしごや;ushigoya
+きんぎょ;kingyo
+うおいちば;uoichiba
+さかなや;sakanaya
+とうきょう;toukyou
+ぺきん;pekin
+つよい;tsuyoi
+きょうかい;kyoukai
+おしえかた;oshiekata
+おそわる;osowaru
+きんじょ;kinjo
+ちかみち;chikamichi
+きょうだい;kyoudai
+ふけい;fukei
+ずけい;zukei
+がんじつ;ganjitsu
+げんき;genki
+もともと;motomoto
+そうげん;sougen
+げんりょう;genryou
+うなばら;unabara
+いう;iu
+げんご;gengo
+こご;kogo
+ふるい;furui
+とだな;todana
+こがいで;kogaide
+ごぜん;gozen
+しょうご;shougo
+あとで;atode
+いご;igo
+がいこくご;gaikokugo
+ものがたり;monogatari
+がいこう;gaikou
+まぜる;mazeru
+まじわる;majiwaru
+にっこう;nikkou
+ひかる;hikaru
+こうりつ;kouritsu
+こういん;kouin
+だいく;daiku
+こうがく;kougaku
+ひろい;hiroi
+こうだい;koudai
+かんがえる;kangaeru
+かんがえかた;kangaekata
+こうあん;kouan
+いく;iku
+いっこう;ikkou
+ぎょうかん;gyoukan
+がっしょう;gasshou
+あいきどう;aikidou
+ぜんこく;zenkoku
+くにぐに;kuniguni
+こくじん;kokujin
+くろい;kuroi
+こんにち;konnichi
+ただいま;tadaima
+さいき;saiki
+なんさい;nansai
+さっか;sakka
+つくる;tsukuru
+さんしゅつする;sanshutsusuru
+こうさん;kousan
+ねえさん;neesan
+しない;shinai
+しがい;shigai
+おもいだす;omoidasu
+おもいあがった;omoiagatta
+とめる;tomeru
+きゅうし;kyuushi
+しつもんようし;shitsumon_youshi
+てがみ;tegami
+しゃじ;shaji
+おてら;otera
+いちじ;ichiji
+ときどき;tokidoki
+じぶん;jibun
+みずからのてで;mizukaranotede
+ほんや;hon_ya
+おくじょう;okujou
+しゃいん;shain
+しゃかい;shakai
+よわい;yowai
+きょうじゃく;kyoujaku
+よわる;yowaru
+しゅちょう;shuchou
+しゅしょう;shushou
+てくび;tekubi
+しゅうき;shuuki
+あきかぜ;akikaze
+こんしゅう;konshuu
+にしゅうかん;nishuukan
+しゅんぶん;shunbun
+はるさめ;harusame
+しょどう;shodou
+しょうじょ;shoujo
+すこし;sukoshi
+しじょう;shijou
+たちば;tachiba
+とくしょく;tokushoku
+きいろ;kiiro
+しょくじ;shokuji
+たべもの;tabemono
+しんぱい;shinpai
+こころもち;kokoromochi
+しんせつ;shinsetsu
+おやがいしゃ;oyagaisha
+ちず;chizu
+としょかん;toshokan
+はかる;hakaru
+かいすう;kaisuu
+かずかずの;kazukazuno
+かせい;kasei
+ほしうらない;hoshiuranai
+せいてん;seiten
+はれのひ;harenohi
+めいせい;meisei
+おおごえ;oogoe
+とうざい;touzai
+にしよおろっぱ;nishiyooroppa
+たいせつな;taisetsuna
+きって;kitte
+しんせつ;shinsetsu
+ゆきまつり;yukimatsuri
+かせん;kasen
+こうせん;kousen
+ないせん;naisen
+せんちょう;senchou
+ふなたび;funatabi
+ごぜん;gozen
+ばんぐみ;bangumi
+くむ;kumu
+そせい;sosei
+はしる;hashiru
+そうこうじかん;soukoujikan
+くちばしる;kuchibashiru
+おおい;ooi
+ふとい;futoi
+こうたいし;koutaishi
+たいへいよう;taiheiyou
+じんたい;jintai
+ごたい;gotai
+たかだい;takadai
+たにま;tanima
+たにがわ;tanigawa
+ちじん;chijin
+しる;shiru
+ちか;chika
+きじ;kiji
+でんち;denchi
+ちゃいろ;chairo
+ちゃのま;chanoma
+ちゅうしょく;chuushoku
+ひるやすみ;hiruyasumi
+ちょうしょく;choushoku
+あさひ;asahi
+けさ;kesa
+ぶちょう;buchou
+ながねん;naganen
+はくちょう;hakuchou
+いっせきにちょう;issekinichou
+ちょくぜん;chokuzen
+ちょくご;chokugo
+つやく;tsuyaku
+かよう;kayou
+でし;deshi
+しょてん;shoten
+でみせ;demise
+てんがよい;tengayoi
+がてん;gaten
+でんりょく;denryoku
+とうき;touki
+ふゆもの;fuyumono
+めいとう;meitou
+こがたな;kogatana
+しない;shinai
+ちゅうとう;chuutou
+ひがしあじあ;higashiajia
+ほんとう;hontou
+とうじ;touji
+ひとりあたり;hitoriatari
+あたる;ataru
+こうとう;koutou
+めいとう;meitou
+こたえる;kotaeru
+しゅっとう;shuttou
+おなじ;onaji
+どうこく;doukoku
+どうじょう;doujou
+かえりみちで;kaerimichide
+どくしゃ;dokusha
+よみかた;yomikata
+たいない;tainai
+なんせい;nansei
+みなみかぜ;minamikaze
+ぎゅうにく;gyuuniku
+にくしん;nikushin
+ばりき;bariki
+うまごや;umagoya
+ばいばい;baibai
+かいもの;kaimono
+ばいてん;baiten
+とくばい;tokubai
+うりきれる;urikireru
+うりば;uriba
+ばくしゅびいる;bakushubiiru
+こむぎ;komugi
+おおむぎ;oomugi
+らいむぎ;raimugi
+つきなかばに;tsukinakabani
+ばんち;banchi
+ばんにん;bannin
+ふぼ;fubo
+ふうりょく;fuuryoku
+にほんふう;nihonfuu
+ふろば;furoba
+きたかぜ;kitakaze
+ぶんけ;bunke
+まいふん;maifun
+ものわかりのよい;monowakarinoyoi
+ふうぶん;fuubun
+みちをきく;michiwokiku
+べいこく;beikoku
+こめや;komeya
+ほこうしゃ;hokousha
+あるく;aruku
+ぼいん;boin
+ぼこくご;bokokugo
+ちほう;chihou
+かんがえかた;kangaekata
+ほっぽう;hoppou
+きたぐち;kitaguchi
+ていまい;teimai
+まいかい;maikai
+ふつかめごとに;futsukamegotoni
+まんねん;mannen
+ばんにん;bannin
+めいげつ;meigetsu
+みょうにち;myounichi
+あかるい;akarui
+なく;naku
+うもう;umou
+けいと;keito
+あかげ;akage
+せいもん;seimon
+にゅうもん;nyuumon
+かどぐち;kadoguchi
+やはん;yahan
+よあけ;yoake
+よぞら;yozora
+よるひる;yoruhiru
+やがい;yagai
+ののはな;nonohana
+ゆみや;yumiya
+やさき;yasaki
+ゆうこう;yuukou
+ともだち;tomodachi
+しちよう;shichiyou
+ようび;youbi
+ようにん;younin
+ようがある;yougaaru
+ひろくもちいる;hirokumochiiru
+らいしゅう;raishuu
+かえってくる;kaettekuru
+ぎりしゃごからきたことば;girishagokarakitakotoba
+りか;rika
+しんりがく;shinrigaku
+むり;muri
+りじん;rijin
+やまざと;yamazato
+かいり;kairi
+わしゃ;washa
+かいわ;kaiwa
+はなしごえ;hanashigoe
+いちがつ;ichigatsu
+きんいつ;kin_itsu
+うは;uha
+うがん;ugan
+みぎて;migite
+うき;uki
+おおあめ;ooame
+あまぐも;amagumo
+えんけい;enkei
+えんだか;endaka
+ひゃくえん;hyakuen
+おうじ;ouji
+じょおう;joou
+おうさま;ousama
+しいん;shiin
+ていか;teika
+げしゃ;gesha
+かわしも;kawashimo
+かようび;kayoubi
+かざん;kazan
+ひばな;hibana
+かべん;kaben
+はなび;hanabi
+はなみ;hanami
+がっこう;gakkou
+がくしゃ;gakusha
+でんき;denki
+じゅうきゅう;juukyuu
+くがつ;kugatsu
+きゅうじつ;kyuujitsu
+きゅうせん;kyuusen
+なつやすみ;natsuyasumi
+きんようび;kin_youbi
+こんじき;konjiki
+かねもち;kanemochi
+そらいろ;sorairo
+からばこ;karabako
+こんげつ;kongetsu
+げつようび;getsuyoubi
+つきみ;tsukimi
+りょうけん;ryouken
+いぬごや;inugoya
+こいぬ;koinu
+はっけん;hakken
+けんぶつ;kenbutsu
+みもの;mimono
+ごがつ;gogatsu
+ごにん;gonin
+いつか;itsuka
+こうじつ;koujitsu
+でぐち;deguchi
+こうせい;kousei
+こうちょう;kouchou
+さは;saha
+ひだりがわ;hidarigawa
+ひだりて;hidarite
+さんがつ;sangatsu
+みっか;mikka
+さんかく;sankaku
+ひょうざん;hyouzan
+やまば;yamaba
+でんし;denshi
+こども;kodomo
+ようす;yousu
+しがつ;shigatsu
+よっか;yokka
+よんかい;yonkai
+せいし;seishi
+けいと;keito
+いとまき;itomaki
+じびき;jibiki
+あかじ;akaji
+すうじ;suuji
+じか;jika
+みみなり;miminari
+みみかざり;mimikazari
+しちがつ;shichigatsu
+なのか;nanoka
+ななばん;nanaban
+はっしゃ;hassha
+くちぐるま;kuchiguruma
+しゅだん;shudan
+てほん;tehon
+じょうず;jouzu
+じゅうがつ;juugatsu
+とおか;tooka
+じゅうじ;juuji
+しゅっぱつ;shuppatsu
+おもいで;omoide
+ひきだし;hikidashi
+じょせい;josei
+にょうぼう;nyoubou
+おんなのこ;onnanoko
+しょうじん;shoujin
+こうし;koushi
+おがわ;ogawa
+いじょう;ijou
+かわかみ;kawakami
+ねあげ;neage
+しんりん;shinrin
+しんげん;shingen
+しんかん;shinkan
+にほんじん;nihonjin
+にんげん;ningen
+ひとで;hitode
+すいようび;suiyoubi
+すいそ;suiso
+おおみず;oomizu
+せいかい;seikai
+しょうがつ;shougatsu
+しょうじき;shoujiki
+がくせい;gakusei
+いっしょう;isshou
+いきもの;ikimono
+せいねん;seinen
+あおぞら;aozora
+あおもの;aomono
+こんせき;konseki
+ゆうしょく;yuushoku
+ゆうひ;yuuhi
+かせき;kaseki
+こいし;koishi
+せきゆ;sekiyu
+せきどう;sekidou
+せきめん;sekimen
+あかんぼう;akanbou
+せんえん;sen_en
+ごせん;gosen
+ちどり;chidori
+かわぐち;kawaguchi
+かわばた;kawabata
+えどがわ;edogawa
+せんげつ;sengetsu
+ゆびさき;yubisaki
+そうきゅう;soukyuu
+はやくち;hayakuchi
+はやじに;hayajini
+ふそく;fusoku
+あしくび;ashikubi
+あしおと;ashioto
+そんちょう;sonchou
+のうそん;nouson
+むらびと;murabito
+たいかい;taikai
+だいがく;daigaku
+おおごえ;oogoe
+だんし;danshi
+ちょうなん;chounan
+おとこぎ;otokogi
+ちゅうりつ;chuuritsu
+ちゅうごく;chuugoku
+まんなか;mannaka
+きせいちゅう;kiseichuu
+がいちゅう;gaichuu
+むしば;mushiba
+ちょうみん;choumin
+ちょうちょう;chouchou
+したまち;shitamachi
+てんし;tenshi
+てんのう;tennou
+あまくだり;amakudari
+でんえん;den_en
+たうえ;taue
+いなか;inaka
+どようび;doyoubi
+とち;tochi
+つちくさい;tsuchikusai
+にがつ;nigatsu
+にじゅう;nijuu
+ふたり;futari
+にちようび;nichiyoubi
+ほんじつ;honjitsu
+ふつか;futsuka
+ゆにゅう;yunyuu
+いりぐち;iriguchi
+いれもの;iremono
+らいねん;rainen
+ごねんせい;gonensei
+としより;toshiyori
+はくしょ;hakusho
+はくじん;hakujin
+はちがつ;hachigatsu
+やおや;yaoya
+やつあたり;yatsuatari
+ひゃくばい;hyakubai
+ひゃくしょう;hyakushou
+ひゃっかてん;hyakkaten
+ぶんがく;bungaku
+もんじ;monji
+もんぶしょう;monbushou
+もくようび;mokuyoubi
+きめ;kime
+こだち;kodachi
+にほん;nihon
+ほんや;hon_ya
+ほんてん;honten
+ゆうめい;yuumei
+めいじん;meijin
+ひとつめ;hitotsume
+ちゅうもく;chuumoku
+ひとめ;hitome
+じりつ;jiritsu
+たちば;tachiba
+めだつ;medatsu
+のうりょく;nouryoku
+じんりきしゃ;jinrikisha
+ちからだめし;chikaradameshi
+りんがく;ringaku
+こばやし;kobayashi
+みつりん;mitsurin
+ろくがつ;rokugatsu
+むいか;muika
+ろっかく;rokkaku
+いんりょく;inryoku
+じびき;jibiki
+とりひき;torihiki
+うんも;unmo
+せいうん;seiun
+うきぐも;ukigumo
+えんそく;ensoku
+とおまわり;toomawari
+えんし;enshi
+なんかい;nankai
+なにもの;nanimono
+なんにん;nannin
+がっか;gakka
+けんきゅうか;kenkyuuka
+しょか;shoka
+まなつ;manatsu
+なつまつり;natsumatsuri
+のうか;nouka
+ぶけ;buke
+さっか;sakka
+かしゅ;kashu
+たんか;tanka
+かぞえうた;kazoeuta
+えいが;eiga
+がめん;gamen
+かいてん;kaiten
+かいすう;kaisuu
+いいまわし;iimawashi
+かいしゃ;kaisha
+えしゃく;eshaku
+こっかい;kokkai
+かいぐん;kaigun
+にほんかい;nihonkai
+うみべ;umibe
+かいが;kaiga
+くちえ;kuchie
+えほん;ehon
+ほたてがい;hotategai
+かいがら;kaigara
+かいるい;kairui
+がいじん;gaijin
+げか;geka
+そとがわ;sotogawa
+にんげん;ningen
+まちがい;machigai
+がんめん;ganmen
+かおいろ;kaoiro
+かおつき;kaotsuki
+きせん;kisen
+きあつ;kiatsu
+きしゃ;kisha
+きじ;kiji
+にっき;nikki
+きか;kika
+きせい;kisei
+かえりみち;kaerimichi
+ぎゅうにく;gyuuniku
+ぎゅうにゅう;gyuunyuu
+うしかい;ushikai
+きんぎょ;kingyo
+うおつり;uotsuri
+さかなや;sakanaya
+とうきょう;toukyou
+じょうきょう;joukyou
+けいひん;keihin
+きょうか;kyouka
+つよみ;tsuyomi
+きょうかい;kyoukai
+きょうしつ;kyoushitsu
+おしえご;oshiego
+ぎょくはい;gyokuhai
+たまつき;tamatsuki
+めだま;medama
+きんじょ;kinjo
+さいきん;saikin
+ちかみち;chikamichi
+けいしき;keishiki
+かたちづくる;katachidukuru
+ごうけい;goukei
+けいさん;keisan
+かんだんけい;kandankei
+げんき;genki
+がんらい;ganrai
+もとどおり;motodoori
+げんし;genshi
+げんぶん;genbun
+くさはら;kusahara
+こがい;kogai
+こしゅ;koshu
+とぐち;toguchi
+ふっこ;fukko
+こうこがく;koukogaku
+ふるほん;furuhon
+ごぜん;gozen
+しょうご;shougo
+いご;igo
+こうはん;kouhan
+あとあじ;atoaji
+ごちょう;gochou
+ものがたり;monogatari
+にほんご;nihongo
+こうじょう;koujou
+じんこう;jinkou
+だいく;daiku
+こうだい;koudai
+ひろしま;hiroshima
+こうこく;koukoku
+がいこう;gaikou
+こうかん;koukan
+にっこう;nikkou
+こうねん;kounen
+こうがく;kougaku
+こうあん;kouan
+さんこう;sankou
+かんがえごと;kangaegoto
+じっこう;jikkou
+ぎょうれつ;gyouretsu
+ゆくえ;yukue
+こうげん;kougen
+さいこう;saikou
+たかね;takane
+こうよう;kouyou
+おうごん;ougon
+きいろ;kiiro
+ごうり;gouri
+かっせん;kassen
+はなしあい;hanashiai
+ゆうこく;yuukoku
+たにぞこ;tanizoko
+はせがわ;hasegawa
+しこく;shikoku
+こっか;kokka
+こくじん;kokujin
+くろじ;kuroji
+こくしびょう;kokushibyou
+こんしゅう;konshuu
+こんど;kondo
+ことし;kotoshi
+てんさい;tensai
+さいのう;sainou
+ごさい;gosai
+せいさく;seisaku
+さくひん;sakuhin
+どうさ;dousa
+さんぷ;sanpu
+よさん;yosan
+さんすう;sansuu
+ちゅうし;chuushi
+とめど;tomedo
+とまりぎ;tomarigi
+すいたし;suitashi
+しじょう;shijou
+うおいち;uoichi
+しそう;shisou
+しこう;shikou
+おもいだす;omoidasu
+ひょうし;hyoushi
+わし;washi
+てがみ;tegami
+りょうあんじ;ryouanji
+じいん;jiin
+やまでら;yamadera
+じぶん;jibun
+しぜん;shizen
+じしん;jishin
+にじ;niji
+ときどき;tokidoki
+しつない;shitsunai
+きょしつ;kyoshitsu
+むろつ;murotsu
+しゃかい;shakai
+じんじゃ;jinja
+しゃいん;shain
+じゃくてん;jakuten
+じゃくしょう;jakushou
+よわむし;yowamushi
+しゅりょう;shuryou
+くびわ;kubiwa
+くびきり;kubikiri
+ばんしゅう;banshuu
+しゅうぶん;shuubun
+あきぞら;akizora
+せいしゅん;seishun
+ばいしゅん;baishun
+はるぎ;harugi
+しょき;shoki
+きょうかしょ;kyoukasho
+はがき;hagaki
+しょうねん;shounen
+しょうすう;shousuu
+たしょう;tashou
+かいじょう;kaijou
+にゅうじょう;nyuujou
+ひろば;hiroba
+こうしょく;koushoku
+しきそ;shikiso
+ぎんいろ;gin_iro
+しょくじ;shokuji
+たべもの;tabemono
+くいもの;kuimono
+ちゅうしん;chuushin
+しんぞう;shinzou
+まごころ;magokoro
+しんねん;shinnen
+しんぴん;shinpin
+しんじん;shinjin
+しんるい;shinrui
+おやこ;oyako
+ちず;chizu
+ずが;zuga
+としょかん;toshokan
+すうがく;suugaku
+じゅず;juzu
+かずかず;kazukazu
+せいよう;seiyou
+かんさい;kansai
+にしび;nishibi
+せいえん;seien
+だいおんじょう;daionjou
+なきごえ;nakigoe
+かせい;kasei
+みょうじょう;myoujou
+ながれぼし;nagareboshi
+せいてん;seiten
+はればれ;harebare
+はれぎ;haregi
+しんせつ;shinsetsu
+いっさい;issai
+はらきり;harakiri
+こうせつ;kousetsu
+おおゆき;ooyuki
+じょせつしゃ;josetsusha
+せんちょう;senchou
+こぎぶね;kogibune
+ふなびん;funabin
+ぜんしゃ;zensha
+くうぜん;kuuzen
+まえばらい;maebarai
+そしき;soshiki
+くみあい;kumiai
+くみたて;kumitate
+きょうそう;kyousou
+ずつう;zutsuu
+あたまうち;atamauchi
+どうよう;douyou
+どうじ;douji
+どうい;doui
+てつどう;tetsudou
+しんとう;shintou
+みちばた;michibata
+どくしゃ;dokusha
+とくほん;tokuhon
+よみかた;yomikata
+とうなん;tounan
+なんきょく;nankyoku
+みなみがわ;minamigawa
+ばじゅつ;bajutsu
+ばしゃ;basha
+うまのり;umanori
+ばいばい;baibai
+ばいてん;baiten
+うりもの;urimono
+ばいしゅう;baishuu
+かいもの;kaimono
+かいて;kaite
+ばくが;bakuga
+むぎちゃ;mugicha
+こむぎ;komugi
+はんとう;hantou
+はんとし;hantoshi
+じゅんばん;junban
+ばんにん;bannin
+ふぼ;fubo
+おとうさま;otousama
+ちちおや;chichioya
+ふうせん;fuusen
+かみかぜ;kamikaze
+わふう;wafuu
+ぶんし;bunshi
+いっぷん;ippun
+いちぶ;ichibu
+ちょうもん;choumon
+ききとる;kikitoru
+べいか;beika
+べいこく;beikoku
+はくまい;hakumai
+しんぽ;shinpo
+ほこうしゃ;hokousha
+あるきだす;arukidasu
+ぼせい;bosei
+おかあさま;okaasama
+ははおや;hahaoya
+ほうがく;hougaku
+おやかた;oyakata
+みかた;mikata
+とうほく;touhoku
+はいぼく;haiboku
+きたかぜ;kitakaze
+まいにち;mainichi
+まいど;maido
+ひごと;higoto
+しまい;shimai
+いもうとぶん;imoutobun
+れいまい;reimai
+めいはく;meihaku
+みょうにち;myounichi
+あけがた;akegata
+めいどう;meidou
+なきごえ;nakigoe
+なりもの;narimono
+ようもう;youmou
+けがわ;kegawa
+けむし;kemushi
+せいもん;seimon
+もんばん;monban
+かどで;kadode
+ほんや;hon_ya
+よあけ;yoake
+よるがお;yorugao
+やせい;yasei
+やきゅう;yakyuu
+のはら;nohara
+ゆうじん;yuujin
+ゆうじょう;yuujou
+ともだち;tomodachi
+ようい;youi
+あくよう;akuyou
+ようび;youbi
+かよう;kayou
+しちよう;shichiyou
+しんらいしゃ;shinraisha
+きらく;kiraku
+たのしみ;tanoshimi
+がっき;gakki
+いちり;ichiri
+さとびと;satobito
+ふるさと;furusato
+りせい;risei
+むり;muri
+しんりがく;shinrigaku
+かいわ;kaiwa
+わだい;wadai
+こばなし;kobanashi
+あくい;akui
+おかん;okan
+わるもの;warumono
+ふあん;fuan
+あんしん;anshin
+やすもの;yasumono
+めいあん;meian
+あんさつ;ansatsu
+まっくら;makkura
+げかい;gekai
+いがく;igaku
+けつい;ketsui
+いけん;iken
+きょういく;kyouiku
+いくじ;ikuji
+そだておや;sodateoya
+かいいん;kaiin
+ぜんいん;zen_in
+どういん;douin
+びょういん;byouin
+じいん;jiin
+ぎいん;giin
+いんようすい;in_yousui
+のみもの;nomimono
+のみや;nomiya
+ふうん;fuun
+うんそう;unsou
+すいえい;suiei
+はいえい;haiei
+ひらおよぎ;hiraoyogi
+えきちょう;ekichou
+えきべん;ekiben
+とうきょうえき;toukyoueki
+どうぶつえん;doubutsuen
+はなぞの;hanazono
+おうだん;oudan
+おうこう;oukou
+よこがお;yokogao
+おくじょう;okujou
+こや;koya
+ぱんや;pan_ya
+おんせん;onsen
+おんじょう;onjou
+おんしつ;onshitsu
+へんか;henka
+けしょう;keshou
+ばけもの;bakemono
+しゅっか;shukka
+ふなに;funani
+にもつ;nimotsu
+きょうかい;kyoukai
+せいかい;seikai
+かいはつ;kaihatsu
+かいし;kaishi
+ひらきづな;hirakiduna
+かいだん;kaidan
+にかい;nikai
+かいきゅう;kaikyuu
+かくど;kakudo
+つのぶえ;tsunobue
+まちかど;machikado
+かっき;kakki
+かつどう;katsudou
+かんぱ;kanpa
+さむけ;samuke
+かんだんけい;kandankei
+かんしん;kanshin
+かんかく;kankaku
+かんじょう;kanjou
+かいかん;kaikan
+りょかん;ryokan
+びじゅつかん;bijutsukan
+かいがん;kaigan
+たいがん;taigan
+かわぎし;kawagishi
+がんせき;ganseki
+いわや;iwaya
+じさ;jisa
+さべつ;sabetsu
+さしこむ;sashikomu
+やさい;yasai
+なたね;natane
+さいしょくしゅぎ;saishokushugi
+さいだい;saidai
+さいご;saigo
+さいしんしき;saishinshiki
+ざいもく;zaimoku
+ざいりょう;zairyou
+じんざい;jinzai
+さくじつ;sakujitsu
+さくや;sakuya
+さくねん;sakunen
+いんさつしょ;insatsusho
+さっしん;sasshin
+こうせいずり;kouseizuri
+さつじん;satsujin
+じさつ;jisatsu
+ころしや;koroshiya
+けいさつ;keisatsu
+さっち;sacchi
+かんさつ;kansatsu
+さんか;sanka
+さんこう;sankou
+さんぎ;sangi
+せいさん;seisan
+さんぶつ;sanbutsu
+しゅっさん;shussan
+さんぶん;sanbun
+ちらし;chirashi
+ざんきん;zankin
+ざんにん;zannin
+ぶし;bushi
+しかん;shikan
+しゅうし;shuushi
+しめい;shimei
+しぞく;shizoku
+かとうし;katoushi
+れきし;rekishi
+じょし;joshi
+しじょう;shijou
+しほう;shihou
+しれいぶ;shireibu
+しかいしゃ;shikaisha
+ねえさん;neesan
+あねうえ;aneue
+しまいとし;shimaitoshi
+しあい;shiai
+しけんかん;shikenkan
+こころみ;kokoromi
+しょうてんがい;shoutengai
+かくだい;kakudai
+かくさん;kakusan
+かくせいき;kakuseiki
+かくめい;kakumei
+かくしん;kakushin
+かわこうば;kawakouba
+かっか;kakka
+ないかく;naikaku
+かくりょう;kakuryou
+ぶんかつ;bunkatsu
+わりびき;waribiki
+わりあい;wariai
+きりかぶ;kirikabu
+かぶしき;kabushiki
+かぶぬし;kabunushi
+かんちょう;kanchou
+かんじょう;kanjou
+ほしにく;hoshiniku
+だいいっかん;daiikkan
+まきもの;makimono
+いとまき;itomaki
+かんごふ;kangofu
+かんばん;kanban
+かんしゅ;kanshu
+かんこく;kankoku
+かんしょう;kanshou
+かんゆう;kan_yuu
+かんたん;kantan
+しょかん;shokan
+かんりゃく;kanryaku
+がんやく;gan_yaku
+まるみ;marumi
+にっぽんまる;nipponmaru
+きき;kiki
+きけん;kiken
+きがい;kigai
+きじょう;kijou
+きへん;kihen
+じむつくえ;jimutsukue
+はっき;hakki
+しき;shiki
+きはつせい;kihatsusei
+きぞく;kizoku
+きちょう;kichou
+しつぎ;shitsugi
+ぎもん;gimon
+ぎじ;giji
+きゅうどう;kyuudou
+きゅうじょう;kyuujou
+ゆみとり;yumitori
+きゅうしゅう;kyuushuu
+ゆせい;yusei
+てんじょう;tenjou
+いど;ido
+せいめい;seimei
+かいせい;kaisei
+ひゃくしょう;hyakushou
+せいふく;seifuku
+えんせい;ensei
+せいい;seii
+いっせい;issei
+せいいつ;seiitsu
+せいしょう;seishou
+ぎせいしゃ;giseisha
+いけにえ;ikenie
+ぎせいてき;giseiteki
+せいきょ;seikyo
+きゅうせい;kyuusei
+ちょうせい;chousei
+ぜんせいき;zenseiki
+おおもり;oomori
+もえさかる;moesakaru
+じょせい;josei
+はなむこ;hanamuko
+むこいり;mukoiri
+せいやく;seiyaku
+せんせい;sensei
+ちかいごと;chikaigoto
+せいきゅう;seikyuu
+ふしん;fushin
+うけおいにん;ukeoinin
+はいせき;haiseki
+せっこう;sekkou
+せきりょく;sekiryoku
+せきじつ;sekijitsu
+むかしふう;mukashifuu
+こんじゃく;konjaku
+ぶんせき;bunseki
+かいせき;kaiseki
+せきしゅつ;sekishutsu
+せきしゅ;sekishu
+いっせき;isseki
+いっせきがん;issekigan
+つうせき;tsuuseki
+おしげ;oshige
+ほねおしみ;honeoshimi
+ついせき;tsuiseki
+あしあと;ashiato
+いせき;iseki
+しょせき;shoseki
+こせき;koseki
+こくせき;kokuseki
+せっしゃ;sessha
+ぼうしょう;boushou
+がくぼう;gakubou
+ぼうだい;boudai
+ぼうまん;bouman
+ぼうちょうべん;bouchouben
+いんぼう;inbou
+むほん;muhon
+ぼうりゃく;bouryaku
+じゅんぼく;junboku
+そぼく;soboku
+ほうのき;hounoki
+こうぼく;kouboku
+どぼく;doboku
+ぼくら;bokura
+ひつぼく;hitsuboku
+はくぼく;hakuboku
+すみえ;sumie
+だぼく;daboku
+すもう;sumou
+ぼくさつ;bokusatsu
+ぼっしゅう;bosshuu
+にちぼつ;nichibotsu
+ぼつご;botsugo
+そとぼり;sotobori
+つりぼり;tsuribori
+ほりかわ;horikawa
+ほんそう;honsou
+ほんぽう;honpou
+しゅっぽん;shuppon
+ほんやくか;hon_yakuka
+ほんい;hon_i
+ひるがえって;hirugaette
+へいぼん;heibon
+ぼんせん;bonsen
+はんれい;hanrei
+ぼんち;bonchi
+ぼんおどり;bon_odori
+ぼんけい;bonkei
+まふ;mafu
+まやく;mayaku
+あさづな;asaduna
+まてんろう;matenrou
+まさつ;masatsu
+まさつおん;masatsuon
+けんま;kenma
+まめつ;mametsu
+くつみがき;kutsumigaki
+あくま;akuma
+まほう;mahou
+まら;mara
+まいそう;maisou
+うめたて;umetate
+うもれぎ;umoregi
+こまく;komaku
+もうまく;moumaku
+まくしつ;makushitsu
+または;mataha
+またとない;matatonai
+またがし;matagashi
+まっさつ;massatsu
+まっちゃ;maccha
+いちまつ;ichimatsu
+たいまん;taiman
+じまん;jiman
+まんせい;mansei
+まんが;manga
+さんまん;sanman
+そぞろごと;sozorogoto
+みりょく;miryoku
+みわく;miwaku
+みりょう;miryou
+こうかく;koukaku
+こうわん;kouwan
+コッドみさき;koddomisaki
+みょうあん;myouan
+びみょう;bimyou
+きみょう;kimyou
+ふみんしょう;fuminshou
+ねむけ;nemuke
+いねむり;inemuri
+ぼうげき;bougeki
+ほこさき;hokosaki
+むじゅんした;mujunshita
+むちゅう;muchuu
+あくむ;akumu
+ゆめみる;yumemiru
+むてき;muteki
+のうむ;noumu
+あさぎり;asagiri
+こむすめ;komusume
+じょうしぐん;joushigun
+むすめざかり;musumezakari
+めいがら;meigara
+めいき;meiki
+めいめい;meimei
+ぜつめつ;zetsumetsu
+めつぼう;metsubou
+はめつ;hametsu
+めんじょ;menjo
+めんぜい;menzei
+ほうめん;houmen
+はんも;hanmo
+もりん;morin
+しげみ;shigemi
+ぼうげん;bougen
+もうそう;mousou
+かせいがん;kaseigan
+きげん;kigen
+はやおき;hayaoki
+きどうりょく;kidouryoku
+がっき;gakki
+きたい;kitai
+さいご;saigo
+らいきゃく;raikyaku
+じょうきゃく;joukyaku
+かくいん;kakuin
+けんきゅう;kenkyuu
+きゅうめい;kyuumei
+たんきゅう;tankyuu
+きゅうし;kyuushi
+きゅうそく;kyuusoku
+おおいそぎ;ooisogi
+しんきゅう;shinkyuu
+どうきゅうせい;doukyuusei
+じょうきゅう;joukyuu
+じんぐう;jinguu
+きゅうちゅう;kyuuchuu
+みやさま;miyasama
+きゅうぎ;kyuugi
+ちきゅう;chikyuu
+たまひろい;tamahiroi
+きょねん;kyonen
+かこ;kako
+たちさる;tachisaru
+てっきょう;tekkyou
+りっきょう;rikkyou
+いしばし;ishibashi
+さんぎょう;sangyou
+ざいごう;zaigou
+しわざ;shiwaza
+きょくせん;kyokusen
+さっきょく;sakkyoku
+まげもの;magemono
+きょくめん;kyokumen
+けっきょく;kekkyoku
+ゆうびんきょく;yuubinkyoku
+ぎんこう;ginkou
+ぎんが;ginga
+ぎんか;ginka
+くしん;kushin
+くつう;kutsuu
+にがみ;nigami
+ぐあい;guai
+ようぐ;yougu
+どうぐ;dougu
+ぼうくん;boukun
+さいくん;saikun
+やまだくん;yamadakun
+ふけい;fukei
+にいさま;niisama
+きょうだいあい;kyoudaiai
+かんけい;kankei
+けいそう;keisou
+かかりいん;kakariin
+けいしょく;keishoku
+けいはく;keihaku
+かるいし;karuishi
+けつえき;ketsueki
+はなぢ;hanadi
+けっとう;kettou
+かいけつ;kaiketsu
+けっしん;kesshin
+けつれつ;ketsuretsu
+けんしゅう;kenshuu
+とぎかわ;togikawa
+けんきゅうしゃ;kenkyuusha
+みえけん;mieken
+けんりつ;kenritsu
+けんちょう;kenchou
+はつげん;hatsugen
+むごん;mugon
+しゃこ;shako
+そうこ;souko
+れいぞうこ;reizouko
+とおわだこ;toowadako
+こがん;kogan
+こすい;kosui
+こうきょう;koukyou
+こうへい;kouhei
+きしゅうこう;kishuukou
+こうじょう;koujou
+いこう;ikou
+まえむき;maemuki
+こううん;kouun
+ふこう;fukou
+こうふく;koufuku
+くうこう;kuukou
+にゅうこう;nyuukou
+みなとまち;minatomachi
+ばんごう;bangou
+ごうれい;gourei
+ごうきゅう;goukyuu
+こんぽん;konpon
+だいこん;daikon
+やね;yane
+さいじつ;saijitsu
+さいだん;saidan
+ゆきまつり;yukimatsuri
+さいく;saiku
+ほそながい;hosonagai
+こまか;komaka
+しごと;shigoto
+しかた;shikata
+しくみ;shikumi
+したい;shitai
+しきょ;shikyo
+わかじに;wakajini
+しよう;shiyou
+たいし;taishi
+こづかい;kodukai
+しじゅう;shijuu
+しどうき;shidouki
+しはじめる;shihajimeru
+しじ;shiji
+おやゆび;oyayubi
+さしず;sashizu
+しこん;shikon
+はいしゃ;haisha
+はぐるま;haguruma
+しじん;shijin
+してき;shiteki
+しじょう;shijou
+さんじ;sanji
+しだい;shidai
+あいついで;aitsuide
+だいじ;daiji
+こうず;kouzu
+できごと;dekigoto
+じさん;jisan
+もちぬし;mochinushi
+ながもち;nagamochi
+しんしき;shinshiki
+ほうしき;houshiki
+かいかいしき;kaikaishiki
+じっこう;jikkou
+じじつ;jijitsu
+みいり;miiri
+しゃしん;shashin
+しゃじつ;shajitsu
+ふくしゃき;fukushaki
+さくしゃ;sakusha
+こうしゃ;kousha
+わかもの;wakamono
+しゅじん;shujin
+じぬし;jinushi
+しゅよう;shuyou
+ほしゅ;hoshu
+るすばん;rusuban
+こもり;komori
+しゅとく;shutoku
+とりだす;toridasu
+ぎゅうじる;gyuujiru
+いんしゅ;inshu
+さかば;sakaba
+さけのみ;sakenomi
+じゅけんしゃ;jukensha
+うけとり;uketori
+うけつけ;uketsuke
+ほんしゅう;honshuu
+さす;sasu
+しゅうぎかい;shuugikai
+しゅうしゅう;shuushuu
+ひろいもの;hiroimono
+じゅういち;juuichi
+しゅうてん;shuuten
+しゅうし;shuushi
+おわり;owari
+れんしゅう;renshuu
+しゅうじ;shuuji
+みならい;minarai
+せんしゅう;senshuu
+にしゅうめ;nishuume
+しゅうだん;shuudan
+へんしゅう;henshuu
+しゅうちゅう;shuuchuu
+じゅうしょ;juusho
+じゅうたく;juutaku
+すみて;sumite
+じゅうだい;juudai
+おもさ;omosa
+みえ;mie
+ばしょ;basho
+しょゆう;shoyuu
+いどころ;idokoro
+こくしょ;kokusho
+ひしょち;hishochi
+あつさ;atsusa
+じょしゅ;joshu
+じょりょく;joryoku
+たすけあい;tasukeai
+しょうわ;shouwa
+しょうしょう;shoushou
+しょうだい;shoudai
+しょうひ;shouhi
+けしゴム;keshigomu
+しょうかき;shoukaki
+しょうぎょう;shougyou
+しょうにん;shounin
+しょうばい;shoubai
+きしょう;kishou
+ぶんしょう;bunshou
+しょうく;shouku
+しょうり;shouri
+しょうぶ;shoubu
+かちき;kachiki
+じょうせん;jousen
+じょうすう;jousuu
+のりもの;norimono
+しょくぶつ;shokubutsu
+たうえ;taue
+しょくみんち;shokuminchi
+しんこく;shinkoku
+もうしこむ;moushikomu
+もうしわけ;moushiwake
+しんたい;shintai
+じしん;jishin
+みぶん;mibun
+せいしん;seishin
+しんぷ;shinpu
+めがみ;megami
+しんえん;shin_en
+しんかい;shinkai
+ふかいり;fukairi
+ぜんしん;zenshin
+しんか;shinka
+しんげん;shingen
+せいき;seiki
+せわ;sewa
+よのなか;yononaka
+せいり;seiri
+せいび;seibi
+びちょうせい;bichousei
+だっせん;dassen
+こうせん;kousen
+ちょくせん;chokusen
+ぜんぶ;zenbu
+ぜんしん;zenshin
+あんぜん;anzen
+ほうそう;housou
+そうきん;soukin
+みおくる;miokuru
+きゅうそく;kyuusoku
+ためいき;tameiki
+むすこ;musuko
+かぞく;kazoku
+みんぞく;minzoku
+しゅぞく;shuzoku
+たにん;tanin
+たこく;takoku
+よそ;yoso
+だしゃ;dasha
+だげき;dageki
+うちかえす;uchikaesu
+たいしょう;taishou
+ついく;tsuiku
+たいき;taiki
+しょうたい;shoutai
+まちぶせ;machibuse
+せだい;sedai
+こうたい;koutai
+へやだい;heyadai
+だいにか;dainika
+しだいしょ;shidaisho
+きゅうだい;kyuudai
+だいめい;daimei
+わだい;wadai
+せきたん;sekitan
+たんそ;tanso
+すみび;sumibi
+たんしょ;tansho
+たんき;tanki
+てみじか;temijika
+とうちゃく;touchaku
+きもの;kimono
+ふなつき;funatsuki
+ちゅうもく;chuumoku
+ちゅうしゃ;chuusha
+ちゅうしゃく;chuushaku
+ちゅうせき;chuuseki
+でんちゅう;denchuu
+つらら;tsurara
+ていねい;teinei
+ちょうめ;choume
+てちょう;techou
+ちょうば;chouba
+かや;kaya
+ちょうせい;chousei
+ちょうさ;chousa
+ちょうし;choushi
+ちょくせつ;chokusetsu
+しょうじき;shoujiki
+ちょくりつ;chokuritsu
+ついきゅう;tsuikyuu
+ついほう;tsuihou
+おいはらう;oiharau
+ていき;teiki
+ふてい;futei
+けってい;kettei
+かてい;katei
+ていえん;teien
+にわし;niwashi
+てっぱん;teppan
+ちかてつ;chikatetsu
+こくてつ;kokutetsu
+てんそう;tensou
+うんてん;unten
+とし;toshi
+しゅと;shuto
+つごう;tsugou
+ていど;teido
+おんど;ondo
+いちど;ichido
+とうしゅ;toushu
+とうひょう;touhyou
+なげだす;nagedasu
+れっとう;rettou
+とうみん;toumin
+しまぐに;shimaguni
+せんとう;sentou
+ゆげ;yuge
+ちゃのゆ;chanoyu
+とうじょう;toujou
+とざん;tozan
+きのぼり;kinobori
+いっとう;ittou
+じょうとう;joutou
+とうあつせん;touatsusen
+じどうしゃ;jidousha
+うごきだす;ugokidasu
+どうわ;douwa
+じどう;jidou
+どうしん;doushin
+ないぶ;naibu
+うちき;uchiki
+ばにく;baniku
+にくや;nikuya
+にくがん;nikugan
+のうじょう;noujou
+のうみん;noumin
+のうぎょう;nougyou
+しゅうは;shuuha
+おんぱ;onpa
+なみのり;naminori
+しんぱい;shinpai
+はいたつ;haitatsu
+くばりて;kubarite
+ちゃばたけ;chabatake
+たはた;tahata
+むぎばたけ;mugibatake
+はっぴょう;happyou
+ほっそく;hossoku
+はつでんき;hatsudenki
+はんおう;han_ou
+はんかく;hankaku
+たんもの;tanmono
+きゅうはん;kyuuhan
+さかみち;sakamichi
+くだりざか;kudarizaka
+こくばん;kokuban
+いたがみ;itagami
+いたまえ;itamae
+ひふ;hifu
+ひにく;hiniku
+きのかわ;kinokawa
+ひげき;higeki
+ひめい;himei
+かなしさ;kanashisa
+びじん;bijin
+びじゅつ;bijutsu
+びがく;bigaku
+びおん;bion
+はなさき;hanasaki
+はなぐすり;hanagusuri
+ひょうげん;hyougen
+ひょうてん;hyouten
+こおりみず;koorimizu
+ひょうめん;hyoumen
+ひょうげん;hyougen
+じこくひょう;jikokuhyou
+にびょう;nibyou
+びょうしん;byoushin
+びょうそく;byousoku
+びょうき;byouki
+びょうにん;byounin
+らいびょう;raibyou
+しょうひん;shouhin
+ひんしつ;hinshitsu
+しなもの;shinamono
+ふしょう;fushou
+ふたん;futan
+まけぎらい;makegirai
+ぶぶん;bubun
+ぶぞく;buzoku
+ふくそう;fukusou
+ふくじゅう;fukujuu
+はっとり;hattori
+こうふく;koufuku
+ふくびき;fukubiki
+ふくいんしょ;fukuinsho
+じんぶつ;jinbutsu
+しょくもつ;shokumotsu
+たべもの;tabemono
+へいき;heiki
+びょうどう;byoudou
+ひらて;hirate
+へんじ;henji
+へんさい;hensai
+しかえし;shikaeshi
+きんべん;kinben
+べんがく;bengaku
+かいほう;kaihou
+ほうしゃ;housha
+てばなす;tebanasu
+ごまん;goman
+ばんじ;banji
+まんねんひつ;mannenhitsu
+いみ;imi
+きょうみ;kyoumi
+あじみ;ajimi
+めいれい;meirei
+せいめい;seimei
+いのちとり;inochitori
+がいめん;gaimen
+かめん;kamen
+はなづら;hanadura
+しつもん;shitsumon
+がくもん;gakumon
+とんや;ton_ya
+やくしゃ;yakusha
+へいえき;heieki
+やっきょく;yakkyoku
+かやく;kayaku
+くすりゆび;kusuriyubi
+ゆらい;yurai
+りゆう;riyuu
+じゆう;jiyuu
+ゆでん;yuden
+とうゆ;touyu
+あぶらえ;aburae
+しょゆうしゃ;shoyuusha
+うむ;umu
+ありがとう;arigatou
+ゆうらん;yuuran
+ゆさん;yusan
+あそびば;asobiba
+よやく;yoyaku
+よそう;yosou
+よてい;yotei
+せいようじん;seiyoujin
+たいせいよう;taiseiyou
+ようしょく;youshoku
+しんようじゅ;shin_youju
+はまき;hamaki
+はがき;hagaki
+ようきょく;youkyoku
+ようき;youki
+たいようけい;taiyoukei
+しよう;shiyou
+ありさま;arisama
+みなさま;minasama
+らっか;rakka
+おちば;ochiba
+おとしもの;otoshimono
+りゅうこう;ryuukou
+るふ;rufu
+ながれぎ;nagaregi
+りょこう;ryokou
+たびびと;tabibito
+りょひ;ryohi
+りょうほう;ryouhou
+りょうて;ryoute
+りょうがえ;ryougae
+じょうりょくじゅ;jouryokuju
+ろくしょう;rokushou
+みどりいろ;midoriiro
+しつれい;shitsurei
+れいふく;reifuku
+けいれい;keirei
+れっしゃ;ressha
+れつじ;retsuji
+ぜんれつ;zenretsu
+どうろ;douro
+せんろ;senro
+たびじ;tabiji
+へいわ;heiwa
+やまと;yamato
+わしょく;washoku
+あいじょう;aijou
+ぼせいあい;boseiai
+あいこくしゃ;aikokusha
+ていあん;teian
+あんがい;angai
+あんじょう;anjou
+いか;ika
+いがい;igai
+いふく;ifuku
+いるい;irui
+ころもがえ;koromogae
+ちい;chii
+がくい;gakui
+じゅうにぐらい;juunigurai
+しゅうい;shuui
+はんい;han_i
+かこいこむ;kakoikomu
+いいんかい;iinkai
+いにん;inin
+いたくきん;itakukin
+いえき;ieki
+いぶくろ;ibukuro
+いじゃく;ijaku
+いんさつ;insatsu
+いんばん;inban
+めじるし;mejirushi
+えいさい;eisai
+えいこく;eikoku
+えいご;eigo
+こうえい;kouei
+えいよう;eiyou
+はんえい;han_ei
+しょくえん;shokuen
+しおみず;shiomizu
+せいえんしょ;seiensho
+ちゅうおう;chuuou
+ちゅうおうぶ;chuuoubu
+ちゅうおうぐち;chuuouguchi
+におく;nioku
+じゅうおく;juuoku
+おくまんちょうじゃ;okumanchouja
+ぞうか;zouka
+さんか;sanka
+くわえざん;kuwaezan
+かもつせん;kamotsusen
+こうか;kouka
+ざっか;zakka
+かぜい;kazei
+かちょう;kachou
+だいにか;dainika
+はつが;hatsuga
+しんめ;shinme
+めばえる;mebaeru
+かいかく;kaikaku
+かいせい;kaisei
+あらためて;aratamete
+きかい;kikai
+きかい;kikai
+きかいか;kikaika
+そんがい;songai
+さつがい;satsugai
+ぼうがい;bougai
+かくえき;kakueki
+かっこく;kakkoku
+かくじ;kakuji
+じかく;jikaku
+めざめ;mezame
+おぼえがき;oboegaki
+かんせい;kansei
+みかん;mikan
+かんぜん;kanzen
+けいかん;keikan
+かんりょう;kanryou
+かんちょう;kanchou
+かんじ;kanji
+あっかん;akkan
+かんし;kanshi
+かんり;kanri
+きかん;kikan
+かんがっき;kangakki
+かんとう;kantou
+かんしん;kanshin
+せきのやま;sekinoyama
+かんこう;kankou
+かんさつ;kansatsu
+かんきゃく;kankyaku
+しがんしゃ;shigansha
+がんぼうてき;ganbouteki
+ねがいごと;negaigoto
+きぼう;kibou
+ききゅう;kikyuu
+きはく;kihaku
+きせつ;kisetsu
+しき;shiki
+きじょ;kijo
+きげん;kigen
+きこう;kikou
+にじゅうせいき;nijuuseiki
+きげき;kigeki
+かんき;kanki
+おおよろこび;ooyorokobi
+こっき;kokki
+はたもち;hatamochi
+かじき;kajiki
+きぐ;kigu
+しょっき;shokki
+きよう;kiyou
+きのう;kinou
+きかい;kikai
+はたおり;hataori
+ぎろん;giron
+かいぎ;kaigi
+ぎかい;gikai
+ようきゅう;youkyuu
+ついきゅう;tsuikyuu
+きゅうしょく;kyuushoku
+きゅうめいブイ;kyuumeibui
+きゅうえん;kyuuen
+すくいだす;sukuidasu
+きょうきゅう;kyoukyuu
+げっきゅう;gekkyuu
+きたまえ;kitamae
+きょしゅ;kyoshu
+せんきょ;senkyo
+いっきょ;ikkyo
+ぎょせん;gyosen
+りょうし;ryoushi
+ぎょぎょう;gyogyou
+きょうつう;kyoutsuu
+ともぐい;tomogui
+きょうさんしゅぎ;kyousanshugi
+きょうてい;kyoutei
+きょうりょく;kyouryoku
+きょうかい;kyoukai
+ぼうえんきょう;bouenkyou
+きょうだい;kyoudai
+てかがみ;tekagami
+きょうそう;kyousou
+けいば;keiba
+せりうり;seriuri
+ほっきょく;hokkyoku
+しごく;shigoku
+しょうきょく;shoukyoku
+くべつ;kubetsu
+ちく;chiku
+きたく;kitaku
+くうぐん;kuugun
+ぐんじん;gunjin
+べいこくぐん;beikokugun
+ぐんぶ;gunbu
+こおりやま;kooriyama
+わけぐん;wakegun
+げんけい;genkei
+おおがた;oogata
+てんけいてき;tenkeiteki
+こうけい;koukei
+けいき;keiki
+げいじゅつ;geijutsu
+しゅげい;shugei
+げいしゃ;geisha
+けっせきしゃ;kessekisha
+けってん;ketten
+かけめ;kakeme
+けっこん;kekkon
+けっか;kekka
+むすびめ;musubime
+けんせつ;kensetsu
+こんりゅう;konryuu
+たてもの;tatemono
+けんこう;kenkou
+けんぜん;kenzen
+けんぴつか;kenpitsuka
+しけん;shiken
+じっけん;jikken
+けいけん;keiken
+こたい;kotai
+きょうこ;kyouko
+かたまり;katamari
+せいこう;seikou
+こうざい;kouzai
+こうろう;kourou
+きこう;kikou
+こうほ;kouho
+そうろうぶん;souroubun
+こうくう;koukuu
+こうかい;koukai
+こうろ;kouro
+しょうこう;shoukou
+ふけんこう;fukenkou
+けんこうたい;kenkoutai
+こうこく;koukoku
+こうこく;koukoku
+こうこく;koukoku
+じしょ;jisho
+じしょく;jishoku
+しゅうじがく;shuujigaku
+しっぱい;shippai
+しっけい;shikkei
+しつぎょう;shitsugyou
+しゃっきん;shakkin
+しゃくや;shakuya
+かりぬし;karinushi
+いっしゅ;isshu
+じんしゅ;jinshu
+たねなし;tanenashi
+しゅうへん;shuuhen
+しゅうとう;shuutou
+いっしゅう;isshuu
+やどや;yadoya
+げしゅくにん;geshukunin
+じゅんじょ;junjo
+じゅうじゅん;juujun
+じゅんちょう;junchou
+はじめて;hajimete
+はつこい;hatsukoi
+ていしょう;teishou
+がっしょう;gasshou
+となえね;tonaene
+ねんしょう;nenshou
+やけあと;yakeato
+やきたて;yakitate
+さんしょう;sanshou
+たいしょう;taishou
+しょうめい;shoumei
+しょうひん;shouhin
+しょうさん;shousan
+いっとうしょう;ittoushou
+しんか;shinka
+しんみん;shinmin
+だいじん;daijin
+しんよう;shin_you
+めいしん;meishin
+かくしん;kakushin
+しんじつ;shinjitsu
+しゃしんき;shashinki
+まっしろ;masshiro
+せいぶん;seibun
+せいじん;seijin
+なりたち;naritachi
+はんせい;hansei
+しょうりゃく;shouryaku
+こうせいしょう;kouseishou
+せいけつ;seiketsu
+せいじょう;seijou
+しみず;shimizu
+せいりょく;seiryoku
+おおぜい;oozei
+いきおいよく;ikioiyoku
+せいし;seishi
+しずけさ;shizukesa
+じょうみゃく;joumyaku
+しゅっせき;shusseki
+けっせき;kesseki
+くうせき;kuuseki
+めんせき;menseki
+せきせつ;sekisetsu
+くっせつ;kussetsu
+おりめ;orime
+おりがみ;origami
+ちょうせつ;chousetsu
+かんせつ;kansetsu
+ふしあな;fushiana
+せつめい;setsumei
+しょうせつ;shousetsu
+がくせつ;gakusetsu
+せんぱく;senpaku
+あさせ;asase
+あさぎ;asagi
+たいせん;taisen
+せんじょう;senjou
+さくせん;sakusen
+とうせん;tousen
+せんしゅ;senshu
+えらびだす;erabidasu
+とうぜん;touzen
+てんねん;tennen
+しかるべく;shikarubeku
+せんそう;sensou
+いいあらそい;iiarasoi
+きょうそうしゃ;kyousousha
+そうだん;soudan
+あいて;aite
+しゅしょう;shushou
+せんそう;sensou
+そうこう;soukou
+くらに;kurani
+ちゃくそう;chakusou
+りそう;risou
+あいそう;aisou
+ぞうげ;zouge
+いんしょう;inshou
+しょうちょうてき;shouchouteki
+そっき;sokki
+じそく;jisoku
+こうそくどうろ;kousokudouro
+そくめん;sokumen
+みぎがわ;migigawa
+そばづかえ;sobadukae
+ぞくぞく;zokuzoku
+れんぞく;renzoku
+てつづき;tetsuduki
+そつぎょう;sotsugyou
+へいそつ;heisotsu
+そっきょ;sokkyo
+しそん;shison
+まごびき;magobiki
+まごむすめ;magomusume
+ちたい;chitai
+おびじ;obiji
+ねったいぎょ;nettaigyo
+へいたい;heitai
+ぐんたい;guntai
+ぶたい;butai
+はったつ;hattatsu
+たつじん;tatsujin
+ひとたち;hitotachi
+たんい;tan_i
+たんじゅん;tanjun
+たんどく;tandoku
+そうだんやく;soudan_yaku
+かいだん;kaidan
+だんわ;danwa
+せいじ;seiji
+ちあん;chian
+ちりょう;chiryou
+ほうち;houchi
+おきもの;okimono
+おきば;okiba
+ちょきん;chokin
+ちょぞう;chozou
+ちょすいち;chosuichi
+ちょうせん;chousen
+ちょうえん;chouen
+だいちょう;daichou
+さいてい;saitei
+ていり;teiri
+ていらく;teiraku
+かいてい;kaitei
+おくそこ;okusoko
+ていりゅう;teiryuu
+ていし;teishi
+ていしゃじょ;teishajo
+ていでん;teiden
+もくてき;mokuteki
+りそうてき;risouteki
+まとはずれ;matohazure
+じてん;jiten
+てんきょ;tenkyo
+てんけい;tenkei
+でんせつ;densetsu
+でんき;denki
+でんせんびょう;densenbyou
+とほしゃ;tohosha
+あだばな;adabana
+どりょく;doryoku
+どりょくか;doryokuka
+つとめて;tsutomete
+とうだい;toudai
+でんとう;dentou
+とうせん;tousen
+しょくどう;shokudou
+どうどう;doudou
+ろうどう;roudou
+はたらきて;hatarakite
+はたらきもの;hatarakimono
+ゆうどく;yuudoku
+きのどく;kinodoku
+しょくちゅうどく;shokuchuudoku
+ねったい;nettai
+ねつりきがく;netsurikigaku
+ねんりき;nenriki
+ねんいり;nen_iri
+ねんぶつ;nenbutsu
+はいせん;haisen
+はいそう;haisou
+はいぼくしゅぎ;haibokushugi
+ごばい;gobai
+ばいか;baika
+ばいすう;baisuu
+はかせ;hakase
+ばくと;bakuto
+はくぶつかん;hakubutsukan
+ひるめし;hirumeshi
+いいだ;iida
+ひこうき;hikouki
+ひご;higo
+とびだす;tobidasu
+ひよう;hiyou
+しょうひしゃ;shouhisha
+せいかつひ;seikatsuhi
+ひつよう;hitsuyou
+ひっし;hisshi
+ひつぜん;hitsuzen
+えんぴつ;enpitsu
+ひっしゃ;hissha
+ふでづかい;fudedukai
+ひょうけつ;hyouketsu
+とうひょう;touhyou
+でんぴょう;denpyou
+ひょうじゅん;hyoujun
+りていひょう;riteihyou
+ひょうしき;hyoushiki
+ふめい;fumei
+ふへい;fuhei
+ぶきみ;bukimi
+にんぷ;ninpu
+ふじん;fujin
+ふうふ;fuufu
+ふちゃく;fuchaku
+つきあう;tsukiau
+なづける;nadukeru
+せいふ;seifu
+ふけん;fuken
+きょうとふ;kyoutofu
+ふくぎょう;fukugyou
+ふくし;fukushi
+ふくりょうじ;fukuryouji
+かふん;kafun
+こなごな;konagona
+むぎこ;mugiko
+へいし;heishi
+ほへい;hohei
+へいき;heiki
+べつめい;betsumei
+とくべつ;tokubetsu
+わかれ;wakare
+へんきょう;henkyou
+きんぺん;kinpen
+かわべ;kawabe
+へんせい;hensei
+たいへん;taihen
+かわりもの;kawarimono
+べんじょ;benjo
+ゆうびん;yuubin
+こづつみ;kodutsumi
+ほうい;houi
+つつみがみ;tsutsumigami
+ほうがく;hougaku
+ふほう;fuhou
+しつぼう;shitsubou
+がんぼう;ganbou
+ぼうけん;bouken
+ぼくじょう;bokujou
+ほうぼく;houboku
+まきばとり;makibatori
+しゅうまつ;shuumatsu
+すえっこ;suekko
+せいきまつ;seikimatsu
+まんげつ;mangetsu
+まんぞく;manzoku
+まんちょう;manchou
+みゃっかん;myakkan
+こうみゃく;koumyaku
+さんみゃく;sanmyaku
+こくみん;kokumin
+みんかん;minkan
+みんしゅしゅぎ;minshushugi
+やくそく;yakusoku
+せつやく;setsuyaku
+やくごじゅうにん;yakugojuunin
+ゆうしゃ;yuusha
+ゆうき;yuuki
+いさみあし;isamiashi
+ふひつよう;fuhitsuyou
+ようてん;youten
+じゅうよう;juuyou
+ようせい;yousei
+えいようし;eiyoushi
+きょうよう;kyouyou
+よくしつ;yokushitsu
+にっこうよく;nikkouyoku
+みずあび;mizuabi
+りえき;rieki
+りよう;riyou
+ききめ;kikime
+りくぐん;rikugun
+じょうりく;jouriku
+たいりく;tairiku
+りょうしん;ryoushin
+かいりょう;kairyou
+よさ;yosa
+げんりょう;genryou
+りょうきん;ryoukin
+じゅうりょう;juuryou
+ぶんりょう;bunryou
+たいりょうせいさん;tairyouseisan
+しゃりん;sharin
+さんりんしゃ;sanrinsha
+わなげ;wanage
+しゅるい;shurui
+ぶんるい;bunrui
+るいじ;ruiji
+れいじょう;reijou
+めいれいほう;meireihou
+しれいかん;shireikan
+れいぞう;reizou
+れいせい;reisei
+ひえしょう;hieshou
+れいがい;reigai
+れいねん;reinen
+たとえば;tatoeba
+れきしか;rekishika
+けいれき;keireki
+へんれき;henreki
+れんらくせん;renrakusen
+れんじゅう;renjuu
+れんそう;rensou
+くんれん;kunren
+せんれん;senren
+ねりこ;neriko
+ろうじん;roujin
+ろうれん;rouren
+ろうれいねんきん;roureinenkin
+ろうどうしゃ;roudousha
+くろう;kurou
+ろうどうかんけい;roudoukankei
+きろく;kiroku
+じつろく;jitsuroku
+ろくおん;rokuon
+あつりょく;atsuryoku
+でんあつ;den_atsu
+あっとうてき;attouteki
+いじゅう;ijuu
+いみん;imin
+いどう;idou
+げんいん;gen_in
+しいん;shiin
+いんがかんけい;ingakankei
+えいぞく;eizoku
+えいじゅうしゃ;eijuusha
+けいえい;keiei
+えいぎょう;eigyou
+えいしょ;eisho
+えいせい;eisei
+しゅえい;shuei
+じえい;jiei
+ぼうえき;boueki
+えきしゃ;ekisha
+あんい;an_i
+ゆうえき;yuueki
+ますます;masumasu
+りえきはいとう;riekihaitou
+えきたい;ekitai
+えきか;ekika
+けつえきがた;ketsuekigata
+えんしゅつ;enshutsu
+しゅつえん;shutsuen
+えんぜつ;enzetsu
+おうとう;outou
+はんのう;hannou
+おうよう;ouyou
+おうふく;oufuku
+おうじ;ouji
+おうらい;ourai
+おんじん;onjin
+おんしらず;onshirazu
+おんがえし;ongaeshi
+かせつ;kasetsu
+かりに;karini
+けびょう;kebyou
+かち;kachi
+かかく;kakaku
+ぶっか;bukka
+せいか;seika
+くだもの;kudamono
+はたして;hatashite
+かこう;kakou
+ふぐ;fugu
+かば;kaba
+つうか;tsuuka
+かこけい;kakokei
+いいすぎ;iisugi
+がし;gashi
+ねんがじょう;nengajou
+しゅくがかい;shukugakai
+ふゆかい;fuyukai
+かいらく;kairaku
+かいかつ;kaikatsu
+かいせつ;kaisetsu
+りかい;rikai
+ぶんかい;bunkai
+しかく;shikaku
+せいかく;seikaku
+しょゆうかく;shoyuukaku
+せいかく;seikaku
+かくにん;kakunin
+かくじつ;kakujitsu
+きんがく;kingaku
+がくめん;gakumen
+ひたいぎわ;hitaigiwa
+かんこう;kankou
+にっかん;nikkan
+はっかん;hakkan
+かんせん;kansen
+かんぶ;kanbu
+かんじ;kanji
+かんれい;kanrei
+よなれた;yonareta
+かんげい;kangei
+かんらく;kanraku
+こうかん;koukan
+そうがんきょう;sougankyou
+にくがん;nikugan
+ちまなこ;chimanako
+きほん;kihon
+ききん;kikin
+きんし;kinshi
+きんえん;kin_en
+げんきん;genkin
+じく;jiku
+くぎり;kugiri
+もんく;monku
+くんよみ;kun_yomi
+くんれんし;kunrenshi
+きょうくんてき;kyoukunteki
+ぐんしゅう;gunshuu
+ぎょぐん;gyogun
+ぐんきょ;gunkyo
+けいざい;keizai
+けいせん;keisen
+けいか;keika
+けっぱく;keppaku
+けっぺき;keppeki
+いさぎよく;isagiyoku
+じけん;jiken
+ようけん;youken
+じょうけん;jouken
+りょけん;ryoken
+しょうけん;shouken
+ていきけん;teikiken
+けんあく;ken_aku
+ほけん;hoken
+けんそ;kenso
+けんとう;kentou
+たんけん;tanken
+けんさいん;kensain
+けんぷ;kenpu
+じんけん;jinken
+きぬもの;kinumono
+げんど;gendo
+げんかい;genkai
+むげん;mugen
+はつげん;hatsugen
+げんしょう;genshou
+げんじつ;genjitsu
+げんしょう;genshou
+かげん;kagen
+めべり;meberi
+こじ;koji
+こやまだし;koyamadashi
+こじん;kojin
+こせい;kosei
+いっこ;ikko
+べんごし;bengoshi
+ほご;hogo
+ごえい;goei
+こうか;kouka
+ゆうこう;yuukou
+ききめ;kikime
+ぶあつ;buatsu
+こうせい;kousei
+こうじょう;koujou
+こうち;kouchi
+こうさく;kousaku
+こううんき;kouunki
+こうぶつ;koubutsu
+こうせき;kouseki
+たんこう;tankou
+こうせい;kousei
+こころがまえ;kokorogamae
+こうぎ;kougi
+こうえん;kouen
+こうし;koushi
+こんけつ;konketsu
+こんらん;konran
+まぜもの;mazemono
+けんさ;kensa
+しんさ;shinsa
+さもん;samon
+さいせい;saisei
+さいかん;saikan
+さらいねん;sarainen
+さいなん;sainan
+さいがい;saigai
+かさい;kasai
+ごさい;gosai
+ふさい;fusai
+ひとづま;hitoduma
+さいよう;saiyou
+さいしゅう;saishuu
+さいしゅ;saishu
+じっさい;jissai
+まどぎわ;madogiwa
+そんざい;sonzai
+ざいりゅう;zairyuu
+ざいしょ;zaisho
+ざいさん;zaisan
+ざいだん;zaidan
+ざいせいてき;zaiseiteki
+はんざい;hanzai
+ざいあく;zaiaku
+つみぶかい;tsumibukai
+ざつだん;zatsudan
+ざつおん;zatsuon
+ぞうひょう;zouhyou
+さんぎょう;sangyou
+ようさん;yousan
+そらまめ;soramame
+さんそ;sanso
+さんせい;sansei
+えんさん;ensan
+さんせい;sansei
+さんびか;sanbika
+さんじ;sanji
+してん;shiten
+しじ;shiji
+してん;shiten
+いし;ishi
+しぼう;shibou
+ゆうし;yuushi
+きょうし;kyoushi
+しひょう;shihyou
+しだん;shidan
+しほん;shihon
+しりょう;shiryou
+しきん;shikin
+あんじ;anji
+てんじ;tenji
+しきょう;shikyou
+るいじひん;ruijihin
+えせ;ese
+にあう;niau
+こじ;koji
+しょうに;shouni
+じどうぶんがく;jidoubungaku
+じょうしき;joushiki
+いしき;ishiki
+ちしきじん;chishikijin
+ひんしつ;hinshitsu
+しちや;shichiya
+ひとじち;hitojichi
+しゅくしゃ;shukusha
+しゃえい;shaei
+いなかもの;inakamono
+しゃざい;shazai
+しゃれい;sharei
+かんしゃ;kansha
+じゅぎょう;jugyou
+じゅよ;juyo
+きょうじゅ;kyouju
+しゅうにゅう;shuunyuu
+しゅうえき;shuueki
+しゅうようりょく;shuuyouryoku
+しゅうり;shuuri
+しゅうせい;shuusei
+しゅうぎょう;shuugyou
+こうしゅう;koushuu
+たいしゅう;taishuu
+がっしゅうこく;gasshuukoku
+しゅくが;shukuga
+しゅくじ;shukuji
+いわいごと;iwaigoto
+ぜんじゅつ;zenjutsu
+じゅつご;jutsugo
+じょじゅつ;jojutsu
+ぎじゅつてき;gijutsuteki
+げいじゅつてき;geijutsuteki
+しゅじゅつ;shujutsu
+じゅんび;junbi
+すいじゅん;suijun
+じゅんけっしょう;junkesshou
+じょぶん;jobun
+じょれつ;joretsu
+じょすう;josuu
+じょきょ;jokyo
+めんじょ;menjo
+そうじ;souji
+しょうたい;shoutai
+しょうしゅう;shoushuu
+てまねく;temaneku
+しょうち;shouchi
+しょうにん;shounin
+けいしょうしゃ;keishousha
+しょうごう;shougou
+しょうさん;shousan
+めいしょう;meishou
+しょうにん;shounin
+ろんしょう;ronshou
+しょうめい;shoumei
+むじょうけん;mujouken
+じょうやく;jouyaku
+じょうてつ;joutetsu
+じょうたい;joutai
+げんじょう;genjou
+しょうたいじょう;shoutaijou
+ひじょう;hijou
+じょうれい;jourei
+にちじょう;nichijou
+どうじょう;doujou
+じょうせい;jousei
+なさけない;nasakenai
+しょっき;shokki
+そしきてき;soshikiteki
+おりもの;orimono
+しょくにん;shokunin
+しょくぎょう;shokugyou
+しょくいん;shokuin
+せいど;seido
+せいし;seishi
+きょうせい;kyousei
+だんせい;dansei
+せいてき;seiteki
+しょうぶん;shoubun
+ぎょうせい;gyousei
+せいじか;seijika
+ちゅうおうせいふ;chuuouseifu
+せいりょく;seiryoku
+せいみつ;seimitsu
+ぶしょう;bushou
+せいぞう;seizou
+せいせい;seisei
+にほんせい;nihonsei
+ぜいきん;zeikin
+ぜいむしょ;zeimusho
+しょとくぜい;shotokuzei
+せきにん;sekinin
+じせき;jiseki
+せきむ;sekimu
+せいせき;seiseki
+ぎょうせき;gyouseki
+ぼうせき;bouseki
+めんせつ;mensetsu
+せつぞく;setsuzoku
+つぎめ;tsugime
+せっち;secchi
+せっけい;sekkei
+せつりつ;setsuritsu
+ぜっせん;zessen
+したたらず;shitatarazu
+べんぜつ;benzetsu
+ぜつぼう;zetsubou
+ぜったいてき;zettaiteki
+たえず;taezu
+こぜに;kozeni
+きんせん;kinsen
+さいせん;saisen
+ぜんい;zen_i
+しんぜん;shinzen
+ぜんごさく;zengosaku
+そせん;sosen
+せんぞ;senzo
+そふぼ;sofubo
+げんそ;genso
+ようそ;youso
+すあし;suashi
+そうがく;sougaku
+そうごう;sougou
+そうりだいじん;souridaijin
+ぞうせん;zousen
+もくぞう;mokuzou
+じんぞう;jinzou
+そうぞう;souzou
+もくぞう;mokuzou
+げんぞう;genzou
+ぞうだい;zoudai
+ぞうぜい;zouzei
+ぞうふく;zoufuku
+きそくてき;kisokuteki
+ほうそく;housoku
+げんそく;gensoku
+そくてい;sokutei
+そくち;sokuchi
+はかりがたい;hakarigatai
+きんぞく;kinzoku
+ふぞく;fuzoku
+ぞくめい;zokumei
+そんしつ;sonshitsu
+そんがいだか;songaidaka
+いいそこない;iisokonai
+こうたい;koutai
+たいしょく;taishoku
+たいい;taii
+たいひ;taihi
+かしきん;kashikin
+かしや;kashiya
+たいど;taido
+たいせい;taisei
+わざわざ;wazawaza
+だんたい;dantai
+ふとん;futon
+だんけつ;danketsu
+せつだん;setsudan
+だんげん;dangen
+ことわりがき;kotowarigaki
+けんちく;kenchiku
+けんちくか;kenchikuka
+きずきなおす;kizukinaosu
+しゅちょう;shuchou
+かくちょう;kakuchou
+みはる;miharu
+ていしゅつ;teishutsu
+ぜんてい;zentei
+ちょうちん;chouchin
+ていど;teido
+かてい;katei
+ほどちかい;hodochikai
+てきとう;tekitou
+てきせい;tekisei
+てっき;tekki
+てきい;tekii
+むてき;muteki
+かたきうち;katakiuchi
+でんとう;dentou
+とうけい;toukei
+だいとうりょう;daitouryou
+どうぞう;douzou
+どうか;douka
+せいどう;seidou
+しどう;shidou
+しゅどうけん;shudouken
+でんどう;dendou
+とくちょう;tokuchou
+とくゆう;tokuyuu
+とくしょく;tokushoku
+とくてん;tokuten
+しょとく;shotoku
+ありうる;ariuru
+どうとく;doutoku
+とくぎ;tokugi
+とっくり;tokkuri
+どくえい;dokuei
+ひとりごと;hitorigoto
+どくりつ;dokuritsu
+にんめい;ninmei
+にんい;nin_i
+せきにんしゃ;sekininsha
+ねんりょう;nenryou
+ねんしょう;nenshou
+もえつく;moetsuku
+かのうせい;kanousei
+のうりょく;nouryoku
+のうめん;noumen
+はさん;hasan
+はそん;hason
+やぶれめ;yabureme
+はんにん;hannin
+はんい;han_i
+はんざいがく;hanzaigaku
+はんだん;handan
+はんじ;hanji
+はんこ;hanko
+しゅっぱんしゃ;shuppansha
+はんが;hanga
+はんけん;hanken
+ひれい;hirei
+ひかく;hikaku
+くらべもの;kurabemono
+ひりょう;hiryou
+ひまん;himan
+こえつち;koetsuchi
+ひにん;hinin
+ひごうりてき;higouriteki
+ひこう;hikou
+せつび;setsubi
+じゅんびちゅう;junbichuu
+そなえつけ;sonaetsuke
+いっぴょう;ippyou
+こめだわら;komedawara
+どひょう;dohyou
+ひょうか;hyouka
+ひょうばん;hyouban
+あくひょう;akuhyou
+ひんけつ;hinketsu
+ひんこん;hinkon
+びんぼうじん;binboujin
+はいふ;haifu
+もうふ;moufu
+ぬのじ;nunoji
+ふじん;fujin
+しゅふ;shufu
+ふちょう;fuchou
+ふゆう;fuyuu
+とみくじ;tomikuji
+ふじさん;fujisan
+ぶしどう;bushidou
+ぶき;buki
+むしゃ;musha
+ふっかつ;fukkatsu
+かいふく;kaifuku
+ちょうふく;choufuku
+ふくせい;fukusei
+ぶっきょう;bukkyou
+じょうぶつ;joubutsu
+のどぼとけ;nodobotoke
+へんしゅうしゃ;henshuusha
+へんせい;hensei
+あみもの;amimono
+べんとう;bentou
+べんろん;benron
+べんまく;benmaku
+かくほ;kakuho
+ほぞん;hozon
+せいめいほけん;seimeihoken
+ぼち;bochi
+ぼひょう;bohyou
+はかまいり;hakamairi
+ほうこく;houkoku
+でんぽう;denpou
+ほうしゅう;houshuu
+ほうさく;housaku
+ほうふ;houfu
+ほうまん;houman
+よぼう;yobou
+ぼうすい;bousui
+ぼうえい;bouei
+ぼうえきぎょう;bouekigyou
+ぼうえきふう;bouekifuu
+ぼうえきしゃ;bouekisha
+ぼうりょく;bouryoku
+ばくろ;bakuro
+あばれもの;abaremono
+みらい;mirai
+みち;michi
+まだまだ;madamada
+ぎむ;gimu
+じむしょ;jimusho
+しょくむ;shokumu
+むりょう;muryou
+ぶじ;buji
+めいろ;meiro
+めいむ;meimu
+まよいご;mayoigo
+もめん;momen
+わたげ;watage
+わたがし;watagashi
+ゆしゅつ;yushutsu
+ゆそう;yusou
+うんゆ;un_yu
+よぶん;yobun
+よけい;yokei
+ごじゅうあまり;gojuuamari
+よきん;yokin
+あずかりにん;azukarinin
+あずかりしょう;azukarishou
+びよういん;biyouin
+ないよう;naiyou
+けいようし;keiyoushi
+のうりつ;nouritsu
+とうそつ;tousotsu
+ぜいりつ;zeiritsu
+りゃくご;ryakugo
+りゃくせつ;ryakusetsu
+りゃくず;ryakuzu
+るすばん;rusuban
+とめがね;tomegane
+りょうじ;ryouji
+りょうど;ryoudo
+ようりょう;youryou
+いよう;iyou
+いじょう;ijou
+いじん;ijin
+いでん;iden
+いしつ;ishitsu
+ゆいごん;yuigon
+りょういき;ryouiki
+ちいき;chiiki
+くいき;kuiki
+いちまんえん;ichiman_en
+いっせん;issen
+にじゅういち;nijuuichi
+うちゅう;uchuu
+どうう;douu
+うちょうてん;uchouten
+うもう;umou
+はおり;haori
+いちわ;ichiwa
+えいがかん;eigakan
+はんえい;han_ei
+ゆうばえ;yuubae
+えんちょう;enchou
+えんき;enki
+のびのび;nobinobi
+えんがん;engan
+えんどう;endou
+えんせん;ensen
+かのう;kanou
+かけつ;kaketsu
+いうべき;iubeki
+じが;jiga
+わがまま;wagamama
+われわれ;wareware
+せっかい;sekkai
+はいいろ;haiiro
+かざんばい;kazanbai
+しがい;shigai
+かいどう;kaidou
+きゅうけつき;kyuuketsuki
+すいとる;suitoru
+きゅうそ;kyuuso
+なきむし;nakimushi
+なきだす;nakidasu
+ていきょう;teikyou
+ともまわり;tomomawari
+くよう;kuyou
+きょうぶ;kyoubu
+むなげ;munage
+どきょう;dokyou
+ぼうきょう;boukyou
+ごうし;goushi
+きょうど;kyoudo
+しゅっきん;shukkin
+きんべんせい;kinbensei
+つとめさき;tsutomesaki
+きんにく;kinniku
+すじみち;sujimichi
+すじがき;sujigaki
+かけい;kakei
+けいとう;keitou
+けいれつ;keiretsu
+ちょっけい;chokkei
+しょうけい;shoukei
+ちょくじょうけいこう;chokujoukeikou
+そんけい;sonkei
+けいご;keigo
+いけい;ikei
+けいかん;keikan
+けいこく;keikoku
+けいほう;keihou
+げきじょう;gekijou
+げきてき;gekiteki
+げきつう;gekitsuu
+けっきょじん;kekkyojin
+あなご;anago
+あなうめ;anaume
+けんぎょう;kengyou
+けんよう;ken_you
+しかねる;shikaneru
+けんり;kenri
+けんこう;kenkou
+ごんげ;gonge
+けんぽう;kenpou
+けんしょう;kenshou
+けんぺい;kenpei
+しげん;shigen
+げんせん;gensen
+げんじ;genji
+げんかく;genkaku
+げんぴ;genpi
+そうごん;sougon
+じこ;jiko
+ちき;chiki
+りこ;riko
+こきゅう;kokyuu
+てんこ;tenko
+よびもの;yobimono
+ごかい;gokai
+ごはん;gohan
+ごやく;goyaku
+こうごう;kougou
+こうひ;kouhi
+ごご;gogo
+こうい;koui
+こうだんし;koudanshi
+こうし;koushi
+こうこう;koukou
+ふこう;fukou
+こうたいし;koutaishi
+ほうおう;houou
+めいじてんのう;meijitennou
+こうよう;kouyou
+しんく;shinku
+こうちゃ;koucha
+こうう;kouu
+こうふく;koufuku
+のりおり;noriori
+こうてつ;koutetsu
+せいこうじょ;seikoujo
+はがねいろ;haganeiro
+じこく;jikoku
+こくいん;kokuin
+きざみめ;kizamime
+こくもつ;kokumotsu
+こくるい;kokurui
+こくそう;kokusou
+こっせつ;kossetsu
+ろうこつ;roukotsu
+ほねおる;honeoru
+こんなん;konnan
+こんく;konku
+こまらせる;komaraseru
+さきん;sakin
+じゃり;jari
+すなはま;sunahama
+ざせき;zaseki
+ざだんかい;zadankai
+ぎんざ;ginza
+けいざいがく;keizaigaku
+へんさい;hensai
+すまない;sumanai
+さいばん;saiban
+たちくず;tachikuzu
+たちかた;tachikata
+せいさく;seisaku
+たいさく;taisaku
+さくどうか;sakudouka
+さっし;sasshi
+にさつ;nisatsu
+たんざく;tanzaku
+しきゅう;shikyuu
+げし;geshi
+いたらない;itaranai
+しりつ;shiritsu
+わたしたち;watashitachi
+しじ;shiji
+しせい;shisei
+ようし;youshi
+すがたみ;sugatami
+しりょく;shiryoku
+しかく;shikaku
+どうし;doushi
+ことばがき;kotobagaki
+ほんし;honshi
+しゅうかんし;shuukanshi
+じしゃく;jishaku
+じき;jiki
+じりょく;jiryoku
+ちゅうしゃき;chuushaki
+いたおす;itaosu
+しゃげきじょう;shagekijou
+きしゃ;kisha
+すてご;sutego
+すておく;suteoku
+しゃくど;shakudo
+しゃくはち;shakuhachi
+せきち;sekichi
+かいしゃく;kaishaku
+しゃくほう;shakuhou
+しゃくめい;shakumei
+じゃくねん;jakunen
+もしくは;moshikuha
+わかもの;wakamono
+じゅよう;juyou
+ひつじゅひん;hitsujuhin
+じゅきゅう;jukyuu
+じゅし;jushi
+じゅりつ;juritsu
+じゅひ;juhi
+しゅうきょう;shuukyou
+そうけ;souke
+しゅうは;shuuha
+じょうじゅ;jouju
+について;nitsuite
+しゅうしょく;shuushoku
+じゅうぎょういん;juugyouin
+じゅうしゃ;juusha
+したがって;shitagatte
+じゅうせん;juusen
+ほうじゅう;houjuu
+たてがき;tategaki
+しゅくしょう;shukushou
+たんしゅく;tanshuku
+ちぢみどめ;chidimidome
+せいじゅく;seijuku
+はんじゅく;hanjuku
+じゅくれん;jukuren
+じゅんすい;junsui
+じゅんもう;junmou
+じゅんえき;jun_eki
+しょり;shori
+しょち;shochi
+しょしょ;shosho
+しょめい;shomei
+しょいん;shoin
+けいさつしょ;keisatsusho
+しょとう;shotou
+しょくん;shokun
+もろて;morote
+しょうらい;shourai
+しょうぐん;shougun
+まさに;masani
+くしょう;kushou
+わらいごえ;waraigoe
+えがお;egao
+ししょうしゃ;shishousha
+しょうがい;shougai
+きずつける;kizutsukeru
+しょうがい;shougai
+しょうじ;shouji
+さしさわる;sashisawaru
+じょうかまち;joukamachi
+ひめじじょう;himejijou
+しろあと;shiroato
+じょうき;jouki
+じょうりゅう;jouryuu
+むしあつい;mushiatsui
+ほうしん;houshin
+しんろ;shinro
+はりがね;harigane
+じんあい;jin_ai
+じんしゃ;jinsha
+におう;niou
+すいちょく;suichoku
+あまだれ;amadare
+たれかざり;tarekazari
+すいり;suiri
+すいせんしゃ;suisensha
+すいしんき;suishinki
+すんぽう;sunpou
+いっすん;issun
+すんぶん;sunbun
+ぜせい;zesei
+これら;korera
+せいしょ;seisho
+せいじん;seijin
+しんせい;shinsei
+せいい;seii
+せいじつ;seijitsu
+まことに;makotoni
+せんでん;senden
+せんこく;senkoku
+せんきょうし;senkyoushi
+せんもん;senmon
+せんよう;sen_you
+せんせい;sensei
+おんせんじょう;onsenjou
+せんすい;sensui
+ひせん;hisen
+せんれい;senrei
+てあらい;tearai
+せんしょく;senshoku
+そめもの;somemono
+しみこむ;shimikomu
+ばんそう;bansou
+そうがくどう;sougakudou
+そうじょう;soujou
+まどぐち;madoguchi
+でまど;demado
+どうそうかい;dousoukai
+そうぞう;souzou
+そうりつしゃ;souritsusha
+そうい;soui
+かそう;kasou
+そううん;souun
+こうそうびる;kousoubiru
+そうじゅうし;soujuushi
+せっそう;sessou
+あやつりにんぎょう;ayatsuriningyou
+ぞうしょ;zousho
+ぞうとく;zoutoku
+さかぐら;sakagura
+ぞうき;zouki
+ないぞう;naizou
+しんぞうがく;shinzougaku
+ぞくご;zokugo
+ぞっか;zokka
+ふうぞく;fuuzoku
+せいぞん;seizon
+ぞんじより;zonjiyori
+そんざいしゃ;sonzaisha
+そんちょう;sonchou
+そんのうか;sonnouka
+そんりょ;sonryo
+じたく;jitaku
+たくち;takuchi
+たんとう;tantou
+にないしょうにん;ninaishounin
+がくしゅうふたん;gakushuufutan
+たんち;tanchi
+たんきゅうしゃ;tankyuusha
+さぐりだす;saguridasu
+だんかい;dankai
+まわりかいだん;mawarikaidan
+てんらんかい;tenrankai
+てんぼう;tenbou
+とうぎ;tougi
+うちいる;uchiiru
+とうばつぐん;toubatsugun
+せいとう;seitou
+ろうどうとう;roudoutou
+とうは;touha
+さとう;satou
+とうい;toui
+とうぶん;toubun
+とどけしょ;todokesho
+とどけでる;todokederu
+ゆきとどく;yukitodoku
+なんみん;nanmin
+なんぎ;nangi
+みがたい;migatai
+にまんえん;niman_en
+にじゅう;nijuu
+にせん;nisen
+ぎゅうにゅう;gyuunyuu
+にゅうさん;nyuusan
+にゅうぼう;nyuubou
+にんしき;ninshiki
+にんか;ninka
+みとめいん;mitomein
+のうぜい;nouzei
+なや;naya
+すいとうぼ;suitoubo
+ずのう;zunou
+しゅのう;shunou
+のうしょうがい;noushougai
+はけん;haken
+たなかは;tanakaha
+れいはい;reihai
+はいぐ;haigu
+はいご;haigo
+せなか;senaka
+はいしん;haishin
+はいびょう;haibyou
+はいえん;haien
+はいぞう;haizou
+はいゆう;haiyuu
+はいく;haiku
+はいじん;haijin
+はんちょう;hanchou
+きゅうごはん;kyuugohan
+はんでん;handen
+ばんめし;banmeshi
+ばんか;banka
+こんばん;konban
+ひにん;hinin
+ひていご;hiteigo
+いなめない;inamenai
+ひはん;hihan
+ひひょう;hihyou
+ひじゅん;hijun
+ひみつ;himitsu
+ごくひ;gokuhi
+ひしょ;hisho
+ふくぶ;fukubu
+はらだち;haradachi
+ちゅうふく;chuufuku
+ふんき;funki
+ふんとう;funtou
+ふるいたつ;furuitatsu
+へいか;heika
+へいけん;heiken
+てんおうへいか;ten_ouheika
+へいてん;heiten
+へいこう;heikou
+しめだす;shimedasu
+だんぺん;danpen
+かたて;katate
+かたづける;katadukeru
+ほじょ;hojo
+ほじゅう;hojuu
+ほきょう;hokyou
+ほうせき;houseki
+ざいほう;zaihou
+こだから;kodakara
+ほうもん;houmon
+らいほうしゃ;raihousha
+たんぼう;tanbou
+しぼう;shibou
+もうじゃ;mouja
+ぼうめい;boumei
+ぼうきゃく;boukyaku
+ぼうおん;bouon
+わすれがち;wasuregachi
+しんぼう;shinbou
+ぼうぐらふ;bougurafu
+ぼうべに;boubeni
+いちまい;ichimai
+にまいじた;nimaijita
+にまいがい;nimaigai
+てんまく;tenmaku
+かいまく;kaimaku
+ばくふ;bakufu
+みつど;mitsudo
+みつゆ;mitsuyu
+めんみつ;menmitsu
+れんめい;renmei
+どうめい;doumei
+かめい;kamei
+もけい;mokei
+もしゃ;mosha
+きぼ;kibo
+やさき;yasaki
+やじるし;yajirushi
+いっし;isshi
+ほんやく;hon_yaku
+つうやく;tsuuyaku
+いいわけ;iiwake
+ゆうびん;yuubin
+ゆうそう;yuusou
+ゆうてい;yuutei
+ゆうしゅう;yuushuu
+ゆうせん;yuusen
+じょゆう;joyuu
+ようじ;youji
+おさなご;osanago
+ようひ;youhi
+ようすい;yousui
+ひつじかい;hitsujikai
+よくぼう;yokubou
+しょくよく;shokuyoku
+ものほしげ;monohoshige
+よくじつ;yokujitsu
+よくちょう;yokuchou
+よくよくねん;yokuyokunen
+らんぼう;ranbou
+はんらん;hanran
+みだれあし;midareashi
+らんおう;ran_ou
+さんらん;sanran
+なまたまご;namatamago
+ごらん;goran
+かいらん;kairan
+かんらん;kanran
+りめん;rimen
+うらけ;urake
+うらづける;uradukeru
+きりつ;kiritsu
+りちぎ;richigi
+りんじ;rinji
+りんかい;rinkai
+りんせき;rinseki
+めいろう;meirou
+ろうほう;rouhou
+ろうどくほう;roudokuhou
+ろんぶん;ronbun
+りろん;riron
+ろんり;ronri
+あねったい;anettai
+おうあ;oua
+ありゅう;aryuu
+ひあい;hiai
+あいか;aika
+もののあわれ;mononoaware
+あくしゅ;akushu
+にぎりや;nigiriya
+にぎりめし;nigirimeshi
+とりあつかい;toriatsukai
+こきつかう;kokitsukau
+きゃくあつかい;kyakuatsukai
+いらい;irai
+いぜん;izen
+えこじ;ekoji
+いりょく;iryoku
+いげん;igen
+おどしもんく;odoshimonku
+こうい;koui
+ためすじ;tamesuji
+しすぎる;shisugiru
+たいい;taii
+しょうい;shoui
+いかん;ikan
+いだい;idai
+いじん;ijin
+えらぶつ;erabutsu
+そうい;soui
+いはん;ihan
+いいちがい;iichigai
+いじ;iji
+いしん;ishin
+せんい;sen_i
+いもん;imon
+いあん;ian
+なぐさみもの;nagusamimono
+いど;ido
+けいいぎ;keiigi
+ぬきいと;nukiito
+いっぴん;ippin
+それや;soreya
+いっしゅつ;isshutsu
+さといも;satoimo
+いもがい;imogai
+やきいも;yakiimo
+こんいん;kon_in
+いんせき;inseki
+いんぞくばつ;inzokubatsu
+いんき;inki
+いんぶ;inbu
+かげぐち;kageguchi
+いんきょ;inkyo
+いんじゃ;inja
+かくれが;kakurega
+いんぶん;inbun
+いんりつ;inritsu
+おんいん;on_in
+えいか;eika
+えいそう;eisou
+えいし;eishi
+えいきょう;eikyou
+えいぞう;eizou
+かげむしゃ;kagemusha
+えいり;eiri
+えいかく;eikaku
+せいえい;seiei
+ぼうえき;boueki
+あくえき;akueki
+やくびょう;yakubyou
+きえつ;kietsu
+えつらく;etsuraku
+まんえつ;man_etsu
+ゆうえつ;yuuetsu
+えっきょう;ekkyou
+おいこす;oikosu
+はいえつ;haietsu
+えっけん;ekken
+えっけんしつ;ekkenshitsu
+えっぺい;eppei
+けんえつ;ken_etsu
+えつらんしつ;etsuranshitsu
+かえん;kaen
+のうえん;nouen
+えんてん;enten
+えんかい;enkai
+えんらく;enraku
+しゅえん;shuen
+えんじょ;enjo
+おうえん;ouen
+せいえん;seien
+えんとつ;entotsu
+きんえん;kin_en
+たばこ;tabako
+るいじんえん;ruijin_en
+やえん;yaen
+さるまねや;sarumaneya
+あえん;aen
+こくえん;kokuen
+えんぴついれ;enpitsuire
+えんがわ;engawa
+ふちぬい;fuchinui
+えんだん;endan
+おせん;osen
+おしょく;oshoku
+よごれもの;yogoremono
+おうめん;oumen
+くぼち;kubochi
+へこみ;hekomi
+おうしゅう;oushuu
+おしいれ;oshiire
+ておしぐるま;teoshiguruma
+おうしゅう;oushuu
+おうべい;oubei
+おうしかん;oushikan
+おうだ;ouda
+なぐりこみ;nagurikomi
+なぐりあう;naguriau
+おうとう;outou
+さくらいろ;sakurairo
+さくらにく;sakuraniku
+ろうおう;rouou
+そんおう;son_ou
+げんおきな;gen_okina
+おくそこ;okusoko
+おくさま;okusama
+おくぎ;okugi
+きおく;kioku
+ついおく;tsuioku
+おくそく;okusoku
+ゆうぐ;yuugu
+ふぐ;fugu
+ぐびじんそう;gubijinsou
+おつしゅ;otsushu
+おとめ;otome
+おつに;otsuni
+おろしうり;oroshiuri
+おろししょう;oroshishou
+おろしだいこん;oroshidaikon
+おんわ;onwa
+おんとう;ontou
+へいおん;heion
+かじん;kajin
+ぜっか;zekka
+かさく;kasaku
+かどうきょう;kadoukyou
+しょか;shoka
+かくう;kakuu
+かび;kabi
+ちゅうか;chuuka
+はなばなしい;hanabanashii
+せいか;seika
+みずがし;mizugashi
+うずまき;uzumaki
+かせん;kasen
+かちゅう;kachuu
+はなよめ;hanayome
+かし;kashi
+てんか;tenka
+きゅうか;kyuuka
+よか;yoka
+ひまどる;himadoru
+かふく;kafuku
+さいか;saika
+かこん;kakon
+せいか;seika
+くつした;kutsushita
+ながぐつ;nagagutsu
+かもく;kamoku
+かふ;kafu
+かげん;kagen
+かじょうがき;kajougaki
+かしょ;kasho
+いっこ;ikko
+かぎょう;kagyou
+かせぎて;kasegite
+ともかせぎ;tomokasegi
+かばり;kabari
+ががんぼ;gaganbo
+かやりび;kayaribi
+ゆうが;yuuga
+がごう;gagou
+がしゅ;gashu
+きが;kiga
+がき;gaki
+がし;gashi
+かいにゅう;kainyuu
+かいかく;kaikaku
+じこしょうかい;jikoshoukai
+けいかい;keikai
+かいりつ;kairitsu
+かいぎょう;kaigyou
+かいだん;kaidan
+かいぶつ;kaibutsu
+あやしげ;ayashige
+かいたいしゃ;kaitaisha
+ゆうかい;yuukai
+かいじょう;kaijou
+こうかい;koukai
+くやしさ;kuyashisa
+くやみじょう;kuyamijou
+かいさい;kaisai
+かいむ;kaimu
+みなさま;minasama
+きんかい;kinkai
+かいこう;kaikou
+さんかい;sankai
+はかい;hakai
+かいめつ;kaimetsu
+かいけつびょう;kaiketsubyou
+かいちゅう;kaichuu
+ふところで;futokorode
+じゅっかい;jukkai
+だんがいしゃ;dangaisha
+だんがい;dangai
+がいそう;gaisou
+しょうがい;shougai
+さいがい;saigai
+てんがい;tengai
+がいたん;gaitan
+かんがい;kangai
+がいぜん;gaizen
+がいとう;gaitou
+とうがい;tougai
+がいはく;gaihaku
+がいねん;gainen
+がいりゃく;gairyaku
+たいがい;taigai
+かきね;kakine
+いけがき;ikegaki
+かいまみる;kaimamiru
+かくしん;kakushin
+けっかく;kekkaku
+かくへいき;kakuheiki
+かいがら;kaigara
+こうかく;koukaku
+ちかく;chikaku
+りんかく;rinkaku
+じょうかく;joukaku
+ゆうかく;yuukaku
+ひかく;hikaku
+こうりょう;kouryou
+たいこう;taikou
+かくり;kakuri
+かんかく;kankaku
+かくしゅう;kakushuu
+かくとく;kakutoku
+ぎょかく;gyokaku
+えもの;emono
+いかく;ikaku
+かくど;kakudo
+いかくてき;ikakuteki
+しゅうかく;shuukaku
+たかく;takaku
+しゅうかくだか;shuukakudaka
+さんがく;sangaku
+がくふ;gakufu
+うんぜんだけ;unzendake
+かかりびと;kakaribito
+みかけ;mikake
+こしかける;koshikakeru
+ひがた;higata
+せきこ;sekiko
+にいがたし;niigatashi
+いっかつ;ikkatsu
+かっこ;kakko
+ほうかつてき;houkatsuteki
+かっさい;kassai
+きょうかつ;kyoukatsu
+いっかつ;ikkatsu
+かっすい;kassui
+かつぼう;katsubou
+かわき;kawaki
+えんかつ;enkatsu
+かっそうろ;kassouro
+すべりやすい;suberiyasui
+かっしょく;kasshoku
+かったん;kattan
+かっぷ;kappu
+しょかつ;shokatsu
+かんかつ;kankatsu
+とうかつ;toukatsu
+かつまた;katsumata
+かつ;katsu
+こうしょ;kousho
+かりいれ;kariire
+かりこむ;karikomu
+くさかりき;kusakariki
+あまざけ;amazake
+かんげん;kangen
+あまえ;amae
+はっかん;hakkan
+かんがん;kangan
+あせみず;asemizu
+かんづめ;kandume
+かんきり;kankiri
+きかん;kikan
+かんぞう;kanzou
+かんじん;kanjin
+きもったま;kimottama
+おうかん;oukan
+えいかん;eikan
+かんもう;kanmou
+かんぼつ;kanbotsu
+けっかん;kekkan
+かんらく;kanraku
+かんでんち;kandenchi
+かんそうき;kansouki
+かわいた;kawaita
+かんべん;kanben
+かんじょう;kanjou
+かんちがい;kanchigai
+かんじゃ;kanja
+かんぶ;kanbu
+ながわずらい;nagawazurai
+かんつう;kantsuu
+じゅうかん;juukan
+かんりゅう;kanryuu
+かんもん;kanmon
+きょうかん;kyoukan
+わめきごえ;wamekigoe
+かんにん;kannin
+たんのう;tannou
+たえがたい;taegatai
+かんき;kanki
+かえぎ;kaegi
+こうかんがくせい;koukangakusei
+ゆうかん;yuukan
+かんぜん;kanzen
+あえなく;aenaku
+かんおけ;kan_oke
+せっかん;sekkan
+ひつぎだい;hitsugidai
+しゃっかん;shakkan
+らっかん;rakkan
+かんたい;kantai
+かんせい;kansei
+かんさん;kansan
+かんじん;kanjin
+かんだい;kandai
+かんよう;kan_you
+かんい;kan_i
+かんし;kanshi
+そうかん;soukan
+かんきん;kankin
+かんわ;kanwa
+かんりゅう;kanryuu
+ゆるゆる;yuruyuru
+いかん;ikan
+かんこん;kankon
+うらみ;urami
+かんげん;kangen
+せいかんしゃ;seikansha
+へんかん;henkan
+ゆびわ;yubiwa
+かんじょうせん;kanjousen
+かんきょう;kankyou
+ぐんかん;gunkan
+かんたい;kantai
+かんしゅ;kanshu
+ねんかん;nenkan
+かんしょう;kanshou
+かんがみて;kangamite
+ほうがん;hougan
+がんゆうりょう;gan_yuuryou
+ふくめて;fukumete
+がんこ;ganko
+がんけん;ganken
+きぎょう;kigyou
+きかく;kikaku
+くわだて;kuwadate
+きろ;kiro
+ぶんき;bunki
+たき;taki
+きちゅう;kichuu
+きんき;kinki
+いみきらう;imikirau
+きすう;kisuu
+しんき;shinki
+きけい;kikei
+きねん;kinen
+きとう;kitou
+いのりあう;inoriau
+きどう;kidou
+むきどう;mukidou
+じょうき;jouki
+きせい;kisei
+きこん;kikon
+きてい;kitei
+きかん;kikan
+うえじに;uejini
+きがこうしん;kigakoushin
+きかい;kikai
+きせき;kiseki
+おにごっこ;onigokko
+きかがく;kikagaku
+きし;kishi
+しょうぎ;shougi
+きてき;kiteki
+ほうき;houki
+きけん;kiken
+きじ;kiji
+こうき;kouki
+きせき;kiseki
+かがやき;kagayaki
+きし;kishi
+きへい;kihei
+いっきうち;ikkiuchi
+てきぎ;tekigi
+べんぎ;bengi
+よろしく;yoroshiku
+にせもの;nisemono
+ぎぜん;gizen
+いつわりもの;itsuwarimono
+さぎ;sagi
+ぎまん;giman
+あざむきとる;azamukitoru
+ぎしき;gishiki
+ぎてん;giten
+れいぎ;reigi
+ゆうぎてき;yuugiteki
+ぎが;giga
+たわごと;tawagoto
+もぎ;mogi
+ぎせい;gisei
+ぎせいご;giseigo
+ぎせい;gisei
+ぎだ;gida
+ぎせいせいど;giseiseido
+のぎく;nogiku
+きっか;kikka
+きくばん;kikuban
+きちにち;kichinichi
+きっぽう;kippou
+ふきつ;fukitsu
+きつえん;kitsuen
+きっすいせん;kissuisen
+きつもん;kitsumon
+つまり;tsumari
+つめこむ;tsumekomu
+きゃっか;kyakka
+たいきゃく;taikyaku
+さて;sate
+きゃっか;kyakka
+きゃたつ;kyatatsu
+あしに;ashini
+ぎゃくさつ;gyakusatsu
+ぎゃくたい;gyakutai
+ざんぎゃく;zangyaku
+きゅうだいてん;kyuudaiten
+ついきゅう;tsuikyuu
+およびごし;oyobigoshi
+さきゅう;sakyuu
+きゅうしん;kyuushin
+おかべ;okabe
+ろうきゅう;roukyuu
+ふきゅう;fukyuu
+くちば;kuchiba
+ふんきゅう;funkyuu
+きゅうだん;kyuudan
+きゅうめい;kyuumei
+きゅうきょく;kyuukyoku
+きゅうきょう;kyuukyou
+きゅうくつ;kyuukutsu
+きょじん;kyojin
+きょだい;kyodai
+きょひ;kyohi
+きょぜつ;kyozetsu
+きょひ;kyohi
+きょし;kyoshi
+こんきょ;konkyo
+しょうこ;shouko
+よりどころ;yoridokoro
+きょぎ;kyogi
+こくう;kokuu
+きょむしゅぎ;kyomushugi
+きょり;kyori
+きょこつ;kyokotsu
+そっきょぎ;sokkyogi
+ぎょしゃ;gyosha
+ごよう;goyou
+おんちゅう;onchuu
+きょうあく;kyouaku
+きょうさく;kyousaku
+きっきょう;kikkyou
+ぜっきょう;zekkyou
+さけびごえ;sakebigoe
+さけびだす;sakebidasu
+きょうじん;kyoujin
+きょうげん;kyougen
+くるった;kurutta
+きょうじゅしゃ;kyoujusha
+きょうゆう;kyouyuu
+きょうらく;kyouraku
+じょうきょう;joukyou
+じっきょう;jikkyou
+いわんや;iwan_ya
+きょうこく;kyoukoku
+ちきょう;chikyou
+かいきょう;kaikyou
+きょうげき;kyougeki
+いたばさみ;itabasami
+はさみむし;hasamimushi
+きょうぎ;kyougi
+こうきょう;koukyou
+せまくるしい;semakurushii
+きょうふ;kyoufu
+きょうえいびょう;kyoueibyou
+おそれいる;osoreiru
+きょうじゅん;kyoujun
+きょうけい;kyoukei
+きょうけん;kyouken
+きょうはく;kyouhaku
+きょうい;kyoui
+おどかして;odokashite
+きょうせいてき;kyouseiteki
+ききょう;kikyou
+ためなおす;tamenaosu
+ひびきわたる;hibikiwataru
+あくえいきょう;akueikyou
+こうきょうきょく;koukyoukyoku
+きょうい;kyoui
+きょうがく;kyougaku
+おどろくべき;odorokubeki
+ぎょうてん;gyouten
+しんこう;shinkou
+おおせだす;oosedasu
+ぎょうてん;gyouten
+つうぎょう;tsuugyou
+ぎょうせい;gyousei
+ぎょうし;gyoushi
+こりしょう;korishou
+こった;kotta
+きんりょう;kinryou
+きんめ;kinme
+ふきん;fukin
+さいきん;saikin
+きんるい;kinrui
+ほきんしゃ;hokinsha
+てふうきん;tefuukin
+きんせん;kinsen
+ことづめ;kotodume
+きんちょう;kinchou
+きんきゅう;kinkyuu
+きんみつ;kinmitsu
+きんげん;kingen
+きんけい;kinkei
+つつしんで;tsutsushinde
+きょうきん;kyoukin
+きんど;kindo
+えりくび;erikubi
+ぎんえい;gin_ei
+ぎんみ;ginmi
+ぎんゆうしじん;gin_yuushijin
+せんくしゃ;senkusha
+かりだす;karidasu
+かけおち;kakeochi
+ぐじん;gujin
+ぐずる;guzuru
+ぐこう;gukou
+ぐうぜん;guuzen
+ぐうぞう;guuzou
+はいぐうしゃ;haiguusha
+きぐう;kiguu
+たいぐう;taiguu
+ふぐう;fuguu
+いちぐう;ichiguu
+すみいし;sumiishi
+かたすみ;katasumi
+くっぷく;kuppuku
+ふくつ;fukutsu
+くっせつ;kussetsu
+はっくつ;hakkutsu
+ほりだす;horidasu
+さいくつ;saikutsu
+くりいと;kuriito
+くりこす;kurikosu
+くりかえす;kurikaesu
+くんしょう;kunshou
+しゅくん;shukun
+くんい;kun_i
+くんこう;kunkou
+くんいく;kun_iku
+くんぷう;kunpuu
+しょけい;shokei
+しけい;shikei
+けいじ;keiji
+きゅうけい;kyuukei
+ちかけい;chikakei
+はぐき;haguki
+けいやく;keiyaku
+けいき;keiki
+けいいん;keiin
+けいよ;keiyo
+ちえ;chie
+めぐみぶかい;megumibukai
+けいはつ;keihatsu
+けいじ;keiji
+はいけい;haikei
+けいじばん;keijiban
+ぜんけい;zenkei
+けいよう;keiyou
+けいこく;keikoku
+せっけい;sekkei
+けいりゅう;keiryuu
+けいこう;keikou
+けいせつ;keisetsu
+ほたるがり;hotarugari
+けいこう;keikou
+けいとう;keitou
+けいしゃど;keishado
+けいたい;keitai
+ていけい;teikei
+ひっけい;hikkei
+けいぞく;keizoku
+ままこ;mamako
+つぎたし;tsugitashi
+けいしゅく;keishuku
+けいじ;keiji
+けいが;keiga
+きゅうけい;kyuukei
+しょうけい;shoukei
+いこい;ikoi
+けいらん;keiran
+けいしゃ;keisha
+けいめい;keimei
+かんげいかい;kangeikai
+げいごう;geigou
+むかえざけ;mukaezake
+げいゆ;geiyu
+ほげい;hogei
+ざとうくじら;zatoukujira
+そげき;sogeki
+こうげき;kougeki
+はやうち;hayauchi
+かんげき;kangeki
+げっか;gekka
+はげしさ;hageshisa
+けっし;kesshi
+けっしゅつ;kesshutsu
+けっさく;kessaku
+けんしょう;kenshou
+ひけん;hiken
+かたがき;katagaki
+けんやく;ken_yaku
+せっけん;sekken
+きんけん;kinken
+けんどう;kendou
+けんぶ;kenbu
+たんけん;tanken
+いっけん;ikken
+けんとう;kentou
+のきさき;nokisaki
+せいそうけん;seisouken
+けんがい;kengai
+きょうさんけん;kyousanken
+けんじつ;kenjitsu
+けんご;kengo
+ちゅうけん;chuuken
+けんお;ken_o
+きげん;kigen
+いやいや;iyaiya
+けんじょう;kenjou
+こんだて;kondate
+けんしん;kenshin
+はけん;haken
+こづかい;kodukai
+やりなおす;yarinaosu
+けんじゃ;kenja
+けんめい;kenmei
+かしこだて;kashikodate
+けんそん;kenson
+けんきょ;kenkyo
+けんじょう;kenjou
+けんちゅう;kenchuu
+おおまゆ;oomayu
+からまゆ;karamayu
+けんちょ;kencho
+けんよう;ken_you
+けんびきょう;kenbikyou
+けんめい;kenmei
+けねん;kenen
+いのちがけ;inochigake
+げんそう;gensou
+げんぞう;genzou
+げんじゅつ;genjutsu
+げんみょう;genmyou
+げんかん;genkan
+くろうと;kurouto
+せいげん;seigen
+ゆみづる;yumiduru
+げんがっき;gengakki
+こじいん;kojiin
+こどく;kodoku
+こりつ;koritsu
+こけい;kokei
+こじょう;kojou
+ことう;kotou
+こし;koshi
+ふゆがれ;fuyugare
+かれは;kareha
+こよう;koyou
+やといにん;yatoinin
+かいこ;kaiko
+こだい;kodai
+こじ;koji
+ほこりがお;hokorigao
+こどう;kodou
+たいこ;taiko
+こつづみ;kotsudumi
+こりょ;koryo
+かいこ;kaiko
+こもん;komon
+そうご;sougo
+ごじょ;gojo
+たがいちがい;tagaichigai
+ごふく;gofuku
+くれぐれも;kureguremo
+くれて;kurete
+ごらく;goraku
+かんご;kango
+ごらくひん;gorakuhin
+ごせい;gosei
+かくご;kakugo
+さとり;satori
+ごいし;goishi
+ごばん;goban
+ごうち;gouchi
+びこう;bikou
+きこう;kikou
+こうし;koushi
+ぎこう;gikou
+こうげん;kougen
+せいこう;seikou
+こうちゅう;kouchuu
+こうしゅ;koushu
+かんだかい;kandakai
+いりえ;irie
+こうこ;kouko
+えど;edo
+たんこう;tankou
+こうふ;koufu
+たいこう;taikou
+こうぎ;kougi
+こうそう;kousou
+こうげきしゃ;kougekisha
+せんこう;senkou
+せめいる;semeiru
+こうしん;koushin
+いまさら;imasara
+よふけ;yofuke
+こうそく;kousoku
+こういん;kouin
+かかわらず;kakawarazu
+しゅこう;shukou
+こうてい;koutei
+こうけい;koukei
+こうじょう;koujou
+こうきゅう;koukyuu
+こうれい;kourei
+こうずい;kouzui
+こうせきそう;kousekisou
+こうだい;koudai
+こうてん;kouten
+あれち;arechi
+あらなみ;aranami
+こうがい;kougai
+きんこう;kinkou
+こうや;kouya
+こうすい;kousui
+こうき;kouki
+いろか;iroka
+こうしゃく;koushaku
+おおたこう;ootakou
+おうこう;oukou
+こうけん;kouken
+ねんぐ;nengu
+みつぎもの;mitsugimono
+ひかえじょ;hikaejo
+こうそ;kouso
+ひかえがき;hikaegaki
+きょうこう;kyoukou
+おおあわて;ooawate
+あわてもの;awatemono
+こうか;kouka
+こうか;kouka
+こうすい;kousui
+こうしゅだい;koushudai
+しめころす;shimekorosu
+しぼりだす;shiboridasu
+こうもく;koumoku
+じこう;jikou
+じょうこう;joukou
+げすいこう;gesuikou
+みぞきり;mizokiri
+どぶねずみ;dobunezumi
+ようこう;youkou
+たいこう;taikou
+つなびき;tsunabiki
+こうぼ;koubo
+こうそ;kouso
+はっこう;hakkou
+げんこう;genkou
+とうこう;toukou
+そうこう;soukou
+きんこう;kinkou
+へいこう;heikou
+こうき;kouki
+こうにゅう;kounyuu
+こうばい;koubai
+こうどく;koudoku
+ごうもん;goumon
+ごうせき;gouseki
+ごうもんだい;goumondai
+ごうけん;gouken
+ごうもう;goumou
+ごうちょく;gouchoku
+ごうう;gouu
+ごうそう;gousou
+ごうしゅう;goushuu
+こくふく;kokufuku
+こっき;kokki
+こくめい;kokumei
+こくし;kokushi
+ざんこく;zankoku
+こくしょ;kokusho
+ごくもん;gokumon
+じごく;jigoku
+ぎごく;gigoku
+みこみ;mikomi
+ひとごみ;hitogomi
+こめもの;komemono
+こんちゅう;konchuu
+こんぶ;konbu
+こうこん;koukon
+かいこん;kaikon
+いこん;ikon
+うらみごと;uramigoto
+こんやく;kon_yaku
+けっこんしき;kekkonshiki
+しんこんふうふ;shinkonfuufu
+こんいろ;kon_iro
+こんや;kon_ya
+のうこん;noukon
+れいこん;reikon
+しょうこん;shoukon
+たまげる;tamageru
+かいこん;kaikon
+こんでん;konden
+みかいこんち;mikaikonchi
+こんだん;kondan
+こんがん;kongan
+こんい;kon_i
+ほさ;hosa
+さかん;sakan
+たいさ;taisa
+しさ;shisa
+きょうさ;kyousa
+きょうさしゃ;kyousasha
+さぎし;sagishi
+さしゅ;sashu
+さしょう;sashou
+さこく;sakoku
+れんさ;rensa
+くさりどめ;kusaridome
+さいひょうせん;saihyousen
+さいへん;saihen
+くだけた;kudaketa
+しゅさいしゃ;shusaisha
+さいりょう;sairyou
+さいしょう;saishou
+さいばい;saibai
+ぼんさい;bonsai
+せんざい;senzai
+しきさい;shikisai
+たんさい;tansai
+さいうん;saiun
+さいかい;saikai
+しょさい;shosai
+けっさい;kessai
+さいむ;saimu
+さいけん;saiken
+さいけんしゃ;saikensha
+しゅさい;shusai
+さいそく;saisoku
+さいみん;saimin
+にさい;nisai
+さいひ;saihi
+せいぼ;seibo
+せきさい;sekisai
+けいさい;keisai
+きさい;kisai
+やくざいし;yakuzaishi
+やくざい;yakuzai
+かんげざい;kangezai
+ながさき;nagasaki
+しまざき;shimazaki
+きく;kiku
+さくじょ;sakujo
+さくげん;sakugen
+けずりとる;kezuritoru
+さくいん;sakuin
+しさく;shisaku
+てっさく;tessaku
+さくさん;sakusan
+すのもの;sunomono
+すづけ;suduke
+さくしゅ;sakushu
+あっさく;assaku
+しぼりとる;shiboritoru
+さくご;sakugo
+さっかく;sakkaku
+とうさく;tousaku
+しきざき;shikizaki
+おそざき;osozaki
+さきのこる;sakinokoru
+さついれ;satsuire
+なふだ;nafuda
+せんえんさつ;sen_ensatsu
+さつえい;satsuei
+とりなおす;torinaosu
+つまみぐい;tsumamigui
+さっかしょう;sakkashou
+すれちがう;surechigau
+すりこむ;surikomu
+はいざら;haizara
+おおざら;oozara
+さらあらい;saraarai
+さんばし;sanbashi
+さじき;sajiki
+さんどう;sandou
+さんげき;sangeki
+ざんさつ;zansatsu
+ひさん;hisan
+さんか;sanka
+あまがさ;amagasa
+ひがさ;higasa
+ざんていてき;zanteiteki
+ざんじ;zanji
+しばらくして;shibarakushite
+ようし;youshi
+しゅし;shushi
+うまうまと;umaumato
+うかがいごと;ukagaigoto
+しこう;shikou
+うかがいさぐる;ukagaisaguru
+めいし;meishi
+さしみ;sashimi
+とげぬき;togenuki
+したい;shitai
+えだづの;edaduno
+かれえだ;kareeda
+しふく;shifuku
+ふくし;fukushi
+ふくしこっか;fukushikokka
+したい;shitai
+かし;kashi
+せんたくし;sentakushi
+しせつ;shisetsu
+じっし;jisshi
+せやく;seyaku
+しぼう;shibou
+あぶらけ;aburake
+やにめ;yanime
+しえん;shien
+むらさきいろ;murasakiiro
+しがいせん;shigaisen
+しし;shishi
+こうし;koushi
+こうし;koushi
+しいく;shiiku
+かいぬし;kainushi
+かいいぬ;kaiinu
+しゆう;shiyuu
+めうし;meushi
+めいぬ;meinu
+しか;shika
+おんし;onshi
+たまもの;tamamono
+しじゅん;shijun
+しもん;shimon
+しもんきかん;shimonkikan
+じじゅう;jijuu
+じじょ;jijo
+じそう;jisou
+じよう;jiyou
+じみ;jimi
+じう;jiu
+じひ;jihi
+じぜん;jizen
+じあい;jiai
+ぎょじ;gyoji
+こくじ;kokuji
+いんじ;inji
+しゃじく;shajiku
+ちじく;chijiku
+じくもの;jikumono
+しっかん;shikkan
+しっそう;shissou
+とっくに;tokkuni
+しっぴつ;shippitsu
+しゅうねん;shuunen
+とりなす;torinasu
+しつど;shitsudo
+しっち;shicchi
+しめっぽい;shimeppoi
+しっき;shikki
+しっこく;shikkoku
+うるしぬり;urushinuri
+しばふ;shibafu
+しばい;shibai
+しばかりき;shibakariki
+ようしゃ;yousha
+しゃめん;shamen
+おんしゃ;onsha
+しゃめん;shamen
+しゃほうけい;shahoukei
+ななめつぎ;nanametsugi
+しゃふつ;shafutsu
+なまにえ;namanie
+にたてる;nitateru
+しゃにむに;shanimuni
+しゃこうまく;shakoumaku
+しゃだんき;shadanki
+じゃあく;jaaku
+むじゃき;mujaki
+かぜ;kaze
+じゃかん;jakan
+だこう;dakou
+へびかわ;hebikawa
+いっしゃく;isshaku
+さんしゃく;sanshaku
+じっしゃく;jisshaku
+しゃくふ;shakufu
+ばんしゃく;banshaku
+しゃくりょう;shakuryou
+しゃくい;shakui
+じゅしゃく;jushaku
+だんしゃく;danshaku
+せいじゃく;seijaku
+せきばく;sekibaku
+さびしさ;sabishisa
+しゅいろ;shuiro
+しゅにく;shuniku
+しゅひつ;shuhitsu
+しゅりょう;shuryou
+かりいぬ;kariinu
+かりこみ;karikomi
+とくしゅ;tokushu
+しゅしょう;shushou
+ことさら;kotosara
+しゅぎょく;shugyoku
+しんじゅ;shinju
+じゅず;juzu
+しゅみ;shumi
+しゅい;shui
+しゅこう;shukou
+じゅみょう;jumyou
+ちょうじゅ;chouju
+べいじゅ;beiju
+じゅきょう;jukyou
+じゅしゃ;jusha
+じゅがく;jugaku
+しゅうじん;shuujin
+しゅうえき;shuueki
+しけいしゅう;shikeishuu
+しゅうこう;shuukou
+ふなあそび;funaasobi
+こぶね;kobune
+しゅうさい;shuusai
+しゅういつ;shuuitsu
+しゅうび;shuubi
+しゅうき;shuuki
+ぞくしゅう;zokushuu
+くさみ;kusami
+しゅうしょう;shuushou
+あいしゅう;aishuu
+うれいがお;ureigao
+ほうしゅう;houshuu
+おうしゅう;oushuu
+けんしゅう;kenshuu
+しゅうあく;shuuaku
+しゅうぶん;shuubun
+みにくさ;minikusa
+しゅうらい;shuurai
+くうしゅう;kuushuu
+せしゅう;seshuu
+かじゅう;kajuu
+ぼくじゅう;bokujuu
+みそしる;misoshiru
+じゅうぶん;juubun
+じゅうじつ;juujitsu
+あてがう;ategau
+じゅうどう;juudou
+にゅうじゃく;nyuujaku
+やわらかもの;yawarakamono
+じゅうたい;juutai
+しぶみ;shibumi
+しぶしぶ;shibushibu
+しょうじゅう;shoujuu
+じゅうけん;juuken
+じゅうか;juuka
+じゅうい;juui
+じゅうてき;juuteki
+ちょうじゅう;choujuu
+おじ;oji
+おば;oba
+はくしゅく;hakushuku
+ていしゅく;teishuku
+しゅくじょ;shukujo
+ししゅく;shishuku
+しゅくぜん;shukuzen
+じしゅく;jishuku
+げんしゅく;genshuku
+じゅくせい;jukusei
+じゅくそく;jukusoku
+しじゅく;shijuku
+しゅんさい;shunsai
+しゅんけつ;shunketsu
+しゅんどう;shundou
+いっしゅん;isshun
+しゅんかん;shunkan
+またたくまに;matatakumani
+じょうじゅん;joujun
+ちゅうじゅん;chuujun
+げじゅん;gejun
+じゅんかい;junkai
+じゅんさ;junsa
+ひとめぐり;hitomeguri
+むじゅん;mujun
+うしろだて;ushirodate
+たてつく;tatetsuku
+じゅんい;jun_i
+ひじゅん;hijun
+じゅんきょ;junkyo
+じゅんし;junshi
+じゅんきょうしゃ;junkyousha
+じゅんしょく;junshoku
+いんじゅん;injun
+じゅんかん;junkan
+あくじゅんかん;akujunkan
+じゅんかつ;junkatsu
+りじゅん;rijun
+じゅんたく;juntaku
+じゅんしゅ;junshu
+じゅんぽう;junpou
+じゅんぽう;junpou
+しょみん;shomin
+しょむ;shomu
+しょし;shoshi
+たんしょ;tansho
+はなお;hanao
+じょじょう;jojou
+にょじつ;nyojitsu
+じょじゅつ;jojutsu
+じょじょうてき;jojouteki
+じょくん;jokun
+じょこう;jokou
+じょじょに;jojoni
+じょほ;joho
+ますめ;masume
+にしょう;nishou
+いっしょうびん;isshoubin
+しょうしゅう;shoushuu
+しょうかん;shoukan
+めしつかい;meshitsukai
+ししょう;shishou
+きょしょう;kyoshou
+いしょう;ishou
+びょうしょう;byoushou
+ゆかはり;yukahari
+とこのま;tokonoma
+しょうほん;shouhon
+ししょう;shishou
+しょうやく;shouyaku
+しょうぞう;shouzou
+ふしょう;fushou
+あやかりもの;ayakarimono
+しょうそう;shousou
+こうしょう;koushou
+なおなお;naonao
+しょうしん;shoushin
+じょうしょう;joushou
+しょうこうき;shoukouki
+まつば;matsuba
+まつばら;matsubara
+しょうちくばい;shouchikubai
+しょうき;shouki
+しょうたく;shoutaku
+ぬまち;numachi
+てっしょう;tesshou
+よいづき;yoiduki
+よいごし;yoigoshi
+しょうじょう;shoujou
+えんしょう;enshou
+きょうふしょう;kyoufushou
+はっしょうち;hasshouchi
+きっしょう;kisshou
+ふしょうじ;fushouji
+こうしょう;koushou
+かんしょう;kanshou
+しょうがい;shougai
+しょうかい;shoukai
+しょうかいしゃ;shoukaisha
+しょうかいじょう;shoukaijou
+そしょう;soshou
+そしょうにん;soshounin
+そしょうひよう;soshouhiyou
+しょうちゅう;shouchuu
+しゃしょう;shashou
+しょくしょう;shokushou
+すいしょう;suishou
+しょうか;shouka
+けっしょう;kesshou
+しょうど;shoudo
+しょうしん;shoushin
+くろこげ;kurokoge
+しょうさん;shousan
+しょうやく;shouyaku
+がらす;garasu
+けしょう;keshou
+けしょうひん;keshouhin
+けしょうしつ;keshoushitsu
+しょうしょ;shousho
+しょうれい;shourei
+たいしょう;taishou
+しょうれい;shourei
+すいしょう;suishou
+しょうがくきん;shougakukin
+しょうさい;shousai
+みしょう;mishou
+くわしく;kuwashiku
+ひょうしょう;hyoushou
+けんしょう;kenshou
+しょうとく;shoutoku
+しょうとつ;shoutotsu
+しょうどう;shoudou
+せっしょう;sesshou
+しょうきん;shoukin
+しょうきゃく;shoukyaku
+べんしょう;benshou
+がんしょう;ganshou
+あんしょう;anshou
+さんごしょう;sangoshou
+けいしょう;keishou
+つりがねどう;tsuriganedou
+しょうにゅうせき;shounyuuseki
+せたけ;setake
+ほうじょう;houjou
+じょうだん;joudan
+じょうちょう;jouchou
+じょうご;jougo
+じょうか;jouka
+ふじょう;fujou
+じょうすい;jousui
+じょうよ;jouyo
+よじょう;yojou
+かじょう;kajou
+じょうく;jouku
+にじょう;nijou
+たたみこむ;tatamikomu
+おきなわ;okinawa
+なわばり;nawabari
+じじょうじばく;jijoujibaku
+どじょう;dojou
+じょうど;joudo
+てんじょう;tenjou
+れいじょう;reijou
+あいじょう;aijou
+じょうまえ;joumae
+てじょう;tejou
+じょうざい;jouzai
+じょうほ;jouho
+じょうと;jouto
+おやゆずり;oyayuzuri
+じょうぞう;jouzou
+じょうせい;jousei
+かもしだす;kamoshidasu
+せいしょく;seishoku
+りしょく;rishoku
+ふえだか;fuedaka
+そうしょく;soushoku
+くびかざり;kubikazari
+かざりもの;kazarimono
+しょくしゅ;shokushu
+せっしょく;sesshoku
+ふれあう;fureau
+いしょく;ishoku
+しょくぼう;shokubou
+しょくたく;shokutaku
+ぶじょく;bujoku
+くつじょく;kutsujoku
+せつじょく;setsujoku
+しんしゅく;shinshuku
+ついしん;tsuishin
+せのび;senobi
+しんく;shinku
+からみ;karami
+かろうじて;karoujite
+しんにゅう;shinnyuu
+しんがい;shingai
+しんりゃく;shinryaku
+しんしん;shinshin
+つなみ;tsunami
+つつうらうら;tsutsuuraura
+しんおん;shin_on
+こうしん;koushin
+こうしん;koushin
+にんしん;ninshin
+にんしんかのう;ninshinkanou
+にんしんけんさ;ninshinkensa
+しんどう;shindou
+ふりきる;furikiru
+にねんぶり;ninenburi
+しんしょく;shinshoku
+しんすい;shinsui
+みずびたし;mizubitashi
+しんし;shinshi
+しんしょう;shinshou
+しんしろく;shinshiroku
+しんだん;shindan
+しんさつ;shinsatsu
+おうしん;oushin
+しんしつ;shinshitsu
+ねいる;neiru
+ねかしもの;nekashimono
+しんちょう;shinchou
+きんしん;kinshin
+つつしみぶかい;tsutsushimibukai
+しんぎ;shingi
+ふしん;fushin
+しんぱん;shinpan
+じしん;jishin
+みぶるい;miburui
+ふるえごえ;furuegoe
+しんたん;shintan
+たきぎこや;takigikoya
+まきわり;makiwari
+はくじん;hakujin
+はもの;hamono
+りょうば;ryouba
+じんりょく;jinryoku
+じんみらい;jinmirai
+こころづくし;kokorodukushi
+じんそく;jinsoku
+じんらい;jinrai
+ふんじん;funjin
+じんだい;jindai
+じんろく;jinroku
+こうじん;koujin
+じんとう;jintou
+じんち;jinchi
+じんつう;jintsuu
+じんもん;jinmon
+じんじょう;jinjou
+たずねだす;tazunedasu
+こすい;kosui
+ふぶき;fubuki
+ふきたおす;fukitaosu
+すいじ;suiji
+めしたき;meshitaki
+じすい;jisui
+とうすい;tousui
+げんすい;gensui
+しょうすい;shousui
+すいび;suibi
+いきごと;ikigoto
+すいじん;suijin
+すいじゃく;suijaku
+ろうすい;rousui
+せいすい;seisui
+ますい;masui
+よっぱらい;yopparai
+ふなよい;funayoi
+すいこう;suikou
+みすい;misui
+しとげる;shitogeru
+すいみん;suimin
+じゅくすい;jukusui
+ごすい;gosui
+すいじょう;suijou
+いなほ;inaho
+ほさき;hosaki
+ぼうすい;bousui
+どくせん;dokusen
+うらないしゃ;uranaisha
+しめた;shimeta
+せんす;sensu
+せんぷうき;senpuuki
+せんけい;senkei
+せんぬき;sennuki
+きゅうすいせん;kyuusuisen
+しょうかせん;shoukasen
+せんかい;senkai
+せんばん;senban
+しゅうせん;shuusen
+じっせん;jissen
+じっせんてき;jissenteki
+じっせんしゅぎ;jissenshugi
+せんてつ;sentetsu
+せんこう;senkou
+ようせん;yousen
+せんざい;senzai
+せんすい;sensui
+もぐりこむ;mogurikomu
+せんえん;sen_en
+へんせん;hensen
+せんげ;senge
+すいせん;suisen
+せんこつ;senkotsu
+じせん;jisen
+せんい;sen_i
+せんさい;sensai
+せんもう;senmou
+せんぎょ;sengyo
+せんめい;senmei
+ちょうせん;chousen
+ざぜん;zazen
+ぜんしゅう;zenshuu
+ぜんでら;zendera
+デパート;depaato
+ほっかいどう;hokkaidou
+ほんしゅう;honshuu
+しこく;shikoku
+インド;indo
+アメリカ;amerika
+それん;soren
+くらい;kurai
+たいへん;taihen
+まんいん;man_in
+もう;mou
+きのう;kinou
+あさ;asa
+ひる;hiru
+よる;yoru
+けさ;kesa
+さくや;sakuya
+いっしょに;isshoni
+ぜんたいで;zentaide
+ぜんたいで;zentaide
+へいほうキロメートル;heihoukiromeetoru
+かい;kai
+キロ;kiro
+おりる;oriru
+ねる;neru
+でる;deru
+うまれる;umareru
+かう;kau
+はいる;hairu
+あめがふる;amegafuru
+ゆきがふる;yukigafuru
+さく;saku
+ふろにはいる;furonihairu
+けっこんする;kekkonsuru
+てら;tera
+ちゃみせ;chamise
+やまみち;yamamichi
+そら;sora
+みどり;midori
+ちょうじゅう;choujuu
+ぎが;giga
+はいく;haiku
+あし;ashi
+はなし;hanashi
+しけん;shiken
+てつづき;tetsuduki
+にわ;niwa
+びょうき;byouki
+じゅぎょう;jugyou
+けんぶつ;kenbutsu
+えはがき;ehagaki
+めいしょ;meisho
+だいぶつ;daibutsu
+たいしゃ;taisha
+じんじゃ;jinja
+しか;shika
+こじか;kojika
+ぎょうじ;gyouji
+かてい;katei
+しょうがつ;shougatsu
+かどまつ;kadomatsu
+しめなわ;shimenawa
+もち;mochi
+せつぶん;setsubun
+まめ;mame
+おに;oni
+ふくのかみ;fukunokami
+ひなまつり;hinamatsuri
+ひなにんぎょう;hinaningyou
+たんごのせっく;tangonosekku
+はじめ;hajime
+まつり;matsuri
+こいのぼり;koinobori
+たなばた;tanabata
+ほし;hoshi
+うしかい;ushikai
+うし;ushi
+でんせつ;densetsu
+あまのがわ;amanogawa
+おりひめ;orihime
+ハイキング;haikingu
+まつおばしょう;matsuobashou
+つめたい;tsumetai
+みじかい;mijikai
+たのしい;tanoshii
+かわいらしい;kawairashii
+あおい;aoi
+さいわい;saiwai
+かんたん;kantan
+ふしんせつ;fushinsetsu
+げんき;genki
+ロマンチック;romanchikku
+びょうき;byouki
+いくつか;ikutsuka
+ごぜん;gozen
+ど;do
+こいのぼりおたてる;koinoboriotateru
+はしる;hashiru
+ハイキングにいく;haikinguniiku
+はいくをつくる;haikuwotsukuru
+しゃしんをとる;shashinwotoru
+おくる;okuru
+かざる;kazaru
+まく;maku
+おいだす;oidasu
+まねく;maneku
+わたる;wataru
+あう;au
+けんぶつする;kenbutsusuru
+くる;kuru
+おおぜい;oozei
+ことり;kotori
+いけ;ike
+はし;hashi
+こい;koi
+しゃせい;shasei
+ちゅうがくせい;chuugakusei
+ぶらんこ;buranko
+こかげ;kokage
+だんじょ;danjo
+ひかり;hikari
+べんとう;bentou
+かだん;kadan
+おか;oka
+とおく;tooku
+すもう;sumou
+かね;kane
+くるま;kuruma
+でんわばんごう;denwabangou
+いけばな;ikebana
+でし;deshi
+おぼん;obon
+せんぞ;senzo
+たましい;tamashii
+まんげつ;mangetsu
+おつきみ;otsukimi
+うんどうかい;undoukai
+ひとびと;hitobito
+こめ;kome
+とりいれ;toriire
+ほうさく;housaku
+むら;mura
+あきまつり;akimatsuri
+しちごさん;shichigosan
+とし;toshi
+とし;toshi
+おおそうじ;oosouji
+おおみそか;oomisoka
+よなか;yonaka
+じょやのかね;joyanokane
+ベンチ;benchi
+ハーモニカ;haamonika
+ボール;booru
+ハンカチ;hankachi
+デパート;depaato
+ジャズ;jazu
+スポーツ;supootsu
+シーズン;shiizun
+サイクリング;saikuringu
+だいもんじ;daimonji
+かんとう;kantou
+かんさい;kansai
+くろい;kuroi
+あかるい;akarui
+ふべん;fuben
+じょうず;jouzu
+モダン;modan
+さいご;saigo
+さい;sai
+おちる;ochiru
+なげる;nageru
+おしえる;oshieru
+おちゃをたてる;ochawotateru
+コーヒーをいれる;koohiiwoireru
+あつめる;atsumeru
+むかえる;mukaeru
+ひをつける;hiwotsukeru
+さく;saku
+あそぶ;asobu
+うたう;utau
+はしがかかる;hashigakakaru
+ぶらんこにのる;burankoninoru
+はなす;hanasu
+もつ;motsu
+まわる;mawaru
+ハーモニカをふく;haamonikawofuku
+すもうをとる;sumouwotoru
+みおろす;miorosu
+ひかる;hikaru
+にすむ;nisumu
+しる;shiru
+ひらく;hiraku
+しまる;shimaru
+まがる;magaru
+ふとる;futoru
+ピアノをひく;pianowohiku
+シャツをぬぐ;shatsuwonugu
+とおる;tooru
+すむ;sumu
+いわう;iwau
+にまいる;nimairu
+もちをつく;mochiwotsuku
+おじゃまする;ojamasuru
+しょうかいする;shoukaisuru
+つゆ;tsuyu
+つゆあけ;tsuyuake
+なつやすみ;natsuyasumi
+はれ;hare
+なつやま;natsuyama
+こうざんしょくぶつ;kouzanshokubutsu
+くも;kumo
+はんとう;hantou
+かいがん;kaigan
+ぶんか;bunka
+せいじ;seiji
+さんぎょう;sangyou
+ちゅうしん;chuushin
+しぜん;shizen
+みずうみ;mizuumi
+のはら;nohara
+ちへいせん;chiheisen
+ゆうひ;yuuhi
+しゅうかく;shuukaku
+もの;mono
+さかな;sakana
+ていりゅうじょ;teiryuujo
+かぜ;kaze
+こけ;koke
+やまごや;yamagoya
+せいき;seiki
+れきし;rekishi
+きもの;kimono
+ぬの;nuno
+あな;ana
+あたま;atama
+こふん;kofun
+はにわ;haniwa
+ふくそう;fukusou
+ころ;koro
+はかま;hakama
+へいあんじだい;heianjidai
+かまくらじだい;kamakurajidai
+むろまちじだい;muromachijidai
+ぜんじ;zenji
+ぜんしんてき;zenshinteki
+とうぜん;touzen
+しゅうぜん;shuuzen
+しゅうぜんこう;shuuzenkou
+つくろいかざる;tsukuroikazaru
+そし;soshi
+そがい;sogai
+けんそ;kenso
+そぜい;sozei
+そしゃく;soshaku
+そしゃっけん;soshakken
+そち;sochi
+そじ;soji
+きょそ;kyoso
+そまつ;somatsu
+そとう;sotou
+あらすじ;arasuji
+そかく;sokaku
+そかいしゃ;sokaisha
+うとうとしい;utoutoshii
+そしょうじけん;soshoujiken
+こくそ;kokuso
+あいそ;aiso
+そぞう;sozou
+ちょうそ;chouso
+かそせい;kasosei
+そせき;soseki
+きそ;kiso
+きそてき;kisoteki
+そうほう;souhou
+むそう;musou
+ふたご;futago
+そうだい;soudai
+きょうそう;kyousou
+そうしゃ;sousha
+そうごん;sougon
+しょうえん;shouen
+べっそう;bessou
+そうさ;sousa
+そうさく;sousaku
+さがしだす;sagashidasu
+そうにゅう;sounyuu
+そうわ;souwa
+さしえ;sashie
+そうえん;souen
+くわいろ;kuwairo
+くわばたけ;kuwabatake
+そうじき;soujiki
+いっそう;issou
+はきだす;hakidasu
+ほうそう;housou
+ぐんそう;gunsou
+そうし;soushi
+きそう;kisou
+すばこ;subako
+すだつ;sudatsu
+そうしつ;soushitsu
+もふく;mofuku
+もちゅう;mochuu
+そうしき;soushiki
+そうぎや;sougiya
+そうか;souka
+そうち;souchi
+いしょう;ishou
+へんそう;hensou
+そういん;souin
+こうそう;kousou
+そうしょく;soushoku
+そうぐう;souguu
+そうなん;sounan
+そうなんしんごう;sounanshingou
+すいそう;suisou
+よくそう;yokusou
+しそう;shisou
+かんそう;kansou
+しょうそう;shousou
+こうそうち;kousouchi
+そうがい;sougai
+しもよ;shimoyo
+しもふりにく;shimofuriniku
+そうおん;souon
+そうどう;soudou
+おおさわぎ;oosawagi
+もぬけ;monuke
+かいそう;kaisou
+しそう;shisou
+ぞうお;zouo
+にくらしい;nikurashii
+にくみあう;nikumiau
+ぞうよ;zouyo
+きぞう;kizou
+おくりもの;okurimono
+そくい;sokui
+そっこく;sokkoku
+そくせき;sokuseki
+けっそく;kessoku
+はなたば;hanataba
+つかのま;tsukanoma
+そくしん;sokushin
+さいそく;saisoku
+そくせい;sokusei
+かいぞく;kaizoku
+とうぞく;touzoku
+ぞくぐん;zokugun
+だとう;datou
+だきょう;dakyou
+だけつ;daketsu
+だらく;daraku
+だたい;datai
+だらくぼうず;darakubouzu
+だりょく;daryoku
+たいだ;taida
+だき;daki
+だもの;damono
+だば;daba
+むだ;muda
+たいきゅう;taikyuu
+たいか;taika
+たえがたい;taegatai
+たいぎょう;taigyou
+なまけもの;namakemono
+おこたりがち;okotarigachi
+たいじ;taiji
+じゅたい;jutai
+たいばん;taiban
+たいぜん;taizen
+あんたい;antai
+たいせい;taisei
+ゆうたい;yuutai
+ゆうたいるい;yuutairui
+てぶくろ;tebukuro
+たいほ;taiho
+たいほしゃ;taihosha
+たいや;taiya
+だいたい;daitai
+りょうがえ;ryougae
+とりかえ;torikae
+たいざい;taizai
+ていたい;teitai
+たいのう;tainou
+きよたき;kiyotaki
+たきがわ;takigawa
+けごんだき;kegondaki
+さいたく;saitaku
+せんたく;sentaku
+せんたくかもく;sentakukamoku
+こうたく;koutaku
+さわち;sawachi
+たっきゅう;takkyuu
+たくえつ;takuetsu
+しょくたく;shokutaku
+たくしょく;takushoku
+かいたく;kaitaku
+ぎょたく;gyotaku
+たくせん;takusen
+たくそう;takusou
+いたく;itaku
+せんたくき;sentakuki
+せんたくもの;sentakumono
+じゅだく;judaku
+しょうだく;shoudaku
+かいだく;kaidaku
+だくりゅう;dakuryuu
+だくおん;dakuon
+にごりえ;nigorie
+ただしがき;tadashigaki
+ただしづき;tadashiduki
+たじま;tajima
+だつい;datsui
+だっぴ;dappi
+だっしゅつ;dasshutsu
+だっしゅ;dasshu
+だっかい;dakkai
+うばいさる;ubaisaru
+とだな;todana
+ほんだな;hondana
+ぶどうだな;budoudana
+たんねん;tannen
+たんせい;tansei
+にぬり;ninuri
+だいたん;daitan
+たんせき;tanseki
+らくたん;rakutan
+たんすい;tansui
+たんしょく;tanshoku
+あわゆき;awayuki
+たんそく;tansoku
+きょうたん;kyoutan
+なげきさけぶ;nagekisakebu
+きょくたん;kyokutan
+たんせい;tansei
+みちばた;michibata
+たんじょうび;tanjoubi
+こうたん;koutan
+こうたん;koutan
+たんこうじょ;tankoujo
+たんれん;tanren
+たんきん;tankin
+だんやく;dan_yaku
+だんりょく;danryoku
+ひきて;hikite
+かだん;kadan
+だんじょう;danjou
+どたんば;dotanba
+ちじょく;chijoku
+むち;muchi
+はじいる;hajiiru
+いっち;icchi
+ちめいてき;chimeiteki
+いたしかた;itashikata
+ちこく;chikoku
+ちち;chichi
+おそざき;osozaki
+はくち;hakuchi
+ぐち;guchi
+ちじょう;chijou
+ちぎょ;chigyo
+ちせつ;chisetsu
+ようちえん;youchien
+かちく;kachiku
+ちくしょう;chikushou
+ちくさん;chikusan
+くちく;kuchiku
+ちくいち;chikuichi
+ちくごてき;chikugoteki
+ちょちく;chochiku
+ちくでん;chikuden
+ちくせき;chikuseki
+ちつじょ;chitsujo
+かんちつ;kanchitsu
+ちつろく;chitsuroku
+ちっし;chisshi
+ちっそく;chissoku
+ちっそ;chisso
+ちゃくし;chakushi
+はいちゃく;haichaku
+ちゃくさい;chakusai
+ちゅうてん;chuuten
+おきあい;okiai
+おきづり;okiduri
+ちゅうしゅつ;chuushutsu
+ちゅうしょう;chuushou
+ちゅうせん;chuusen
+せっちゅう;secchuu
+ちゅうしん;chuushin
+くちゅう;kuchuu
+ちゅうぞう;chuuzou
+ちゅうてつ;chuutetsu
+いがた;igata
+ちゅうしゃ;chuusha
+ちゅうざい;chuuzai
+ちゅうにち;chuunichi
+けいちょう;keichou
+ちょうもん;choumon
+とむらいがっせん;tomuraigassen
+ちょうはつ;chouhatsu
+ちょうせん;chousen
+ちょうせんてき;chousenteki
+ちょうこく;choukoku
+ちょうぞう;chouzou
+てぼり;tebori
+ちょうぼう;choubou
+ながめ;nagame
+ちょうぼうぜっけい;choubouzekkei
+つりば;tsuriba
+ちょうぎょ;chougyo
+つりせん;tsurisen
+ぼうちょう;bouchou
+ふくれっつら;fukurettsura
+ふくらしこ;fukurashiko
+ちょうじん;choujin
+ちょうか;chouka
+にゅうちょう;nyuuchou
+ちょうやく;chouyaku
+とびいた;tobiita
+はねかえる;hanekaeru
+しょうちょう;shouchou
+ちょうしゅう;choushuu
+とくちょう;tokuchou
+せいちょう;seichou
+すみきる;sumikiru
+すましがお;sumashigao
+ちょうこう;choukou
+とうちょう;touchou
+ちょうしんき;choushinki
+ちょうばつ;choubatsu
+ちょうかい;choukai
+こりごり;korigori
+ちょくご;chokugo
+ちょくし;chokushi
+ちょくにん;chokunin
+ちんぼつ;chinbotsu
+ちんたい;chintai
+ちんか;chinka
+ちんき;chinki
+ちんぴん;chinpin
+ちんぽん;chinpon
+ちん;chin
+ちんの;chinno
+ちんとく;chintoku
+ちんじょう;chinjou
+ちんれつ;chinretsu
+しんちんたいしゃ;shinchintaisha
+ちんつうざい;chintsuuzai
+ちんせい;chinsei
+ぶんちん;bunchin
+ついらく;tsuiraku
+げきつい;gekitsui
+ついし;tsuishi
+かいづか;kaiduka
+つかあな;tsukaana
+たからづか;takaraduka
+つけもの;tsukemono
+ちゃづけ;chaduke
+しおづけ;shioduke
+たてつぼ;tatetsubo
+ごつぼ;gotsubo
+つぼすう;tsubosuu
+きゅうてい;kyuutei
+ほうてい;houtei
+ていしん;teishin
+ていじょう;teijou
+ぞうてい;zoutei
+しんてい;shintei
+ていこう;teikou
+ていとう;teitou
+ていたく;teitaku
+ていない;teinai
+かんてい;kantei
+ていしゅ;teishu
+りょてい;ryotei
+りょうてい;ryoutei
+ていそう;teisou
+ていせつ;teisetsu
+ていじつ;teijitsu
+ていこく;teikoku
+ていおう;teiou
+ていおうせっかい;teiousekkai
+ていせい;teisei
+かいてい;kaitei
+かいていばん;kaiteiban
+ていそう;teisou
+ていしん;teishin
+ていじ;teiji
+たんてい;tantei
+ないてい;naitei
+ていさつ;teisatsu
+ぼうはてい;bouhatei
+ていぼう;teibou
+ていぼうづたい;teiboudutai
+かんてい;kantei
+ていこ;teiko
+きゅうめいてい;kyuumeitei
+しめきり;shimekiri
+ていやく;teiyaku
+しめだし;shimedashi
+でいど;deido
+こうでい;koudei
+どろあし;doroashi
+きてき;kiteki
+てきしゅ;tekishu
+くちぶえ;kuchibue
+てきよう;tekiyou
+てきはつ;tekihatsu
+つみとる;tsumitoru
+すいてき;suiteki
+いってき;itteki
+てきか;tekika
+こうてつ;koutetsu
+てつりつ;tetsuritsu
+てっき;tekki
+てつがく;tetsugaku
+てつじん;tetsujin
+せんてつ;sentetsu
+てつや;tetsuya
+てっていてき;tetteiteki
+かんてつ;kantetsu
+てっしゅう;tesshuu
+てっきょ;tekkyo
+てっかい;tekkai
+てんか;tenka
+てんぷ;tenpu
+そえぎ;soegi
+きゅうでん;kyuuden
+ごてん;goten
+とのさま;tonosama
+ほくとせい;hokutosei
+としゅ;toshu
+たいと;taito
+とざい;tozai
+はきけ;hakike
+といき;toiki
+とちゅう;tochuu
+とたん;totan
+ぜんと;zento
+とこう;tokou
+とせい;tosei
+いいわたす;iiwatasu
+ぬりもの;nurimono
+とそう;tosou
+ぬりぐすり;nurigusuri
+どれい;dorei
+やつら;yatsura
+やっこさん;yakkosan
+どき;doki
+どなる;donaru
+いかりぐるう;ikariguruu
+とうふ;toufu
+だいず;daizu
+まめほん;mamehon
+とうらい;tourai
+とうたつ;toutatsu
+とうてい;toutei
+とうぼうしゃ;toubousha
+みのがす;minogasu
+にげみち;nigemichi
+とうさん;tousan
+めんどう;mendou
+とうち;touchi
+れいとうざい;reitouzai
+とうけつ;touketsu
+こおりつく;kooritsuku
+とうほん;touhon
+けとうじん;ketoujin
+からて;karate
+はくとう;hakutou
+ももいろ;momoiro
+とうげんきょう;tougenkyou
+とうめい;toumei
+とうしゃ;tousha
+すきとおる;sukitooru
+あいとう;aitou
+ついとう;tsuitou
+いたむべき;itamubeki
+とうよう;touyou
+ごうとう;goutou
+ぬすびと;nusubito
+とうき;touki
+くんとう;kuntou
+とうぜん;touzen
+せきとう;sekitou
+そとば;sotoba
+ごじゅうのとう;gojuunotou
+とうさい;tousai
+とうじょう;toujou
+とうじょうけん;toujouken
+びょうとう;byoutou
+むなぎ;munagi
+べつむね;betsumune
+てんねんとう;tennentou
+すいとう;suitou
+しゅとう;shutou
+えんとう;entou
+つつぬけ;tsutsunuke
+つつがた;tsutsugata
+すいとう;suitou
+いなさく;inasaku
+わせだ;waseda
+とうは;touha
+ふみこむ;fumikomu
+あしぶみ;ashibumi
+とうほん;touhon
+とうしゃ;tousha
+とうしゃき;toushaki
+とうし;toushi
+とうし;toushi
+せんとうき;sentouki
+とうき;touki
+とうらく;touraku
+ぼうとう;boutou
+どうさつ;dousatsu
+くうどう;kuudou
+どうくつ;doukutsu
+どうたい;doutai
+そうどうせん;soudousen
+どうまわり;doumawari
+とうげみち;tougemichi
+うすいとうげ;usuitouge
+よんじゅうのとうげ;yonjuunotouge
+とくめい;tokumei
+いんとく;intoku
+ひとく;hitoku
+かんとく;kantoku
+とくれい;tokurei
+とくそく;tokusoku
+とくし;tokushi
+きとく;kitoku
+とくと;tokuto
+とつめん;totsumen
+でこぼこ;dekoboko
+おうとつ;outotsu
+とつぜん;totsuzen
+とつにゅう;totsunyuu
+つっこむ;tsukkomu
+とんえい;ton_ei
+ちゅうとん;chuuton
+ちゅうとんち;chuutonchi
+とんもう;tonmou
+ぶたにく;butaniku
+とんカツ;tonkatsu
+どんかん;donkan
+どんさい;donsai
+にびいろ;nibiiro
+どんてん;donten
+くもりがち;kumorigachi
+はなぐもり;hanagumori
+なんか;nanka
+なんすい;nansui
+なんじゃく;nanjaku
+にそう;nisou
+あまでら;amadera
+びくに;bikuni
+とうにょうびょう;tounyoubyou
+にょうそ;nyouso
+にょうい;nyoui
+にんぷ;ninpu
+ふにんしょう;funinshou
+にんしんちょうせつ;ninshinchousetsu
+にんたい;nintai
+にんじゃ;ninja
+しのびこむ;shinobikomu
+あんねい;annei
+ていねい;teinei
+ねいじつ;neijitsu
+ねんど;nendo
+ねんちゃく;nenchaku
+ねばりづよい;nebariduyoi
+くのう;kunou
+のうさつ;nousatsu
+おうのう;ounou
+のうか;nouka
+のうこう;noukou
+あぶらっこい;aburakkoi
+はあく;haaku
+はじゅう;hajuu
+とって;totte
+はけん;haken
+はき;haki
+せいは;seiha
+ろうば;rouba
+さんば;sanba
+おにばば;onibaba
+ぎょくはい;gyokuhai
+さかずきごと;sakazukigoto
+はいじょ;haijo
+はいすい;haisui
+はいきガス;haikigasu
+はいし;haishi
+はいじ;haiji
+すたりもの;sutarimono
+わがはい;wagahai
+せんぱい;senpai
+はいしゅつ;haishutsu
+ばいか;baika
+うめしゅ;umeshu
+つゆ;tsuyu
+ばいよう;baiyou
+さいばいしゃ;saibaisha
+ばいち;baichi
+ばいせきしゃ;baisekisha
+ばいしん;baishin
+ばいおん;baion
+ばいかい;baikai
+しょくばい;shokubai
+ばいたい;baitai
+ばいしょう;baishou
+ばいしょうきん;baishoukin
+そんがいばいしょう;songaibaishou
+はくしゃく;hakushaku
+おじ;oji
+がはく;gahaku
+はくしゅ;hakushu
+ひょうし;hyoushi
+はくしゃ;hakusha
+しゅくはく;shukuhaku
+とまりばん;tomariban
+いっぱく;ippaku
+はくがい;hakugai
+はくりょく;hakuryoku
+せっぱく;seppaku
+せんぱく;senpaku
+はくらい;hakurai
+はくよう;hakuyou
+うすぎ;usugi
+けいはく;keihaku
+うすかわ;usukawa
+ばくぜん;bakuzen
+ばくばく;bakubaku
+さばく;sabaku
+そくばく;sokubaku
+ほばく;hobaku
+しばりくび;shibarikubi
+ばくはつ;bakuhatsu
+ばくだん;bakudan
+げんばく;genbaku
+こばこ;kobako
+はこぶね;hakobune
+はこいり;hakoiri
+はだいろ;hadairo
+すはだ;suhada
+きめ;kime
+うえきばち;uekibachi
+はちまき;hachimaki
+いはつ;ihatsu
+とうはつ;touhatsu
+さんぱつ;sanpatsu
+かみがた;kamigata
+ばっさい;bassai
+せいばつ;seibatsu
+さつばつ;satsubatsu
+ばつぐん;batsugun
+ぬけあな;nukeana
+てぬかり;tenukari
+ばっきん;bakkin
+しょばつ;shobatsu
+ばちあたり;bachiatari
+もんばつ;monbatsu
+ばつぞく;batsuzoku
+ざいばつ;zaibatsu
+はんせん;hansen
+ほばしら;hobashira
+ほかける;hokakeru
+どうはんしゃ;douhansha
+ばんそうしゃ;bansousha
+あいともなう;aitomonau
+ちはん;chihan
+こはん;kohan
+こはんしじん;kohanshijin
+いっぱん;ippan
+ぜんぱん;zenpan
+かはん;kahan
+はんばい;hanbai
+しはん;shihan
+はんろ;hanro
+うんぱん;unpan
+はんそう;hansou
+はんそうたい;hansoutai
+はんざつ;hanzatsu
+ぼんのう;bonnou
+はんろう;hanrou
+はんぷ;hanpu
+はんこう;hankou
+はんぱく;hanpaku
+もはん;mohan
+きはん;kihan
+はんいない;han_inai
+はんじょう;hanjou
+はんざつ;hanzatsu
+はんしょく;hanshoku
+はんしゅ;hanshu
+はんべい;hanbei
+かがはん;kagahan
+ばんじん;banjin
+ばんこう;bankou
+やばん;yaban
+えんばん;enban
+きばん;kiban
+すいばん;suiban
+おうひ;ouhi
+ひでんか;hidenka
+こうたいしひ;koutaishihi
+かれし;kareshi
+かのじょ;kanojo
+ひがん;higan
+ひけん;hiken
+ひれき;hireki
+ひろう;hirou
+ひげ;hige
+ひくつ;hikutsu
+ひきん;hikin
+ひろう;hirou
+つかれめ;tsukareme
+つかれきる;tsukarekiru
+ひがいしゃ;higaisha
+ひふく;hifuku
+ひこくにん;hikokunin
+かいひ;kaihi
+もんぴ;monpi
+とびらえ;tobirae
+ひめい;himei
+せきひ;sekihi
+きねんひ;kinenhi
+ひぎょう;higyou
+ひめん;himen
+まかりとおる;makaritooru
+かいひ;kaihi
+ふかひ;fukahi
+ひにん;hinin
+びこつ;bikotsu
+こうび;koubi
+しっぽ;shippo
+びさい;bisai
+びこう;bikou
+びこう;bikou
+ひってき;hitteki
+ひっぷ;hippu
+いっぴき;ippiki
+ぶんぴつ;bunpitsu
+ひにょう;hinyou
+ひにょうきか;hinyoukika
+ひめみや;himemiya
+ひめがき;himegaki
+ようこひめ;youkohime
+ひょうはく;hyouhaku
+ひょうちゃく;hyouchaku
+ひょうりゅうしゃ;hyouryuusha
+しゅびょう;shubyou
+みょうじ;myouji
+なえぎ;naegi
+びょうしゃ;byousha
+てんびょう;tenbyou
+えがきだす;egakidasu
+あいびょう;aibyou
+ねこぜ;nekoze
+シャムねこ;shamuneko
+かいひん;kaihin
+はまべ;hamabe
+はまとびむし;hamatobimushi
+しゅひん;shuhin
+らいひん;raihin
+ひんきゃく;hinkyaku
+ひんぱんに;hinpanni
+ひんぱつ;hinpatsu
+ひんど;hindo
+びんそく;binsoku
+えいびん;eibin
+きびん;kibin
+びんづめ;bindume
+かびん;kabin
+つるべ;tsurube
+ふじょ;fujo
+ふよう;fuyou
+ふいく;fuiku
+きょうふしょう;kyoufushou
+いふ;ifu
+きょうふしょうせつ;kyoufushousetsu
+ふぞく;fuzoku
+きふ;kifu
+ふきん;fukin
+ふえん;fuen
+ふにん;funin
+ふにんち;funinchi
+ふりょく;furyoku
+うわき;uwaki
+うきよ;ukiyo
+きっぷ;kippu
+ふごう;fugou
+ふごう;fugou
+ふつう;futsuu
+ふへん;fuhen
+ふきゅう;fukyuu
+ふしん;fushin
+ふはい;fuhai
+くされ;kusare
+ふせつ;fusetsu
+しきもの;shikimono
+やしき;yashiki
+ひふえん;hifuen
+かんぷ;kanpu
+はだぎ;hadagi
+ふか;fuka
+ふし;fushi
+げっぷ;geppu
+がくふ;gakufu
+けいふ;keifu
+ねんぷ;nenpu
+ぶじょくてき;bujokuteki
+けいぶ;keibu
+ぶまん;buman
+ぶたい;butai
+まいこ;maiko
+ふるまい;furumai
+ふうとう;fuutou
+ふうさ;fuusa
+ほうけん;houken
+きふく;kifuku
+せんぷく;senpuku
+ふして;fushite
+しんぷく;shinpuku
+がふく;gafuku
+よこはば;yokohaba
+てんぷく;tenpuku
+ふくめん;fukumen
+ふくすい;fukusui
+はらいもどす;haraimodosu
+ふってい;futtei
+はらいだす;haraidasu
+ふってん;futten
+わきたつ;wakitatsu
+わきでる;wakideru
+ふんしつ;funshitsu
+ふんそう;funsou
+ふんぷん;funpun
+ふんいき;fun_iki
+むふん;mufun
+そうふん;soufun
+ふんか;funka
+ふんすい;funsui
+ふきだす;fukidasu
+こふん;kofun
+ふんぼ;funbo
+ふんぼのち;funbonochi
+ふんがい;fungai
+ふんど;fundo
+ぎふん;gifun
+へいしゅ;heishu
+こうおつへい;kouotsuhei
+ひのえ;hinoe
+がっぺい;gappei
+へいよう;heiyou
+へいはつ;heihatsu
+へいこう;heikou
+なみき;namiki
+つきなみ;tsukinami
+おうへい;ouhei
+いえがら;iegara
+おおがら;oogara
+いたべい;itabei
+どべい;dobei
+へいごし;heigoshi
+しへい;shihei
+かへい;kahei
+ごへい;gohei
+へいしゃ;heisha
+ひへい;hihei
+へいがい;heigai
+へきが;hekiga
+がんぺき;ganpeki
+かべがみ;kabegami
+とうへき;touheki
+しゅうへき;shuuheki
+くせげ;kusege
+へんこう;henkou
+へんけん;henken
+へんくつ;henkutsu
+ふへんせい;fuhensei
+へんざい;henzai
+いっぺん;ippen
+ほかく;hokaku
+とらえどころ;toraedokoro
+つかまえどころ;tsukamaedokoro
+うらなみ;uranami
+うらかぜ;urakaze
+うらざと;urazato
+てんぽ;tenpo
+ほそう;hosou
+ほそうどうろ;hosoudouro
+ぼしゅう;boshuu
+ぼきん;bokin
+おうぼ;oubo
+ぼじょう;bojou
+けいぼ;keibo
+ぼしん;boshin
+ぼしゅん;boshun
+ゆうぐれ;yuugure
+くらしかた;kurashikata
+めいぼ;meibo
+ぼき;boki
+ちょうぼ;choubo
+ほうこう;houkou
+ほうし;houshi
+ほうき;houki
+ほうが;houga
+れんぽう;renpou
+ほんぽう;honpou
+ほうし;houshi
+ほうのう;hounou
+しんぽう;shinpou
+だきつく;dakitsuku
+ほうかい;houkai
+かかえこむ;kakaekomu
+きほう;kihou
+はっぽう;happou
+あわだつ;awadatsu
+ほうし;houshi
+ほうい;houi
+さいぼう;saibou
+ほうきゅう;houkyuu
+ねんぽう;nenpou
+ほうろくまい;hourokumai
+もほう;mohou
+もほうしゃ;mohousha
+ならいけずり;naraikezuri
+しゅほう;shuhou
+れんぽう;renpou
+みねうち;mineuchi
+ほうがん;hougan
+てっぽう;teppou
+たいほう;taihou
+ほうかい;houkai
+なだれ;nadare
+やまくずれ;yamakuzure
+ほうわ;houwa
+ほうしょく;houshoku
+あきしょう;akishou
+ほうしょう;houshou
+ほうび;houbi
+ほめことば;homekotoba
+ほうごう;hougou
+ぬいもの;nuimono
+ぬいめ;nuime
+けつぼう;ketsubou
+びんぼう;binbou
+たいぼう;taibou
+たぼう;tabou
+はんぼう;hanbou
+ぼうさつ;bousatsu
+ぼうず;bouzu
+ぼうや;bouya
+ぼうかん;boukan
+ぼうがい;bougai
+ぼうし;boushi
+さまたげなし;samatagenashi
+ぼうしつ;boushitsu
+ふさふさ;fusafusa
+せわにょうぼう;sewanyoubou
+しぼうそう;shibousou
+しぼうかた;shiboukata
+しぼうそしき;shibousoshiki
+ぼうし;boushi
+ぼうしょ;bousho
+おおたなにがし;ootananigashi
+ぼうけん;bouken
+かんぼう;kanbou
+おかして;okashite
+かいぼう;kaibou
+かいぼうがく;kaibougaku
+せいたいかいぼう;seitaikaibou
+ぼうき;bouki
+ぼうもう;boumou
+ぼうせきぎょう;bousekigyou
+ぼうちょう;bouchou
+ぼうかん;boukan
+ぼうちゅう;bouchuu
+ぼうし;boushi
+めいもう;meimou
+もうもく;moumoku
+もんもう;monmou
+めくらばん;mekuraban
+しょうもう;shoumou
+そんもう;sonmou
+しんしんもうじゃく;shinshinmoujaku
+もうれつ;mouretsu
+もうじゅう;moujuu
+もさ;mosa
+ぎょもう;gyomou
+あみど;amido
+つうしんもう;tsuushinmou
+もくさつ;mokusatsu
+ちんもく;chinmoku
+だまりこむ;damarikomu
+もんしょう;monshou
+しもん;shimon
+はもん;hamon
+にもんめ;nimonme
+ごもんめ;gomonme
+さんもんめ;sanmonme
+やっかい;yakkai
+やくび;yakubi
+さいやく;saiyaku
+やくしん;yakushin
+ひやく;hiyaku
+おどりこむ;odorikomu
+ゆかい;yukai
+ゆえつ;yuetsu
+ゆらく;yuraku
+きょうゆ;kyouyu
+せつゆ;setsuyu
+ゆし;yushi
+ちゆ;chiyu
+へいゆ;heiyu
+ゆごう;yugou
+ゆいいつ;yuiitsu
+ただいま;tadaima
+いいだくだく;iidakudaku
+ゆうきょう;yuukyou
+ゆうげん;yuugen
+ゆうかい;yuukai
+ゆうぜん;yuuzen
+ゆうちょう;yuuchou
+ゆうきゅう;yuukyuu
+ゆうし;yuushi
+ゆうよ;yuuyo
+ゆうよきかん;yuuyokikan
+ゆうふく;yuufuku
+よゆう;yoyuu
+ふゆうかいきゅう;fuyuukaikyuu
+ゆうべん;yuuben
+ゆうしゃ;yuusha
+おうし;oushi
+ゆうわく;yuuwaku
+ゆうどう;yuudou
+さそいみず;sasoimizu
+ゆうしゅう;yuushuu
+うれえがお;ureegao
+ものうい;monoui
+ゆうわ;yuuwa
+きんゆう;kin_yuu
+ゆうずう;yuuzuu
+あたえぬし;ataenushi
+かんよ;kan_yo
+じゅよしき;juyoshiki
+めいよ;meiyo
+えいよ;eiyo
+ほまれたかい;homaretakai
+ちゅうよう;chuuyou
+ぼんよう;bon_you
+そようちょう;soyouchou
+ようすい;yousui
+あげば;ageba
+あげもの;agemono
+どうよう;douyou
+ゆりいす;yuriisu
+ゆれどめ;yuredome
+ようえき;youeki
+ようかい;youkai
+とけあう;tokeau
+ようつう;youtsuu
+こしにく;koshiniku
+ものごし;monogoshi
+おどりこ;odoriko
+ぶよう;buyou
+おどりじ;odoriji
+ようぎょう;yougyou
+ようぎょうか;yougyouka
+かんそうがま;kansougama
+ようご;yougo
+ようりつ;youritsu
+ほうよう;houyou
+ようきょく;youkyoku
+みんよう;min_you
+うたいぼん;utaibon
+よくし;yokushi
+よくあつ;yokuatsu
+よくせい;yokusei
+うよく;uyoku
+よくたん;yokutan
+よくりゅう;yokuryuu
+らしん;rashin
+せきらら;sekirara
+はだかうま;hadakauma
+られつ;raretsu
+らてん;raten
+もうらてき;mourateki
+らいう;raiu
+らいめい;raimei
+ぎょらい;gyorai
+しんらい;shinrai
+たよりない;tayorinai
+たのみ;tanomi
+れんらく;renraku
+からみあう;karamiau
+からみつく;karamitsuku
+らくのう;rakunou
+らくさん;rakusan
+かんらく;kanraku
+らんよう;ran_you
+らんぴ;ranpi
+はんらん;hanran
+らんかん;rankan
+くうらん;kuuran
+らんがい;rangai
+りいん;riin
+のうり;nouri
+りしゅう;rishuu
+げり;geri
+せきり;sekiri
+えきり;ekiri
+りれき;rireki
+りこう;rikou
+はきもの;hakimono
+ぶんり;bunri
+りりく;ririku
+ちばなれ;chibanare
+りゅうし;ryuushi
+かりゅうかい;karyuukai
+せんりゅう;senryuu
+きょうりゅう;kyouryuu
+りゅうじん;ryuujin
+たつまき;tatsumaki
+りゅうし;ryuushi
+ひとつぶ;hitotsubu
+りゅうりゅう;ryuuryuu
+りゅうせい;ryuusei
+りゅうき;ryuuki
+こうりゅう;kouryuu
+りゅうさん;ryuusan
+いおう;iou
+りゅうかぎん;ryuukagin
+りょしゅう;ryoshuu
+ほりょ;horyo
+ふりょ;furyo
+えんりょ;enryo
+こうりょ;kouryo
+むりょ;muryo
+りょうかい;ryoukai
+りょうしょう;ryoushou
+しゅうりょう;shuuryou
+りょうみ;ryoumi
+すずみだい;suzumidai
+すずかぜ;suzukaze
+りょうし;ryoushi
+りょうじゅう;ryoujuu
+しょうりょう;shouryou
+りょうぼ;ryoubo
+きゅうりょう;kyuuryou
+ごりょう;goryou
+どうりょう;douryou
+りょうゆう;ryouyuu
+かんりょう;kanryou
+りょうせい;ryousei
+りょうか;ryouka
+りょうちょう;ryouchou
+りょうほう;ryouhou
+りょうよう;ryouyou
+いりょうはん;iryouhan
+しょくりょう;shokuryou
+ひょうろう;hyourou
+りょうどう;ryoudou
+りんもう;rinmou
+にりん;nirin
+いちぶいちりん;ichibuichirin
+りんり;rinri
+じんりん;jinrin
+ぜつりん;zetsurin
+りんしつ;rinshitsu
+りんせつ;rinsetsu
+となりあう;tonariau
+るいかん;ruikan
+なみだあめ;namidaame
+そらなみだ;soranamida
+るいけい;ruikei
+るいせき;ruiseki
+けいるい;keirui
+どるい;dorui
+てきるい;tekirui
+るいしん;ruishin
+せいれい;seirei
+しょうれいきん;shoureikin
+はげみあう;hagemiau
+もどしぜい;modoshizei
+へんれい;henrei
+もどしそう;modoshisou
+でんれい;denrei
+ふうりん;fuurin
+すずなり;suzunari
+れいさい;reisai
+れいか;reika
+れいらく;reiraku
+ゆうれい;yuurei
+あくりょう;akuryou
+たまや;tamaya
+どれいせい;doreisei
+れいじゅう;reijuu
+れいぞく;reizoku
+ねんれい;nenrei
+みょうれい;myourei
+こうれい;kourei
+れいじん;reijin
+びれい;birei
+しゅうれい;shuurei
+れきねん;rekinen
+せいれき;seireki
+はなごよみ;hanagoyomi
+ひれつ;hiretsu
+れつじょう;retsujou
+れっとう;rettou
+れっか;rekka
+れつじょ;retsujo
+れっぷう;reppuu
+はれつ;haretsu
+ぶんれつ;bunretsu
+さけめ;sakeme
+れんあい;ren_ai
+しつれん;shitsuren
+こいびと;koibito
+れんちょく;renchoku
+れんか;renka
+はれんち;harenchi
+れんきんじゅつ;renkinjutsu
+れんせい;rensei
+ねりがね;nerigane
+ろへん;rohen
+だんろ;danro
+げんしろ;genshiro
+ろしゅつ;roshutsu
+よつゆ;yotsuyu
+ろてん;roten
+しんろう;shinrou
+ろうどう;roudou
+たろう;tarou
+はろう;harou
+ろうひ;rouhi
+ろうにん;rounin
+ろうか;rouka
+がろう;garou
+かいろう;kairou
+しょうろう;shourou
+ぼうろう;bourou
+ろうかく;roukaku
+ろうでん;rouden
+ろうしゅつ;roushutsu
+あまもり;amamori
+しゅうわい;shuuwai
+ぞうわい;zouwai
+まかないつき;makanaitsuki
+めいわく;meiwaku
+わくせい;wakusei
+とまどい;tomadoi
+わくぐみ;wakugumi
+わくなし;wakunashi
+わくない;wakunai
+こうわん;kouwan
+わんにゅう;wannyuu
+とうきょうわん;toukyouwan
+わんしょう;wanshou
+しゅわん;shuwan
+ほそうで;hosoude
+はな;hana
+もも;momo
+ばら;bara
+にほん;nihon
+にほんじん;nihonjin
+がくせい;gakusei
+かいしゃいん;kaishain
+いもうと;imouto
+いとこ;itoko
+ひと;hito
+ぎんこう;ginkou
+ゆうびんきょく;yuubinkyoku
+きって;kitte
+うりば;uriba
+ほん;hon
+びょういん;byouin
+としょかん;toshokan
+とうきょうえき;toukyoueki
+だいがく;daigaku
+しゃしん;shashin
+かいしゃ;kaisha
+じどうしゃ;jidousha
+しゅと;shuto
+めいし;meishi
+しごと;shigoto
+けんちくか;kenchikuka
+おとうと;otouto
+でんきすたんど;denkisutando
+ドイツ;doitsu
+ドイツジン;doitsujin
+カメラ;kamera
+タバコ;tabako
+メガネ;megane
+ノート;nooto
+ボールペン;boorupen
+イギリス;igirisu
+ロンダン;rondan
+びじゅつかん;bijutsukan
+あたり;atari
+ふん;fun
+こうじょう;koujou
+たてもの;tatemono
+げきじょう;gekijou
+まち;machi
+さけ;sake
+うみ;umi
+やま;yama
+みず;mizu
+にほんご;nihongo
+きかい;kikai
+ひとたち;hitotachi
+しょうせつ;shousetsu
+おんな;onna
+おんなのひと;onnanohito
+つぎ;tsugi
+むこう;mukou
+がか;gaka
+やね;yane
+れんが;renga
+タイヤ;taiya
+ホテル;hoteru
+タイプライター;taipuraitaa
+ビル;biru
+コーヒー;koohii
+ちいさい;chiisai
+ながい;nagai
+あかい;akai
+わかい;wakai
+おおきい;ookii
+やさしい;yasashii
+ふるい;furui
+やすい;yasui
+かるい;karui
+つよい;tsuyoi
+とおい;tooi
+しろい;shiroi
+おもい;omoi
+しんせつ;shinsetsu
+しずか;shizuka
+ゆうめい;yuumei
+たいへん;taihen
+とても;totemo
+ふん;fun
+えいぎょうか;eigyouka
+かちょう;kachou
+ほんだな;hondana
+けいさんき;keisanki
+こくばん;kokuban
+えんぴつ;enpitsu
+りんご;ringo
+どうろ;douro
+こども;kodomo
+おんなのこ;onnanoko
+おとこのこ;otokonoko
+いぬ;inu
+とり;tori
+ねこ;neko
+かんこくじん;kankokujin
+かぞく;kazoku
+しゅみ;shumi
+しゅうしゅう;shuushuu
+こうこうせい;koukousei
+きょうだい;kyoudai
+ドア;doa
+カレンダー;karendaa
+ロッカー;rokkaa
+トイレ;toire
+テレビ;terebi
+テーブル;teeburu
+コンピューター;konpyuutaa
+ゴルフ;gorufu
+ごるふじょう;gorufujou
+メンバー;menbaa
+クラブ;kurabu
+ヤード;yaado
+キャヂィー;kyadii
+うえ;ue
+うしろ;ushiro
+ひだり;hidari
+みぎ;migi
+よこ;yoko
+まんなか;mannaka
+おく;oku
+すみ;sumi
+かど;kado
+あいだ;aida
+いま;ima
+つ;tsu
+にん;nin
+さつ;satsu
+ほん;hon
+だい;dai
+ほう;hou
+ほほう;hohou
+はん;han
+ちゅうごくご;chuugokugo
+あさごはん;asagohan
+こうがい;kougai
+えき;eki
+しごと;shigoto
+りょこうしゃ;ryokousha
+してん;shiten
+ぜんこく;zenkoku
+しゅっちょう;shucchou
+しゃいん;shain
+がいしゅつ;gaishutsu
+てがみ;tegami
+てんいん;ten_in
+しゅるい;shurui
+ていか;teika
+めんぜい;menzei
+さつ;satsu
+ほしょうしょ;hoshousho
+じびき;jibiki
+えいご;eigo
+けんぽう;kenpou
+きねんび;kinenbi
+たばこや;tabakoya
+ぶどうしゅ;budoushu
+こうたい;koutai
+タクシー;takushii
+ビール;biiru
+パン;pan
+フイルム;fuirumu
+カラー;karaa
+ネガカラー;negakaraa
+ポジ;poji
+ズームレンズ;zuumurenzu
+ショートズーム;shootozuumu
+ミリ;miri
+ズーム;zuumu
+パスポート;pasupooto
+バス;basu
+きゅうしゅう;kyuushuu
+たいへん;taihen
+よく;yoku
+ときどき;tokidoki
+すこし;sukoshi
+ゆっくり;yukkuri
+めったに;mettani
+あさ;asa
+ひる;hiru
+よる;yoru
+らいしゅう;raishuu
+えん;en
+かい;kai
+ですから;desukara
+それでわ;soredewa
+でわじゃあ;dewajaa
+それから;sorekara
+なるほど;naruhodo
+から;kara
+まで;made
+ほど;hodo
+おきる;okiru
+みる;miru
+テレビおみる;terebiomiru
+いる;iru
+はじめる;hajimeru
+たべる;taberu
+でんわおかける;denwaokakeru
+ある;aru
+あるく;aruku
+いく;iku
+かかる;kakaru
+はじまる;hajimaru
+よむ;yomu
+のむ;nomu
+たばこおすう;tabakoosuu
+まつ;matsu
+しゅっちょうする;shucchousuru
+がいしゅつする;gaishutsusuru
+さんぽする;sanposuru
+ひるごはん;hirugohan
+ばんごはん;bangohan
+ちか;chika
+ちかてつ;chikatetsu
+しょくどう;shokudou
+ろうか;rouka
+いりぐち;iriguchi
+すし;sushi
+ちゅっちょうりょこう;chucchouryokou
+きっぷ;kippu
+こうつうこうしゃ;koutsuukousha
+ざせき;zaseki
+ざせきしていけん;zasekishiteiken
+していせき;shiteiseki
+しんだいけん;shindaiken
+しかた;shikata
+いき;iki
+かえり;kaeri
+はやおき;hayaoki
+こうちゃ;koucha
+ほうこくしょ;houkokusho
+えいが;eiga
+えいがかん;eigakan
+ともだち;tomodachi
+ふく;fuku
+くつ;kutsu
+したぎ;shitagi
+じょうくう;joukuu
+きゅうこう;kyuukou
+きゅうりょう;kyuuryou
+けっこん;kekkon
+なつ;natsu
+あき;aki
+ふゆ;fuyu
+しま;shima
+しまぐに;shimaguni
+おおきさ;ookisa
+じんこうみつど;jinkoumitsudo
+ぜんたい;zentai
+やま;yama
+かざん;kazan
+へいや;heiya
+かわ;kawa
+ゆき;yuki
+あめ;ame
+たいふう;taifuu
+もみじ;momiji
+こうよう;kouyou
+チャンネル;channeru
+エレベーター;erebeetaa
+カレーライス;kareeraisu
+コメヂィー;komedii
+きゅうてい;kyuutei
+ふじん;fujin
+じゅうにひとえ;juunihitoe
+こそで;kosode
+ふだんぎ;fudangi
+きこう;kikou
+そで;sode
+すそ;suso
+かつどう;katsudou
+ようふく;youfuku
+けっこんしき;kekkonshiki
+きかい;kikai
+ガイドブック;gaidobukku
+テント;tento
+ゲーム;geemu
+キャンプファイヤー;kyanpufaiyaa
+ループ;ruupu
+ワンピース;wanpiisu
+ツーピース;tsuupiisu
+スタイル;sutairu
+プウル;puuru
+ちょうせん;chousen
+さっぽろ;sapporo
+ましゅうこ;mashuuko
+しれとこはんとう;shiretokohantou
+ほだか;hodaka
+のりくら;norikura
+みなみアルプス;minamiarupusu
+きただけ;kitadake
+しょうなんかいがん;shounankaigan
+こけでら;kokedera
+おそい;osoi
+ひろい;hiroi
+ユニーク;yuniiku
+せいしき;seishiki
+とくべつ;tokubetsu
+ゆうだい;yuudai
+だいじょうぶ;daijoubu
+ちいさな;chiisana
+おなじ;onaji
+ドイツせい;doitsusei
+そんなに;sonnani
+じつに;jitsuni
+けっして;kesshite
+すこしも;sukoshimo
+あす;asu
+それとも;soretomo
+ばかり;bakari
+しか;shika
+だれも;daremo
+どこにも;dokonimo
+なにも;nanimo
+とも;tomo
+かんじる;kanjiru
+ににる;niniru
+コートをきる;kootowokiru
+かんがえる;kangaeru
+たずねる;tazuneru
+あける;akeru
+かさねる;kasaneru
+にのぼる;ninoboru
+ひらく;hiraku
+しぬ;shinu
+とぶ;tobu
+とまる;tomaru
+テントをはる;tentowoharu
+かこむ;kakomu
+はく;haku
+じゅうじつする;juujitsusuru
+はったつする;hattatsusuru
+にてきする;nitekisuru
+にかんどうする;nikandousuru
+あたり;atari
+しんごう;shingou
+ひゃく;hyaku
+こうさてん;kousaten
+がわ;gawa
+ほう;hou
+みせ;mise
+じしょ;jisho
+きそく;kisoku
+こえ;koe
+しょくじ;shokuji
+わしょく;washoku
+ちゅうかりょうり;chuukaryouri
+すしや;sushiya
+てっか;tekka
+もりあわせ;moriawase
+あかだし;akadashi
+のみもの;nomimono
+さしみ;sashimi
+いたまえ;itamae
+のうぎょう;nougyou
+のうぎょうこく;nougyoukoku
+のうぎょうじんこう;nougyoujinkou
+のうぎょうせいさんぶつ;nougyouseisanbutsu
+せんご;sengo
+せんぜん;senzen
+こうぎょう;kougyou
+こうぎょうこく;kougyoukoku
+ろうどうじんこう;roudoujinkou
+すいさんぎょう;suisangyou
+えんようぎょぎょう;en_yougyogyou
+だいいちじさんぎょう;daiichijisangyou
+だいにじさんぎょう;dainijisangyou
+だいさんじさんぎょう;daisanjisangyou
+サービスぎょう;saabisugyou
+きかいか;kikaika
+まわり;mawari
+えんがん;engan
+はいすい;haisui
+もくざい;mokuzai
+じゅよう;juyou
+きょうきゅう;kyoukyuu
+こくない;kokunai
+こくがい;kokugai
+がいこくじん;gaikokujin
+がいこくご;gaikokugo
+ゆにゅう;yunyuu
+ゆしゅつ;yushutsu
+てつ;tetsu
+どう;dou
+こうぶつ;koubutsu
+せきゆ;sekiyu
+せきたん;sekitan
+メートル;meetoru
+バイク;baiku
+ケーキ;keeki
+ペン;pen
+スウプ;suupu
+ジョギング;jogingu
+さむい;samui
+あつい;atsui
+あつい;atsui
+あたたかい;atatakai
+あたたかい;atatakai
+かわいそう;kawaisou
+きゅうそく;kyuusoku
+おも;omo
+すっかり;sukkari
+もっと;motto
+かならず;kanarazu
+ねんねん;nennen
+やく;yaku
+すぐ;sugu
+もともと;motomoto
+こんや;kon_ya
+このまえ;konomae
+みな;mina
+いっしょに;isshoni
+にちかん;nichikan
+しゅうかん;shuukan
+ねんかん;nenkan
+それに;soreni
+のうち;nouchi
+しめる;shimeru
+よごれる;yogoreru
+ふえる;fueru
+きをつける;kiwotsukeru
+まつ;matsu
+はらう;harau
+はたらく;hataraku
+とまる;tomaru
+まもる;mamoru
+すすむ;susumu
+にへる;niheru
+ねつがある;netsugaaru
+せんたくする;sentakusuru
+しゅっぱつする;shuppatsusuru
+ちゅうもんする;chuumonsuru
+ゆにゅうする;yunyuusuru
+ゆしゅつする;yushutsusuru
+あいさつする;aisatsusuru
+せいさんする;seisansuru
+りっしゅん;risshun
+りっか;rikka
+りっしゅう;risshuu
+りっとう;rittou
+はじまり;hajimari
+おわり;owari
+まなつ;manatsu
+まふゆ;mafuyu
+あつさ;atsusa
+はんじつ;hanjitsu
+はんつき;hantsuki
+はんとし;hantoshi
+かいすいよく;kaisuiyoku
+やまやま;yamayama
+まど;mado
+ぼんおどり;bon_odori
+わらいごえ;waraigoe
+けんぶつにん;kenbutsunin
+わ;wa
+からだ;karada
+くうこう;kuukou
+かいもの;kaimono
+は;ha
+きがえ;kigae
+やきゅう;yakyuu
+しゅうしょく;shuushoku
+こうこがく;koukogaku
+しりょう;shiryou
+てんのうけ;tennouke
+しぞく;shizoku
+うったえ;uttae
+はんだん;handan
+みやこ;miyako
+りゅうがくせい;ryuugakusei
+せいじたいせい;seijitaisei
+かくりつ;kakuritsu
+ちほう;chihou
+せいしん;seishin
+ざいせい;zaisei
+せいりょく;seiryoku
+ヨーロッパ;yooroppa
+ホーム;hoomu
+ドア;doa
+テニス;tenisu
+ラケット;raketto
+コート;kooto
+ベンチ;benchi
+ジュース;juusu
+バレーボール;bareebooru
+バスケットボール;basukettobooru
+スポーツ;supootsu
+テニスシューズ;tenisushuuzu
+ちゅうぶちほう;chuubuchihou
+こじき;kojiki
+じょうもんぶんか;joumonbunka
+やよいぶんか;yayoibunka
+こふんぶんか;kofunbunka
+あすかじだい;asukajidai
+ならじだい;narajidai
+しせいせいど;shiseiseido
+しょうとくたいし;shoutokutaishi
+ほうりゅうじ;houryuuji
+たいかのかいしん;taikanokaishin
+じんしんのらん;jinshinnoran
+とき;toki
+あいだ;aida
+さびしい;sabishii
+さわがしい;sawagashii
+すずしい;suzushii
+せまい;semai
+かしこい;kashikoi
+むしあつい;mushiatsui
+せいしんてき;seishinteki
+ざいせいてき;zaiseiteki
+いわゆる;iwayuru
+わが;waga
+ずっと;zutto
+すこし;sukoshi
+そのご;sonogo
+シャワーをあびる;shawaawoabiru
+のびる;nobiru
+ながれる;nagareru
+ながれる;nagareru
+ながれる;nagareru
+ラジオをつける;rajiowotsukeru
+ベンチにこしかける;benchinikoshikakeru
+わすれる;wasureru
+うったえる;uttaeru
+たてる;tateru
+つたえる;tsutaeru
+ごちそうをつくる;gochisouwotsukuru
+はく;haku
+ねむる;nemuru
+すわる;suwaru
+うごく;ugoku
+しまる;shimaru
+はをみがく;hawomigaku
+ねがう;negau
+とる;toru
+つくる;tsukuru
+つくる;tsukuru
+はんだんをくだす;handanwokudasu
+うつる;utsuru
+こまる;komaru
+うんてんする;untensuru
+しゅうしょくする;shuushokusuru
+かくりつする;kakuritsusuru
+しょくじをする;shokujiwosuru
+かいものをする;kaimonowosuru
+きがえをする;kigaewosuru
+テニスをする;tenisuwosuru
+やきゅうをする;yakyuuwosuru
+りゅうがくする;ryuugakusuru
+ちきゅう;chikyuu
+もとめる;motomeru
+すくう;sukuu
+やきもち;yakimochi
+すなお;sunao
+たいした;taishita
+うつ;utsu
+いじょう;ijou
+きゅうし;kyuushi
+びっくり;bikkuri
+みちしお;michishio
+をのぼる;wonoboru
+そびえとしゃかいしゅぎきょうわこくれんぽう;sobietoshakaishugikyouwakokurenpou
+ふけんこう;fukenkou
diff --git a/_test/cases/inc/utf8_romanize.test.php b/_test/cases/inc/utf8_romanize.test.php
new file mode 100644
index 000000000..950c8842a
--- /dev/null
+++ b/_test/cases/inc/utf8_romanize.test.php
@@ -0,0 +1,36 @@
+<?php
+// use no mbstring help here
+if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
+require_once DOKU_INC.'inc/utf8.php';
+
+class utf8_romanize_test extends UnitTestCase {
+
+ /**
+ * Check Japanese romanization
+ *
+ * @author Denis Scheither <amorphis@uni-bremen.de>
+ */
+ function test_japanese(){
+ $tests = file(dirname(__FILE__).'/utf8_kanaromaji.txt');
+ $line = 1;
+ foreach($tests as $test){
+ list($jap,$rom) = explode(';',trim($test));
+
+ $chk = utf8_romanize($jap);
+ #if($chk != $rom) echo "$jap\t->\t$chk\t!=\t$rom\t($line)\n";
+ $this->assertEqual($chk,$rom);
+ $line++;
+ }
+ }
+
+ /**
+ * Test romanization of character that would usually be deaccented in a different
+ * way FS#1117
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function test_deaccented(){
+ $this->assertEqual("a A a A a o O",utf8_romanize("å Å ä Ä ä ö Ö"));
+ }
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/utf8_stripspecials.test.php b/_test/cases/inc/utf8_stripspecials.test.php
new file mode 100644
index 000000000..481f47650
--- /dev/null
+++ b/_test/cases/inc/utf8_stripspecials.test.php
@@ -0,0 +1,28 @@
+<?php
+// use no mbstring help here
+if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
+require_once DOKU_INC.'inc/utf8.php';
+
+class utf8_stripspecials extends UnitTestCase {
+
+
+ function test1(){
+ // we test multiple cases here - format: string, repl, additional, test
+ $tests = array();
+ $tests[] = array('asciistring','','','asciistring');
+ $tests[] = array('asciistring','','\._\-:','asciistring');
+ $tests[] = array('ascii.string','','\._\-:','asciistring');
+ $tests[] = array('ascii.string',' ','\._\-:','ascii string');
+ $tests[] = array('2.1.14',' ','\._\-:','2 1 14');
+ $tests[] = array('ascii.string','','\._\-:\*','asciistring');
+ $tests[] = array('ascii.string',' ','\._\-:\*','ascii string');
+ $tests[] = array('2.1.14',' ','\._\-:\*','2 1 14');
+ $tests[] = array('string with nbsps','_','\*','string_with_nbsps');
+
+ foreach($tests as $test){
+ $this->assertEqual(utf8_stripspecials($test[0],$test[1],$test[2]),$test[3]);
+ }
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/utf8_substr.test.php b/_test/cases/inc/utf8_substr.test.php
new file mode 100644
index 000000000..2806d34f1
--- /dev/null
+++ b/_test/cases/inc/utf8_substr.test.php
@@ -0,0 +1,43 @@
+<?php
+// use no mbstring help here
+if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
+require_once DOKU_INC.'inc/utf8.php';
+
+class utf8_substr_test extends UnitTestCase {
+
+
+ function test1(){
+ // we test multiple cases here - format: in, offset, length, out
+ $tests = array();
+ $tests[] = array('asciistring',2,null,'ciistring');
+ $tests[] = array('asciistring',2,4,'ciis');
+ $tests[] = array('asciistring',-4,null,'ring');
+ $tests[] = array('asciistring',2,-4,'ciist');
+ $tests[] = array('asciistring',-6,-2,'stri');
+
+ $tests[] = array('живπά우리をあöä',2,null,'вπά우리をあöä');
+ $tests[] = array('живπά우리をあöä',2,4,'вπά우');
+ $tests[] = array('живπά우리をあöä',-4,null,'をあöä');
+ $tests[] = array('живπά우리をあöä',2,-4,'вπά우리');
+ $tests[] = array('живπά우리をあöä',-6,-2,'우리をあ');
+
+ foreach($tests as $test){
+ $this->assertEqual(utf8_substr($test[0],$test[1],$test[2]),$test[3]);
+ }
+ }
+
+ function test2_bug891() {
+ // we test multiple cases here - format: in, offset, length, out
+ $tests = array();
+
+ $str = str_repeat('в',66000).'@@';
+ $tests[] = array($str, 65600, 1, 'в');
+ $tests[] = array($str,0,66002,$str);
+
+ foreach($tests as $test){
+ $this->assertEqual(utf8_substr($test[0],$test[1],$test[2]),$test[3]);
+ }
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/utf8_unicode.test.php b/_test/cases/inc/utf8_unicode.test.php
new file mode 100644
index 000000000..424f47d11
--- /dev/null
+++ b/_test/cases/inc/utf8_unicode.test.php
@@ -0,0 +1,60 @@
+<?php
+
+require_once DOKU_INC.'inc/utf8.php';
+
+// use no mbstring help here
+if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
+
+class utf8_unicode_test extends UnitTestCase {
+
+ function test_from_1byte(){
+ $in = 'a';
+ $out = array(97);
+ $this->assertEqual(utf8_to_unicode($in),$out);
+ }
+
+ function test_from_2byte(){
+ $in = "\xc3\xbc";
+ $out = array(252);
+ $this->assertEqual(utf8_to_unicode($in),$out);
+ }
+
+ function test_from_3byte(){
+ $in = "\xe2\x99\x8a";
+ $out = array(9802);
+ $this->assertEqual(utf8_to_unicode($in),$out);
+ }
+
+ function test_from_4byte(){
+ $in = "\xf4\x80\x80\x81";
+ $out = array(1048577);
+ $this->assertEqual(utf8_to_unicode($in),$out);
+ }
+
+ function test_to_1byte(){
+ $out = 'a';
+ $in = array(97);
+ $this->assertEqual(unicode_to_utf8($in),$out);
+ }
+
+ function test_to_2byte(){
+ $out = "\xc3\xbc";
+ $in = array(252);
+ $this->assertEqual(unicode_to_utf8($in),$out);
+ }
+
+ function test_to_3byte(){
+ $out = "\xe2\x99\x8a";
+ $in = array(9802);
+ $this->assertEqual(unicode_to_utf8($in),$out);
+ }
+
+ function test_to_4byte(){
+ $out = "\xf4\x80\x80\x81";
+ $in = array(1048577);
+ $this->assertEqual(unicode_to_utf8($in),$out);
+ }
+
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/inc/utf8_utf16be.test.php b/_test/cases/inc/utf8_utf16be.test.php
new file mode 100644
index 000000000..d8b8746f2
--- /dev/null
+++ b/_test/cases/inc/utf8_utf16be.test.php
@@ -0,0 +1,28 @@
+<?php
+
+require_once DOKU_INC.'inc/utf8.php';
+
+// use no mbstring help here
+if(!defined('UTF8_NOMBSTRING')) define('UTF8_NOMBSTRING',1);
+
+class utf8_utf16be_test extends UnitTestCase {
+ // some chars from various code regions
+ var $utf8 = '鈩ℵŁöx';
+ var $utf16 = "\x92\x29\x21\x35\x1\x41\x0\xf6\x0\x78";
+
+ /**
+ * Convert from UTF-8 to UTF-16BE
+ */
+ function test_to16be(){
+ $this->assertEqual(utf8_to_utf16be($this->utf8), $this->utf16);
+ }
+
+ /**
+ * Convert from UTF-16BE to UTF-8
+ */
+ function test_from16be(){
+ $this->assertEqual(utf16be_to_utf8($this->utf16),$this->utf8);
+ }
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/_test/cases/lib/exe/css_css_compress.test.php b/_test/cases/lib/exe/css_css_compress.test.php
new file mode 100644
index 000000000..527071bbe
--- /dev/null
+++ b/_test/cases/lib/exe/css_css_compress.test.php
@@ -0,0 +1,68 @@
+<?php
+
+require_once DOKU_INC.'lib/exe/css.php';
+
+
+class css_css_compress_test extends UnitTestCase {
+
+ function test_mlcom1(){
+ $text = '/**
+ * A multi
+ * line *test*
+ * check
+ */';
+ $this->assertEqual(css_compress($text), '');
+ }
+
+ function test_mlcom2(){
+ $text = '#comment/* */ {
+ color: lime;
+ }';
+ $this->assertEqual(css_compress($text), '#comment/* */{color:lime;}');
+ }
+
+ function test_slcom1(){
+ $text = '// this is a comment';
+ $this->assertEqual(css_compress($text), '');
+ }
+
+ function test_slcom2(){
+ $text = '#foo {
+ color: lime; // another comment
+ }';
+ $this->assertEqual(css_compress($text), '#foo{color:lime;}');
+ }
+
+ function test_slcom3(){
+ $text = '#foo {
+ background-image: url(http://foo.bar/baz.jpg);
+ }';
+ $this->assertEqual(css_compress($text), '#foo{background-image:url(http://foo.bar/baz.jpg);}');
+ }
+
+ function test_hack(){
+ $text = '/* Mac IE will not see this and continue with inline-block */
+ /* \\*/
+ display: inline;
+ /* */';
+ $this->assertEqual(css_compress($text), '/* \\*/display:inline;/* */');
+ }
+
+ function test_hack2(){
+ $text = '/* min-height hack for Internet Explorer http://www.cssplay.co.uk/boxes/minheight.html */
+ /*\\*/
+ * html .page {
+ height: 450px;
+ }
+ /**/';
+ $this->assertEqual(css_compress($text), '/*\\*/* html .page{height:450px;}/**/');
+ }
+
+ function test_nl1(){
+ $text = "a{left:20px;\ntop:20px}";
+ $this->assertEqual(css_compress($text), 'a{left:20px;top:20px}');
+ }
+
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/lib/exe/css_css_loadfile.test.php b/_test/cases/lib/exe/css_css_loadfile.test.php
new file mode 100644
index 000000000..a444d0086
--- /dev/null
+++ b/_test/cases/lib/exe/css_css_loadfile.test.php
@@ -0,0 +1,57 @@
+<?php
+
+require_once DOKU_INC.'lib/exe/css.php';
+
+class css_css_loadfile_test extends UnitTestCase {
+ public function setUp() {
+ $this->file = tempnam('/tmp', 'css');
+ parent::setUp();
+ }
+
+ private function csstest($input, $output = null, $location = 'http://www.example.com/') {
+ io_saveFile($this->file, $input);
+ $this->assertEqual(css_loadfile($this->file, $location), (is_null($output) ? $input : $output));
+ }
+
+ public function test_url_relative() {
+ $this->csstest('#test { background: url("test/test.png"); }', '#test { background: url("http://www.example.com/test/test.png"); }');
+ $this->csstest('#test { background: url(\'test/test.png\'); }', '#test { background: url(\'http://www.example.com/test/test.png\'); }');
+ }
+
+ public function test_url_absolute() {
+ $this->csstest('#test { background: url("/test/test.png"); }');
+ $this->csstest('#test { background: url(\'/test/test.png\'); }');
+ }
+
+ public function test_url_with_protocol() {
+ $this->csstest('#test { background: url("http://www.test.com/test/test.png"); }');
+ $this->csstest('#test { background: url("https://www.test.com/test/test.png"); }');
+ $this->csstest('#test { background: url(\'http://www.test.com/test/test.png\'); }');
+ $this->csstest('#test { background: url(\'https://www.test.com/test/test.png\'); }');
+ }
+
+ public function test_import_relative() {
+ $this->csstest('@import "test/test.png";', '@import "http://www.example.com/test/test.png";');
+ $this->csstest('@import \'test/test.png\';', '@import \'http://www.example.com/test/test.png\';');
+ }
+
+ public function test_import_absolute() {
+ $this->csstest('@import "/test/test.png";');
+ $this->csstest('@import \'/test/test.png\';');
+ }
+
+ public function test_import_with_protocol() {
+ $this->csstest('@import "http://www.test.com/test/test.png";');
+ $this->csstest('@import "https://www.test.com/test/test.png";');
+ $this->csstest('@import \'http://www.test.com/test/test.png\';');
+ $this->csstest('@import \'https://www.test.com/test/test.png\';');
+ }
+
+ public function tearDown() {
+ unlink($this->file);
+ unset($this->file);
+ parent::tearDown();
+ }
+}
+
+//Setup VIM: ex: et ts=4 sw=4 :
diff --git a/_test/cases/lib/exe/js_js_compress.test.php b/_test/cases/lib/exe/js_js_compress.test.php
new file mode 100644
index 000000000..4702d35d3
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress.test.php
@@ -0,0 +1,129 @@
+<?php
+
+require_once DOKU_INC.'lib/exe/js.php';
+
+
+class js_js_compress_test extends UnitTestCase {
+
+ function test_mlcom1(){
+ $text = '/**
+ * A multi
+ * line *test*
+ * check
+ */';
+ $this->assertEqual(js_compress($text), '');
+ }
+
+ function test_mlcom2(){
+ $text = 'var foo=6;/* another comment */';
+ $this->assertEqual(js_compress($text), 'var foo=6;');
+ }
+
+ function test_mlcomcond(){
+ $text = '/*@if (@_win32)';
+ $this->assertEqual(js_compress($text), '/*@if(@_win32)');
+ }
+
+ function test_slcom1(){
+ $text = '// an comment';
+ $this->assertEqual(js_compress($text), '');
+ }
+
+ function test_slcom2(){
+ $text = 'var foo=6;// another comment ';
+ $this->assertEqual(js_compress($text), 'var foo=6;');
+ }
+
+ function test_slcom3(){
+ $text = 'var foo=6;// another comment / or something with // comments ';
+ $this->assertEqual(js_compress($text), 'var foo=6;');
+ }
+
+ function test_regex1(){
+ $text = 'foo.split( /[a-Z\/]*/ );';
+ $this->assertEqual(js_compress($text), 'foo.split(/[a-Z\/]*/);');
+ }
+
+ function test_regex_in_array(){
+ $text = '[/"/ , /"/ , /"/]';
+ $this->assertEqual(js_compress($text), '[/"/,/"/,/"/]');
+ }
+
+ function test_regex_in_hash(){
+ $text = '{ a : /"/ }';
+ $this->assertEqual(js_compress($text), '{a:/"/}');
+ }
+
+ function test_regex_preceded_by_spaces_caracters(){
+ $text = "text.replace( \t \r\n /\"/ , ".'"//" )';
+ $this->assertEqual(js_compress($text), 'text.replace(/"/,"//")');
+ }
+
+ function test_dquot1(){
+ $text = 'var foo="Now what \\" \'do we//get /*here*/ ?";';
+ $this->assertEqual(js_compress($text), $text);
+ }
+
+ function test_dquot2(){
+ $text = 'var foo="Now what \\\\\\" \'do we//get /*here*/ ?";';
+ $this->assertEqual(js_compress($text), $text);
+ }
+
+ function test_dquotrunaway(){
+ $text = 'var foo="Now where does it end';
+ $this->assertEqual(js_compress($text), $text);
+ }
+
+ function test_squot1(){
+ $text = "var foo='Now what \\' \"do we//get /*here*/ ?';";
+ $this->assertEqual(js_compress($text), $text);
+ }
+
+ function test_squotrunaway(){
+ $text = "var foo='Now where does it end";
+ $this->assertEqual(js_compress($text), $text);
+ }
+
+ function test_nl1(){
+ $text = "var foo=6;\nvar baz=7;";
+ $this->assertEqual(js_compress($text), 'var foo=6;var baz=7;');
+ }
+
+ function test_lws1(){
+ $text = " \t var foo=6;";
+ $this->assertEqual(js_compress($text), 'var foo=6;');
+ }
+
+ function test_tws1(){
+ $text = "var foo=6; \t ";
+ $this->assertEqual(js_compress($text), 'var foo=6;');
+ }
+
+ function test_shortcond(){
+ $text = "var foo = (baz) ? 'bar' : 'bla';";
+ $this->assertEqual(js_compress($text), "var foo=(baz)?'bar':'bla';");
+
+ }
+
+ function test_complexminified(){
+ $text = 'if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class=\'test e\'></div><div class=\'test\'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;foo="text/*";bla="*/"';
+
+ $this->assertEqual(js_compress($text),$text);
+ }
+
+ /**
+ * Test the files provided with the original JsStrip
+ */
+ function test_original(){
+ $files = glob(dirname(__FILE__).'/js_js_compress/test-*-in.js');
+
+ foreach($files as $file){
+ $info = "Using file $file";
+ $this->signal('failinfo',$info);
+ $this->assertEqual(js_compress(file_get_contents($file)),
+ file_get_contents(substr($file,0,-5).'out.js'));
+ };
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes1-in.js b/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes1-in.js
new file mode 100644
index 000000000..771dc1640
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes1-in.js
@@ -0,0 +1,5 @@
+
+ var s = " /* this is a comment */ " ;
+
+
+
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes1-out.js b/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes1-out.js
new file mode 100644
index 000000000..7d6a5346e
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes1-out.js
@@ -0,0 +1 @@
+var s=" /* this is a comment */ "; \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes2-in.js b/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes2-in.js
new file mode 100644
index 000000000..a59f1b774
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes2-in.js
@@ -0,0 +1,5 @@
+
+
+var s = "// this is a comment ";
+
+
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes2-out.js b/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes2-out.js
new file mode 100644
index 000000000..caa2fdca2
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentInDoubleQuotes2-out.js
@@ -0,0 +1 @@
+var s="// this is a comment "; \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes1-in.js b/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes1-in.js
new file mode 100644
index 000000000..845c59bdf
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes1-in.js
@@ -0,0 +1,5 @@
+
+ var s = ' /* this is a comment */ ' ;
+
+
+
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes1-out.js b/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes1-out.js
new file mode 100644
index 000000000..b2696cb98
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes1-out.js
@@ -0,0 +1 @@
+var s=' /* this is a comment */ '; \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes2-in.js b/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes2-in.js
new file mode 100644
index 000000000..0459a4891
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes2-in.js
@@ -0,0 +1,5 @@
+
+
+var s = '// this is a comment ';
+
+
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes2-out.js b/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes2-out.js
new file mode 100644
index 000000000..21b6a410e
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentInSingleQuotes2-out.js
@@ -0,0 +1 @@
+var s='// this is a comment '; \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentMultiline-in.js b/_test/cases/lib/exe/js_js_compress/test-CommentMultiline-in.js
new file mode 100644
index 000000000..b9d16a7bd
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentMultiline-in.js
@@ -0,0 +1,11 @@
+
+ if (true) {
+ /* this
+ * is a
+ * multiline comment */
+ document.write("true"); /* this
+ is another
+ */
+
+}
+
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentMultiline-out.js b/_test/cases/lib/exe/js_js_compress/test-CommentMultiline-out.js
new file mode 100644
index 000000000..8eed2e57a
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentMultiline-out.js
@@ -0,0 +1 @@
+if(true){document.write("true");} \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentSingleLine-in.js b/_test/cases/lib/exe/js_js_compress/test-CommentSingleLine-in.js
new file mode 100644
index 000000000..302d7160b
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentSingleLine-in.js
@@ -0,0 +1,7 @@
+
+ if (true) {
+ // this is a single line comment
+ document.write("true") ; // another
+}
+
+
diff --git a/_test/cases/lib/exe/js_js_compress/test-CommentSingleLine-out.js b/_test/cases/lib/exe/js_js_compress/test-CommentSingleLine-out.js
new file mode 100644
index 000000000..8eed2e57a
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-CommentSingleLine-out.js
@@ -0,0 +1 @@
+if(true){document.write("true");} \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-IfThenElseBraces-in.js b/_test/cases/lib/exe/js_js_compress/test-IfThenElseBraces-in.js
new file mode 100644
index 000000000..afc824762
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-IfThenElseBraces-in.js
@@ -0,0 +1,7 @@
+
+
+if ( true ) {
+ document.write("foo");
+} else {
+ document.write("bar");
+}
diff --git a/_test/cases/lib/exe/js_js_compress/test-IfThenElseBraces-out.js b/_test/cases/lib/exe/js_js_compress/test-IfThenElseBraces-out.js
new file mode 100644
index 000000000..2a982a98e
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-IfThenElseBraces-out.js
@@ -0,0 +1 @@
+if(true){document.write("foo");}else{document.write("bar");} \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-IfThenElseNoBraces-in.js b/_test/cases/lib/exe/js_js_compress/test-IfThenElseNoBraces-in.js
new file mode 100644
index 000000000..79d10775e
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-IfThenElseNoBraces-in.js
@@ -0,0 +1,7 @@
+
+
+if ( true )
+ document.write("foo");
+ else
+ document.write("bar");
+
diff --git a/_test/cases/lib/exe/js_js_compress/test-IfThenElseNoBraces-out.js b/_test/cases/lib/exe/js_js_compress/test-IfThenElseNoBraces-out.js
new file mode 100644
index 000000000..b087c42fc
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-IfThenElseNoBraces-out.js
@@ -0,0 +1 @@
+if(true)document.write("foo");else document.write("bar"); \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-RegexpBackslash-in.js b/_test/cases/lib/exe/js_js_compress/test-RegexpBackslash-in.js
new file mode 100644
index 000000000..503e07283
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-RegexpBackslash-in.js
@@ -0,0 +1,3 @@
+
+var r = / a backslash\// ;
+
diff --git a/_test/cases/lib/exe/js_js_compress/test-RegexpBackslash-out.js b/_test/cases/lib/exe/js_js_compress/test-RegexpBackslash-out.js
new file mode 100644
index 000000000..e5c83770c
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-RegexpBackslash-out.js
@@ -0,0 +1 @@
+var r=/ a backslash\//; \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-RegexpSimple-in.js b/_test/cases/lib/exe/js_js_compress/test-RegexpSimple-in.js
new file mode 100644
index 000000000..2741e74c2
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-RegexpSimple-in.js
@@ -0,0 +1,3 @@
+
+
+var r = /simple/g ;
diff --git a/_test/cases/lib/exe/js_js_compress/test-RegexpSimple-out.js b/_test/cases/lib/exe/js_js_compress/test-RegexpSimple-out.js
new file mode 100644
index 000000000..bb530b0a1
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-RegexpSimple-out.js
@@ -0,0 +1 @@
+var r=/simple/g; \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-RegexpSimpleWhitespace-in.js b/_test/cases/lib/exe/js_js_compress/test-RegexpSimpleWhitespace-in.js
new file mode 100644
index 000000000..c7dbdba3d
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-RegexpSimpleWhitespace-in.js
@@ -0,0 +1,5 @@
+
+
+ var r = / simple with whitespace /g ;
+
+
diff --git a/_test/cases/lib/exe/js_js_compress/test-RegexpSimpleWhitespace-out.js b/_test/cases/lib/exe/js_js_compress/test-RegexpSimpleWhitespace-out.js
new file mode 100644
index 000000000..5c2db510b
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-RegexpSimpleWhitespace-out.js
@@ -0,0 +1 @@
+var r=/ simple with whitespace /g; \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-RegexpString-in.js b/_test/cases/lib/exe/js_js_compress/test-RegexpString-in.js
new file mode 100644
index 000000000..debb983e5
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-RegexpString-in.js
@@ -0,0 +1,3 @@
+
+ var r = "fruit" ;
+ r.replace ( /fruit/g, "apple") ;
diff --git a/_test/cases/lib/exe/js_js_compress/test-RegexpString-out.js b/_test/cases/lib/exe/js_js_compress/test-RegexpString-out.js
new file mode 100644
index 000000000..92ffc7d47
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-RegexpString-out.js
@@ -0,0 +1 @@
+var r="fruit";r.replace(/fruit/g,"apple"); \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-StatementDoWhile-in.js b/_test/cases/lib/exe/js_js_compress/test-StatementDoWhile-in.js
new file mode 100644
index 000000000..0c84c66ec
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StatementDoWhile-in.js
@@ -0,0 +1,2 @@
+var x = 0;
+ do x=x+1 while (x < 10);
diff --git a/_test/cases/lib/exe/js_js_compress/test-StatementDoWhile-out.js b/_test/cases/lib/exe/js_js_compress/test-StatementDoWhile-out.js
new file mode 100644
index 000000000..593e9a664
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StatementDoWhile-out.js
@@ -0,0 +1 @@
+var x=0;do x=x+1 while(x<10); \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-StatementForIn-in.js b/_test/cases/lib/exe/js_js_compress/test-StatementForIn-in.js
new file mode 100644
index 000000000..1b0aeb6ff
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StatementForIn-in.js
@@ -0,0 +1,2 @@
+for ( var x in foo )
+ document.write(x);
diff --git a/_test/cases/lib/exe/js_js_compress/test-StatementForIn-out.js b/_test/cases/lib/exe/js_js_compress/test-StatementForIn-out.js
new file mode 100644
index 000000000..95c85871e
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StatementForIn-out.js
@@ -0,0 +1 @@
+for(var x in foo)document.write(x); \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-StatementNew-in.js b/_test/cases/lib/exe/js_js_compress/test-StatementNew-in.js
new file mode 100644
index 000000000..61f357f34
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StatementNew-in.js
@@ -0,0 +1 @@
+var x = new Object(); \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-StatementNew-out.js b/_test/cases/lib/exe/js_js_compress/test-StatementNew-out.js
new file mode 100644
index 000000000..0d4ff7f58
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StatementNew-out.js
@@ -0,0 +1 @@
+var x=new Object(); \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-StatementSwitchCase-in.js b/_test/cases/lib/exe/js_js_compress/test-StatementSwitchCase-in.js
new file mode 100644
index 000000000..39ffc1239
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StatementSwitchCase-in.js
@@ -0,0 +1,4 @@
+var x = 1;
+switch (x) {
+ case 1: document.write(1);
+} \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-StatementSwitchCase-out.js b/_test/cases/lib/exe/js_js_compress/test-StatementSwitchCase-out.js
new file mode 100644
index 000000000..e51c07371
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StatementSwitchCase-out.js
@@ -0,0 +1 @@
+var x=1;switch(x){case 1:document.write(1);} \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-StringDoubleQuotes-in.js b/_test/cases/lib/exe/js_js_compress/test-StringDoubleQuotes-in.js
new file mode 100644
index 000000000..57fe13b90
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StringDoubleQuotes-in.js
@@ -0,0 +1,3 @@
+
+var s1 = "double \"quotes\"" ;
+var s2 = "'test'" ;
diff --git a/_test/cases/lib/exe/js_js_compress/test-StringDoubleQuotes-out.js b/_test/cases/lib/exe/js_js_compress/test-StringDoubleQuotes-out.js
new file mode 100644
index 000000000..9f91fc83d
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StringDoubleQuotes-out.js
@@ -0,0 +1 @@
+var s1="double \"quotes\"";var s2="'test'"; \ No newline at end of file
diff --git a/_test/cases/lib/exe/js_js_compress/test-StringSingleQuotes-in.js b/_test/cases/lib/exe/js_js_compress/test-StringSingleQuotes-in.js
new file mode 100644
index 000000000..bb5f9951a
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StringSingleQuotes-in.js
@@ -0,0 +1,8 @@
+
+var s1 = 'single \'quotes\' ' ;
+
+var s2= '/* test */' ;
+
+var s3 = '// test' ;
+
+var s4 = '"test"' ;
diff --git a/_test/cases/lib/exe/js_js_compress/test-StringSingleQuotes-out.js b/_test/cases/lib/exe/js_js_compress/test-StringSingleQuotes-out.js
new file mode 100644
index 000000000..f38b26544
--- /dev/null
+++ b/_test/cases/lib/exe/js_js_compress/test-StringSingleQuotes-out.js
@@ -0,0 +1 @@
+var s1='single \'quotes\' ';var s2='/* test */';var s3='// test';var s4='"test"'; \ No newline at end of file
diff --git a/_test/debug.note b/_test/debug.note
new file mode 100644
index 000000000..28c34d8ee
--- /dev/null
+++ b/_test/debug.note
@@ -0,0 +1,4 @@
+print "-----------------------------------------------------\n";
+print_r(array_map('stripbyteindex',$this->H->calls));
+print "-----------------------------------------------------\n";
+print_r($calls);
diff --git a/_test/index.php b/_test/index.php
new file mode 100644
index 000000000..f59c44cf4
--- /dev/null
+++ b/_test/index.php
@@ -0,0 +1,228 @@
+<?php
+define('DOKU_UNITTEST',true);
+define('DOKU_TESTSCRIPT',$_SERVER['PHP_SELF']);
+
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+define('DOKU_CONF',realpath(dirname(__FILE__).'/../conf').'/');
+
+require_once DOKU_CONF . 'dokuwiki.php';
+if(@file_exists(DOKU_CONF.'local.php')){ require_once(DOKU_CONF.'local.php'); }
+
+$conf['lang'] = 'en';
+define('TEST_ROOT', dirname(__FILE__));
+define('TMPL_FILESCHEME_PATH', TEST_ROOT . '/filescheme/');
+error_reporting(E_ALL);
+
+set_time_limit(600);
+ini_set('memory_limit','128M');
+
+/* Used to determine output to display */
+define('DW_TESTS_OUTPUT_HTML',1);
+define('DW_TESTS_OUTPUT_XML',2);
+
+if ( isset($_GET['output']) && $_GET['output'] == 'xml' ) {
+ define('DW_TESTS_OUTPUT',DW_TESTS_OUTPUT_XML);
+} else {
+ define('DW_TESTS_OUTPUT',DW_TESTS_OUTPUT_HTML);
+}
+
+require_once 'lib/testmanager.php';
+TestManager::setup('tests.ini');
+
+if ( !defined('SIMPLE_TEST') ) {
+ define('SIMPLE_TEST', ConfigManager::getOptionAsPath('tests', 'simpletest', 'library_path'));
+}
+
+if (!@include_once SIMPLE_TEST . 'reporter.php') {
+ RaiseError('runtime', 'LIBRARY_REQUIRED', array(
+ 'library' => 'Simple Test',
+ 'path' => SIMPLE_TEST));
+}
+
+function & DW_TESTS_GetReporter() {
+ static $Reporter = NULL;
+ if ( !$Reporter ) {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ require_once SIMPLE_TEST . 'xml.php';
+ $Reporter = new XmlReporter();
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ $Reporter = new HTMLReporter('utf-8');
+ break;
+ }
+ }
+ return $Reporter;
+}
+
+function DW_TESTS_PaintRunMore() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo "<p><a href='" . DOKU_TESTSCRIPT . "'>Run more tests</a></p>";
+ break;
+ }
+}
+
+function DW_TESTS_PaintHeader() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ header('Content-Type: text/xml; charset="utf-8"');
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ $header = <<<EOD
+<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
+ 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
+<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
+ <head>
+ <meta http-equiv='Content-Type'
+ content='text/html; charset=iso-8859-1' />
+
+ <title>Dokuwiki: Unit Test Suite</title>
+ <link href="tests.css" type="text/css" rel="stylesheet" media="all"/>
+
+ </head>
+ <body>
+EOD;
+ echo $header;
+ default:
+ break;
+ }
+}
+
+function DW_TESTS_PaintSuiteHeader() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo "<h1>Dokuwiki: Unit Test Suite</h1>\n";
+ echo "<p><a href='". DOKU_TESTSCRIPT ."?show=groups'>Test groups</a>";
+ echo " || <a href='". DOKU_TESTSCRIPT ."?show=cases'>Test cases</a></p>";
+ break;
+ }
+}
+
+function DW_TESTS_PaintCaseList() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ echo XMLTestManager::getTestCaseList(TEST_CASES);
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo HTMLTestManager::getTestCaseList(TEST_CASES);
+ break;
+ }
+}
+
+function DW_TESTS_PaintGroupTestList() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ echo XMLTestManager::getGroupTestList(TEST_GROUPS);
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo HTMLTestManager::getGroupTestList(TEST_GROUPS);
+ break;
+ }
+}
+
+function DW_TESTS_PaintPluginTestCaseList() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ echo XMLTestManager::getPluginTestCaseList(TEST_PLUGINS);
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo HTMLTestManager::getPluginTestCaseList(TEST_PLUGINS);
+ break;
+ }
+}
+
+function DW_TESTS_PaintPluginGroupTestList() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ echo XMLTestManager::getPluginGroupTestList(TEST_PLUGINS);
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ echo HTMLTestManager::getPluginGroupTestList(TEST_PLUGINS);
+ break;
+ }
+}
+
+function DW_TESTS_PaintFooter() {
+ switch ( DW_TESTS_OUTPUT ) {
+ case DW_TESTS_OUTPUT_XML:
+ break;
+ case DW_TESTS_OUTPUT_HTML:
+ default:
+ $footer = <<<EOD
+ </body>
+</html>
+EOD;
+ echo $footer;
+ break;
+ }
+}
+
+/** OUTPUT STARTS HERE **/
+
+// If it's a group test
+if (isset($_GET['group'])) {
+ if ('all' == $_GET['group']) {
+ TestManager::runAllTests(DW_TESTS_GetReporter());
+ } else {
+ TestManager::runGroupTest(ucfirst($_GET['group']),
+ TEST_GROUPS,
+ DW_TESTS_GetReporter());
+ }
+ DW_TESTS_PaintRunMore();
+ exit();
+}
+
+// If it's a plugin group test
+if (isset($_GET['plugin_group'])) {
+ if ('all' == $_GET['plugin_group']) {
+ TestManager::runAllPluginTests(DW_TESTS_GetReporter());
+ } else {
+ TestManager::runGroupTest(ucfirst($_GET['plugin_group']),
+ TEST_PLUGINS,
+ DW_TESTS_GetReporter());
+ }
+ DW_TESTS_PaintRunMore();
+ exit();
+}
+
+// If it's a single test case
+if (isset($_GET['case'])) {
+ TestManager::runTestCase($_GET['case'], TEST_CASES, DW_TESTS_GetReporter());
+ DW_TESTS_PaintRunMore();
+ exit();
+}
+
+// If it's a single plugin test case
+if (isset($_GET['plugin_case'])) {
+ TestManager::runTestCase($_GET['plugin_case'], TEST_PLUGINS, DW_TESTS_GetReporter());
+ DW_TESTS_PaintRunMore();
+ exit();
+}
+
+// Else it's the main page
+DW_TESTS_PaintHeader();
+
+DW_TESTS_PaintSuiteHeader();
+
+if (isset($_GET['show']) && $_GET['show'] == 'cases') {
+ DW_TESTS_PaintCaseList();
+ DW_TESTS_PaintPluginTestCaseList();
+} else {
+ /* no group specified, so list them all */
+ DW_TESTS_PaintGroupTestList();
+ DW_TESTS_PaintPluginGroupTestList();
+}
+
+DW_TESTS_PaintFooter();
diff --git a/_test/jslint.js b/_test/jslint.js
new file mode 100644
index 000000000..730f8d8a8
--- /dev/null
+++ b/_test/jslint.js
@@ -0,0 +1,89 @@
+/**
+ * Copy to a JavaScript console on your DokuWiki instance and execute
+ * Runs JSLint on all our JavaScript files with our settings
+ */
+
+(function () {
+var globals = ['jQuery', 'SIG', 'NS', 'JSINFO', 'LANG', 'DOKU_BASE',
+ 'DOKU_UHC' // FIXME: Should be moved to JSINFO
+ ], files = {
+ 'scripts/behaviour.js': null,
+ //"scripts/compatibility.js": null,
+ "scripts/cookie.js": null,
+ //"scripts/delay.js": null,
+ //"scripts/drag.js": null,
+ "scripts/edit.js": null,
+ "scripts/editor.js": null,
+ "scripts/helpers.js": null,
+ "scripts/hotkeys.js": null,
+ "scripts/index.js": null,
+ "scripts/linkwiz.js": null,
+ "scripts/locktimer.js": null,
+ "scripts/media.js": null,
+ "scripts/page.js": null,
+ "scripts/qsearch.js": null,
+ "scripts/script.js": null,
+ "scripts/textselection.js": null,
+ "scripts/toolbar.js": null,
+ "scripts/tree.js": null //,
+ //"scripts/tw-sack.js": null
+ }, overwrites = {
+ "scripts/script.js": {evil: true},
+ "scripts/media.js": {devel: true, windows: true},
+ "scripts/locktimer.js": {devel: true},
+ "scripts/behaviour.js": {devel: true},
+ "scripts/helpers.js": {windows: true}
+ };
+
+jQuery.ajax({
+ dataType: 'script',
+ type: "GET",
+// url: 'http://jshint.com/jshint.js'
+ url: 'https://raw.github.com/douglascrockford/JSLint/master/jslint.js',
+ success: function () {
+ for (var file in files) {
+ jQuery.ajax({
+ cache: false,
+ async: false,
+ type: "GET",
+ url: DOKU_BASE + 'lib/' + file,
+ dataType: 'text',
+ success: function (res) {
+ files[file] = res;
+ var data = lint(files[file]);
+ jQuery.merge(globals, data.globals);
+ }});
+ }
+
+ for (var file in files) {
+ if (!files[file]) {
+ continue;
+ }
+ // FIXME more fine-grained write access
+ var data = lint('/*global ' + globals.join(':true, ') +
+ ':true*/\n' + files[file], overwrites[file]);
+ console.log(file);
+ jQuery.each(data.errors || [], function (_, val) {
+ if (val === null) {
+ return;
+ }
+ console.error(val.reason + ' (Line ' + (val.line - 1) +
+ ', character ' + val.character + '):\n' +
+ val.evidence);
+ });
+ };
+ }
+});
+
+function lint(txt, overwrite) {
+ JSLINT(txt, jQuery.extend({
+ // These settings are necessary
+ browser: true,
+
+ // Things we probably should learn someday
+ sloppy: true, white: true, eqeq: true, nomen: true,
+ plusplus: true, regexp: true
+ }, overwrite));
+ return JSLINT.data();
+}
+})();
diff --git a/_test/lib/cli_reporter.php b/_test/lib/cli_reporter.php
new file mode 100644
index 000000000..3ad88119d
--- /dev/null
+++ b/_test/lib/cli_reporter.php
@@ -0,0 +1,114 @@
+<?php // -*- fill-column: 80; tab-width: 4; c-basic-offset: 4 -*-
+
+if (! defined('ST_FAILDETAIL_SEPARATOR')) {
+ define('ST_FAILDETAIL_SEPARATOR', "->");
+}
+
+if (! defined('ST_FAILS_RETURN_CODE')) {
+ define('ST_FAILS_RETURN_CODE', 1);
+}
+
+if (version_compare(phpversion(), '4.3.0', '<') ||
+ php_sapi_name() == 'cgi') {
+ define('STDOUT', fopen('php://stdout', 'w'));
+ define('STDERR', fopen('php://stderr', 'w'));
+ register_shutdown_function(
+ create_function('', 'fclose(STDOUT); fclose(STDERR); return true;'));
+}
+
+/**
+ * Minimal command line test displayer. Writes fail details to STDERR. Returns 0
+ * to the shell if all tests pass, ST_FAILS_RETURN_CODE if any test fails.
+ */
+class CLIReporter extends SimpleReporter {
+
+ var $faildetail_separator = ST_FAILDETAIL_SEPARATOR;
+ var $_failinfo;
+
+ function CLIReporter($faildetail_separator = NULL) {
+ $this->SimpleReporter();
+ if (! is_null($faildetail_separator)) {
+ $this->setFailDetailSeparator($faildetail_separator);
+ }
+ }
+
+ function setFailDetailSeparator($separator) {
+ $this->faildetail_separator = $separator;
+ }
+
+ /**
+ * Return a formatted faildetail for printing.
+ */
+ function &_paintTestFailDetail(&$message) {
+ $buffer = '';
+ $faildetail = $this->getTestList();
+ array_shift($faildetail);
+ $buffer .= implode($this->faildetail_separator, $faildetail);
+ $buffer .= $this->faildetail_separator . "$message\n";
+ return $buffer;
+ }
+
+ /**
+ * Paint fail faildetail to STDERR.
+ */
+ function paintFail($message) {
+ parent::paintFail($message);
+ fwrite(STDERR, 'FAIL' . $this->faildetail_separator .
+ $this->_paintTestFailDetail($message));
+ if($this->_failinfo){
+ fwrite(STDERR, ' additional info was: '.$this->_failinfo."\n");
+ $this->_failinfo = '';
+ }
+ }
+
+ /**
+ * reset failinfo
+ */
+ function paintPass($message) {
+ parent::paintPass($message);
+ $this->_failinfo = '';
+ }
+
+ /**
+ * Paint exception faildetail to STDERR.
+ */
+ function paintException($message) {
+ parent::paintException($message);
+ fwrite(STDERR, 'EXCEPTION' . $this->faildetail_separator .
+ $this->_paintTestFailDetail($message));
+ }
+
+ /**
+ * Handle failinfo message
+ */
+ function paintSignal($type,$message) {
+ parent::paintSignal($type,$message);
+ if($type = 'failinfo') $this->_failinfo = $message;
+ }
+
+
+
+ /**
+ * Paint a footer with test case name, timestamp, counts of fails and
+ * exceptions.
+ */
+ function paintFooter($test_name) {
+ $buffer = $this->getTestCaseProgress() . '/' .
+ $this->getTestCaseCount() . ' test cases complete: ';
+
+ if (0 < ($this->getFailCount() + $this->getExceptionCount())) {
+ $buffer .= $this->getPassCount() . " passes";
+ if (0 < $this->getFailCount()) {
+ $buffer .= ", " . $this->getFailCount() . " fails";
+ }
+ if (0 < $this->getExceptionCount()) {
+ $buffer .= ", " . $this->getExceptionCount() . " exceptions";
+ }
+ $buffer .= ".\n";
+ fwrite(STDOUT, $buffer);
+ exit(ST_FAILS_RETURN_CODE);
+ } else {
+ fwrite(STDOUT, $buffer . $this->getPassCount() . " passes.\n");
+ }
+ }
+}
diff --git a/_test/lib/mock_functions.php b/_test/lib/mock_functions.php
new file mode 100644
index 000000000..9ef5b7b8f
--- /dev/null
+++ b/_test/lib/mock_functions.php
@@ -0,0 +1,519 @@
+<?php
+ /**
+ * base include file for SimpleTest
+ * @package SimpleTest
+ * @subpackage MockFunctions
+ * @version $Id: mock_objects.php,v 1.86 2005/09/10 23:01:56 lastcraft Exp $
+ */
+
+ /**
+ * Generates a mock version of a function.
+ * Note that all public methods in this class should be called
+ * statically
+ * Note that you must call the restore method yourself, to remove
+ * a mock function implementation after associated tests are
+ * complete
+ * @package SimpleTest
+ * @subpackage MockFunctions
+ */
+ class MockFunction {
+
+ /**
+ * Raises an error if you construct MockFunction
+ * @access private
+ */
+ function MockFunction() {
+ trigger_error('MockFunction only provides static methods',
+ E_USER_ERROR);
+ }
+
+ /**
+ * Generates a mock function
+ * @param string $function Function name to mock
+ * @access public
+ * @return SimpleMockFunction
+ * @static
+ */
+ function & generate($function) {
+ $mock = & MockFunction::_instance($function, TRUE);
+ $mock->deploy();
+ return $mock;
+ }
+
+ /**
+ * Removes the mock function implementation and restores
+ * the real implementation (if one existed)
+ * @TODO Would be good to have this called automatically
+ * @param string $function Function name
+ * @access public
+ * @static
+ */
+ function restore($function) {
+ $mock = & MockFunction::_instance($function);
+ $mock->restore();
+ }
+
+ /**
+ * Fetch a singleton instance of SimpleMockFunction
+ * @param string $function Function name
+ * @param boolean $fresh Force a fresh instance
+ * @access private
+ * @static
+ */
+ function &_instance($function, $fresh = FALSE) {
+ static $singleton = array();
+
+ $function = strtolower($function);
+
+ if ( $fresh ) {
+ if ( isset($singleton[$function]) ) {
+ unset($singleton[$function]);
+ }
+ }
+
+ if ( !isset($singleton[$function]) ) {
+ // TODO: case sensitivity issues
+ $class = $function."MockFunction";
+ MockFunction::_generateSubClass($class, $function);
+ $singleton[$function] = new $class($function);
+ }
+
+ return $singleton[$function];
+ }
+
+ /**
+ * Required for strict mode and SimpleMock
+ * @TODO Should perhaps be placed in SimpleFunctionGenerator
+ * @param string $class subclass name
+ * @param string $method method name
+ * @access private
+ * @static
+ */
+ function _generateSubClass($class, $method) {
+ if ( class_exists($class) ) {
+ return;
+ }
+ $code = "class $class extends SimpleMockFunction {\n";
+ $code .= " function $method () {}\n";
+ $code .= "}\n";
+ eval($code);
+ }
+
+ /**
+ * Changes the default wildcard object.
+ * @param string $function Function name wildcard applies to
+ * @param mixed $wildcard Parameter matching wildcard.
+ * @access public
+ * @static
+ */
+ function setWildcard($function, $wildcard) {
+ $mock = & MockFunction::_instance($function);
+ $mock->setWildcard($wildcard);
+ }
+
+ /**
+ * Fetches the call count of a function so far.
+ * @param string $function Function name called.
+ * @return Number of calls so far.
+ * @access public
+ * @static
+ */
+ function getCallCount($function) {
+ $mock = & MockFunction::_instance($function);
+ return $mock->getCallCount($function);
+ }
+
+ /**
+ * Sets a return for a parameter list that will
+ * be passed by value for all calls to this function.
+ * @param string $function Function name.
+ * @param mixed $value Result of call passed by value.
+ * @param array $args List of parameters to match
+ * including wildcards.
+ * @access public
+ * @static
+ */
+ function setReturnValue($function, $value, $args = false) {
+ $mock = & MockFunction::_instance($function);
+ $mock->setReturnValue($function, $value, $args);
+ }
+
+ /**
+ * Sets a return for a parameter list that will
+ * be passed by value only when the required call count
+ * is reached.
+ * @param integer $timing Number of calls in the future
+ * to which the result applies. If
+ * not set then all calls will return
+ * the value.
+ * @param string $function Function name.
+ * @param mixed $value Result of call passed by value.
+ * @param array $args List of parameters to match
+ * including wildcards.
+ * @access public
+ * @static
+ */
+ function setReturnValueAt($timing, $function, $value, $args = false) {
+ $mock = & MockFunction::_instance($function);
+ $mock->setReturnValueAt($timing, $function, $value, $args);
+ }
+
+ /**
+ * Sets a return for a parameter list that will
+ * be passed by reference for all calls.
+ * @param string $function Function name.
+ * @param mixed $reference Result of the call will be this object.
+ * @param array $args List of parameters to match
+ * including wildcards.
+ * @access public
+ * @static
+ */
+ function setReturnReference($function, &$reference, $args = false) {
+ $mock = & MockFunction::_instance($function);
+ $mock->setReturnReference($function, $reference, $args);
+ }
+
+ /**
+ * Sets a return for a parameter list that will
+ * be passed by value only when the required call count
+ * is reached.
+ * @param integer $timing Number of calls in the future
+ * to which the result applies. If
+ * not set then all calls will return
+ * the value.
+ * @param string $function Function name.
+ * @param mixed $reference Result of the call will be this object.
+ * @param array $args List of parameters to match
+ * including wildcards.
+ * @access public
+ * @static
+ */
+ function setReturnReferenceAt($timing, $function, &$reference, $args = false) {
+ $mock = & MockFunction::_instance($function);
+ $mock->setReturnReferenceAt($timing, $function, $reference, $args);
+ }
+
+ /**
+ * Sets up an expected call with a set of
+ * expected parameters in that call. All
+ * calls will be compared to these expectations
+ * regardless of when the call is made.
+ * @param string $function Function call to test.
+ * @param array $args Expected parameters for the call
+ * including wildcards.
+ * @param string $message Overridden message.
+ * @access public
+ * @static
+ */
+ function expectArguments($function, $args, $message = '%s') {
+ $mock = & MockFunction::_instance($function);
+ $mock->expectArguments($function, $args, $message);
+ }
+
+ /**
+ * Sets up an expected call with a set of
+ * expected parameters in that call. The
+ * expected call count will be adjusted if it
+ * is set too low to reach this call.
+ * @param integer $timing Number of calls in the future at
+ * which to test. Next call is 0.
+ * @param string $function Function call to test.
+ * @param array $args Expected parameters for the call
+ * including wildcards.
+ * @param string $message Overridden message.
+ * @access public
+ * @static
+ */
+ function expectArgumentsAt($timing, $function, $args, $message = '%s') {
+ $mock = & MockFunction::_instance($function);
+ $mock->expectArgumentsAt($timing, $function, $args, $message);
+ }
+
+ /**
+ * Sets an expectation for the number of times
+ * a function will be called.
+ * @param string $function Function call to test.
+ * @param integer $count Number of times it should
+ * have been called at tally.
+ * @param string $message Overridden message.
+ * @access public
+ * @static
+ */
+ function expectCallCount($function, $count, $message = '%s') {
+ $mock = & MockFunction::_instance($function);
+ $mock->expectCallCount($function, $count, $message);
+ }
+
+ /**
+ * Sets the number of times a function may be called
+ * before a test failure is triggered.
+ * @param string $function Function call to test.
+ * @param integer $count Most number of times it should
+ * have been called.
+ * @param string $message Overridden message.
+ * @access public
+ * @static
+ */
+ function expectMaximumCallCount($function, $count, $message = '%s') {
+ $mock = & MockFunction::_instance($function);
+ $mock->expectMaximumCallCount($function, $count, $message);
+ }
+
+ /**
+ * Sets the minimum number of times the function must be called
+ * otherwise a test failure is triggered
+ * @param string $function Function call to test.
+ * @param integer $count Least number of times it should
+ * have been called.
+ * @param string $message Overridden message.
+ * @access public
+ * @static
+ */
+ function expectMinimumCallCount($function, $count, $message = '%s') {
+ $mock = & MockFunction::_instance($function);
+ $mock->expectMinimumCallCount($function, $count, $message);
+ }
+
+ /**
+ * Convenience method for barring a function
+ * call.
+ * @param string $function Function call to ban.
+ * @param string $message Overridden message.
+ * @access public
+ * @static
+ */
+ function expectNever($function, $message = '%s') {
+ $mock = & MockFunction::_instance($function);
+ $mock->expectNever($function, $message);
+ }
+
+ /**
+ * Convenience method for a single function
+ * call.
+ * @param string $function Function call to track.
+ * @param array $args Expected argument list or
+ * false for any arguments.
+ * @param string $message Overridden message.
+ * @access public
+ * @static
+ */
+ function expectOnce($function, $args = false, $message = '%s') {
+ $mock = & MockFunction::_instance($function);
+ $mock->expectOnce($function, $args, $message);
+ }
+
+ /**
+ * Convenience method for requiring a function
+ * call.
+ * @param string $function Function call to track.
+ * @param array $args Expected argument list or
+ * false for any arguments.
+ * @param string $message Overridden message.
+ * @access public
+ * @static
+ */
+ function expectAtLeastOnce($function, $args = false, $message = '%s') {
+ $mock = & MockFunction::_instance($function);
+ $mock->expectAtLeastOnce($function, $args, $message);
+ }
+
+ function atTestEnd($function) {
+ $mock = & MockFunction::_instance($function);
+ $mock->atTestEnd($function);
+ }
+
+ }
+
+ /**
+ * Represents a single, mocked function, tracking calls made to it
+ * @package SimpleTest
+ * @subpackage MockFunctions
+ */
+ class SimpleMockFunction extends SimpleMock {
+
+ var $_is_mocked = FALSE;
+ var $_generator;
+
+ /**
+ * Sets up the mock, creating a generator depending on whether
+ * the function is already declared
+ * @param string $function Name of function being mocked
+ */
+ function SimpleMockFunction($function) {
+
+ SimpleMock :: SimpleMock();
+
+ if ( function_exists($function) ) {
+ $this->_generator = new SimpleDeclaredFunctionGenerator($function);
+ } else {
+ $this->_generator = new SimpleUndeclaredFunctionGenerator($function);
+ }
+
+ }
+
+ /**
+ * Deploys the mock function implementation into PHP's function
+ * table, replacing any existing implementation
+ * @access public
+ */
+ function deploy() {
+
+ if ( !$this->_is_mocked ) {
+
+ $this->_is_mocked = TRUE;
+ $this->_generator->deploy();
+
+ }
+
+ }
+
+ /**
+ * Restores the state of PHP's function table to that before
+ * the mock function was deployed. Removes the mock function
+ * implementation and restores any existing implementation of
+ * that function
+ * @access public
+ */
+ function restore() {
+
+ if ( $this->_is_mocked ) {
+
+ $this->_is_mocked = FALSE;
+ $this->_generator->restore();
+
+ }
+
+ }
+
+ }
+
+ /**
+ * Base class for deploying and restoring from mock functions
+ * @package SimpleTest
+ * @subpackage MockFunctions
+ * @abstract
+ */
+ class SimpleFunctionGenerator {
+
+ var $_function;
+
+ /**
+ * @TODO Validate the function name (as it's being used in eval)
+ * @TODO Add list of illegal functions (ones which must not be mocked
+ * as they will break SimpleTest, which uses them)
+ * @param string $function Name of function being mocked
+ */
+ function SimpleFunctionGenerator($function) {
+ $this->_function = $function;
+ }
+
+ /**
+ * Generates the mock function implementation, using eval
+ * @access private
+ */
+ function _generateMockFunction() {
+ $code = "function " . $this->_function . "() {\n";
+ $code .= " \$args = func_get_args();\n";
+ $code .= " \$mock = & MockFunction::_instance('".$this->_function."');\n";
+ $code .= " \$result = &\$mock->_invoke(\"".$this->_function."\", \$args);\n";
+ $code .= " return \$result;\n";
+ $code .= "}\n";
+ eval($code);
+ }
+ }
+
+ /**
+ * Mock function generator for functions which have already been declared
+ * @package SimpleTest
+ * @subpackage MockFunctions
+ */
+ class SimpleDeclaredFunctionGenerator extends SimpleFunctionGenerator {
+
+ var $_tmp_function = NULL;
+
+ /**
+ * Invokes the _generateTmpFnFname
+ * @param string $function Name of function being mocked
+ */
+ function SimpleDeclaredFunctionGenerator($function) {
+
+ SimpleFunctionGenerator::SimpleFunctionGenerator($function);
+ $this->_generateTmpFnFname();
+
+ }
+
+ /**
+ * Generates a temporary name for the declared function implementation
+ * which is will be renamed to while the mock function is in use
+ * @access private
+ */
+ function _generateTmpFnFname() {
+ static $count = 1;
+ $this->_tmp_function = 'tmp_'.md5(time().$this->_function.$count);
+ $count++;
+ }
+
+ /**
+ * Deploys the mock function implementation
+ * @access public
+ */
+ function deploy() {
+
+ runkit_function_rename(
+ $this->_function,
+ $this->_tmp_function
+ ) or
+ trigger_error('Error archiving real function implementation',
+ E_USER_ERROR);
+
+ $this->_generateMockFunction();
+ }
+
+ /**
+ * Removes the mock function implementation and restores
+ * the previously declared implementation
+ * @access public
+ */
+ function restore() {
+
+ runkit_function_remove($this->_function) or
+ trigger_error('Error removing mock function',
+ E_USER_ERROR);
+
+ runkit_function_rename(
+ $this->_tmp_function,
+ $this->_function
+ ) or
+ trigger_error('Error restoring real function',
+ E_USER_ERROR);
+ }
+ }
+
+ /**
+ * Mock function generator for functions which have not
+ * already been declared
+ * @package SimpleTest
+ * @subpackage MockFunctions
+ */
+ class SimpleUndeclaredFunctionGenerator extends SimpleFunctionGenerator {
+
+ /**
+ * Deploys the mock function implementation
+ * @access public
+ */
+ function deploy() {
+ $this->_generateMockFunction();
+ }
+
+ /**
+ * Removes the mock function implementation
+ * @access public
+ */
+ function restore() {
+ runkit_function_remove($this->_function) or
+ trigger_error('Error removing mock function',
+ E_USER_ERROR);
+ }
+
+ }
+
diff --git a/_test/lib/rss_writer_class.php b/_test/lib/rss_writer_class.php
new file mode 100644
index 000000000..684acfcfa
--- /dev/null
+++ b/_test/lib/rss_writer_class.php
@@ -0,0 +1,369 @@
+<?php
+if(!defined("METAL_LIBRARY_XML_RSS_WRITER_CLASS"))
+{
+ define("METAL_LIBRARY_XML_RSS_WRITER_CLASS",1);
+
+/*
+ *
+ * Copyright � (C) Manuel Lemos 2002
+ *
+ * @(#) $Id: rss_writer_class.php,v 1.5 2005/08/20 09:46:06 pachanga Exp $
+ *
+ */
+
+class rss_writer_class extends xml_writer_class
+{
+ /*
+ * Protected variables
+ *
+ */
+ var $root="";
+ var $channel="";
+ var $image="";
+ var $textinput="";
+ var $items=0;
+ var $itemsequence="";
+
+ /*
+ * Public variables
+ *
+ */
+ var $specification="1.0";
+ var $about="";
+ var $rssnamespaces=array();
+ var $allownoitems=0;
+ var $generatedcomment="Generated by: http://www.phpclasses.org/rsswriter";
+
+
+ /*
+ * Protected functions
+ *
+ */
+ Function addrssproperties(&$properties,$parent,&$required,&$optional,$scope)
+ {
+ $noattributes=array();
+ $required_properties=0;
+ Reset($properties);
+ $end=(GetType($property=Key($properties))!="string");
+ for(;!$end;)
+ {
+ if(IsSet($required[$property]))
+ {
+ if($required[$property])
+ {
+ $this->error=("required ".$scope." property \"".$property."\" is already set");
+ return 0;
+ }
+ $required[$property]=1;
+ $required_properties++;
+ }
+ else
+ {
+ if(IsSet($optional[$property]))
+ {
+ if($optional[$property])
+ {
+ $this->error=("optional ".$scope." property \"".$property."\" is already set");
+ return 0;
+ }
+ $optional[$property]=1;
+ }
+ else
+ {
+ if(GetType($colon=strpos($property,":",0))=="integer")
+ {
+ $namespace=substr($property,0,$colon);
+ if(!(!strcmp($namespace,"rdf") || IsSet($this->rssnamespaces[$namespace])))
+ $this->error=("the name space of property \"".$property."\" was not declared");
+ }
+ else
+ $this->error=("\"".$property."\" is not a supported ".$scope." property");
+ }
+ }
+ if(!($this->adddatatag($property,$noattributes,$properties[$property],$parent,$path)))
+ return 0;
+ Next($properties);
+ $end=(GetType($property=Key($properties))!="string");
+ }
+ if($required_properties<count($required))
+ {
+ Reset($required);
+ $end=(GetType($property=Key($required))!="string");
+ for(;!$end;)
+ {
+ if(!($required[$property]))
+ {
+ $this->error=("it was not specified the required ".$scope." property \"".$property."\"");
+ return 0;
+ }
+ Next($required);
+ $end=(GetType($property=Key($required))!="string");
+ }
+ }
+ return 1;
+ }
+
+ /*
+ * Public functions
+ *
+ */
+ Function addchannel(&$properties)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(strcmp($this->channel,""))
+ {
+ $this->error="a channel was already added";
+ return 0;
+ }
+ $channel_attributes=array();
+ switch($this->specification)
+ {
+ case "0.9":
+ $root="rdf:RDF";
+ $attributes=array("xmlns:rdf"=>"http://www.w3.org/1999/02/22-rdf-syntax-ns#","xmlns"=>"http://my.netscape.com/rdf/simple/0.9/");
+ $required=array("description"=>0,"link"=>0,"title"=>0);
+ $optional=array();
+ break;
+ case "0.91":
+ $root="rss";
+ $attributes=array("version"=>$this->specification);
+ $required=array("description"=>0,"language"=>0,"link"=>0,"title"=>0);
+ $optional=array("copyright"=>0,"docs"=>0,"lastBuildDate"=>0,"managingEditor"=>0,"pubDate"=>0,"rating"=>0,"webMaster"=>0);
+ break;
+ case "1.0":
+ if(!strcmp($this->about,""))
+ {
+ $this->error="it was not specified the about URL attribute";
+ return 0;
+ }
+ $root="rdf:RDF";
+ $attributes=array("xmlns:rdf"=>"http://www.w3.org/1999/02/22-rdf-syntax-ns#","xmlns"=>"http://purl.org/rss/1.0/");
+ Reset($this->rssnamespaces);
+ $end=(GetType($namespace=Key($this->rssnamespaces))!="string");
+ for(;!$end;)
+ {
+ if(!strcmp($namespace,"rdf"))
+ {
+ $this->error="the rdf namespace is being redeclared";
+ return 0;
+ }
+ $attributes[("xmlns:".$namespace)]=$this->rssnamespaces[$namespace];
+ Next($this->rssnamespaces);
+ $end=(GetType($namespace=Key($this->rssnamespaces))!="string");
+ }
+ $channel_attributes=array("rdf:about"=>$this->about);
+ $required=array("description"=>0,"link"=>0,"title"=>0);
+ $optional=array();
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ $this->addtag($root,$attributes,"",$path,1);
+ $this->root=$path;
+ if(!($this->addtag("channel",$channel_attributes,$this->root,$path,1)))
+ return 0;
+ if(!($this->addrssproperties($properties,$path,$required,$optional,"channel")))
+ return 0;
+ $this->channel=$path;
+ return 1;
+ }
+
+ Function additem(&$properties)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!strcmp($this->channel,""))
+ {
+ $this->error="the channel was not yet added";
+ return 0;
+ }
+ if(strcmp($this->textinput,""))
+ {
+ $this->error="items can not be added to the channel after defining the textinput";
+ return 0;
+ }
+ $attributes=array();
+ switch($this->specification)
+ {
+ case "0.9":
+ $parent=$this->root;
+ break;
+ case "0.91":
+ $parent=$this->channel;
+ break;
+ case "1.0":
+ if(IsSet($properties["link"]))
+ $attributes["rdf:about"]=$properties["link"];
+ $parent=$this->root;
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ if(!($this->addtag("item",$attributes,$parent,$path,1)))
+ return 0;
+ $required=array("link"=>0,"title"=>0);
+ $optional=array("description"=>0);
+ if(!($this->addrssproperties($properties,$path,$required,$optional,"item")))
+ return 0;
+ if(!strcmp($this->specification,"1.0"))
+ {
+ if(!strcmp($this->itemsequence,""))
+ {
+ $attributes=array();
+ if(!($this->addtag("items",$attributes,$this->channel,$path,1) && $this->addtag("rdf:Seq",$attributes,$path,$path,1)))
+ return 0;
+ $this->itemsequence=$path;
+ }
+ $attributes=array("rdf:resource"=>$properties["link"]);
+ if(!($this->addtag("rdf:li",$attributes,$this->itemsequence,$path,0)))
+ return 0;
+ }
+ $this->items++;
+ return 1;
+ }
+
+ Function addimage(&$properties)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!strcmp($this->channel,""))
+ {
+ $this->error="the channel was not yet added";
+ return 0;
+ }
+ if(strcmp($this->image,""))
+ {
+ $this->error="the channel image was already associated";
+ return 0;
+ }
+ if($this->items!=0)
+ {
+ $this->error="the image can only be defined before adding the channel items";
+ return 0;
+ }
+ $attributes=array();
+ switch($this->specification)
+ {
+ case "0.9":
+ $parent=$this->root;
+ break;
+ case "0.91":
+ $parent=$this->channel;
+ break;
+ case "1.0":
+ if(IsSet($properties["url"]))
+ $attributes["rdf:about"]=$properties["url"];
+ $parent=$this->root;
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ if(!($this->addtag("image",$attributes,$parent,$path,1)))
+ return 0;
+ $this->image=$path;
+ $required=array("link"=>0,"title"=>0,"url"=>0);
+ $optional=array("description"=>0,"width"=>0,"height"=>0);
+ if(!($this->addrssproperties($properties,$this->image,$required,$optional,"image")))
+ return 0;
+ if(!strcmp($this->specification,"1.0"))
+ {
+ $attributes=array("rdf:resource"=>$properties["url"]);
+ return $this->addtag("image",$attributes,$this->channel,$path,0);
+ }
+ return 1;
+ }
+
+ Function addtextinput(&$properties)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!strcmp($this->channel,""))
+ {
+ $this->error="the channel was not yet added";
+ return 0;
+ }
+ if(strcmp($this->textinput,""))
+ {
+ $this->error="the channel text input was already associated";
+ return 0;
+ }
+ if($this->items==0 && !$this->allownoitems)
+ {
+ $this->error="it were not specified any items before defining the channel text input";
+ return 0;
+ }
+ $attributes=array();
+ switch($this->specification)
+ {
+ case "0.9":
+ $parent=$this->root;
+ break;
+ case "0.91":
+ $parent=$this->channel;
+ break;
+ case "1.0":
+ if(IsSet($properties["link"]))
+ $attributes["rdf:about"]=$properties["link"];
+ $parent=$this->root;
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ if(!($this->addtag("textinput",$attributes,$parent,$path,1)))
+ return 0;
+ $this->textinput=$path;
+ $required=array("description"=>0,"link"=>0,"name"=>0,"title"=>0);
+ $optional=array();
+ if(!($this->addrssproperties($properties,$this->textinput,$required,$optional,"textinput")))
+ return 0;
+ if(!strcmp($this->specification,"1.0"))
+ {
+ $attributes=array("rdf:resource"=>$properties["link"]);
+ return $this->addtag("textinput",$attributes,$this->channel,$path,0);
+ }
+ return 1;
+ }
+
+ Function writerss(&$output)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!strcmp($this->channel,""))
+ {
+ $this->error="it was not defined the RSS channel";
+ return 0;
+ }
+ if($this->items==0 && !$this->allownoitems)
+ {
+ $this->error="it were not defined any RSS channel items";
+ return 0;
+ }
+ switch($this->specification)
+ {
+ case "0.9":
+ $this->dtdtype="PUBLIC";
+ $this->dtddefinition="-//Netscape Communications//DTD RSS 0.9//EN";
+ $this->dtdurl="http://my.netscape.com/publish/formats/rss-0.9.dtd";
+ break;
+ case "0.91":
+ $this->dtdtype="PUBLIC";
+ $this->dtddefinition="-//Netscape Communications//DTD RSS 0.91//EN";
+ $this->dtdurl="http://my.netscape.com/publish/formats/rss-0.91.dtd";
+ break;
+ case "1.0":
+ $this->dtdtype="";
+ break;
+ default:
+ $this->error="it was not specified a supported RSS specification version";
+ return 0;
+ }
+ return $this->write($output);
+ }
+};
+
+}
diff --git a/_test/lib/testmanager.php b/_test/lib/testmanager.php
new file mode 100644
index 000000000..06efd2694
--- /dev/null
+++ b/_test/lib/testmanager.php
@@ -0,0 +1,579 @@
+<?php // -*- fill-column: 80; tab-width: 4; c-basic-offset: 4 -*-
+/**
+* Lots TODO here...
+*/
+
+define('TEST_GROUPS',realpath(dirname(__FILE__).'/../cases'));
+define('TEST_CASES',realpath(dirname(__FILE__).'/../cases'));
+define('TEST_PLUGINS',realpath(dirname(__FILE__).'/../../lib/plugins'));
+
+// try to load runkit extension
+if (!extension_loaded('runkit') && function_exists('dl')) {
+ if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')) {
+ @dl('php_runkit.dll');
+ } else {
+ @dl('runkit.so');
+ }
+}
+
+class TestManager {
+ var $_testcase_extension = '.test.php';
+ var $_grouptest_extension = '.group.php';
+
+ function setup() {
+ $ini_file = realpath(dirname(__FILE__).'/../tests.ini');
+
+ if (! file_exists($ini_file)) {
+ trigger_error("Missing configuration file {$ini_file}",
+ E_USER_ERROR);
+ }
+ $config = parse_ini_file($ini_file);
+ foreach ($config as $key => $value) {
+ define($key, $value);
+ }
+ TestManager::_installSimpleTest();
+
+ list($version) = file(SIMPLE_TEST.'VERSION');
+ $version = trim($version);
+ if(!version_compare('1.0.1alpha',$version,'<')){
+ echo "At least SimpleTest Version 1.0.1alpha is required.";
+ echo " Yours is $version\n";
+ exit;
+ }
+ }
+
+ function _installSimpleTest() {
+ require_once SIMPLE_TEST . 'unit_tester.php';
+ require_once SIMPLE_TEST . 'web_tester.php';
+ require_once SIMPLE_TEST . 'mock_objects.php';
+ require_once 'web.inc.php';
+ require_once 'mock_functions.php';
+ }
+
+ function runAllTests(&$reporter) {
+ $manager = new TestManager();
+ $test_cases =& $manager->_getTestFileList();
+ $test = new GroupTest('All Tests');
+ foreach ($test_cases as $test_case) {
+ $test->addTestFile($test_case);
+ }
+ $test->run($reporter);
+ }
+
+ function runAllPluginTests(&$reporter) {
+ $manager = new TestManager();
+ $test_cases =& $manager->_getTestFileList(TEST_PLUGINS);
+ $test = new GroupTest('All Plugin Tests');
+ foreach ($test_cases as $test_case) {
+ $test->addTestFile($test_case);
+ }
+ $test->run($reporter);
+ }
+
+
+ function runTestCase($testcase_name, $test_case_directory, &$reporter) {
+ $manager = new TestManager();
+
+ $testcase_name = preg_replace('/[^a-zA-Z0-9_:]/','',$testcase_name);
+ $testcase_name = str_replace(':',DIRECTORY_SEPARATOR,$testcase_name);
+
+ $testcase_file = $test_case_directory . DIRECTORY_SEPARATOR .
+ strtolower($testcase_name) . $manager->_testcase_extension;
+
+ if (! file_exists($testcase_file)) {
+ trigger_error("Test case {$testcase_file} cannot be found",
+ E_USER_ERROR);
+ }
+
+ $test = new GroupTest("Individual test case: " . $testcase_name);
+ $test->addTestFile($testcase_file);
+ $test->run($reporter);
+ }
+
+ function runTestFile($testcase_file, &$reporter) {
+ $manager = new TestManager();
+
+ if (! file_exists($testcase_file)) {
+ trigger_error("Test case {$testcase_file} cannot be found",
+ E_USER_ERROR);
+ }
+
+ $test = new GroupTest("Individual test case: " . $testcase_file);
+ $test->addTestFile($testcase_file);
+ $test->run($reporter);
+ }
+
+ function runGroupTest($group_test_name, $group_test_directory, &$reporter) {
+ $manager = new TestManager();
+ $group_test_name = preg_replace('/[^a-zA-Z0-9_:]/','',$group_test_name);
+ $group_test_name = str_replace(':',DIRECTORY_SEPARATOR,$group_test_name);
+ $file_path = $group_test_directory . DIRECTORY_SEPARATOR .
+ strtolower($group_test_name) . $manager->_grouptest_extension;
+
+ if (! file_exists($file_path)) {
+ trigger_error("Group test {$group_test_name} cannot be found at {$file_path}",
+ E_USER_ERROR);
+ }
+
+ require_once $file_path;
+ $test = new GroupTest($group_test_name . ' group test');
+ foreach ($manager->_getGroupTestClassNames($file_path) as $group_test) {
+ $test->addTestCase(new $group_test());
+ }
+ $test->run($reporter);
+ }
+
+ function addTestCasesFromDirectory(&$group_test, $directory = '.') {
+ $manager = new TestManager();
+ $test_cases =& $manager->_getTestFileList($directory);
+ foreach ($test_cases as $test_case) {
+ $group_test->addTestFile($test_case);
+ }
+ }
+
+ function &getTestCaseList($directory = '.') {
+ $manager = new TestManager();
+ return $manager->_getTestCaseList($directory);
+ }
+
+ function &_getTestCaseList($directory = '.') {
+ $file_list =& $this->_getTestFileList($directory);
+ $testcases = array();
+ foreach ($file_list as $testcase_file) {
+ $case = str_replace($this->_testcase_extension, '',$testcase_file);
+ $case = str_replace(TEST_GROUPS . DIRECTORY_SEPARATOR, '', $case);
+ $case = str_replace(TEST_PLUGINS . DIRECTORY_SEPARATOR, '', $case);
+ $case = str_replace(DIRECTORY_SEPARATOR, ':', $case);
+ $testcases[$testcase_file] = $case;
+ }
+ return $testcases;
+ }
+
+ function &_getTestFileList($directory = '.') {
+ return $this->_getRecursiveFileList($directory,
+ array(&$this, '_isTestCaseFile'));
+ }
+
+ function &getPluginTestCaseList($directory = '.') {
+ $manager = new TestManager();
+ return $manager->_getTestCaseList($directory);
+ }
+
+ function &getPluginGroupTestList($directory = '.') {
+ $manager = new TestManager();
+ return $manager->_getTestGroupList($directory);
+ }
+
+ function &getGroupTestList($directory = '.') {
+ $manager = new TestManager();
+ return $manager->_getTestGroupList($directory);
+ }
+
+ function &_getTestGroupFileList($directory = '.') {
+ return $this->_getRecursiveFileList($directory,
+ array(&$this, '_isTestGroupFile'));
+ }
+
+ function &_getTestGroupList($directory = '.') {
+ $file_list =& $this->_getTestGroupFileList($directory);
+ $grouptests = array();
+ foreach ($file_list as $grouptest_file) {
+ $group = str_replace($this->_grouptest_extension, '',$grouptest_file);
+ $group = str_replace(TEST_GROUPS . DIRECTORY_SEPARATOR, '', $group);
+ $group = str_replace(TEST_PLUGINS . DIRECTORY_SEPARATOR, '', $group);
+ $group = str_replace(DIRECTORY_SEPARATOR, ':', $group);
+ $grouptests[$grouptest_file] = $group;
+ }
+ sort($grouptests);
+ return $grouptests;
+ }
+
+ function &_getGroupTestClassNames($grouptest_file) {
+ $file = implode("\n", file($grouptest_file));
+ preg_match("~lass\s+?(.*)\s+?extends .*?GroupTest~", $file, $matches);
+ if (! empty($matches)) {
+ unset($matches[0]);
+ return $matches;
+ } else {
+ return array();
+ }
+ }
+
+ function &_getRecursiveFileList($directory = '.', $file_test_function) {
+ $dh = opendir($directory);
+ if (! is_resource($dh)) {
+ trigger_error("Couldn't open {$directory}", E_USER_ERROR);
+ }
+
+ $file_list = array();
+ while ($file = readdir($dh)) {
+ $file_path = $directory . DIRECTORY_SEPARATOR . $file;
+
+ if (0 === strpos($file, '.')) continue;
+
+ if (is_dir($file_path)) {
+ $file_list =
+ array_merge($file_list,
+ $this->_getRecursiveFileList($file_path,
+ $file_test_function));
+ }
+ if ($file_test_function[0]->$file_test_function[1]($file)) {
+ $file_list[] = $file_path;
+ }
+ }
+ closedir($dh);
+ return $file_list;
+ }
+
+ function _isTestCaseFile($file) {
+ return $this->_hasExpectedExtension($file, $this->_testcase_extension);
+ }
+
+ function _isTestGroupFile($file) {
+ return $this->_hasExpectedExtension($file, $this->_grouptest_extension);
+ }
+
+ function _hasExpectedExtension($file, $extension) {
+ return $extension ==
+ strtolower(substr($file, (0 - strlen($extension))));
+ }
+}
+
+/**
+* @package WACT_TESTS
+*/
+class CLITestManager extends TestManager {
+ function &getGroupTestList($directory = '.') {
+ $manager = new CLITestManager();
+ $group_tests =& $manager->_getTestGroupList($directory);
+
+ $buffer = "Available grouptests:\n";
+ foreach ($group_tests as $group_test) {
+ $buffer .= " " . $group_test . "\n";
+ }
+ return $buffer . "\n";
+ }
+
+ function &getTestCaseList($directory = '.') {
+ $manager = new CLITestManager();
+ $test_cases =& $manager->_getTestCaseList($directory);
+
+ $buffer = "Available test cases:\n";
+ foreach ($test_cases as $test_case) {
+ $buffer .= " " . $test_case . "\n";
+ }
+ return $buffer . "\n";
+ }
+
+ function &getPluginTestCaseList($directory = '.') {
+ $manager = new CLITestManager();
+ $test_cases =& $manager->_getTestCaseList($directory);
+
+ $buffer = "Available test cases:\n";
+ foreach ($test_cases as $test_case) {
+ $buffer .= " " . $test_case . "\n";
+ }
+ return $buffer . "\n";
+ }
+
+ function &getPluginGroupTestList($directory = '.') {
+ $manager = new CLITestManager();
+ $test_cases =& $manager->_getTestGroupList($directory);
+
+ $buffer = "Available test cases:\n";
+ foreach ($test_cases as $test_case) {
+ $buffer .= " " . $test_case . "\n";
+ }
+ return $buffer . "\n";
+ }
+
+}
+
+class HTMLTestManager extends TestManager {
+ var $_url;
+
+ function HTMLTestManager() {
+ $this->_url = $_SERVER['PHP_SELF'];
+ }
+
+ function getBaseURL() {
+ return $this->_url;
+ }
+
+ function &getGroupTestList($directory = '.') {
+ $manager = new HTMLTestManager();
+ $group_tests =& $manager->_getTestGroupList($directory);
+ if (1 > count($group_tests)) {
+ return "<p>No test groups set up!</p>";
+ }
+ $buffer = "<p>Available test groups:</p>\n<ul>";
+ $buffer .= "<li><a href='" . $manager->getBaseURL() . "?group=all'>All tests</a></li>\n";
+ foreach ($group_tests as $group_test) {
+ $buffer .= "<li><a href='" . $manager->getBaseURL() . "?group={$group_test}'>" .
+ $group_test . "</a></li>\n";
+ }
+
+ $buffer .= "</ul>\n";
+ return $buffer;
+ }
+
+ function &getTestCaseList($directory = '.') {
+ $manager = new HTMLTestManager();
+ $testcases =& $manager->_getTestCaseList($directory);
+
+ if (1 > count($testcases)) {
+ return "<p>No test cases set up!</p>";
+ }
+ $buffer = "<p>Available test cases:</p>\n<ul>";
+ foreach ($testcases as $testcase) {
+ $buffer .= "<li><a href='" . $manager->getBaseURL() .
+ "?case=" . urlencode($testcase) . "'>" .
+ $testcase . "</a></li>\n";
+ }
+
+ $buffer .= "</ul>\n";
+ return $buffer;
+ }
+
+ function &getPluginTestCaseList($directory = '.') {
+ $manager = new HTMLTestManager();
+ $testcases =& $manager->_getTestCaseList($directory);
+
+ if (1 > count($testcases)) {
+ return "<p>No plugin test cases set up!</p>";
+ }
+ $buffer = "<p>Available plugin test cases:</p>\n<ul>";
+ foreach ($testcases as $testcase) {
+ $buffer .= "<li><a href='" . $manager->getBaseURL() .
+ "?plugin_case=" . urlencode($testcase) . "'>" .
+ $testcase . "</a></li>\n";
+ }
+
+ $buffer .= "</ul>\n";
+ return $buffer;
+ }
+
+ function &getPluginGroupTestList($directory = '.') {
+ $manager = new HTMLTestManager();
+ $group_tests =& $manager->_getTestGroupList($directory);
+ if (1 > count($group_tests)) {
+ return "<p>No plugin test groups set up!</p>";
+ }
+ $buffer = "<p>Available plugin groups:</p>\n<ul>";
+ $buffer .= "<li><a href='" . $manager->getBaseURL() . "?plugin_group=all'>All tests</a></li>\n";
+ foreach ($group_tests as $group_test) {
+ $buffer .= "<li><a href='" . $manager->getBaseURL() . "?plugin_group={$group_test}'>" .
+ $group_test . "</a></li>\n";
+ }
+
+ $buffer .= "</ul>\n";
+ return $buffer;
+ }
+
+}
+
+/**
+* @package WACT_TESTS
+*/
+class XMLTestManager extends HTMLTestManager {
+
+ function XMLTestManager() {
+ parent::HTMLTestManager();
+ }
+
+ function &getGroupTestList($directory = '.') {
+
+ $manager = new XMLTestManager();
+ $group_tests =& $manager->_getTestGroupList($directory);
+
+ $rss = & $manager->_getRssWriter();
+
+ if (1 > count($group_tests)) {
+ $rss->writeRss($output);
+ return $output;
+ }
+
+ $properties["title"]="All Tests";
+ $properties["description"]="All Tests";
+ $properties["link"]='http://'.$_SERVER['SERVER_NAME'].
+ $manager->getBaseURL()."?group=all&output=xml";
+
+ $rss->additem($properties);
+
+ foreach ($group_tests as $group_test) {
+ $properties["title"]=$group_test;
+ $properties["description"]=$group_test;
+ $properties["link"]='http://'.$_SERVER['SERVER_NAME'].
+ $manager->getBaseURL().
+ "?group={$group_test}&output=xml";
+
+ $rss->additem($properties);
+ }
+ if ( !$rss->writeRss($output) ) {
+ die ( $rss->error );
+ }
+ return $output;
+
+ }
+
+ function &getTestCaseList($directory = '.') {
+
+ $manager = new XMLTestManager();
+ $testcases =& $manager->_getTestCaseList($directory);
+
+ $rss = & $manager->_getRssWriter();
+
+ if (1 > count($testcases)) {
+ $rss->writeRss($output);
+ return $output;
+ }
+
+ foreach ($testcases as $testfile => $testcase) {
+ $properties["title"]=$testcase;
+ $properties["description"]=$testcase;
+ $properties["link"]='http://'.$_SERVER['SERVER_NAME'].
+ $manager->getBaseURL()."?case=" .
+ urlencode($testcase) . "&output=xml";
+
+ // Comment this out for performance?
+ $properties["dc:date"]=gmdate("Y-m-d\TH:i:sO",filemtime($testfile));
+
+ $rss->additem($properties);
+ }
+
+ $rss->writeRss($output);
+ return $output;
+ }
+
+ function &_getRssWriter() {
+
+ $url = 'http://'.$_SERVER['SERVER_NAME'].str_replace('index.php','',$_SERVER['PHP_SELF']);
+
+ require_once TEST_ROOT . '/lib/xml_writer_class.php';
+ require_once TEST_ROOT . '/lib/rss_writer_class.php';
+
+ $rss_writer_object= new rss_writer_class();
+ $rss_writer_object->specification="1.0";
+ $rss_writer_object->about=$url."index.php?output=xml";
+ $rss_writer_object->stylesheet=$url."rss2html.xsl";
+ $rss_writer_object->rssnamespaces["dc"]="http://purl.org/dc/elements/1.1/";
+
+ // Channel Properties
+ $properties=array();
+ $properties["title"]="Dokuwiki Unit Test Cases";
+ $properties["description"]="Dokuwiki Unit Test Cases";
+ $properties["link"]="http://wiki.splitbrain.org/";
+ $properties["dc:date"]=gmdate("Y-m-d\TH:i:sO");
+ $rss_writer_object->addchannel($properties);
+
+ // Logo like this (if we had one)
+ /*
+ $properties=array();
+
+ $properties["link"]="http://www.phpclasses.org/";
+ $properties["title"]="PHP Classes repository logo";
+ $properties["description"]="Repository of components and other resources for PHP developers";
+ $rss_writer_object->addimage($properties);
+ */
+
+ return $rss_writer_object;
+ }
+
+}
+
+/**
+* @package WACT_TESTS
+*/
+class RemoteTestManager extends TestManager {
+
+ function RemoteTestManager() {
+ RemoteTestManager::_installSimpleTest();
+ }
+
+ function _installSimpleTest() {
+ require_once SIMPLE_TEST . 'remote.php';
+ }
+
+ function runAllTests(&$reporter, $url = FALSE) {
+ $groups = RemoteTestManager::getGroupTestList($url);
+ $T = new RemoteTestCase($groups['All Tests']);
+ $T->run($reporter);
+ }
+
+ function runTestUrl($case_url,& $reporter, $url = FALSE) {
+ RemoteTestManager::_installSimpleTest();
+ $T = new RemoteTestCase($case_url);
+ $T->run($reporter);
+ }
+
+ function runTestCase($case_id,& $reporter, $url = FALSE) {
+ $cases = RemoteTestManager::getTestCaseList($url);
+ if ( !array_key_exists($case_id, $cases) ) {
+ trigger_error("Unknown test id $case_id\n",E_USER_ERROR);
+ }
+ $T = new RemoteTestCase($cases[$case_id]);
+ $T->run($reporter);
+ }
+
+ function runGroupTest($group_name, &$reporter, $url = FALSE) {
+ $groups = RemoteTestManager::getGroupTestList($url);
+ if ( !array_key_exists($group_name, $groups) ) {
+ trigger_error("Unknown group $group_name\n",E_USER_ERROR);
+ }
+ $T = new RemoteTestCase($groups[$group_name]);
+ $T->run($reporter);
+ }
+
+ function & getGroupTestList($url = FALSE) {
+
+ if ( !$url ) {
+ $url = REMOTE_TEST_URL;
+ }
+
+ $url .= '?output=xml';
+
+ $manager = new RemoteTestManager();
+ $rss = & $manager->_getRssReader($url);
+
+ $groupList = array();
+
+ foreach ($rss->getItems() as $item) {
+ $groupList[$item['title']] = $item['link'];
+ }
+
+ return $groupList;
+ }
+
+ function &getTestCaseList($url = FALSE) {
+ if ( !$url ) {
+ $url = REMOTE_TEST_URL;
+ }
+
+ $url .= '?show=cases&output=xml';
+ $manager = new RemoteTestManager();
+ $rss = & $manager->_getRssReader($url);
+
+ $caseList = array();
+
+ foreach ($rss->getItems() as $item) {
+ $caseList[$item['title']] = $item['link'];
+ }
+
+ return $caseList;
+ }
+
+ function &_getRssReader($url) {
+ require_once "XML/RSS.php";
+
+ $rss_reader = new XML_RSS($url);
+
+ $status = $rss_reader->parse();
+
+ if (PEAR::isError($status) ) {
+ trigger_error($status->getMessage(),E_USER_WARNING);
+ }
+
+ return $rss_reader;
+ }
+
+}
diff --git a/_test/lib/unittest.php b/_test/lib/unittest.php
new file mode 100644
index 000000000..220aa6c1b
--- /dev/null
+++ b/_test/lib/unittest.php
@@ -0,0 +1,5 @@
+<?php
+class Doku_UnitTestCase extends UnitTestCase {
+}
+class Doku_GroupTest extends GroupTest {
+}
diff --git a/_test/lib/web.inc.php b/_test/lib/web.inc.php
new file mode 100644
index 000000000..7ca70f204
--- /dev/null
+++ b/_test/lib/web.inc.php
@@ -0,0 +1,47 @@
+<?php
+/**
+* @package WACT_TESTS
+* @version $Id: web.inc.php,v 1.6 2005/08/20 09:46:06 pachanga Exp $
+*/
+
+SimpleTestOptions::ignore('DWWebTestCase');
+
+class DWWebTestCase extends WebTestCase {
+
+ function assertNormalPage() {
+ $this->assertResponse(array(200));
+ $this->assertNoUnwantedPattern('/Warning:/i');
+ $this->assertNoUnwantedPattern('/Error:/i');
+ $this->assertNoUnwantedPattern('/Fatal error/i');
+ }
+
+ function assertWantedLiteral($str) {
+ $this->assertWantedPattern('/' . preg_quote($str, '/'). '/');
+ }
+
+ function assertNoUnWantedLiteral($str) {
+ $this->assertNoUnWantedPattern('/' . preg_quote($str, '/'). '/');
+ }
+
+ function &_fileToPattern($file) {
+ $file_as_array = file($file);
+ $pattern = '#^';
+ foreach ($file_as_array as $line) {
+ /* strip trailing newline */
+ if ($line[strlen($line) - 1] == "\n") {
+ $line = substr($line, 0, strlen($line) - 1);
+ }
+ $line = preg_quote($line, '#');
+
+ /* replace paths with wildcard */
+ $line = preg_replace("#'/[^']*#", "'.*", $line);
+
+ $pattern .= $line . '\n';
+ }
+ /* strip final newline */
+ $pattern = substr($pattern, 0, strlen($pattern) - 2);
+ $pattern .= '$#i';
+ return $pattern;
+ }
+
+}
diff --git a/_test/lib/xml_writer_class.php b/_test/lib/xml_writer_class.php
new file mode 100644
index 000000000..97fb1bee0
--- /dev/null
+++ b/_test/lib/xml_writer_class.php
@@ -0,0 +1,292 @@
+<?php
+if(!defined("METAL_LIBRARY_XML_XML_WRITER_CLASS"))
+{
+ define("METAL_LIBRARY_XML_XML_WRITER_CLASS",1);
+
+/*
+ *
+ * Copyright � (C) Manuel Lemos 2001-2002
+ *
+ * @(#) $Id: xml_writer_class.php,v 1.5 2005/08/20 09:46:06 pachanga Exp $
+ *
+ */
+
+class xml_writer_class
+{
+ /*
+ * Protected variables
+ *
+ */
+ var $structure=array();
+ var $nodes=array();
+
+ /*
+ * Public variables
+ *
+ */
+ var $stylesheet="";
+ var $stylesheettype="text/xsl";
+ var $dtdtype="";
+ var $dtddefinition="";
+ var $dtdurl="";
+ var $outputencoding="utf-8";
+ var $inputencoding="iso-8859-1";
+ var $linebreak="\n";
+ var $indenttext=" ";
+ var $generatedcomment="Generated by: http://www.phpclasses.org/xmlwriter";
+ var $error="";
+
+
+ /*
+ * Protected functions
+ *
+ */
+ Function escapedata($data)
+ {
+ $position=0;
+ $length=strlen($data);
+ $escapeddata="";
+ for(;$position<$length;)
+ {
+ $character=substr($data,$position,1);
+ $code=Ord($character);
+ switch($code)
+ {
+ case 34:
+ $character="&quot;";
+ break;
+ case 38:
+ $character="&amp;";
+ break;
+ case 39:
+ $character="&apos;";
+ break;
+ case 60:
+ $character="&lt;";
+ break;
+ case 62:
+ $character="&gt;";
+ break;
+ default:
+ if($code<32)
+ $character=("&#".strval($code).";");
+ break;
+ }
+ $escapeddata.=$character;
+ $position++;
+ }
+ return $escapeddata;
+ }
+
+ Function encodedata($data,&$encodeddata)
+ {
+ if(!strcmp($this->inputencoding,$this->outputencoding))
+ $encodeddata=$this->escapedata($data);
+ else
+ {
+ switch(strtolower($this->outputencoding))
+ {
+ case "utf-8":
+ if(!strcmp(strtolower($this->inputencoding),"iso-8859-1"))
+ {
+ $encoded_data=utf8_encode($this->escapedata($data));
+ $encodeddata=$encoded_data;
+ }
+ else
+ {
+ $this->error=("can not encode iso-8859-1 data in ".$this->outputencoding);
+ return 0;
+ }
+ break;
+ case "iso-8859-1":
+ if(!strcmp(strtolower($this->inputencoding),"utf-8"))
+ {
+ $decoded=utf8_decode($data);
+ $encodeddata=$this->escapedata($decoded);
+ }
+ else
+ {
+ $this->error=("can not encode utf-8 data in ".$this->outputencoding);
+ return 0;
+ }
+ break;
+ default:
+ $this->error=("can not encode data in ".$this->inputencoding);
+ return 0;
+ }
+ }
+ return 1;
+ }
+
+ Function writetag(&$output,$path,$indent)
+ {
+ $tag=$this->structure[$path]["Tag"];
+ $output.=("<".$tag);
+ $attributecount=count($this->structure[$path]["Attributes"]);
+ if($attributecount>0)
+ {
+ $attributes=$this->structure[$path]["Attributes"];
+ Reset($attributes);
+ $end=(GetType($key=Key($attributes))!="string");
+ for(;!$end;)
+ {
+ $output.=(" ".$key."=\"".$attributes[$key]."\"");
+ Next($attributes);
+ $end=(GetType($key=Key($attributes))!="string");
+ }
+ }
+ $elements=$this->structure[$path]["Elements"];
+ if($elements>0)
+ {
+ $output.=">";
+ $doindent=$this->structure[$path]["Indent"];
+ $elementindent=(($doindent) ? $this->linebreak.$indent.$this->indenttext : "");
+ $element=0;
+ for(;$element<$elements;)
+ {
+ $elementpath=($path.",".strval($element));
+ $output.=$elementindent;
+ if(IsSet($this->nodes[$elementpath]))
+ {
+ if(!($this->writetag($output,$elementpath,$indent.$this->indenttext)))
+ return 0;
+ }
+ else
+ $output.=$this->structure[$elementpath];
+ $element++;
+ }
+ $output.=((($doindent) ? $this->linebreak.$indent : "")."</".$tag.">");
+ }
+ else
+ $output.="/>";
+ return 1;
+ }
+
+ /*
+ * Public functions
+ *
+ */
+ Function write(&$output)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!(IsSet($this->structure["0"])))
+ {
+ $this->error="XML document structure is empty";
+ return 0;
+ }
+ $output=("<?xml version=\"1.0\" encoding=\"".$this->outputencoding."\"?>".$this->linebreak);
+ if(strcmp($this->dtdtype,""))
+ {
+ $output.=("<!DOCTYPE ".$this->structure["0"]["Tag"]." ");
+ switch($this->dtdtype)
+ {
+ case "INTERNAL":
+ if(!strcmp($this->dtddefinition,""))
+ {
+ $this->error="it was not specified a valid internal DTD definition";
+ return 0;
+ }
+ $output.=("[".$this->linebreak.$this->dtddefinition.$this->linebreak."]");
+ break;
+ case "SYSTEM":
+ if(!strcmp($this->dtdurl,""))
+ {
+ $this->error="it was not specified a valid system DTD url";
+ return 0;
+ }
+ $output.="SYSTEM";
+ if(strcmp($this->dtddefinition,""))
+ $output.=(" \"".$this->dtddefinition."\"");
+ $output.=(" \"".$this->dtdurl."\"");
+ break;
+ case "PUBLIC":
+ if(!strcmp($this->dtddefinition,""))
+ {
+ $this->error="it was not specified a valid public DTD definition";
+ return 0;
+ }
+ $output.=("PUBLIC \"".$this->dtddefinition."\"");
+ if(strcmp($this->dtdurl,""))
+ $output.=(" \"".$this->dtdurl."\"");
+ break;
+ default:
+ $this->error="it was not specified a valid DTD type";
+ return 0;
+ }
+ $output.=(">".$this->linebreak);
+ }
+ if(strcmp($this->stylesheet,""))
+ {
+ if(!strcmp($this->stylesheettype,""))
+ {
+ $this->error="it was not specified a valid stylesheet type";
+ return 0;
+ }
+ $output.=("<?xml-stylesheet type=\"".$this->stylesheettype."\" href=\"".$this->stylesheet."\"?>".$this->linebreak);
+ }
+ if(strcmp($this->generatedcomment,""))
+ $output.=("<!-- ".$this->generatedcomment." -->".$this->linebreak);
+ return $this->writetag($output,"0","");
+ }
+
+ Function addtag($tag,&$attributes,$parent,&$path,$indent)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ $path=((!strcmp($parent,"")) ? "0" : ($parent.",".strval($this->structure[$parent]["Elements"])));
+ if(IsSet($this->structure[$path]))
+ {
+ $this->error=("tag with path ".$path." is already defined");
+ return 0;
+ }
+ $encodedattributes=array();
+ Reset($attributes);
+ $end=(GetType($attribute_name=Key($attributes))!="string");
+ for(;!$end;)
+ {
+ $encodedattributes[$attribute_name]="";
+ if(!($this->encodedata($attributes[$attribute_name],$encoded_data)))
+ return 0;
+ $encodedattributes[$attribute_name]=$encoded_data;
+ Next($attributes);
+ $end=(GetType($attribute_name=Key($attributes))!="string");
+ }
+ $this->structure[$path]=array(
+ "Tag"=>$tag,
+ "Attributes"=>$encodedattributes,
+ "Elements"=>0,
+ "Indent"=>$indent
+ );
+ $this->nodes[$path]=1;
+ if(strcmp($parent,""))
+ $this->structure[$parent]["Elements"]=($this->structure[$parent]["Elements"]+1);
+ return 1;
+ }
+
+ Function adddata($data,$parent,&$path)
+ {
+ if(strcmp($this->error,""))
+ return 0;
+ if(!(IsSet($this->structure[$parent])))
+ {
+ $this->error=("the parent tag path".$path."is not defined");
+ return 0;
+ }
+ if(!strcmp($data,""))
+ return 1;
+ $path=($parent.",".strval($this->structure[$parent]["Elements"]));
+ if(!($this->encodedata($data,$encoded_data)))
+ return 0;
+ $this->structure[$path]=$encoded_data;
+ $this->structure[$parent]["Elements"]=($this->structure[$parent]["Elements"]+1);
+ return 1;
+ }
+
+ Function adddatatag($tag,&$attributes,$data,$parent,&$path)
+ {
+ return $this->addtag($tag,$attributes,$parent,$path,0) && $this->adddata($data,$path,$datapath);
+ }
+};
+
+}
diff --git a/_test/remotetests.php b/_test/remotetests.php
new file mode 100755
index 000000000..3dd290712
--- /dev/null
+++ b/_test/remotetests.php
@@ -0,0 +1,163 @@
+#!/usr/bin/php -q
+<?php
+ini_set('memory_limit','128M');
+
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+
+require_once 'lib/testmanager.php';
+TestManager::setup();
+
+function usage() {
+ $usage = <<<EOD
+Usage: ./remotetests.php [OPTION]...
+Run the Dokuwiki unit tests remotely executing tests over HTTP and delivering
+results to the command line. If ALL of the test cases pass a count of
+total passes is printed on STDOUT. If ANY of the test cases fail (or raise
+errors) details are printed on STDERR and this script returns a non-zero
+exit code.
+ -c --case=NAME specify a test case by it's ID (see -i for list)
+ -f --caseurl=NAME specify a test case file (full or relative path)
+ -g --group=NAME specify a grouptest. If no grouptest is
+ specified, all test cases will be run.
+ -i --caselist list individual test cases by their ID
+ -l --grouplist list available grouptests
+ -s, --separator=SEP set the character(s) used to separate fail
+ details to SEP
+ -p, --path path to SimpleTest installation
+ -h, --help display this help and exit
+ -u --url=TEST_URL specify remote server test url (w. index.php)
+
+EOD;
+ echo $usage;
+ exit(0);
+}
+
+/* default test options */
+$opt_separator = '->';
+$opt_caselist = FALSE;
+$opt_grouplist = FALSE;
+$opt_caseid = FALSE;
+$opt_caseurl = FALSE;
+$opt_groupfile = FALSE;
+$opt_url = FALSE;
+
+include_once(DOKU_INC.'inc/cliopts.php');
+$short_opts = "c:f:g:hils:p:u:";
+$long_opts = array("case=","caselist","help", "caseurl=", "group=", "grouplist", "separator=", "path=","url=");
+$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
+if ( $OPTS->isError() ) {
+ fwrite( STDERR, $OPTS->getMessage() . "\n");
+ usage($available_grouptests);
+ exit(1);
+}
+
+foreach ($OPTS->options as $key => $val) {
+ switch ($key) {
+ case 'c':
+ case 'case':
+ $opt_caseid = $val;
+ break;
+ case 'h':
+ case 'help':
+ usage();
+ break;
+ case 'f':
+ case 'caseurl':
+ $opt_caseurl = $val;
+ break;
+ case 'g':
+ case 'group':
+ $opt_groupfile = $val;
+ break;
+ case 'i':
+ case 'caselist':
+ $opt_caselist = TRUE;
+ break;
+ case 'l':
+ case 'grouplist':
+ $opt_grouplist = TRUE;
+ break;
+ case 's':
+ case 'separator':
+ $opt_separator = $val;
+ break;
+ case 'p':
+ case 'path':
+ if (file_exists($val)) {
+ define('SIMPLE_TEST', $val);
+ }
+ break;
+ case 'u':
+ case '--url':
+ $opt_url = $val;
+ break;
+ }
+}
+
+if ( ! $opt_url ) {
+ if ( !defined('REMOTE_TEST_URL') ) {
+ fwrite( STDERR, "No test URL defined. Either modify tests.ini or use -u option\n");
+ exit(1);
+ } else {
+ $opt_url = REMOTE_TEST_URL;
+ }
+}
+
+
+if (!@include_once SIMPLE_TEST . 'reporter.php') {
+ if ( defined(SIMPLE_TEST) ) {
+ fwrite( STDERR, "Where's Simple Test ?!? Not at ".SIMPLE_TEST." \n");
+ } else {
+ fwrite( STDERR, "Where's Simple Test ?!? SIMPLE_TEST not even defined!\n");
+ }
+ exit(1);
+}
+
+require_once 'lib/cli_reporter.php';
+
+/* list grouptests */
+if ($opt_grouplist) {
+ $groups = RemoteTestManager::getGroupTestList($opt_url);
+ fwrite( STDOUT, "Available grouptests:\n");
+ foreach ( array_keys($groups) as $group ) {
+ fwrite( STDOUT, $group."\n");
+ }
+}
+
+/* list test cases */
+if ($opt_caselist) {
+ $cases = RemoteTestManager::getTestCaseList($opt_url);
+ fwrite( STDOUT, "Available tests tests:\n");
+ foreach ( array_keys($cases) as $case ) {
+ fwrite( STDOUT, $case."\n");
+ }
+}
+
+/* exit if we've displayed a list */
+if ( $opt_grouplist || $opt_caselist ) {
+ exit(0);
+}
+
+/* run a test case given it's URL */
+if ($opt_caseurl) {
+ RemoteTestManager::runTestUrl($opt_caseurl, new CLIReporter($opt_separator), $opt_url);
+ exit(0);
+}
+
+/* run a test case by id*/
+if ($opt_caseid) {
+ RemoteTestManager::runTestCase($opt_caseid, new CLIReporter($opt_separator), $opt_url);
+ exit(0);
+}
+
+/* run a grouptest */
+if ($opt_groupfile) {
+ RemoteTestManager::runGroupTest(
+ $opt_groupfile, new CLIReporter($opt_separator), $opt_url
+ );
+ exit(0);
+}
+/* run all tests */
+RemoteTestManager::runAllTests(new CLIReporter($opt_separator), $opt_url);
+exit(0);
+?> \ No newline at end of file
diff --git a/_test/rss2html.xsl b/_test/rss2html.xsl
new file mode 100644
index 000000000..ae56d2c20
--- /dev/null
+++ b/_test/rss2html.xsl
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!--
+ @(#) $Id: rss2html.xsl,v 1.1 2004/06/11 22:00:57 harryf Exp $
+ -->
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rss="http://purl.org/rss/1.0/" xmlns="http://www.w3.org/1999/xhtml">
+
+<xsl:output method="html"/>
+
+<xsl:template match="/">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+<style type="text/css">
+div.channel-title { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.image { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.image-description { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.item-title { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.item-description { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.textinput-title { font-family: sans-serif, arial, helvetica }
+</style>
+<style type="text/css">
+div.textinput-form { font-family: sans-serif, arial, helvetica }
+</style>
+<title>
+<xsl:for-each select="rdf:RDF/rss:channel">
+<xsl:value-of select="rss:description"/>
+</xsl:for-each>
+</title>
+</head>
+<body>
+
+<xsl:for-each select="rdf:RDF/rss:image">
+<center><div class="image">
+<xsl:element name="a">
+ <xsl:attribute name="href"><xsl:value-of select="rss:link"/></xsl:attribute>
+ <xsl:element name="img">
+ <xsl:attribute name="src"><xsl:value-of select="rss:url"/></xsl:attribute>
+ <xsl:attribute name="alt"><xsl:value-of select="rss:title"/></xsl:attribute>
+ <xsl:attribute name="border">0</xsl:attribute>
+ </xsl:element>
+</xsl:element>
+</div></center>
+<center><div class="image-description">
+<xsl:value-of select="rss:description"/>
+</div></center>
+</xsl:for-each>
+
+<xsl:for-each select="rdf:RDF/rss:channel">
+<center><div class="channel-title">
+<xsl:element name="a">
+ <xsl:attribute name="href"><xsl:value-of select="rss:link"/></xsl:attribute>
+ <xsl:value-of select="rss:title"/>
+ <xsl:text> (</xsl:text>
+ <xsl:value-of select="dc:date"/>
+ <xsl:text>)</xsl:text>
+</xsl:element>
+</div></center>
+</xsl:for-each>
+
+<ul>
+<hr />
+<xsl:for-each select="rdf:RDF/rss:item">
+<div class="item-title"><li>
+<xsl:element name="a">
+ <xsl:attribute name="href"><xsl:value-of select="rss:link"/></xsl:attribute>
+ <xsl:value-of select="rss:title"/>
+</xsl:element>
+<xsl:text> (</xsl:text>
+<xsl:value-of select="dc:date"/>
+<xsl:text>)</xsl:text>
+</li></div>
+<div class="item-description"><xsl:value-of select="rss:description"/></div>
+<hr />
+</xsl:for-each>
+</ul>
+
+<xsl:for-each select="rdf:RDF/rss:textinput">
+<center><b><div class="textinput-title"><xsl:value-of select="rss:description"/></div></b></center>
+<xsl:element name="form">
+ <xsl:attribute name="action"><xsl:value-of select="rss:link"/></xsl:attribute>
+ <xsl:attribute name="method">POST</xsl:attribute>
+ <center><div class="textinput-form">
+ <xsl:element name="input">
+ <xsl:attribute name="name"><xsl:value-of select="rss:name"/></xsl:attribute>
+ <xsl:attribute name="type">text</xsl:attribute>
+ </xsl:element>
+ <xsl:text> </xsl:text>
+ <xsl:element name="input">
+ <xsl:attribute name="value"><xsl:value-of select="rss:title"/></xsl:attribute>
+ <xsl:attribute name="type">submit</xsl:attribute>
+ </xsl:element>
+</div></center>
+</xsl:element>
+</xsl:for-each>
+
+</body>
+</html>
+</xsl:template>
+
+</xsl:stylesheet> \ No newline at end of file
diff --git a/_test/runtests.php b/_test/runtests.php
new file mode 100755
index 000000000..8b93efec3
--- /dev/null
+++ b/_test/runtests.php
@@ -0,0 +1,187 @@
+#!/usr/bin/php -q
+<?php
+ini_set('memory_limit','128M');
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+define('DOKU_UNITTEST',true);
+
+require_once(DOKU_INC.'inc/init.php');
+require_once(DOKU_INC.'inc/events.php');
+
+define('TEST_ROOT', dirname(__FILE__));
+define('TMPL_FILESCHEME_PATH', TEST_ROOT . '/filescheme/');
+
+require_once 'lib/testmanager.php';
+TestManager::setup();
+
+function usage() {
+ $usage = <<<EOD
+Usage: ./runtests.php [OPTION]...
+Run the Dokuwiki unit tests. If ALL of the test cases pass a count of total
+passes is printed on STDOUT. If ANY of the test cases fail (or raise
+errors) details are printed on STDERR and this script returns a non-zero
+exit code.
+ -c --case=NAME specify a test case by it's ID (see -i for list)
+ --pcase=NAME specify a plugin test case by it's ID
+ (see --plugincaselist for list)
+ -f --file=NAME specify a test case file (full or relative path)
+ -g --group=NAME specify a grouptest. If no grouptest is
+ specified, all test cases will be run.
+ --pgroup=NAME specify a plugin grouptest. If no grouptest is
+ specified, all test cases will be run.
+ -i --caselist list individual test cases by their ID
+ -l --grouplist list available grouptests
+ --plugincaselist list all individual plugin test cases by their ID
+ --plugingrouplist list avialable plugin grouptests
+ -s, --separator=SEP set the character(s) used to separate fail
+ details to SEP
+ -p, --path path to SimpleTest installation
+ -h, --help display this help and exit
+
+EOD;
+ echo $usage;
+ exit(0);
+}
+
+/* test options */
+$opt_separator = '->';
+$opt_caselist = FALSE;
+$opt_grouplist = FALSE;
+$opt_plugincaselist = FALSE;
+$opt_plugingrouplist = FALSE;
+$opt_caseid = FALSE;
+$top_plugincaseid = FALSE;
+$opt_casefile = FALSE;
+$opt_groupfile = FALSE;
+$opt_plugingroupfile = FALSE;
+
+include_once(DOKU_INC.'inc/cliopts.php');
+
+$short_opts = "c:f:g:hils:p:";
+$long_opts = array("case=","pcase=","caselist","help", "file=", "group=", "pgroup=", "grouplist", "plugincaselist", "plugingrouplist", "separator=", "path=");
+$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
+if ( $OPTS->isError() ) {
+ fwrite( STDERR, $OPTS->getMessage() . "\n");
+ usage($available_grouptests);
+ exit(1);
+}
+
+foreach ($OPTS->options as $key => $val) {
+ switch ($key) {
+ case 'c':
+ case 'case':
+ $opt_caseid = $val;
+ break;
+ case 'pcase':
+ $opt_plugincaseid = $val;
+ break;
+ case 'h':
+ case 'help':
+ usage();
+ break;
+ case 'f':
+ case 'file':
+ $opt_casefile = $val;
+ break;
+ case 'g':
+ case 'group':
+ $opt_groupfile = $val;
+ break;
+ case 'pgroup':
+ $opt_plugingroupfile = $val;
+ break;
+ case 'i':
+ case 'caselist':
+ $opt_caselist = TRUE;
+ break;
+ case 'l':
+ case 'grouplist':
+ $opt_grouplist = TRUE;
+ break;
+ case 'plugincaselist':
+ $opt_plugincaselist = TRUE;
+ break;
+ case 'plugingrouplist':
+ $opt_plugingrouplist = TRUE;
+ break;
+ case 's':
+ case 'separator':
+ $opt_separator = $val;
+ break;
+ case 'p':
+ case 'path':
+ if (file_exists($val)) {
+ define('SIMPLE_TEST', $val);
+ }
+ break;
+ }
+}
+
+if (!@include_once SIMPLE_TEST . 'reporter.php') {
+ die("Where's Simple Test ?!? Not at ".SIMPLE_TEST);
+}
+
+require_once 'lib/cli_reporter.php';
+
+/* list grouptests */
+if ($opt_grouplist) {
+ echo CLITestManager::getGroupTestList(TEST_GROUPS);
+}
+
+/* list test cases */
+if ($opt_caselist) {
+ echo CLITestManager::getTestCaseList(TEST_CASES);
+}
+
+/* list plugin test cases */
+if ($opt_plugincaselist) {
+ echo CLITestManager::getPluginTestCaseList(TEST_PLUGINS);
+}
+
+/* list plugin group tests */
+if($opt_plugingrouplist) {
+ echo CLITestManager::getPluginGroupTestList(TEST_PLUGINS);
+}
+
+/* exit if we've displayed a list */
+if ( $opt_grouplist || $opt_caselist || $opt_plugincaselist || $opt_plugingrouplist ) {
+ exit(0);
+}
+
+/* run a test case */
+if ($opt_casefile) {
+ TestManager::runTestFile($opt_casefile, new CLIReporter($opt_separator));
+ exit(0);
+}
+
+/* run a test case by id */
+if ($opt_caseid) {
+ TestManager::runTestCase($opt_caseid, TEST_CASES, new CLIReporter($opt_separator));
+ exit(0);
+}
+
+/* run a plugin test by case id */
+if ($opt_plugincaseid) {
+ TestManager::runTestCase($opt_plugincaseid, TEST_PLUGINS, new CLIReporter($opt_separator));
+ exit(0);
+}
+
+/* run a grouptest */
+if ($opt_groupfile) {
+ TestManager::runGroupTest($opt_groupfile, TEST_GROUPS,
+ new CLIReporter($opt_separator));
+ exit(0);
+}
+
+/* run a plugin grouptest */
+if ($opt_plugingroupfile) {
+ TestManager::runGroupTest($opt_plugingroupfile, TEST_PLUGINS,
+ new CLIReporter($opt_separator));
+ exit(0);
+}
+
+/* run a plugin group test */
+//FIXME
+/* run all tests */
+TestManager::runAllTests(new CLIReporter($opt_separator));
+exit(0);
+?>
diff --git a/_test/tests.css b/_test/tests.css
new file mode 100644
index 000000000..c20d8bb4f
--- /dev/null
+++ b/_test/tests.css
@@ -0,0 +1,27 @@
+body {
+ background-color:#eee;
+ color:#000;
+ font:100%/1.2em Georgia,Verdana,Arial,Helvetica,sans-serif;
+ margin-left:20ex;
+ max-width:120ex;
+ }
+
+#sf { float:right; }
+
+h1 {
+ background-image:url(rephlux.png);
+ background-repeat:no-repeat;
+ margin-top:0;
+ padding:20px 0 0 90px;
+ color:#600;
+ font-size:3em;
+ line-height: 1em;
+ background-color:inherit;
+ border-bottom:9px double #333;
+ }
+
+pre {
+ font-size:120%;
+ line-height:1.2em;
+ color:#006;
+ } \ No newline at end of file
diff --git a/_test/tests.ini b/_test/tests.ini
new file mode 100644
index 000000000..cb16d4f1b
--- /dev/null
+++ b/_test/tests.ini
@@ -0,0 +1,12 @@
+TEST_ENABLED = 0
+
+; For performing "web tests" - PHP scripts acting as web browser
+WEB_TEST_URL = http://localhost/dokuwiki
+
+; See http://www.sitepoint.com/blogs/2004/06/15/simple-test-remote-testing/
+REMOTE_TEST_URL = http://localhost/dokuwiki/test/index.php
+
+;PROXY = http://proxyuser:proxypwd@proxy.yourdomain.com:8080
+
+; Path to Simple Test
+SIMPLE_TEST = ../../simpletest/
diff --git a/_test/webtest-stripper.sh b/_test/webtest-stripper.sh
new file mode 100755
index 000000000..f7991cc0b
--- /dev/null
+++ b/_test/webtest-stripper.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+################################################################################
+# Quick script to make simpletest web test fail output more legible
+#
+# Run the web test group from the command line w/ the command:
+#
+# $ ./runtests.php -g [GROUP] 2> tmp
+#
+# redirecting the error messages to the file tmp
+#
+# Then run this command on the tmp file
+#
+# $ ./webtest-stripper.sh tmp
+#
+################################################################################
+
+usage="Usage: ${0} [WEB_TEST_OUTPUT_FILE]";
+
+if [ -z "$1" ]; then
+ echo $usage;
+ exit 1;
+elif [ ! -f "$1" ]; then
+ echo "${1} is not a file!";
+ echo $usage;
+ exit 1;
+fi
+
+sed -e 's/\\n/\
+/g' "${1}" |\
+sed -e 's/\\//g' |\
+sed -e 's/FAIL.*Pattern \[\#\^/EXPECTED:\
+/g' |\
+sed -e 's/\$#i\].*string \[/\
+\
+GOT:\
+/g' |\
+sed -e 's/\]$/\
+----------------------------------------------------------------\
+/g'
+
+exit 0 \ No newline at end of file
diff --git a/bin/.htaccess b/bin/.htaccess
new file mode 100644
index 000000000..9c96d3742
--- /dev/null
+++ b/bin/.htaccess
@@ -0,0 +1,2 @@
+order allow,deny
+deny from all
diff --git a/bin/dwpage.php b/bin/dwpage.php
new file mode 100755
index 000000000..211bc5a9e
--- /dev/null
+++ b/bin/dwpage.php
@@ -0,0 +1,378 @@
+#!/usr/bin/php
+<?php
+#------------------------------------------------------------------------------
+if ('cli' != php_sapi_name()) die();
+
+ini_set('memory_limit','128M');
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+require_once DOKU_INC.'inc/init.php';
+require_once DOKU_INC.'inc/common.php';
+require_once DOKU_INC.'inc/cliopts.php';
+
+#------------------------------------------------------------------------------
+function usage($action) {
+ switch ( $action ) {
+ case 'checkout':
+ print "Usage: dwpage.php [opts] checkout <wiki:page> [working_file]
+
+ Checks out a file from the repository, using the wiki id and obtaining
+ a lock for the page.
+ 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.
+
+ EXAMPLE
+ $ ./dwpage.php checkout wiki:syntax ./new_syntax.txt
+
+ OPTIONS
+ -h, --help=<action>: get help
+ -f: force obtaining a lock for the page (generally bad idea)
+";
+ break;
+ case 'commit':
+ print "Usage: dwpage.php [opts] -m \"Msg\" commit <working_file> <wiki:page>
+
+ Checks in the working_file into the repository using the specified
+ wiki id, archiving the previous version.
+
+ EXAMPLE
+ $ ./dwpage.php -m \"Some message\" commit ./new_syntax.txt wiki:syntax
+
+ OPTIONS
+ -h, --help=<action>: get help
+ -f: force obtaining a lock for the page (generally bad idea)
+ -t, trivial: minor change
+ -m (required): Summary message describing the change
+";
+ break;
+ case 'lock':
+ print "Usage: dwpage.php [opts] lock <wiki:page>
+
+ Obtains or updates a lock for a wiki page
+
+ EXAMPLE
+ $ ./dwpage.php lock wiki:syntax
+
+ OPTIONS
+ -h, --help=<action>: get help
+ -f: force obtaining a lock for the page (generally bad idea)
+";
+ break;
+ case 'unlock':
+ print "Usage: dwpage.php [opts] unlock <wiki:page>
+
+ Removes a lock for a wiki page.
+
+ EXAMPLE
+ $ ./dwpage.php unlock wiki:syntax
+
+ OPTIONS
+ -h, --help=<action>: get help
+ -f: force obtaining a lock for the page (generally bad idea)
+";
+ break;
+ default:
+ print "Usage: dwpage.php [opts] <action>
+
+ Utility to help command line Dokuwiki page editing, allow
+ pages to be checked out for editing then committed after changes
+
+ Normal operation would be;
+
+
+
+ ACTIONS
+ checkout: see $ dwpage.php --help=checkout
+ commit: see $ dwpage.php --help=commit
+ lock: see $ dwpage.php --help=lock
+
+ OPTIONS
+ -h, --help=<action>: get help
+ e.g. $ ./dwpage.php -hcommit
+ e.g. $ ./dwpage.php --help=commit
+";
+ break;
+ }
+}
+
+#------------------------------------------------------------------------------
+function getUser() {
+ $user = getenv('USER');
+ if (empty ($user)) {
+ $user = getenv('USERNAME');
+ } else {
+ return $user;
+ }
+ if (empty ($user)) {
+ $user = 'admin';
+ }
+ return $user;
+}
+
+#------------------------------------------------------------------------------
+function getSuppliedArgument($OPTS, $short, $long) {
+ $arg = $OPTS->get($short);
+ if ( is_null($arg) ) {
+ $arg = $OPTS->get($long);
+ }
+ return $arg;
+}
+
+#------------------------------------------------------------------------------
+function obtainLock($WIKI_ID) {
+
+ global $USERNAME;
+
+ if ( !file_exists(wikiFN($WIKI_ID)) ) {
+ fwrite( STDERR, "$WIKI_ID does not yet exist\n");
+ }
+
+ $_SERVER['REMOTE_USER'] = $USERNAME;
+ if ( checklock($WIKI_ID) ) {
+ fwrite( STDERR, "Page $WIKI_ID is already locked by another user\n");
+ exit(1);
+ }
+
+ lock($WIKI_ID);
+
+ $_SERVER['REMOTE_USER'] = '_'.$USERNAME.'_';
+
+ if ( checklock($WIKI_ID) != $USERNAME ) {
+
+ fwrite( STDERR, "Unable to obtain lock for $WIKI_ID\n" );
+ exit(1);
+
+ }
+}
+
+#------------------------------------------------------------------------------
+function clearLock($WIKI_ID) {
+
+ global $USERNAME ;
+
+ if ( !file_exists(wikiFN($WIKI_ID)) ) {
+ fwrite( STDERR, "$WIKI_ID does not yet exist\n");
+ }
+
+ $_SERVER['REMOTE_USER'] = $USERNAME;
+ if ( checklock($WIKI_ID) ) {
+ fwrite( STDERR, "Page $WIKI_ID is locked by another user\n");
+ exit(1);
+ }
+
+ unlock($WIKI_ID);
+
+ if ( file_exists(wikiLockFN($WIKI_ID)) ) {
+ fwrite( STDERR, "Unable to clear lock for $WIKI_ID\n" );
+ exit(1);
+ }
+
+}
+
+#------------------------------------------------------------------------------
+function deleteLock($WIKI_ID) {
+
+ $wikiLockFN = wikiLockFN($WIKI_ID);
+
+ if ( file_exists($wikiLockFN) ) {
+ if ( !unlink($wikiLockFN) ) {
+ fwrite( STDERR, "Unable to delete $wikiLockFN\n" );
+ exit(1);
+ }
+ }
+
+}
+
+#------------------------------------------------------------------------------
+$USERNAME = getUser();
+$CWD = getcwd();
+$SYSTEM_ID = '127.0.0.1';
+
+#------------------------------------------------------------------------------
+$OPTS = Doku_Cli_Opts::getOptions(
+ __FILE__,
+ 'h::fm:u:s:t',
+ array(
+ 'help==',
+ 'user=',
+ 'system=',
+ 'trivial',
+ )
+);
+
+if ( $OPTS->isError() ) {
+ print $OPTS->getMessage()."\n";
+ exit(1);
+}
+
+if ( $OPTS->has('h') or $OPTS->has('help') or !$OPTS->hasArgs() ) {
+ usage(getSuppliedArgument($OPTS,'h','help'));
+ exit(0);
+}
+
+if ( $OPTS->has('u') or $OPTS->has('user') ) {
+ $USERNAME = getSuppliedArgument($OPTS,'u','user');
+}
+
+if ( $OPTS->has('s') or $OPTS->has('system') ) {
+ $SYSTEM_ID = getSuppliedArgument($OPTS,'s','system');
+}
+
+#------------------------------------------------------------------------------
+switch ( $OPTS->arg(0) ) {
+
+ #----------------------------------------------------------------------
+ case 'checkout':
+
+ $WIKI_ID = $OPTS->arg(1);
+
+ if ( !$WIKI_ID ) {
+ fwrite( STDERR, "Wiki page ID required\n");
+ exit(1);
+ }
+
+ $WIKI_FN = wikiFN($WIKI_ID);
+
+ if ( !file_exists($WIKI_FN) ) {
+ fwrite( STDERR, "$WIKI_ID does not yet exist\n");
+ exit(1);
+ }
+
+ $TARGET_FN = $OPTS->arg(2);
+
+ if ( empty($TARGET_FN) ) {
+ $TARGET_FN = getcwd().'/'.basename($WIKI_FN);
+ }
+
+ if ( !file_exists(dirname($TARGET_FN)) ) {
+ fwrite( STDERR, "Directory ".dirname($TARGET_FN)." does not exist\n");
+ exit(1);
+ }
+
+ if ( stristr( realpath(dirname($TARGET_FN)), realpath($conf['datadir']) ) !== false ) {
+ fwrite( STDERR, "Attempt to check out file into data directory - not allowed\n");
+ exit(1);
+ }
+
+ if ( $OPTS->has('f') ) {
+ deleteLock($WIKI_ID);
+ }
+
+ obtainLock($WIKI_ID);
+
+ # Need to lock the file first?
+ if ( !copy($WIKI_FN, $TARGET_FN) ) {
+ fwrite( STDERR, "Unable to copy $WIKI_FN to $TARGET_FN\n");
+ clearLock($WIKI_ID);
+ exit(1);
+ }
+
+ print "$WIKI_ID > $TARGET_FN\n";
+ exit(0);
+
+ break;
+
+ #----------------------------------------------------------------------
+ case 'commit':
+
+ $TARGET_FN = $OPTS->arg(1);
+
+ if ( !$TARGET_FN ) {
+ fwrite( STDERR, "Target filename required\n");
+ exit(1);
+ }
+
+ if ( !file_exists($TARGET_FN) ) {
+ fwrite( STDERR, "$TARGET_FN does not exist\n");
+ exit(1);
+ }
+
+ if ( !is_readable($TARGET_FN) ) {
+ fwrite( STDERR, "Cannot read from $TARGET_FN\n");
+ exit(1);
+ }
+
+ $WIKI_ID = $OPTS->arg(2);
+
+ if ( !$WIKI_ID ) {
+ fwrite( STDERR, "Wiki page ID required\n");
+ exit(1);
+ }
+
+ if ( !$OPTS->has('m') ) {
+ fwrite( STDERR, "Summary message required\n");
+ exit(1);
+ }
+
+ if ( $OPTS->has('f') ) {
+ deleteLock($WIKI_ID);
+ }
+
+ $_SERVER['REMOTE_USER'] = $USERNAME;
+ if ( checklock($WIKI_ID) ) {
+ fwrite( STDERR, "$WIKI_ID is locked by another user\n");
+ exit(1);
+ }
+
+ obtainLock($WIKI_ID);
+
+ saveWikiText($WIKI_ID, file_get_contents($TARGET_FN), $OPTS->get('m'), $OPTS->has('t'));
+
+ clearLock($WIKI_ID);
+
+ exit(0);
+
+ break;
+
+ #----------------------------------------------------------------------
+ case 'lock':
+
+ $WIKI_ID = $OPTS->arg(1);
+
+ if ( !$WIKI_ID ) {
+ fwrite( STDERR, "Wiki page ID required\n");
+ exit(1);
+ }
+
+ if ( $OPTS->has('f') ) {
+ deleteLock($WIKI_ID);
+ }
+
+ obtainLock($WIKI_ID);
+
+ print "Locked : $WIKI_ID\n";
+ exit(0);
+
+ break;
+
+ #----------------------------------------------------------------------
+ case 'unlock':
+
+ $WIKI_ID = $OPTS->arg(1);
+
+ if ( !$WIKI_ID ) {
+ fwrite( STDERR, "Wiki page ID required\n");
+ exit(1);
+ }
+
+ if ( $OPTS->has('f') ) {
+ deleteLock($WIKI_ID);
+ } else {
+ clearLock($WIKI_ID);
+ }
+
+ print "Unlocked : $WIKI_ID\n";
+ exit(0);
+
+ break;
+
+ #----------------------------------------------------------------------
+ default:
+
+ fwrite( STDERR, "Invalid action ".$OPTS->arg(0)."\n" );
+ exit(1);
+
+ break;
+
+}
+
diff --git a/bin/indexer.php b/bin/indexer.php
new file mode 100755
index 000000000..f6aeb4f0e
--- /dev/null
+++ b/bin/indexer.php
@@ -0,0 +1,158 @@
+#!/usr/bin/php
+<?php
+if ('cli' != php_sapi_name()) die();
+
+ini_set('memory_limit','128M');
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+require_once(DOKU_INC.'inc/init.php');
+require_once(DOKU_INC.'inc/common.php');
+require_once(DOKU_INC.'inc/pageutils.php');
+require_once(DOKU_INC.'inc/search.php');
+require_once(DOKU_INC.'inc/indexer.php');
+require_once(DOKU_INC.'inc/auth.php');
+require_once(DOKU_INC.'inc/cliopts.php');
+session_write_close();
+
+// handle options
+$short_opts = 'hcuq';
+$long_opts = array('help', 'clear', 'update', 'quiet');
+$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
+if ( $OPTS->isError() ) {
+ fwrite( STDERR, $OPTS->getMessage() . "\n");
+ _usage();
+ exit(1);
+}
+$CLEAR = false;
+$QUIET = false;
+$INDEXER = null;
+foreach ($OPTS->options as $key => $val) {
+ switch ($key) {
+ case 'h':
+ case 'help':
+ _usage();
+ exit;
+ case 'c':
+ case 'clear':
+ $CLEAR = true;
+ break;
+ case 'q':
+ case 'quiet':
+ $QUIET = true;
+ break;
+ }
+}
+
+#------------------------------------------------------------------------------
+# Action
+
+if($CLEAR) _clearindex();
+_update();
+
+
+
+#------------------------------------------------------------------------------
+
+function _usage() {
+ print "Usage: indexer.php <options>
+
+ Updates the searchindex by indexing all new or changed pages
+ when the -c option is given the index is cleared first.
+
+ OPTIONS
+ -h, --help show this help and exit
+ -c, --clear clear the index before updating
+ -q, --quiet don't produce any output
+";
+}
+
+function _update(){
+ global $conf;
+ global $INDEXER;
+
+ $INDEXER = idx_get_indexer();
+
+ $data = array();
+ _quietecho("Searching pages... ");
+ search($data,$conf['datadir'],'search_allpages',array('skipacl' => true));
+ _quietecho(count($data)." pages found.\n");
+
+ foreach($data as $val){
+ _index($val['id']);
+ }
+}
+
+function _index($id){
+ global $INDEXER;
+ global $CLEAR;
+ global $QUIET;
+
+ _quietecho("$id... ");
+ idx_addPage($id, !$QUIET, $CLEAR);
+ _quietecho("done.\n");
+}
+
+/**
+ * lock the indexer system
+ */
+function _lock(){
+ global $conf;
+ $lock = $conf['lockdir'].'/_indexer.lock';
+ $said = false;
+ while(!@mkdir($lock, $conf['dmode'])){
+ if(time()-@filemtime($lock) > 60*5){
+ // looks like a stale lock - remove it
+ @rmdir($lock);
+ }else{
+ if($said){
+ _quietecho(".");
+ }else{
+ _quietecho("Waiting for lockfile (max. 5 min)");
+ $said = true;
+ }
+ sleep(15);
+ }
+ }
+ if($conf['dperm']) chmod($lock, $conf['dperm']);
+ if($said) _quietecho("\n");
+}
+
+/**
+ * unlock the indexer sytem
+ */
+function _unlock(){
+ global $conf;
+ $lock = $conf['lockdir'].'/_indexer.lock';
+ @rmdir($lock);
+}
+
+/**
+ * Clear all index files
+ */
+function _clearindex(){
+ global $conf;
+ _lock();
+ _quietecho("Clearing index... ");
+ io_saveFile($conf['indexdir'].'/page.idx','');
+ io_saveFile($conf['indexdir'].'/title.idx','');
+ io_saveFile($conf['indexdir'].'/pageword.idx','');
+ io_saveFile($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');
+ _quietecho("done.\n");
+ _unlock();
+}
+
+function _quietecho($msg) {
+ global $QUIET;
+ if(!$QUIET) echo $msg;
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/bin/render.php b/bin/render.php
new file mode 100755
index 000000000..d30ef2958
--- /dev/null
+++ b/bin/render.php
@@ -0,0 +1,67 @@
+#!/usr/bin/php
+<?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>
+ */
+if ('cli' != php_sapi_name()) die();
+
+ini_set('memory_limit','128M');
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+define('NOSESSION',1);
+require_once(DOKU_INC.'inc/init.php');
+require_once(DOKU_INC.'inc/common.php');
+require_once(DOKU_INC.'inc/parserutils.php');
+require_once(DOKU_INC.'inc/cliopts.php');
+
+// handle options
+$short_opts = 'hr:';
+$long_opts = array('help','renderer:');
+$OPTS = Doku_Cli_Opts::getOptions(__FILE__,$short_opts,$long_opts);
+if ( $OPTS->isError() ) {
+ fwrite( STDERR, $OPTS->getMessage() . "\n");
+ _usage();
+ exit(1);
+}
+$RENDERER = 'xhtml';
+foreach ($OPTS->options as $key => $val) {
+ switch ($key) {
+ case 'h':
+ case 'help':
+ _usage();
+ exit;
+ case 'r':
+ case 'renderer':
+ $RENDERER = $val;
+ }
+}
+
+
+// do the action
+$source = stream_get_contents(STDIN);
+$info = array();
+$result = p_render($RENDERER,p_get_instructions($source),$info);
+if(is_null($result)) die("No such renderer $RENDERER\n");
+echo $result;
+
+/**
+ * Print usage info
+ */
+function _usage(){
+ print "Usage: render.php <options>
+
+ Reads DokuWiki syntax from STDIN and renders it with the given renderer
+ to STDOUT
+
+ OPTIONS
+ -h, --help show this help and exit
+ -r, --renderer <renderer> the render mode (default: xhtml)
+";
+}
diff --git a/bin/striplangs.php b/bin/striplangs.php
new file mode 100644
index 000000000..40cef5063
--- /dev/null
+++ b/bin/striplangs.php
@@ -0,0 +1,148 @@
+#!/usr/bin/php
+<?php
+/**
+ * Strip unwanted languages from the DokuWiki install
+ *
+ * @author Martin 'E.T.' Misuth <et.github@ethome.sk>
+ */
+if ('cli' != php_sapi_name()) die();
+
+#------------------------------------------------------------------------------
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+require_once DOKU_INC.'inc/cliopts.php';
+
+#------------------------------------------------------------------------------
+function usage($show_examples = false) {
+ print "Usage: striplangs.php [-h [-x]] [-e] [-k lang1[,lang2]..[,langN]]
+
+ Removes all languages from the instalation, besides the ones
+ after the -k option. English language is never removed!
+
+ OPTIONS
+ -h, --help get this help
+ -x, --examples get also usage examples
+ -k, --keep comma separated list of languages, -e is always implied
+ -e, --english keeps english, dummy to use without -k\n";
+ if ( $show_examples ) {
+ print "\n
+ EXAMPLES
+ Strips all languages, but keeps 'en' and 'de':
+ striplangs -k de
+
+ Strips all but 'en','ca-valencia','cs','de','is','sk':
+ striplangs --keep ca-valencia,cs,de,is,sk
+
+ Strips all but 'en':
+ striplangs -e
+
+ No option specified, prints usage and throws error:
+ striplangs\n";
+ }
+}
+
+function getSuppliedArgument($OPTS, $short, $long) {
+ $arg = $OPTS->get($short);
+ if ( is_null($arg) ) {
+ $arg = $OPTS->get($long);
+ }
+ return $arg;
+}
+
+function processPlugins($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 ) ) {
+ stripDirLangs($plugin_langs, $keep_langs);
+ }
+ }
+ }
+ }
+ }
+}
+
+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 ) ) {
+ killDir($path.'/'.$cur_dir);
+ }
+ }
+ }
+ $dir->close();
+}
+
+function killDir($dir) {
+ if (is_dir($dir)) {
+ $entries = scandir($dir);
+
+ foreach ($entries as $entry) {
+ if ($entry != "." && $entry != "..") {
+ if ( is_dir($dir.'/'.$entry) ) {
+ killDir($dir.'/'.$entry);
+ } else {
+ unlink($dir.'/'.$entry);
+ }
+ }
+ }
+ reset($entries);
+ rmdir($dir);
+ }
+}
+#------------------------------------------------------------------------------
+
+// handle options
+$short_opts = 'hxk:e';
+$long_opts = array('help', 'examples', 'keep=','english');
+
+$OPTS = Doku_Cli_Opts::getOptions(__FILE__, $short_opts, $long_opts);
+
+if ( $OPTS->isError() ) {
+ fwrite( STDERR, $OPTS->getMessage() . "\n");
+ exit(1);
+}
+
+// handle '--examples' option
+$show_examples = ( $OPTS->has('x') or $OPTS->has('examples') ) ? true : false;
+
+// handle '--help' option
+if ( $OPTS->has('h') or $OPTS->has('help') ) {
+ usage($show_examples);
+ exit(0);
+}
+
+// handle both '--keep' and '--english' options
+if ( $OPTS->has('k') or $OPTS->has('keep') ) {
+ $preserved_langs = getSuppliedArgument($OPTS,'k','keep');
+ $langs = explode(',', $preserved_langs);
+
+ // ! always enforce 'en' lang when using '--keep' (DW relies on it)
+ if ( !isset($langs['en']) ) {
+ $langs[]='en';
+ }
+} elseif ( $OPTS->has('e') or $OPTS->has('english') ) {
+ // '--english' was specified strip everything besides 'en'
+ $langs = array ('en');
+} else {
+ // no option was specified, print usage but don't do anything as
+ // this run might not be intented
+ usage();
+ print "\n
+ ERROR
+ No option specified, use either -h -x to get more info,
+ or -e to strip every language besides english.\n";
+ exit(1);
+}
+
+// Kill all language directories in /inc/lang and /lib/plugins besides those in $langs array
+stripDirLangs(realpath(dirname(__FILE__).'/../inc/lang'), $langs);
+processPlugins(realpath(dirname(__FILE__).'/../lib/plugins'), $langs);
diff --git a/bin/wantedpages.php b/bin/wantedpages.php
new file mode 100755
index 000000000..30171fc15
--- /dev/null
+++ b/bin/wantedpages.php
@@ -0,0 +1,134 @@
+#!/usr/bin/php
+<?php
+if ('cli' != php_sapi_name()) die();
+
+#------------------------------------------------------------------------------
+ini_set('memory_limit','128M');
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+require_once DOKU_INC.'inc/init.php';
+require_once DOKU_INC.'inc/common.php';
+require_once DOKU_INC.'inc/search.php';
+require_once DOKU_INC.'inc/cliopts.php';
+
+#------------------------------------------------------------------------------
+function usage() {
+ print "Usage: wantedpages.php [wiki:namespace]
+
+ Outputs a list of wanted pages (pages which have
+ internal links but do not yet exist).
+
+ If the optional [wiki:namespace] is not provided,
+ defaults to the root wiki namespace
+
+ OPTIONS
+ -h, --help get help
+";
+}
+
+#------------------------------------------------------------------------------
+define ('DW_DIR_CONTINUE',1);
+define ('DW_DIR_NS',2);
+define ('DW_DIR_PAGE',3);
+
+#------------------------------------------------------------------------------
+function dw_dir_filter($entry, $basepath) {
+ if ($entry == '.' || $entry == '..' ) {
+ return DW_DIR_CONTINUE;
+ }
+ if ( is_dir($basepath . '/' . $entry) ) {
+ if ( strpos($entry, '_') === 0 ) {
+ return DW_DIR_CONTINUE;
+ }
+ return DW_DIR_NS;
+ }
+ if ( preg_match('/\.txt$/',$entry) ) {
+ return DW_DIR_PAGE;
+ }
+ return DW_DIR_CONTINUE;
+}
+
+#------------------------------------------------------------------------------
+function dw_get_pages($dir) {
+ static $trunclen = NULL;
+ if ( !$trunclen ) {
+ global $conf;
+ $trunclen = strlen($conf['datadir'].':');
+ }
+
+ if ( !is_dir($dir) ) {
+ fwrite( STDERR, "Unable to read directory $dir\n");
+ exit(1);
+ }
+
+ $pages = array();
+ $dh = opendir($dir);
+ while ( false !== ( $entry = readdir($dh) ) ) {
+ $status = dw_dir_filter($entry, $dir);
+ if ( $status == DW_DIR_CONTINUE ) {
+ continue;
+ } else if ( $status == DW_DIR_NS ) {
+ $pages = array_merge($pages, dw_get_pages($dir . '/' . $entry));
+ } else {
+ $page = array(
+ 'id' => pathID(substr($dir.'/'.$entry,$trunclen)),
+ 'file'=> $dir.'/'.$entry,
+ );
+ $pages[] = $page;
+ }
+ }
+ closedir($dh);
+ return $pages;
+}
+
+#------------------------------------------------------------------------------
+function dw_internal_links($page) {
+ global $conf;
+ $instructions = p_get_instructions(file_get_contents($page['file']));
+ $links = array();
+ $cns = getNS($page['id']);
+ $exists = false;
+ 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 hashs
+ $links[] = $mid;
+ }
+ }
+ }
+ return $links;
+}
+
+#------------------------------------------------------------------------------
+$OPTS = Doku_Cli_Opts::getOptions(__FILE__,'h',array('help'));
+
+if ( $OPTS->isError() ) {
+ fwrite( STDERR, $OPTS->getMessage() . "\n");
+ exit(1);
+}
+
+if ( $OPTS->has('h') or $OPTS->has('help') ) {
+ usage();
+ exit(0);
+}
+
+$START_DIR = $conf['datadir'];
+
+if ( $OPTS->numArgs() == 1 ) {
+ $START_DIR .= '/' . $OPTS->arg(0);
+}
+
+#------------------------------------------------------------------------------
+$WANTED_PAGES = array();
+
+foreach ( dw_get_pages($START_DIR) as $WIKI_PAGE ) {
+ $WANTED_PAGES = array_merge($WANTED_PAGES,dw_internal_links($WIKI_PAGE));
+}
+$WANTED_PAGES = array_unique($WANTED_PAGES);
+sort($WANTED_PAGES);
+
+foreach ( $WANTED_PAGES as $WANTED_PAGE ) {
+ print $WANTED_PAGE."\n";
+}
+exit(0);
diff --git a/conf/.htaccess b/conf/.htaccess
new file mode 100644
index 000000000..f5dda6086
--- /dev/null
+++ b/conf/.htaccess
@@ -0,0 +1,4 @@
+## no access to the conf directory
+order allow,deny
+deny from all
+Satisfy All
diff --git a/conf/acl.auth.php.dist b/conf/acl.auth.php.dist
new file mode 100644
index 000000000..14344d778
--- /dev/null
+++ b/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/conf/acronyms.conf b/conf/acronyms.conf
new file mode 100644
index 000000000..058e85550
--- /dev/null
+++ b/conf/acronyms.conf
@@ -0,0 +1,145 @@
+# Acronyms.
+
+ACL Access Control List
+AFAICS As far as I can see
+AFAIK As far as I know
+AFAIR As far as I remember
+AJAX Asynchronous JavaScript and XML
+AIM AOL (America Online) Instant Messenger
+AOL America Online
+API Application Programming Interface
+ASAP As soon as possible
+ASCII American Standard Code for Information Interchange
+ASP Active Server Pages
+BTW By the way
+CGI Common Gateway Interface
+CMS Content Management System
+CSS Cascading Style Sheets
+CVS Concurrent Versions System
+DBA Database Administrator
+DHCP Dynamic Host Configuration Protocol
+DHTML Dynamic HyperText Markup Language
+DMCA Digital Millenium Copyright Act
+DNS Domain Name System
+DOM Document Object Model
+DTD Document Type Definition
+EOF End of file
+EOL End of line
+EOM End of message
+EOT End of text
+ESMTP Extended Simple Mail Transfer Protocol
+FAQ Frequently Asked Questions
+FDL GNU Free Documentation License
+FTP File Transfer Protocol
+FOSS Free & Open-Source Software
+FLOSS Free/Libre and Open Source Software
+FUD Fear, Uncertainty, and Doubt
+GB Gigabyte
+GHz Gigahertz
+GIF Graphics Interchange Format
+GPL GNU General Public License
+GUI Graphical User Interface
+HTML HyperText Markup Language
+HTTP Hyper Text Transfer Protocol
+IANAL I am not a lawyer (but)
+ICANN Internet Corporation for Assigned Names and Numbers
+ICQ I seek you (Instant Messenger)
+IE5 Internet Explorer 5
+IE6 Internet Explorer 6
+IE Internet Explorer
+IIRC If I remember correctly
+IIS Internet Information Services
+IMAP Internet Message Access Protocol
+IMHO In my humble opinion
+IMO In my opinion
+IOW In other words
+IRC Internet Relay Chat
+IRL In real life
+ISO International Organization for Standardization
+ISP Internet Service Provider
+JDK Java Development Kit
+JPEG Joint Photographics Experts Group
+JPG Joint Photographics Experts Group
+JS JavaScript
+KISS Keep it simple stupid
+LAN Local Area Network
+LDAP Lightweight Directory Access Protocol
+LGPL GNU Lesser General Public License
+LOL Laughing out loud
+MathML Mathematical Markup Language
+MB Megabyte
+MHz Megahertz
+MIME Multipurpose Internet Mail Extension
+MIT Massachusetts Institute of Technology
+MML Mathematical Markup Language
+MP3 Moving Picture Experts Group Layer 3
+MPEG Moving Picture Experts Group
+MSDN Microsoft Developer Network
+MS Microsoft
+MSIE Microsoft Internet Explorer
+NIS Network Information Service
+NS4.7 Netscape 4.7
+NS4 Netscape 4
+NS6 Netscape 6
+NS7 Netscape 7
+OMG Oh my God
+OPML Outline Processor Markup Language
+OS Operating System
+OSS Open Source Software
+OTOH On the other hand
+P2P Peer to Peer
+PDA Personal Digital Assistant
+PDF Portable Document Format
+Perl Practical Extraction and Report Language
+PERL Practical Extraction and Report Language
+PHP Hypertext Preprocessor
+PICS Platform for Internet Content Selection
+PIN Personal Identification Number
+PITA Pain in the Ass
+PNG Portable Network Graphics
+POP3 Post Office Protocol 3
+POP Post Office Protocol
+QoS Quality of Service
+RAID Redundant Array of Inexpensive Disks
+RDF Resource Description Framework
+RFC Request for Comments
+ROTFL Rolling on the floor laughing
+RPC Remote Procedure Call
+RSS Rich Site Summary
+RTFM Read The Fine Manual
+RTF Rich Text File
+SCSI Small Computer System Interface
+SDK Software Development Kit
+SGML Standard General Markup Language
+SMIL Synchronized Multimedia Integration Language
+SMTP Simple Mail Transfer Protocol
+SOAP Simple Object Access Protocol
+spec specification
+SQL Structured Query Language
+SSH Secure Shell
+SSI Server Side Includes
+SSL Secure Sockets Layer
+SVG Scalable Vector Graphics
+TIA Thanks in advance
+TIFF Tagged Image File Format
+TLD Top Level Domain
+TOC Table of Contents
+URI Uniform Resource Identifier
+URL Uniform Resource Locator
+URN Uniform Resource Name
+VBA Visual Basic for Applications
+VB Visual Basic
+W3C World Wide Web Consortium
+WAN Wide Area Network
+WAP Wireless Access Protocol
+WML Wireless Markup Language
+WTF? What the f***
+WWW World Wide Web
+WYSIWYG What You See Is What You Get
+XHTML Extensible HyperText Markup Language
+XML Extensible Markup Language
+XSD XML (Extensible Markup Language) Schema Definition
+XSL Extensible Stylesheet Language
+XSLT Extensible Stylesheet Language Transformations
+XUL XML User Interface Language
+YMMV Your mileage may vary
diff --git a/conf/dokuwiki.php b/conf/dokuwiki.php
new file mode 100644
index 000000000..7a7e4bf1a
--- /dev/null
+++ b/conf/dokuwiki.php
@@ -0,0 +1,167 @@
+<?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 see http://www.dokuwiki.org/config
+ */
+
+
+/* Datastorage and Permissions */
+
+$conf['fmode'] = 0644; //set file creation mode
+$conf['dmode'] = 0755; //set directory creation mode
+$conf['lang'] = 'en'; //your language
+$conf['basedir'] = ''; //absolute dir from serveroot - blank for autodetection
+$conf['baseurl'] = ''; //URL to server including protocol - blank for autodetect
+$conf['cookiedir'] = ''; //Cookie path. Leave blank for using baseurl.
+$conf['savedir'] = './data'; //where to store all the files
+$conf['allowdebug'] = 0; //allow debug output, enable if needed 0|1
+$conf['mediarevisions'] = 1; //enable/disable media revisions
+
+/* Display Options */
+
+$conf['start'] = 'start'; //name of start page
+$conf['title'] = 'DokuWiki'; //what to show in the title
+$conf['template'] = 'default'; //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['fullpath'] = 0; //show full path of the document or relative to datadir only? 0|1
+$conf['recent'] = 20; //how many entries to show in recent
+$conf['breadcrumbs'] = 10; //how many recent visited pages to show
+$conf['youarehere'] = 0; //show "You are here" navigation? 0|1
+$conf['typography'] = 1; //smartquote conversion 0=off, 1=doublequotes, 2=all quotes
+$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['dformat'] = '%Y/%m/%d %H:%M'; //dateformat accepted by PHPs strftime() function
+$conf['signature'] = ' --- //[[@MAIL@|@NAME@]] @DATE@//'; //signature see wiki:config for details
+$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['refcheck'] = 1; //check for references before deleting media files
+$conf['refshow'] = 0; //how many references should be shown, 5 is a good value
+$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)
+
+/* Antispam Features */
+
+$conf['usewordblock']= 1; //block spam based on words? 0|1
+$conf['indexdelay'] = 60*60*24*5; //allow indexing after this time (seconds) default is 5 days
+$conf['relnofollow'] = 1; //use rel="nofollow" for external links?
+$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
+
+/* Authentication Options - read http://www.splitbrain.org/dokuwiki/wiki:acl */
+
+$conf['useacl'] = 0; //Use Access Control Lists to restrict access?
+$conf['autopasswd'] = 1; //autogenerate passwords and email them to user
+$conf['authtype'] = 'plain'; //which authentication backend should be used
+$conf['passcrypt'] = 'smd5'; //Used crypt method (smd5,md5,sha1,ssha,crypt,mysql,my411)
+$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['disableactions'] = ''; //comma separated list of actions to disable
+$conf['sneaky_index'] = 0; //check for namespace read permission in index view (0|1) (1 might cause unexpected behavior)
+$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['xmlrpc'] = 0; //Enable/disable XML-RPC interface
+$conf['xmlrpcuser'] = '!!not set!!'; //Restrict XML-RPC access to this groups/users
+
+/* Advanced Options */
+
+$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['usedraft'] = 1; //automatically save a draft while editing (0|1)
+$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['cachetime'] = 60*60*24; //maximum age for cachefile in seconds (defaults to a day)
+$conf['locktime'] = 15*60; //maximum age for lockfiles (defaults to 15 minutes)
+$conf['fetchsize'] = 0; //maximum size (bytes) fetch.php may download from extern, disabled by default
+$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['mailprefix'] = ''; //use this as prefix of outgoing mails
+$conf['gzip_output'] = 0; //use gzip content encodeing for the output xhtml (if allowed by browser)
+$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['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['compress'] = 1; //Strip whitespaces and comments from Styles and JavaScript? 1|0
+$conf['cssdatauri'] = 0; //Maximum byte size of small images to embed into CSS, won't work on IE<8
+$conf['hidepages'] = ''; //Regexp for pages to be skipped from RSS, Search and Recent Changes
+$conf['send404'] = 0; //Send a HTTP 404 status for non existing pages?
+$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_update'] = 5*60; //Update the RSS feed every n seconds (defaults to 5 minutes)
+$conf['recent_days'] = 7; //How many days of recent changes to keep. (days)
+$conf['rss_show_summary'] = 1; //Add revision summary to title? 0|1
+$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['rememberme'] = 1; //Enable/disable remember me on login
+
+//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'] = '';
+
+//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'] = '';
+
+/* Safemode Hack */
+
+$conf['safemodehack'] = 0; //read http://www.dokuwiki.org/config:safemodehack !
+$conf['ftp']['host'] = 'localhost';
+$conf['ftp']['port'] = '21';
+$conf['ftp']['user'] = 'user';
+$conf['ftp']['pass'] = 'password';
+$conf['ftp']['root'] = '/home/user/htdocs';
+
+$conf['readdircache'] = 0; //time cache in second for the readdir opération, 0 to deactivate.
diff --git a/conf/entities.conf b/conf/entities.conf
new file mode 100644
index 000000000..be9ed6d40
--- /dev/null
+++ b/conf/entities.conf
@@ -0,0 +1,22 @@
+# Typography replacements
+#
+# Order does matter!
+#
+# You can use HTML entities here, but it is not recomended because it may break
+# non-HTML renderers. Use UTF-8 chars directly instead.
+
+<-> ↔
+-> →
+<- ←
+<=> ⇔
+=> ⇒
+<= ⇐
+>> »
+<< «
+--- —
+-- –
+(c) ©
+(tm) ™
+(r) ®
+... …
+
diff --git a/conf/interwiki.conf b/conf/interwiki.conf
new file mode 100644
index 000000000..28d603de2
--- /dev/null
+++ b/conf/interwiki.conf
@@ -0,0 +1,131 @@
+# Each URL may contain one of the placeholders {URL} or {NAME}
+# {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
+# no further encoding is done
+# 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 http://en.wikipedia.org/wiki/{NAME}
+wpfr http://fr.wikipedia.org/wiki/{NAME}
+wpde http://de.wikipedia.org/wiki/{NAME}
+wpes http://es.wikipedia.org/wiki/{NAME}
+wppl http://pl.wikipedia.org/wiki/{NAME}
+wpjp http://ja.wikipedia.org/wiki/{NAME}
+wpmeta http://meta.wikipedia.org/wiki/{NAME}
+doku http://www.dokuwiki.org/
+dokubug http://bugs.dokuwiki.org/index.php?do=details&amp;task_id=
+rfc http://www.cs.ccu.edu.tw/~chm91u/rfc2html.php?in=
+man http://man.cx/
+amazon http://www.amazon.com/exec/obidos/ASIN/{URL}/splitbrain-20/
+amazon.de http://www.amazon.de/exec/obidos/ASIN/{URL}/splitbrain-21/
+amazon.uk http://www.amazon.co.uk/exec/obidos/ASIN/
+paypal https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=
+phpfn http://www.php.net/{NAME}
+coral http://{HOST}.{PORT}.nyud.net:8090/{PATH}?{QUERY}
+freecache http://freecache.org/{NAME}
+sb http://www.splitbrain.org/go/
+skype skype:{NAME}
+google.de http://www.google.de/search?q=
+go http://www.google.com/search?q={URL}&amp;btnI=lucky
+
+# To support VoIP/SIP links
+callto callto://{NAME}
+
+# Standards from http://usemod.com/intermap.txt follow
+
+AbbeNormal http://www.ourpla.net/cgi-bin/pikie.cgi?
+AcadWiki http://xarch.tu-graz.ac.at/autocad/wiki/
+Acronym http://www.acronymfinder.com/af-query.asp?String=exact&amp;Acronym=
+Advogato http://www.advogato.org/
+AIWiki http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?
+ALife http://news.alife.org/wiki/index.php?
+AndStuff http://andstuff.org/wiki.php?
+Annotation http://bayle.stanford.edu/crit/nph-med.cgi/
+AnnotationWiki http://www.seedwiki.com/page.cfm?wikiid=368&amp;doc=
+AwarenessWiki http://taoriver.net/aware/
+BenefitsWiki http://www.benefitslink.com/cgi-bin/wiki.cgi?
+BridgesWiki http://c2.com/w2/bridges/
+C2find http://c2.com/cgi/wiki?FindPage&amp;value=
+Cache http://www.google.com/search?q=cache:
+CLiki http://ww.telent.net/cliki/
+CmWiki http://www.ourpla.net/cgi-bin/wiki.pl?
+CreationMatters http://www.ourpla.net/cgi-bin/wiki.pl?
+DejaNews http://www.deja.com/=dnc/getdoc.xp?AN=
+DeWikiPedia http://www.wikipedia.de/wiki.cgi?
+Dictionary http://www.dict.org/bin/Dict?Database=*&amp;Form=Dict1&amp;Strategy=*&amp;Query=
+DiveIntoOsx http://diveintoosx.org/
+DocBook http://docbook.org/wiki/moin.cgi/
+DolphinWiki http://www.object-arts.com/wiki/html/Dolphin/
+EfnetCeeWiki http://purl.net/wiki/c/
+EfnetCppWiki http://purl.net/wiki/cpp/
+EfnetPythonWiki http://purl.net/wiki/python/
+EfnetXmlWiki http://purl.net/wiki/xml/
+EljWiki http://elj.sourceforge.net/phpwiki/index.php/
+EmacsWiki http://www.emacswiki.org/cgi-bin/wiki.pl?
+FinalEmpire http://final-empire.sourceforge.net/cgi-bin/wiki.pl?
+Foldoc http://www.foldoc.org/foldoc/foldoc.cgi?
+FoxWiki http://fox.wikis.com/wc.dll?Wiki~
+FreeBSDman http://www.FreeBSD.org/cgi/man.cgi?apropos=1&amp;query=
+Google http://www.google.com/search?q=
+GoogleGroups http://groups.google.com/groups?q=
+GreenCheese http://www.greencheese.org/
+HammondWiki http://www.dairiki.org/HammondWiki/index.php3?
+Haribeau http://wiki.haribeau.de/cgi-bin/wiki.pl?
+IAWiki http://www.IAwiki.net/
+IMDB http://us.imdb.com/Title?
+JargonFile http://sunir.org/apps/meta.pl?wiki=JargonFile&amp;redirect=
+JiniWiki http://www.cdegroot.com/cgi-bin/jini?
+JspWiki http://www.ecyrd.com/JSPWiki/Wiki.jsp?page=
+KmWiki http://www.voght.com/cgi-bin/pywiki?
+KnowHow http://www2.iro.umontreal.ca/~paquetse/cgi-bin/wiki.cgi?
+LanifexWiki http://opt.lanifex.com/cgi-bin/wiki.pl?
+LegoWiki http://www.object-arts.com/wiki/html/Lego-Robotics/
+LinuxWiki http://www.linuxwiki.de/
+LugKR http://lug-kr.sourceforge.net/cgi-bin/lugwiki.pl?
+MathSongsWiki http://SeedWiki.com/page.cfm?wikiid=237&amp;doc=
+MbTest http://www.usemod.com/cgi-bin/mbtest.pl?
+MeatBall http://www.usemod.com/cgi-bin/mb.pl?
+MetaWiki http://sunir.org/apps/meta.pl?
+MetaWikiPedia http://meta.wikipedia.com/wiki/
+MoinMoin http://purl.net/wiki/moin/
+MuWeb http://www.dunstable.com/scripts/MuWebWeb?
+NetVillage http://www.netbros.com/?
+OpenWiki http://openwiki.com/?
+OrgPatterns http://www.bell-labs.com/cgi-user/OrgPatterns/OrgPatterns?
+PangalacticOrg http://www.pangalactic.org/Wiki/
+PersonalTelco http://www.personaltelco.net/index.cgi/
+PhpWiki http://phpwiki.sourceforge.net/phpwiki/index.php?
+Pikie http://pikie.darktech.org/cgi/pikie?
+PPR http://c2.com/cgi/wiki?
+PurlNet http://purl.oclc.org/NET/
+PythonInfo http://www.python.org/cgi-bin/moinmoin/
+PythonWiki http://www.pythonwiki.de/
+PyWiki http://www.voght.com/cgi-bin/pywiki?
+SeaPig http://www.seapig.org/
+SeattleWireless http://seattlewireless.net/?
+SenseisLibrary http://senseis.xmp.net/?
+Shakti http://cgi.algonet.se/htbin/cgiwrap/pgd/ShaktiWiki/
+SourceForge http://sourceforge.net/{NAME}
+Squeak http://minnow.cc.gatech.edu/squeak/
+StrikiWiki http://ch.twi.tudelft.nl/~mostert/striki/teststriki.pl?
+SVGWiki http://www.protocol7.com/svg-wiki/default.asp?
+Tavi http://tavi.sourceforge.net/index.php?
+TmNet http://www.technomanifestos.net/?
+TMwiki http://www.EasyTopicMaps.com/?page=
+TWiki http://twiki.org/cgi-bin/view/{NAME}
+TwistedWiki http://purl.net/wiki/twisted/
+Unreal http://wiki.beyondunreal.com/wiki/
+UseMod http://www.usemod.com/cgi-bin/wiki.pl?
+VisualWorks http://wiki.cs.uiuc.edu/VisualWorks/
+WebDevWikiNL http://www.promo-it.nl/WebDevWiki/index.php?page=
+WebSeitzWiki http://webseitz.fluxent.com/wiki/
+Why http://clublet.com/c/c/why?
+Wiki http://c2.com/cgi/wiki?
+WikiPedia http://www.wikipedia.com/wiki/
+WikiWorld http://WikiWorld.com/wiki/index.php/
+YpsiEyeball http://sknkwrks.dyndns.org:1957/writewiki/wiki.pl?
+ZWiki http://www.zwiki.org/
+
diff --git a/conf/license.php b/conf/license.php
new file mode 100644
index 000000000..89728ab57
--- /dev/null
+++ b/conf/license.php
@@ -0,0 +1,36 @@
+<?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.
+ */
+
+$license['cc-zero'] = array(
+ 'name' => 'CC0 1.0 Universal',
+ 'url' => 'http://creativecommons.org/publicdomain/zero/1.0/',
+);
+$license['publicdomain'] = array(
+ 'name' => 'Public Domain',
+ 'url' => 'http://creativecommons.org/licenses/publicdomain/',
+);
+$license['cc-by'] = array(
+ 'name' => 'CC Attribution 3.0 Unported',
+ 'url' => 'http://creativecommons.org/licenses/by/3.0/',
+);
+$license['cc-by-sa'] = array(
+ 'name' => 'CC Attribution-Share Alike 3.0 Unported',
+ 'url' => 'http://creativecommons.org/licenses/by-sa/3.0/',
+);
+$license['gnufdl'] = array(
+ 'name' => 'GNU Free Documentation License 1.3',
+ 'url' => 'http://www.gnu.org/licenses/fdl-1.3.html',
+);
+$license['cc-by-nc'] = array(
+ 'name' => 'CC Attribution-Noncommercial 3.0 Unported',
+ 'url' => 'http://creativecommons.org/licenses/by-nc/3.0/',
+);
+$license['cc-by-nc-sa'] = array(
+ 'name' => 'CC Attribution-Noncommercial-Share Alike 3.0 Unported',
+ 'url' => 'http://creativecommons.org/licenses/by-nc-sa/3.0/',
+);
+
diff --git a/conf/local.php.dist b/conf/local.php.dist
new file mode 100644
index 000000000..0397954f4
--- /dev/null
+++ b/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/conf/mediameta.php b/conf/mediameta.php
new file mode 100644
index 000000000..0428a4b88
--- /dev/null
+++ b/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' or 'textarea'
+ * 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/conf/mime.conf b/conf/mime.conf
new file mode 100644
index 000000000..24529b06c
--- /dev/null
+++ b/conf/mime.conf
@@ -0,0 +1,64 @@
+# 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
+
+swf application/x-shockwave-flash
+mp3 audio/mpeg
+ogg audio/ogg
+wav audio/wav
+
+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
+
diff --git a/conf/mysql.conf.php.example b/conf/mysql.conf.php.example
new file mode 100644
index 000000000..94bc14e1f
--- /dev/null
+++ b/conf/mysql.conf.php.example
@@ -0,0 +1,253 @@
+<?php
+/*
+ * This is an example configuration for the mysql auth module.
+ *
+ * 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['auth']['mysql']['server'] = '';
+$conf['auth']['mysql']['user'] = '';
+$conf['auth']['mysql']['password'] = '';
+$conf['auth']['mysql']['database'] = '';
+
+/* This option enables debug messages in the mysql module. It is
+ * mostly usefull for system admins.
+ */
+$conf['auth']['mysql']['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['auth']['mysql']['forwardClearPass'] = 0;
+
+/* Multiple table operations will be protected by locks. This array tolds
+ * the module 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['auth']['mysql']['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 module access the password as 'pass' so a 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['auth']['mysql']['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['auth']['mysql']['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 module access the group name as 'group' so a alias
+ * might be nessecary.
+ *
+ * Following patters will be replaced:
+ * %{user} user name
+ */
+$conf['auth']['mysql']['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 module. At the end a sort expression will be added.
+ * Important is that this list contains no double entries fo a user. Each
+ * user name is only allowed once in the table.
+ *
+ * The login name will be accessed as 'user' to a 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['auth']['mysql']['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['auth']['mysql']['FilterLogin'] = "login LIKE '%{user}'";
+$conf['auth']['mysql']['FilterName'] = "CONCAT(firstname,' ',lastname) LIKE '%{name}'";
+$conf['auth']['mysql']['FilterEmail'] = "email LIKE '%{email}'";
+$conf['auth']['mysql']['FilterGroup'] = "name LIKE '%{group}'";
+$conf['auth']['mysql']['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['auth']['mysql']['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['auth']['mysql']['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['auth']['mysql']['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['auth']['mysql']['delGroup'] = "DELETE FROM groups
+ WHERE gid='%{gid}'";
+
+/* This statement should return the database index of a given user name.
+ * The module will access the index with the name 'id' so a alias might be
+ * necessary.
+ * following patters will be replaced:
+ * %{user} user name
+ */
+$conf['auth']['mysql']['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['auth']['mysql']['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['auth']['mysql']['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['auth']['mysql']['updateUser'] = "UPDATE users SET";
+$conf['auth']['mysql']['UpdateLogin'] = "login='%{user}'";
+$conf['auth']['mysql']['UpdatePass'] = "pass='%{pass}'";
+$conf['auth']['mysql']['UpdateEmail'] = "email='%{email}'";
+$conf['auth']['mysql']['UpdateName'] = "firstname=SUBSTRING_INDEX('%{name}',' ', 1),
+ lastname=SUBSTRING_INDEX('%{name}',' ', -1)";
+$conf['auth']['mysql']['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['auth']['mysql']['delUserGroup']= "DELETE FROM usergroup
+ WHERE uid='%{uid}'
+ AND gid='%{gid}'";
+
+/* This statement should return the database index of a given group name.
+ * The module will access the index with the name 'id' so a alias might
+ * be necessary.
+ *
+ * Following patters will be replaced:
+ * %{group} group name
+ */
+$conf['auth']['mysql']['getGroupID'] = "SELECT gid AS id
+ FROM groups
+ WHERE name='%{group}'";
+
+
diff --git a/conf/plugins.required.php b/conf/plugins.required.php
new file mode 100644
index 000000000..26eb8888b
--- /dev/null
+++ b/conf/plugins.required.php
@@ -0,0 +1,11 @@
+<?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['plugin'] = 1;
+$plugins['config'] = 1;
+$plugins['usermanager'] = 1;
+$plugins['revert'] = 1;
diff --git a/conf/scheme.conf b/conf/scheme.conf
new file mode 100644
index 000000000..88cb3c44d
--- /dev/null
+++ b/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/conf/smileys.conf b/conf/smileys.conf
new file mode 100644
index 000000000..80daed57a
--- /dev/null
+++ b/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/conf/users.auth.php.dist b/conf/users.auth.php.dist
new file mode 100644
index 000000000..6576eeb5f
--- /dev/null
+++ b/conf/users.auth.php.dist
@@ -0,0 +1,10 @@
+# users.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Userfile
+#
+# Format:
+#
+# user:MD5password:Real Name:email:groups,comma,seperated
+
diff --git a/conf/wordblock.conf b/conf/wordblock.conf
new file mode 100644
index 000000000..fe451f278
--- /dev/null
+++ b/conf/wordblock.conf
@@ -0,0 +1,32 @@
+# 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)
+gay\s*sex
+bi\s*sex
+incest
+zoosex
+gang\s*bang
+facials
+ladyboy
+fetish
+\btits\b
+\brape\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
diff --git a/data/.htaccess b/data/.htaccess
new file mode 100644
index 000000000..2cbb757e7
--- /dev/null
+++ b/data/.htaccess
@@ -0,0 +1,3 @@
+order allow,deny
+deny from all
+Satisfy All
diff --git a/data/_dummy b/data/_dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/data/_dummy
diff --git a/data/attic/_dummy b/data/attic/_dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/data/attic/_dummy
diff --git a/data/cache/_dummy b/data/cache/_dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/data/cache/_dummy
diff --git a/data/deleted.files b/data/deleted.files
new file mode 100644
index 000000000..d034e1d5b
--- /dev/null
+++ b/data/deleted.files
@@ -0,0 +1,257 @@
+# 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
+# A copy of this list is maintained at
+# http://www.dokuwiki.org/install:upgrade#files_to_remove
+
+# 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/lang/lt/stopwords.txt
+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/data/index/_dummy b/data/index/_dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/data/index/_dummy
diff --git a/data/locks/_dummy b/data/locks/_dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/data/locks/_dummy
diff --git a/data/media/wiki/dokuwiki-128.png b/data/media/wiki/dokuwiki-128.png
new file mode 100644
index 000000000..b2306ac95
--- /dev/null
+++ b/data/media/wiki/dokuwiki-128.png
Binary files differ
diff --git a/data/media_attic/_dummy b/data/media_attic/_dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/data/media_attic/_dummy
diff --git a/data/media_meta/_dummy b/data/media_meta/_dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/data/media_meta/_dummy
diff --git a/data/meta/_dummy b/data/meta/_dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/data/meta/_dummy
diff --git a/data/pages/wiki/dokuwiki.txt b/data/pages/wiki/dokuwiki.txt
new file mode 100644
index 000000000..e6fac5b65
--- /dev/null
+++ b/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/data/pages/wiki/syntax.txt b/data/pages/wiki/syntax.txt
new file mode 100644
index 000000000..b03435787
--- /dev/null
+++ b/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 is the same like in the code and file blocks in the previous section, but this time the name of the used language is inserted inside the tag. Eg. ''<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, abap, actionscript-french, actionscript, actionscript3, ada, apache, applescript, asm, asp, autoconf, autohotkey, autoit, avisynth, awk, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, cpp, cpp-qt, csharp, css, cuesheet, d, dcs, delphi, diff, div, dos, dot, ecmascript, eiffel, email, erlang, fo, fortran, freebasic, fsharp, gambas, genero, genie, gdb, glsl, gml, gnuplot, groovy, gettext, gwbasic, haskell, hicest, hq9plus, html, icon, idl, ini, inno, intercal, io, j, java5, java, javascript, jquery, kixtart, klonec, klonecpp, latex, lisp, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, modula2, modula3, mmix, mpasm, mxml, mysql, newlisp, nsis, oberon2, objc, ocaml-brief, ocaml, oobas, oracle8, oracle11, oxygene, oz, pascal, pcre, perl, perl6, per, pf, php-brief, php, pike, pic16, pixelbender, plsql, postgresql, povray, powerbuilder, powershell, progress, prolog, properties, providex, purebasic, 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, vala, vbnet, vb, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, winbatch, whois, xbasic, xml, xorg_conf, xpp, z80//
+
+==== 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 to 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/data/security.png b/data/security.png
new file mode 100644
index 000000000..c4f1a9771
--- /dev/null
+++ b/data/security.png
Binary files differ
diff --git a/data/security.xcf b/data/security.xcf
new file mode 100644
index 000000000..990287830
--- /dev/null
+++ b/data/security.xcf
Binary files differ
diff --git a/data/tmp/_dummy b/data/tmp/_dummy
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/data/tmp/_dummy
diff --git a/doku.php b/doku.php
new file mode 100644
index 000000000..e699c818b
--- /dev/null
+++ b/doku.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * DokuWiki mainscript
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// update message version
+$updateVersion = 36;
+
+// xdebug_start_profiling();
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/');
+
+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
+$_REQUEST['id'] = str_replace("\xC2\xAD",'',$_REQUEST['id']); //soft-hyphen
+$QUERY = trim($_REQUEST['id']);
+$ID = getID();
+
+// deprecated 2011-01-14
+$NS = getNS($ID);
+
+$REV = $_REQUEST['rev'];
+$IDX = $_REQUEST['idx'];
+$DATE = $_REQUEST['date'];
+$RANGE = $_REQUEST['range'];
+$HIGH = $_REQUEST['s'];
+if(empty($HIGH)) $HIGH = getGoogleQuery();
+
+if (isset($_POST['wikitext'])) {
+ $TEXT = cleanText($_POST['wikitext']);
+}
+$PRE = cleanText(substr($_POST['prefix'], 0, -1));
+$SUF = cleanText($_POST['suffix']);
+$SUM = $_REQUEST['summary'];
+
+//sanitize revision
+$REV = preg_replace('/[^0-9]/','',$REV);
+
+//make infos about the selected page available
+$INFO = pageinfo();
+
+//export minimal infos to JS, plugins can add more
+$JSINFO['id'] = $ID;
+$JSINFO['namespace'] = (string) $INFO['namespace'];
+
+
+// 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
+trigger_event('DOKUWIKI_STARTED',$tmp);
+
+//close session
+session_write_close();
+
+//do the work
+act_dispatch($ACT);
+
+$tmp = array(); // No event data
+trigger_event('DOKUWIKI_DONE', $tmp);
+
+// xdebug_dump_function_profile(1);
diff --git a/feed.php b/feed.php
new file mode 100644
index 000000000..a7fa95620
--- /dev/null
+++ b/feed.php
@@ -0,0 +1,457 @@
+<?php
+/**
+ * XML feed export
+ *
+ * @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();
+
+// 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)
+$cache = getCacheName(join('',array_values($opt)).$_SERVER['REMOTE_USER'],'.feed');
+$key = join('', array_values($opt)) . $_SERVER['REMOTE_USER'];
+$cache = new cache($key, '.feed');
+
+// prepare cache depends
+$depends['files'] = getConfigFiles('main');
+$depends['age'] = $conf['rss_update'];
+$depends['purge'] = isset($_REQUEST['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->_time);
+ if($conf['allowdebug']) header("X-CacheUsed: $cache->cache");
+ print $cache->retrieveCache();
+ exit;
+} else {
+ http_conditionalRequest(time());
+ }
+
+// create new feed
+$rss = new DokuWikiFeedCreator();
+$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('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 Doku_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'],'utf-8');
+
+// 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;
+
+ $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('mode', 'recent'),
+ // One of: diff, page, rev, current
+ 'link_to' => array('linkto', $conf['rss_linkto']),
+ // One of: abstract, diff, htmldiff, html
+ 'item_content' => array('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('ns', null),
+ // Positive integer, only used in rc mode
+ 'items' => array('num', $conf['recent']),
+ // Boolean, only used in rc mode
+ 'show_minor' => array('minor', false),
+ // String, only used in search mode
+ 'search_query' => array('q', null),
+ // One of: pages, media, both
+ 'content_type' => array('view', 'both')
+
+ ) as $name => $val) {
+ $opt[$name] = (isset($_REQUEST[$val[0]]) && !empty($_REQUEST[$val[0]]))
+ ? $_REQUEST[$val[0]] : $val[1];
+ }
+
+ $opt['items'] = max(0, (int) $opt['items']);
+ $opt['show_minor'] = (bool) $opt['show_minor'];
+
+ $opt['guardmail'] = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none');
+
+ $type = valid_input_set('type', array('rss','rss2','atom','atom1','rss1',
+ 'default' => $conf['rss_type']),
+ $_REQUEST);
+ 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,
+ );
+ trigger_event('FEED_OPTS_POSTPROCESS', $eventData);
+ return $opt;
+}
+
+/**
+ * Add recent changed pages to a feed object
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param object $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;
+ global $auth;
+
+ $eventData = array(
+ 'rss' => &$rss,
+ 'data' => &$data,
+ 'opt' => &$opt,
+ );
+ $event = new Doku_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);
+ }
+
+ // add date
+ if($ditem['date']){
+ $date = $ditem['date'];
+ }elseif($meta['date']['modified']){
+ $date = $meta['date']['modified'];
+ }else{
+ $date = @filemtime(wikiFN($id));
+ }
+ 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,'&', 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']) {
+ $revs = getRevisions($id, 0, 1, 8192, true);
+ $rev = $revs[0];
+ $src_r = '';
+ $src_l = '';
+
+ if ($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)), 300)) {
+ $more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id));
+ $src_r = ml($id, $more);
+ }
+ 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);
+ }
+ $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');
+ $revs = getRevisions($id, 0, 1);
+ $rev = $revs[0];
+
+ if($rev){
+ $df = new Diff(explode("\n",htmlspecialchars(rawWiki($id,$rev))),
+ explode("\n",htmlspecialchars(rawWiki($id,''))));
+ }else{
+ $df = new Diff(array(''),
+ explode("\n",htmlspecialchars(rawWiki($id,''))));
+ }
+
+ if($opt['item_content'] == 'htmldiff'){
+ $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{
+ $udf = new UnifiedDiffFormatter();
+ $content = "<pre>\n".$udf->format($df)."\n</pre>";
+ }
+ }
+ break;
+ case 'html':
+ if ($ditem['media']) {
+ if ($size = media_image_preview_size($id, false, new JpegMeta(mediaFN($id)))) {
+ $more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id));
+ $src = ml($id, $more);
+ $content = '<img src="'.$src.'" alt="'.$id.'" />';
+ } else {
+ $content = '';
+ }
+ } else {
+ $content = p_wiki_xhtml($id,$date,false);
+ // no TOC in feeds
+ $content = preg_replace('/(<!-- TOC START -->).*(<!-- TOC END -->)/s','',$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, false, new JpegMeta(mediaFN($id)))) {
+ $more = 'w='.$size[0].'&h='.$size[1].'t='.@filemtime(mediaFN($id));
+ $src = ml($id, $more);
+ $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
+ $item->author = '';
+ if($user && $conf['useacl'] && $auth){
+ $userInfo = $auth->getUserData($user);
+ if ($userInfo){
+ switch ($conf['showuseras']){
+ case 'username':
+ $item->author = $userInfo['name'];
+ break;
+ default:
+ $item->author = $user;
+ break;
+ }
+ } else {
+ $item->author = $user;
+ }
+ if($userInfo && !$opt['guardmail']){
+ $item->authorEmail = $userInfo['mail'];
+ }else{
+ //cannot obfuscate because some RSS readers may check validity
+ $item->authorEmail = $user.'@'.$ditem['ip'];
+ }
+ }elseif($user){
+ // this happens when no ACL but some Apache auth is used
+ $item->author = $user;
+ $item->authorEmail = $user.'@'.$ditem['ip'];
+ }else{
+ $item->authorEmail = 'anonymous@'.$ditem['ip'];
+ }
+
+ // 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 Doku_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 = RECENTS_SKIP_DELETED;
+ if(!$opt['show_minor']) $flags += RECENTS_SKIP_MINORS;
+ 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=str_replace(':','/',$ns);
+
+ $data = array();
+ sort($data);
+ search($data,$conf['datadir'],'search_list','',$ns);
+
+ 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;
+
+ 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/inc/.htaccess b/inc/.htaccess
new file mode 100644
index 000000000..68ae43e72
--- /dev/null
+++ b/inc/.htaccess
@@ -0,0 +1,4 @@
+## no access to the inc directory
+order allow,deny
+deny from all
+Satisfy All
diff --git a/inc/DifferenceEngine.php b/inc/DifferenceEngine.php
new file mode 100644
index 000000000..6e1d07382
--- /dev/null
+++ b/inc/DifferenceEngine.php
@@ -0,0 +1,1163 @@
+<?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;
+
+ 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 {
+
+ 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.
+ */
+ 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];
+ reset($matches);
+ while (list ($junk, $y) = each($matches))
+ if (empty($this->in_seq[$y])) {
+ $k = $this->_lcs_pos($y);
+ USE_ASSERTS && assert($k > 0);
+ $ymids[$k] = $ymids[$k-1];
+ break;
+ }
+ while (list ($junk, $y) = each($matches)) {
+ if ($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];
+ }
+ }
+ }
+ }
+
+ $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.
+ */
+ 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).
+ */
+ 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 $from_lines array An array of strings.
+ * (Typically these are lines from a file.)
+ * @param $to_lines array 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 object 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.
+ */
+ 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 $from_lines array An array of strings.
+ * (Typically these are lines from a file.)
+ *
+ * @param $to_lines array An array of strings.
+ *
+ * @param $mapped_from_lines array 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 $mapped_to_lines array 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 object A Diff object.
+ * @return string The formatted output.
+ */
+ function format($diff) {
+
+ $xi = $yi = 1;
+ $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();
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ function _start_block($header) {
+ echo $header;
+ }
+
+ function _end_block() {
+ }
+
+ function _lines($lines, $prefix = ' ') {
+ foreach ($lines as $line)
+ echo "$prefix $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);
+ }
+}
+
+
+/**
+ * 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>'.$this->_group.'</strong>';
+ elseif ($this->_tag == 'add')
+ $this->_line .= '<span class="diff-addedline">'.$this->_group.'</span>';
+ elseif ($this->_tag == 'del')
+ $this->_line .= '<span class="diff-deletedline"><del>'.$this->_group.'</del></span>';
+ else
+ $this->_line .= $this->_group;
+ }
+ $this->_group = '';
+ $this->_tag = $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;
+ }
+}
+
+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.
+ */
+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 {
+
+ function __construct() {
+ $this->leading_context_lines = 2;
+ $this->trailing_context_lines = 2;
+ }
+
+ 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(' ','&nbsp; ', $val);
+ $val = preg_replace('/ (?=<)|(?<=[ >]) /', '&nbsp;', $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 class="diff-blockheader" colspan="2">'.$l1.":</td>\n".
+ '<td class="diff-blockheader" colspan="2">'.$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) {
+ return '<td>+</td><td class="diff-addedline">' . $line.'</td>';
+ }
+
+ function deletedLine($line) {
+ return '<td>-</td><td class="diff-deletedline">' . $line.'</td>';
+ }
+
+ function emptyLine() {
+ return '<td colspan="2">&nbsp;</td>';
+ }
+
+ function contextLine($line) {
+ return '<td> </td><td class="diff-context">'.$line.'</td>';
+ }
+
+ function _added($lines) {
+ foreach ($lines as $line) {
+ print('<tr>' . $this->emptyLine() . $this->addedLine($line) . "</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);
+ $del = $diff->orig();
+ $add = $diff->closing();
+
+ while ($line = array_shift($del)) {
+ $aline = array_shift($add);
+ print('<tr>' . $this->deletedLine($line) . $this->addedLine($aline) . "</tr>\n");
+ }
+ $this->_added($add); # If any leftovers
+ }
+}
+
+/**
+ * Inline style diff formatter.
+ *
+ */
+class InlineDiffFormatter extends DiffFormatter {
+ var $colspan = 4;
+
+ function __construct() {
+ $this->leading_context_lines = 2;
+ $this->trailing_context_lines = 2;
+ }
+
+ 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(' ','&nbsp; ', $val);
+ $val = preg_replace('/ (?=<)|(?<=[ >]) /', '&nbsp;', $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.'" class="diff-blockheader">@@ '.$lang['line']." -$xbeg +$ybeg @@";
+ $r .= ' <span class="diff-deletedline"><del>'.$lang['deleted'].'</del></span>';
+ $r .= ' <span class="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 colspan="'.$this->colspan.'" class="diff-addedline">'. $line . "</td></tr>\n");
+ }
+ }
+
+ function _deleted($lines) {
+ foreach ($lines as $line) {
+ print('<tr><td colspan="'.$this->colspan.'" class="diff-deletedline"><del>' . $line . "</del></td></tr>\n");
+ }
+ }
+
+ function _context($lines) {
+ foreach ($lines as $line) {
+ print('<tr><td colspan="'.$this->colspan.'" class="diff-context">'.$line."</td></tr>\n");
+ }
+ }
+
+ function _changed($orig, $closing) {
+ $diff = new InlineWordLevelDiff($orig, $closing);
+ $add = $diff->inline();
+
+ foreach ($add as $line)
+ print('<tr><td colspan="'.$this->colspan.'">'.$line."</td></tr>\n");
+ }
+}
+
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/EmailAddressValidator.php b/inc/EmailAddressValidator.php
new file mode 100644
index 000000000..bb4ef0ca9
--- /dev/null
+++ b/inc/EmailAddressValidator.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * EmailAddressValidator Class
+ *
+ * @author Dave Child <dave@addedbytes.com>
+ * @link http://code.google.com/p/php-email-address-validation/
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ * @version SVN r10 + Issue 15 fix + Issue 12 fix
+ */
+class EmailAddressValidator {
+ /**
+ * Set true to allow addresses like me@localhost
+ */
+ public $allowLocalAddresses = false;
+
+ /**
+ * Check email address validity
+ * @param strEmailAddress Email address to be checked
+ * @return True if email is valid, false if not
+ */
+ public function check_email_address($strEmailAddress) {
+
+ // 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()) {
+ // $strEmailAddress = stripslashes($strEmailAddress);
+ //}
+
+ // Control characters are not allowed
+ if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $strEmailAddress)) {
+ return false;
+ }
+
+ // Check email length - min 3 (a@a), max 256
+ if (!$this->check_text_length($strEmailAddress, 3, 256)) {
+ return false;
+ }
+
+ // Split it into sections using last instance of "@"
+ $intAtSymbol = strrpos($strEmailAddress, '@');
+ if ($intAtSymbol === false) {
+ // No "@" symbol in email.
+ return false;
+ }
+ $arrEmailAddress[0] = substr($strEmailAddress, 0, $intAtSymbol);
+ $arrEmailAddress[1] = substr($strEmailAddress, $intAtSymbol + 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.
+ $arrTempAddress[0] = preg_replace('/\./'
+ ,''
+ ,$arrEmailAddress[0]);
+ $arrTempAddress[0] = preg_replace('/"[^"]+"/'
+ ,''
+ ,$arrTempAddress[0]);
+ $arrTempAddress[1] = $arrEmailAddress[1];
+ $strTempAddress = $arrTempAddress[0] . $arrTempAddress[1];
+ // Then check - should be no "@" symbols.
+ if (strrpos($strTempAddress, '@') !== false) {
+ // "@" symbol found
+ return false;
+ }
+
+ // Check local portion
+ if (!$this->check_local_portion($arrEmailAddress[0])) {
+ return false;
+ }
+
+ // Check domain portion
+ if (!$this->check_domain_portion($arrEmailAddress[1])) {
+ return false;
+ }
+
+ // If we're still here, all checks above passed. Email is valid.
+ return true;
+
+ }
+
+ /**
+ * Checks email section before "@" symbol for validity
+ * @param strLocalPortion Text to be checked
+ * @return True if local portion is valid, false if not
+ */
+ protected function check_local_portion($strLocalPortion) {
+ // 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 (!$this->check_text_length($strLocalPortion, 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)
+ $arrLocalPortion = explode('.', $strLocalPortion);
+ for ($i = 0, $max = sizeof($arrLocalPortion); $i < $max; $i++) {
+ if (!preg_match('.^('
+ . '([A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]'
+ . '[A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]{0,63})'
+ .'|'
+ . '("[^\\\"]{0,62}")'
+ .')$.'
+ ,$arrLocalPortion[$i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Checks email section after "@" symbol for validity
+ * @param strDomainPortion Text to be checked
+ * @return True if domain portion is valid, false if not
+ */
+ protected function check_domain_portion($strDomainPortion) {
+ // Total domain can only be from 1 to 255 characters, inclusive
+ if (!$this->check_text_length($strDomainPortion, 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]))?)";
+
+ // Check if domain is IP, possibly enclosed in square brackets.
+ if (preg_match("/^($IPv4Address|\[$IPv4Address\]|\[$IPv6Address\])$/",
+ $strDomainPortion)){
+ return true;
+ } else {
+ $arrDomainPortion = explode('.', $strDomainPortion);
+ if (!$this->allowLocalAddresses && sizeof($arrDomainPortion) < 2) {
+ return false; // Not enough parts to domain
+ }
+ for ($i = 0, $max = sizeof($arrDomainPortion); $i < $max; $i++) {
+ // Each portion must be between 1 and 63 characters, inclusive
+ if (!$this->check_text_length($arrDomainPortion[$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]+))$/', $arrDomainPortion[$i])) {
+ return false;
+ }
+ if ($i == $max - 1) { // TLD cannot be only numbers
+ if (strlen(preg_replace('/[0-9]/', '', $arrDomainPortion[$i])) <= 0) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Check given text length is between defined bounds
+ * @param strText Text to be checked
+ * @param intMinimum Minimum acceptable length
+ * @param intMaximum Maximum acceptable length
+ * @return True if string is within bounds (inclusive), false if not
+ */
+ protected function check_text_length($strText, $intMinimum, $intMaximum) {
+ // Minimum and maximum are both inclusive
+ $intTextLength = strlen($strText);
+ if (($intTextLength < $intMinimum) || ($intTextLength > $intMaximum)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+}
+
diff --git a/inc/FeedParser.php b/inc/FeedParser.php
new file mode 100644
index 000000000..e5f1fb636
--- /dev/null
+++ b/inc/FeedParser.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Class used to parse RSS and ATOM feeds
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * We override some methods of the original SimplePie class here
+ */
+class FeedParser extends SimplePie {
+
+ /**
+ * Constructor. Set some defaults
+ */
+ function FeedParser(){
+ $this->SimplePie();
+ $this->enable_cache(false);
+ $this->set_file_class('FeedParser_File');
+ }
+
+ /**
+ * Backward compatibility for older plugins
+ */
+ function feed_url($url){
+ $this->set_feed_url($url);
+ }
+}
+
+/**
+ * Fetch an URL using our own HTTPClient
+ *
+ * Replaces SimplePie's own class
+ */
+class FeedParser_File extends SimplePie_File {
+ var $http;
+ var $useragent;
+ var $success = true;
+ var $headers = array();
+ var $body;
+ var $error;
+
+ /**
+ * Inititializes the HTTPClient
+ *
+ * We ignore all given parameters - they are set in DokuHTTPClient
+ */
+ function FeedParser_File($url, $timeout=10, $redirects=5,
+ $headers=null, $useragent=null, $force_fsockopen=false) {
+ $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;
+ }
+
+ function headers(){
+ return $this->headers;
+ }
+
+ function body(){
+ return $this->body;
+ }
+
+ function close(){
+ return true;
+ }
+
+}
diff --git a/inc/HTTPClient.php b/inc/HTTPClient.php
new file mode 100644
index 000000000..641950348
--- /dev/null
+++ b/inc/HTTPClient.php
@@ -0,0 +1,686 @@
+<?php
+/**
+ * HTTP Client
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Goetz <cpuidle@gmx.de>
+ */
+
+
+define('HTTP_NL',"\r\n");
+
+
+/**
+ * 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>
+ */
+ function DokuHTTPClient(){
+ global $conf;
+
+ // call parent constructor
+ $this->HTTPClient();
+
+ // 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'];
+ }
+
+
+ /**
+ * Wraps an event around the parent function
+ *
+ * @triggers HTTPCLIENT_REQUEST_SEND
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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);
+ }
+
+}
+
+/**
+ * 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
+ var $agent; // User agent
+ var $http; // HTTP version defaults to 1.0
+ var $timeout; // read timeout (seconds)
+ var $cookies;
+ var $referer;
+ var $max_redirect;
+ var $max_bodysize;
+ var $max_bodysize_abort = true; // if set, abort if the response body is bigger than max_bodysize
+ var $header_regexp; // if set this RE must match against the headers, else abort
+ var $headers;
+ var $debug;
+ var $start = 0; // for timings
+ var $keep_alive = true; // keep alive rocks
+
+ // don't set these, read on error
+ var $error;
+ var $redirect_count;
+
+ // read these after a successful request
+ var $status;
+ var $resp_body;
+ var $resp_headers;
+
+ // set these to do basic authentication
+ var $user;
+ var $pass;
+
+ // set these if you need to use a proxy
+ var $proxy_host;
+ var $proxy_port;
+ var $proxy_user;
+ var $proxy_pass;
+ var $proxy_ssl; //boolean set to true if your proxy needs SSL
+ var $proxy_except; // regexp of URLs to exclude from proxy
+
+ // list of kept alive connections
+ static $connections = array();
+
+ // what we use as boundary on multipart/form-data posts
+ var $boundary = '---DokuWikiHTTPClient--4523452351';
+
+ /**
+ * Constructor.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function HTTPClient(){
+ $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
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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;
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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>
+ */
+ function sendRequest($url,$data='',$method='GET'){
+ $this->start = $this->_time();
+ $this->error = '';
+ $this->status = 0;
+
+ // 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(isset($uri['port']) && !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->proxy_host && (!$this->proxy_except || !preg_match('/'.$this->proxy_except.'/i',$url)) ){
+ $request_url = $url;
+ $server = $this->proxy_host;
+ $port = $this->proxy_port;
+ if (empty($port)) $port = 8080;
+ }else{
+ $request_url = $path;
+ $server = $server;
+ if (!isset($port)) $port = ($uri['scheme'] == 'https') ? 443 : 80;
+ }
+
+ // add SSL stream prefix if needed - needs SSL support in PHP
+ if($port == 443 || $this->proxy_ssl) $server = 'ssl://'.$server;
+
+ // prepare headers
+ $headers = $this->headers;
+ $headers['Host'] = $uri['host'];
+ if($uri['port']) $headers['Host'].= ':'.$uri['port'];
+ $headers['User-Agent'] = $this->agent;
+ $headers['Referer'] = $this->referer;
+ if ($this->keep_alive) {
+ $headers['Connection'] = 'Keep-Alive';
+ } else {
+ $headers['Connection'] = 'Close';
+ }
+ if($method == 'POST'){
+ if(is_array($data)){
+ if($headers['Content-Type'] == 'multipart/form-data'){
+ $headers['Content-Type'] = 'multipart/form-data; boundary='.$this->boundary;
+ $data = $this->_postMultipartEncode($data);
+ }else{
+ $headers['Content-Type'] = 'application/x-www-form-urlencoded';
+ $data = $this->_postEncode($data);
+ }
+ }
+ $headers['Content-Length'] = strlen($data);
+ $rmethod = 'POST';
+ }elseif($method == 'GET'){
+ $data = ''; //no data allowed on GET requests
+ }
+ 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);
+ }
+
+ // stop time
+ $start = time();
+
+ // already connected?
+ $connectionId = $this->_uniqueConnectionId($server,$port);
+ $this->_debug('connection pool', $this->connections);
+ $socket = null;
+ if (isset($this->connections[$connectionId])) {
+ $this->_debug('reusing connection', $connectionId);
+ $socket = $this->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;
+ }
+
+ // keep alive?
+ if ($this->keep_alive) {
+ $this->connections[$connectionId] = $socket;
+ } else {
+ unset($this->connections[$connectionId]);
+ }
+ }
+
+ //set blocking
+ stream_set_blocking($socket,1);
+
+ // 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);
+
+ // select parameters
+ $sel_r = null;
+ $sel_w = array($socket);
+ $sel_e = null;
+
+ // send request
+ $towrite = strlen($request);
+ $written = 0;
+ while($written < $towrite){
+ // check timeout
+ if(time()-$start > $this->timeout){
+ $this->status = -100;
+ $this->error = sprintf('Timeout while sending request (%.3fs)',$this->_time() - $this->start);
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+
+ // wait for stream ready or timeout (1sec)
+ if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){
+ usleep(1000);
+ continue;
+ }
+
+ // write to stream
+ $ret = fwrite($socket, substr($request,$written,4096));
+ if($ret === false){
+ $this->status = -100;
+ $this->error = 'Failed writing to socket';
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+ $written += $ret;
+ }
+
+ // continue non-blocking
+ stream_set_blocking($socket,0);
+
+ // read headers from socket
+ $r_headers = '';
+ do{
+ if(time()-$start > $this->timeout){
+ $this->status = -100;
+ $this->error = sprintf('Timeout while reading headers (%.3fs)',$this->_time() - $this->start);
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+ if(feof($socket)){
+ $this->error = 'Premature End of File (socket)';
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+ usleep(1000);
+ $r_headers .= fgets($socket,1024);
+ }while(!preg_match('/\r?\n\r?\n$/',$r_headers));
+
+ $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){
+ $this->error = 'Reported content length exceeds allowed response size';
+ if ($this->max_bodysize_abort)
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+ }
+
+ // get Status
+ if (!preg_match('/^HTTP\/(\d\.\d)\s*(\d+).*?\n/', $r_headers, $m)) {
+ $this->error = 'Server returned bad answer';
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+ $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 ){
+ // close the connection because we don't handle content retrieval here
+ // that's the easiest way to clean up the connection
+ fclose($socket);
+ unset($this->connections[$connectionId]);
+
+ if (empty($this->resp_headers['location'])){
+ $this->error = 'Redirect but no Location Header found';
+ return false;
+ }elseif($this->redirect_count == $this->max_redirect){
+ $this->error = 'Maximum number of redirects exceeded';
+ return false;
+ }else{
+ $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)){
+ $this->error = 'The received headers did not match the given regexp';
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+
+ //read body (with chunked encoding if needed)
+ $r_body = '';
+ if(preg_match('/transfer\-(en)?coding:\s*chunked\r\n/i',$r_headers)){
+ do {
+ unset($chunk_size);
+ do {
+ if(feof($socket)){
+ $this->error = 'Premature End of File (socket)';
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+ if(time()-$start > $this->timeout){
+ $this->status = -100;
+ $this->error = sprintf('Timeout while reading chunk (%.3fs)',$this->_time() - $this->start);
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+ $byte = fread($socket,1);
+ $chunk_size .= $byte;
+ } while (preg_match('/[a-zA-Z0-9]/',$byte)); // read chunksize including \r
+
+ $byte = fread($socket,1); // readtrailing \n
+ $chunk_size = hexdec($chunk_size);
+ if ($chunk_size) {
+ $this_chunk = fread($socket,$chunk_size);
+ $r_body .= $this_chunk;
+ $byte = fread($socket,2); // read trailing \r\n
+ }
+
+ if($this->max_bodysize && strlen($r_body) > $this->max_bodysize){
+ $this->error = 'Allowed response size exceeded';
+ if ($this->max_bodysize_abort){
+ unset($this->connections[$connectionId]);
+ return false;
+ } else {
+ break;
+ }
+ }
+ } while ($chunk_size);
+ }else{
+ // read entire socket
+ while (!feof($socket)) {
+ if(time()-$start > $this->timeout){
+ $this->status = -100;
+ $this->error = sprintf('Timeout while reading response (%.3fs)',$this->_time() - $this->start);
+ unset($this->connections[$connectionId]);
+ return false;
+ }
+ $r_body .= fread($socket,4096);
+ $r_size = strlen($r_body);
+ if($this->max_bodysize && $r_size > $this->max_bodysize){
+ $this->error = 'Allowed response size exceeded';
+ if ($this->max_bodysize_abort) {
+ unset($this->connections[$connectionId]);
+ return false;
+ } else {
+ break;
+ }
+ }
+ if(isset($this->resp_headers['content-length']) &&
+ !isset($this->resp_headers['transfer-encoding']) &&
+ $this->resp_headers['content-length'] == $r_size){
+ // we read the content-length, finish here
+ break;
+ }
+ }
+ }
+
+ if (!$this->keep_alive ||
+ (isset($this->resp_headers['connection']) && $this->resp_headers['connection'] == 'Close')) {
+ // close socket
+ $status = socket_get_status($socket);
+ fclose($socket);
+ unset($this->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;
+ }
+
+ /**
+ * print debug info
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _debug($info,$var=null){
+ if(!$this->debug) return;
+ 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>';
+ }
+ }
+
+ /**
+ * Return current timestamp in microsecond resolution
+ */
+ 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>
+ */
+ function _parseHeaders($string){
+ $headers = array();
+ if (!preg_match_all('/^\s*([\w-]+)\s*:\s*([\S \t]+)\s*$/m', $string,
+ $matches, PREG_SET_ORDER)) {
+ return $headers;
+ }
+ foreach($matches as $match){
+ list(, $key, $val) = $match;
+ $key = strtolower($key);
+ 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>
+ */
+ function _buildHeaders($headers){
+ $string = '';
+ foreach($headers as $key => $value){
+ if(empty($value)) continue;
+ $string .= $key.': '.$value.HTTP_NL;
+ }
+ return $string;
+ }
+
+ /**
+ * get cookies as http header string
+ *
+ * @author Andreas Goetz <cpuidle@gmx.de>
+ */
+ 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>
+ */
+ function _postEncode($data){
+ $url = '';
+ foreach($data as $key => $val){
+ if($url) $url .= '&';
+ $url .= urlencode($key).'='.urlencode($val);
+ }
+ return $url;
+ }
+
+ /**
+ * Encode data for posting using multipart encoding
+ *
+ * @fixme use of urlencode might be wrong here
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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.
+ *
+ * @return string unique identifier
+ */
+ function _uniqueConnectionId($server, $port) {
+ return "$server:$port";
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/IXR_Library.php b/inc/IXR_Library.php
new file mode 100644
index 000000000..c8255e6d9
--- /dev/null
+++ b/inc/IXR_Library.php
@@ -0,0 +1,816 @@
+<?php
+/**
+ * IXR - The Inutio XML-RPC Library - (c) Incutio Ltd 2002
+ *
+ * @version 1.61
+ * @author Simon Willison
+ * @date 11th July 2003
+ * @link http://scripts.incutio.com/xmlrpc/
+ * @link http://scripts.incutio.com/xmlrpc/manual.php
+ * @license Artistic License http://www.opensource.org/licenses/artistic-license.php
+ *
+ * Modified for DokuWiki
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+
+class IXR_Value {
+ var $data;
+ var $type;
+ function IXR_Value ($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]);
+ }
+ }
+ }
+ 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';
+ }
+ }
+ 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;
+ }
+ function isStruct($array) {
+ /* Nasty function to check if an array is a struct or not */
+ $expected = 0;
+ foreach ($array as $key => $value) {
+ if ((string)$key != (string)$expected) {
+ return true;
+ }
+ $expected++;
+ }
+ return false;
+ }
+}
+
+
+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;
+ function IXR_Message ($message) {
+ $this->message = $message;
+ }
+ function parse() {
+ // first remove the XML declaration
+ $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message);
+ // 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');
+ if (!xml_parse($this->_parser, $this->message)) {
+ /* die(sprintf('XML error: %s at line %d',
+ xml_error_string(xml_get_error_code($this->_parser)),
+ xml_get_current_line_number($this->_parser))); */
+ return false;
+ }
+ 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;
+ }
+ function tag_open($parser, $tag, $attr) {
+ $this->currentTag = $tag;
+ $this->_currentTagContents = '';
+ 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 puposes more interesting than array
+ $this->_arraystructstypes[] = 'array';
+ $this->_arraystructs[] = array();
+ break;
+ case 'struct':
+ $this->_arraystructstypes[] = 'struct';
+ $this->_arraystructs[] = array();
+ break;
+ }
+ $this->_lastseen = $tag;
+ }
+ function cdata($parser, $cdata) {
+ $this->_currentTagContents .= $cdata;
+ }
+ function tag_close($parser, $tag) {
+ $valueFlag = false;
+ switch($tag) {
+ case 'int':
+ case 'i4':
+ $value = (int)trim($this->_currentTagContents);
+ $this->_currentTagContents = '';
+ $valueFlag = true;
+ break;
+ case 'double':
+ $value = (double)trim($this->_currentTagContents);
+ $this->_currentTagContents = '';
+ $valueFlag = true;
+ break;
+ case 'string':
+ $value = (string)$this->_currentTagContents;
+ $this->_currentTagContents = '';
+ $valueFlag = true;
+ break;
+ case 'dateTime.iso8601':
+ $value = new IXR_Date(trim($this->_currentTagContents));
+ // $value = $iso->getTimestamp();
+ $this->_currentTagContents = '';
+ $valueFlag = true;
+ break;
+ case 'value':
+ // "If no type is indicated, the type is string."
+ if($this->_lastseen == 'value'){
+ $value = (string)$this->_currentTagContents;
+ $this->_currentTagContents = '';
+ $valueFlag = true;
+ }
+ break;
+ case 'boolean':
+ $value = (boolean)trim($this->_currentTagContents);
+ $this->_currentTagContents = '';
+ $valueFlag = true;
+ break;
+ case 'base64':
+ $value = base64_decode($this->_currentTagContents);
+ $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);
+ $this->_currentTagContents = '';
+ break;
+ case 'methodName':
+ $this->methodName = trim($this->_currentTagContents);
+ $this->_currentTagContents = '';
+ break;
+ }
+ if ($valueFlag) {
+ /*
+ if (!is_array($value) && !is_object($value)) {
+ $value = trim($value);
+ }
+ */
+ 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 paramater
+ $this->params[] = $value;
+ }
+ }
+ $this->_lastseen = $tag;
+ }
+}
+
+
+class IXR_Server {
+ var $data;
+ var $callbacks = array();
+ var $message;
+ var $capabilities;
+ function IXR_Server($callbacks = false, $data = false) {
+ $this->setCapabilities();
+ if ($callbacks) {
+ $this->callbacks = $callbacks;
+ }
+ $this->setCallbacks();
+ $this->serve($data);
+ }
+ function serve($data = false) {
+ if (!$data) {
+ global $HTTP_RAW_POST_DATA;
+ if (!$HTTP_RAW_POST_DATA) {
+ die('XML-RPC server accepts POST requests only.');
+ }
+ $data = $HTTP_RAW_POST_DATA;
+ }
+ $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);
+ }
+ 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 paramater 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 (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 (!function_exists($method)) {
+ return new IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.');
+ }
+ // Call the function
+ #$result = $method($args);
+ $result = call_user_func_array($method,$args);
+ }
+ return $result;
+ }
+
+ 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());
+ }
+ function output($xml) {
+ header('Content-Type: text/xml; charset=utf-8');
+ echo '<?xml version="1.0"?>', "\n", $xml;
+ exit;
+ }
+ 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
+ ),
+ );
+ }
+ 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';
+ }
+ 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));
+ }
+ 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(-32600, '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;
+ }
+}
+
+class IXR_Request {
+ var $method;
+ var $args;
+ var $xml;
+ function IXR_Request($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>';
+ }
+ function getLength() {
+ return strlen($this->xml);
+ }
+ function getXml() {
+ return $this->xml;
+ }
+}
+
+/**
+ * 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 $message = false;
+ var $xmlerror = false;
+
+ function IXR_Client($server, $path = false, $port = 80) {
+ $this->DokuHTTPClient();
+ if (!$path) {
+ // Assume we have been given a URL instead
+ $this->posturl = $server;
+ }else{
+ $this->posturl = 'http://'.$server.':'.$port.$path;
+ }
+ }
+
+ 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;
+ }
+ function getResponse() {
+ // methodResponses can only have one param - return that
+ return $this->message->params[0];
+ }
+ function isError() {
+ return (is_object($this->xmlerror));
+ }
+ function getErrorCode() {
+ return $this->xmlerror->code;
+ }
+ function getErrorMessage() {
+ return $this->xmlerror->message;
+ }
+}
+
+
+class IXR_Error {
+ var $code;
+ var $message;
+ function IXR_Error($code, $message) {
+ $this->code = $code;
+ $this->message = $message;
+ }
+ 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;
+ }
+}
+
+
+class IXR_Date {
+ var $year;
+ var $month;
+ var $day;
+ var $hour;
+ var $minute;
+ var $second;
+ function IXR_Date($time) {
+ // $time can be a PHP timestamp or an ISO one
+ if (is_numeric($time)) {
+ $this->parseTimestamp($time);
+ } else {
+ $this->parseIso($time);
+ }
+ }
+ function parseTimestamp($timestamp) {
+ $this->year = gmdate('Y', $timestamp);
+ $this->month = gmdate('m', $timestamp);
+ $this->day = gmdate('d', $timestamp);
+ $this->hour = gmdate('H', $timestamp);
+ $this->minute = gmdate('i', $timestamp);
+ $this->second = gmdate('s', $timestamp);
+ }
+ function parseIso($iso) {
+ if(preg_match('/^(\d\d\d\d)-?(\d\d)-?(\d\d)([T ](\d\d):(\d\d)(:(\d\d))?)?/',$iso,$match)){
+ $this->year = (int) $match[1];
+ $this->month = (int) $match[2];
+ $this->day = (int) $match[3];
+ $this->hour = (int) $match[5];
+ $this->minute = (int) $match[6];
+ $this->second = (int) $match[8];
+ }
+ }
+ function getIso() {
+ return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second;
+ }
+ function getXml() {
+ return '<dateTime.iso8601>'.$this->getIso().'</dateTime.iso8601>';
+ }
+ function getTimestamp() {
+ return gmmktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
+ }
+}
+
+
+class IXR_Base64 {
+ var $data;
+ function IXR_Base64($data) {
+ $this->data = $data;
+ }
+ function getXml() {
+ return '<base64>'.base64_encode($this->data).'</base64>';
+ }
+}
+
+
+class IXR_IntrospectionServer extends IXR_Server {
+ var $signatures;
+ var $help;
+ function IXR_IntrospectionServer() {
+ $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'
+ );
+ }
+ function addCallback($method, $callback, $args, $help) {
+ $this->callbacks[$method] = $callback;
+ $this->signatures[$method] = $args;
+ $this->help[$method] = $help;
+ }
+ 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);
+ }
+ 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;
+ }
+ function methodHelp($method) {
+ return $this->help[$method];
+ }
+}
+
+
+class IXR_ClientMulticall extends IXR_Client {
+ var $calls = array();
+ function IXR_ClientMulticall($server, $path = false, $port = 80) {
+ parent::IXR_Client($server, $path, $port);
+ //$this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)';
+ }
+ function addCall() {
+ $args = func_get_args();
+ $methodName = array_shift($args);
+ $struct = array(
+ 'methodName' => $methodName,
+ 'params' => $args
+ );
+ $this->calls[] = $struct;
+ }
+ function query() {
+ // Prepare multicall, then call the parent::query() method
+ return parent::query('system.multicall', $this->calls);
+ }
+}
+
diff --git a/inc/JSON.php b/inc/JSON.php
new file mode 100644
index 000000000..2dea44003
--- /dev/null
+++ b/inc/JSON.php
@@ -0,0 +1,661 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * Converts to and from JSON format.
+ *
+ * JSON (JavaScript Object Notation) is a lightweight data-interchange
+ * format. It is easy for humans to read and write. It is easy for machines
+ * to parse and generate. It is based on a subset of the JavaScript
+ * Programming Language, Standard ECMA-262 3rd Edition - December 1999.
+ * This feature can also be found in Python. JSON is a text format that is
+ * completely language independent but uses conventions that are familiar
+ * to programmers of the C-family of languages, including C, C++, C#, Java,
+ * JavaScript, Perl, TCL, and many others. These properties make JSON an
+ * ideal data-interchange language.
+ *
+ * This package provides a simple encoder and decoder for JSON notation. It
+ * is intended for use with client-side Javascript applications that make
+ * use of HTTPRequest to perform server communication functions - data can
+ * be encoded into JSON notation for use in a client-side javascript, or
+ * decoded from incoming Javascript requests. JSON format is native to
+ * Javascript, and can be directly eval()'ed with no further parsing
+ * overhead
+ *
+ * All strings should be in ASCII or UTF-8 format!
+ *
+ * PHP versions 4 and 5
+ *
+ * LICENSE: 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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``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 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.
+ *
+ * @category
+ * @package
+ * @author Michal Migurski <mike-json@teczno.com>
+ * @author Matt Knapp <mdknapp[at]gmail[dot]com>
+ * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
+ * @copyright 2005 Michal Migurski
+ * @license http://www.freebsd.org/copyright/freebsd-license.html
+ * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
+ */
+
+// for DokuWiki
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * Marker constant for JSON::decode(), used to flag stack state
+ */
+define('JSON_SLICE', 1);
+
+/**
+ * Marker constant for JSON::decode(), used to flag stack state
+ */
+define('JSON_IN_STR', 2);
+
+/**
+ * Marker constant for JSON::decode(), used to flag stack state
+ */
+define('JSON_IN_ARR', 4);
+
+/**
+ * Marker constant for JSON::decode(), used to flag stack state
+ */
+define('JSON_IN_OBJ', 8);
+
+/**
+ * Marker constant for JSON::decode(), used to flag stack state
+ */
+define('JSON_IN_CMT', 16);
+
+/**
+ * Behavior switch for JSON::decode()
+ */
+define('JSON_LOOSE_TYPE', 10);
+
+/**
+ * Behavior switch for JSON::decode()
+ */
+define('JSON_STRICT_TYPE', 11);
+
+/**
+ * Converts to and from JSON format.
+ *
+ * @category
+ * @package
+ * @author Michal Migurski <mike-json@teczno.com>
+ * @author Matt Knapp <mdknapp[at]gmail[dot]com>
+ * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
+ * @copyright 2005 Michal Migurski
+ * @license http://www.php.net/license/3_0.txt PHP License 3.0
+ * @version
+ * @link
+ * @see
+ * @since
+ * @deprecated
+ */
+class JSON {
+
+ /**
+ * Disables the use of PHP5's native json_decode()
+ *
+ * You shouldn't change this usually because the native function is much
+ * faster. However, this non-native will also parse slightly broken JSON
+ * which might be handy when talking to a non-conform endpoint
+ */
+ public $skipnative = false;
+
+ /**
+ * constructs a new JSON instance
+ *
+ * @param int $use object behavior: when encoding or decoding,
+ * be loose or strict about object/array usage
+ *
+ * possible values:
+ * JSON_STRICT_TYPE - strict typing, default
+ * "{...}" syntax creates objects in decode.
+ * JSON_LOOSE_TYPE - loose typing
+ * "{...}" syntax creates associative arrays in decode.
+ */
+ function JSON($use=JSON_STRICT_TYPE) {
+ $this->use = $use;
+ }
+
+ /**
+ * encodes an arbitrary variable into JSON format
+ * If available the native PHP JSON implementation is used.
+ *
+ * @param mixed $var any number, boolean, string, array, or object to be encoded.
+ * see argument 1 to JSON() above for array-parsing behavior.
+ * if var is a strng, note that encode() always expects it
+ * to be in ASCII or UTF-8 format!
+ *
+ * @return string JSON string representation of input var
+ * @access public
+ */
+ function encode($var) {
+ if (function_exists('json_encode')) return json_encode($var);
+ switch (gettype($var)) {
+ case 'boolean':
+ return $var ? 'true' : 'false';
+
+ case 'NULL':
+ return 'null';
+
+ case 'integer':
+ return sprintf('%d', $var);
+
+ case 'double':
+ case 'float':
+ return sprintf('%f', $var);
+
+ case 'string':
+ // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
+ $ascii = '';
+ $strlen_var = strlen($var);
+
+ /*
+ * Iterate over every character in the string,
+ * escaping with a slash or encoding to UTF-8 where necessary
+ */
+ for ($c = 0; $c < $strlen_var; ++$c) {
+
+ $ord_var_c = ord($var{$c});
+
+ switch ($ord_var_c) {
+ case 0x08:
+ $ascii .= '\b';
+ break;
+ case 0x09:
+ $ascii .= '\t';
+ break;
+ case 0x0A:
+ $ascii .= '\n';
+ break;
+ case 0x0C:
+ $ascii .= '\f';
+ break;
+ case 0x0D:
+ $ascii .= '\r';
+ break;
+
+ case 0x22:
+ case 0x2F:
+ case 0x5C:
+ // double quote, slash, slosh
+ $ascii .= '\\'.$var{$c};
+ break;
+
+ case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
+ // characters U-00000000 - U-0000007F (same as ASCII)
+ $ascii .= $var{$c};
+ break;
+
+ case (($ord_var_c & 0xE0) == 0xC0):
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c, ord($var{$c+1}));
+ $c+=1;
+ //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8');
+ $utf16 = utf8_to_utf16be($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF0) == 0xE0):
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c+1}),
+ ord($var{$c+2}));
+ $c+=2;
+ //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8');
+ $utf16 = utf8_to_utf16be($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xF8) == 0xF0):
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c+1}),
+ ord($var{$c+2}),
+ ord($var{$c+3}));
+ $c+=3;
+ //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8');
+ $utf16 = utf8_to_utf16be($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFC) == 0xF8):
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c+1}),
+ ord($var{$c+2}),
+ ord($var{$c+3}),
+ ord($var{$c+4}));
+ $c+=4;
+ //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8');
+ $utf16 = utf8_to_utf16be($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+
+ case (($ord_var_c & 0xFE) == 0xFC):
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $char = pack('C*', $ord_var_c,
+ ord($var{$c+1}),
+ ord($var{$c+2}),
+ ord($var{$c+3}),
+ ord($var{$c+4}),
+ ord($var{$c+5}));
+ $c+=5;
+ //$utf16 = mb_convert_encoding($char, 'UTF-16', 'UTF-8');
+ $utf16 = utf8_to_utf16be($char);
+ $ascii .= sprintf('\u%04s', bin2hex($utf16));
+ break;
+ }
+ }
+
+ return '"'.$ascii.'"';
+
+ case 'array':
+ /*
+ * As per JSON spec if any array key is not an integer
+ * we must treat the the whole array as an object. We
+ * also try to catch a sparsely populated associative
+ * array with numeric keys here because some JS engines
+ * will create an array with empty indexes up to
+ * max_index which can cause memory issues and because
+ * the keys, which may be relevant, will be remapped
+ * otherwise.
+ *
+ * As per the ECMA and JSON specification an object may
+ * have any string as a property. Unfortunately due to
+ * a hole in the ECMA specification if the key is a
+ * ECMA reserved word or starts with a digit the
+ * parameter is only accessible using ECMAScript's
+ * bracket notation.
+ */
+
+ // treat as a JSON object
+ if (is_array($var) && count($var) && (array_keys($var) !== range(0, count($var) - 1))) {
+ return sprintf('{%s}', join(',', array_map(array($this, 'name_value'),
+ array_keys($var),
+ array_values($var))));
+ }
+
+ // treat it like a regular array
+ return sprintf('[%s]', join(',', array_map(array($this, 'encode'), $var)));
+
+ case 'object':
+ $vars = get_object_vars($var);
+ return sprintf('{%s}', join(',', array_map(array($this, 'name_value'),
+ array_keys($vars),
+ array_values($vars))));
+
+ default:
+ return '';
+ }
+ }
+
+ /**
+ * encodes an arbitrary variable into JSON format, alias for encode()
+ */
+ function enc($var) {
+ return $this->encode($var);
+ }
+
+ /** function name_value
+ * array-walking function for use in generating JSON-formatted name-value pairs
+ *
+ * @param string $name name of key to use
+ * @param mixed $value reference to an array element to be encoded
+ *
+ * @return string JSON-formatted name-value pair, like '"name":value'
+ * @access private
+ */
+ function name_value($name, $value) {
+ return (sprintf("%s:%s", $this->encode(strval($name)), $this->encode($value)));
+ }
+
+ /**
+ * reduce a string by removing leading and trailing comments and whitespace
+ *
+ * @param $str string string value to strip of comments and whitespace
+ *
+ * @return string string value stripped of comments and whitespace
+ * @access private
+ */
+ function reduce_string($str) {
+ $str = preg_replace(array(
+
+ // eliminate single line comments in '// ...' form
+ '#^\s*//(.+)$#m',
+
+ // eliminate multi-line comments in '/* ... */' form, at start of string
+ '#^\s*/\*(.+)\*/#Us',
+
+ // eliminate multi-line comments in '/* ... */' form, at end of string
+ '#/\*(.+)\*/\s*$#Us'
+
+ ), '', $str);
+
+ // eliminate extraneous space
+ return trim($str);
+ }
+
+ /**
+ * decodes a JSON string into appropriate variable
+ * If available the native PHP JSON implementation is used.
+ *
+ * @param string $str JSON-formatted string
+ *
+ * @return mixed number, boolean, string, array, or object
+ * corresponding to given JSON input string.
+ * See argument 1 to JSON() above for object-output behavior.
+ * Note that decode() always returns strings
+ * in ASCII or UTF-8 format!
+ * @access public
+ */
+ function decode($str) {
+ if (!$this->skipnative && function_exists('json_decode')){
+ return json_decode($str,($this->use == JSON_LOOSE_TYPE));
+ }
+
+ $str = $this->reduce_string($str);
+
+ switch (strtolower($str)) {
+ case 'true':
+ return true;
+
+ case 'false':
+ return false;
+
+ case 'null':
+ return null;
+
+ default:
+ if (is_numeric($str)) {
+ // Lookie-loo, it's a number
+
+ // This would work on its own, but I'm trying to be
+ // good about returning integers where appropriate:
+ // return (float)$str;
+
+ // Return float or int, as appropriate
+ return ((float)$str == (integer)$str)
+ ? (integer)$str
+ : (float)$str;
+
+ } elseif (preg_match('/^("|\').+("|\')$/s', $str, $m) && $m[1] == $m[2]) {
+ // STRINGS RETURNED IN UTF-8 FORMAT
+ $delim = substr($str, 0, 1);
+ $chrs = substr($str, 1, -1);
+ $utf8 = '';
+ $strlen_chrs = strlen($chrs);
+
+ for ($c = 0; $c < $strlen_chrs; ++$c) {
+
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
+ $ord_chrs_c = ord($chrs{$c});
+
+ switch ($substr_chrs_c_2) {
+ case '\b':
+ $utf8 .= chr(0x08);
+ $c+=1;
+ break;
+ case '\t':
+ $utf8 .= chr(0x09);
+ $c+=1;
+ break;
+ case '\n':
+ $utf8 .= chr(0x0A);
+ $c+=1;
+ break;
+ case '\f':
+ $utf8 .= chr(0x0C);
+ $c+=1;
+ break;
+ case '\r':
+ $utf8 .= chr(0x0D);
+ $c+=1;
+ break;
+
+ case '\\"':
+ case '\\\'':
+ case '\\\\':
+ case '\\/':
+ if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
+ ($delim == "'" && $substr_chrs_c_2 != '\\"')) {
+ $utf8 .= $chrs{++$c};
+ }
+ break;
+
+ default:
+ if (preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))) {
+ // single, escaped unicode character
+ $utf16 = chr(hexdec(substr($chrs, ($c+2), 2)))
+ . chr(hexdec(substr($chrs, ($c+4), 2)));
+ //$utf8 .= mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
+ $utf8 .= utf16be_to_utf8($utf16);
+ $c+=5;
+
+ } elseif(($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F)) {
+ $utf8 .= $chrs{$c};
+
+ } elseif(($ord_chrs_c & 0xE0) == 0xC0) {
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
+ //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 2);
+ $c += 1;
+
+ } elseif(($ord_chrs_c & 0xF0) == 0xE0) {
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 3);
+ $c += 2;
+
+ } elseif(($ord_chrs_c & 0xF8) == 0xF0) {
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 4);
+ $c += 3;
+
+ } elseif(($ord_chrs_c & 0xFC) == 0xF8) {
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 5);
+ $c += 4;
+
+ } elseif(($ord_chrs_c & 0xFE) == 0xFC) {
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
+ $utf8 .= substr($chrs, $c, 6);
+ $c += 5;
+
+ }
+ break;
+
+ }
+
+ }
+
+ return $utf8;
+
+ } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
+ // array, or object notation
+
+ if ($str{0} == '[') {
+ $stk = array(JSON_IN_ARR);
+ $arr = array();
+ } else {
+ if ($this->use == JSON_LOOSE_TYPE) {
+ $stk = array(JSON_IN_OBJ);
+ $obj = array();
+ } else {
+ $stk = array(JSON_IN_OBJ);
+ $obj = new stdClass();
+ }
+ }
+
+ array_push($stk, array('what' => JSON_SLICE,
+ 'where' => 0,
+ 'delim' => false));
+
+ $chrs = substr($str, 1, -1);
+ $chrs = $this->reduce_string($chrs);
+
+ if ($chrs == '') {
+ if (reset($stk) == JSON_IN_ARR) {
+ return $arr;
+
+ } else {
+ return $obj;
+
+ }
+ }
+
+ //print("\nparsing {$chrs}\n");
+
+ $strlen_chrs = strlen($chrs);
+
+ for ($c = 0; $c <= $strlen_chrs; ++$c) {
+
+ $top = end($stk);
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
+
+ if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == JSON_SLICE))) {
+ // found a comma that is not inside a string, array, etc.,
+ // OR we've reached the end of the character list
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
+ array_push($stk, array('what' => JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+ //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ if (reset($stk) == JSON_IN_ARR) {
+ // we are in an array, so just push an element onto the stack
+ array_push($arr, $this->decode($slice));
+
+ } elseif (reset($stk) == JSON_IN_OBJ) {
+ // we are in an object, so figure
+ // out the property name and set an
+ // element in an associative array,
+ // for now
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ // "name":value pair
+ $key = $this->decode($parts[1]);
+ $val = $this->decode($parts[2]);
+
+ if ($this->use == JSON_LOOSE_TYPE) {
+ $obj[$key] = $val;
+ } else {
+ $obj->$key = $val;
+ }
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ // name:value pair, where name is unquoted
+ $key = $parts[1];
+ $val = $this->decode($parts[2]);
+
+ if ($this->use == JSON_LOOSE_TYPE) {
+ $obj[$key] = $val;
+ } else {
+ $obj->$key = $val;
+ }
+ }
+
+ }
+
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) &&
+ in_array($top['what'], array(JSON_SLICE, JSON_IN_ARR, JSON_IN_OBJ))) {
+ // found a quote, and we are not inside a string
+ array_push($stk, array('what' => JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+ //print("Found start of string at {$c}\n");
+
+ } elseif (($chrs{$c} == $top['delim']) &&
+ ($top['what'] == JSON_IN_STR) &&
+ (($chrs{$c - 1} != "\\") ||
+ ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) {
+ // found a quote, we're in a string, and it's not escaped
+ array_pop($stk);
+ //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
+
+ } elseif (($chrs{$c} == '[') &&
+ in_array($top['what'], array(JSON_SLICE, JSON_IN_ARR, JSON_IN_OBJ))) {
+ // found a left-bracket, and we are in an array, object, or slice
+ array_push($stk, array('what' => JSON_IN_ARR, 'where' => $c, 'delim' => false));
+ //print("Found start of array at {$c}\n");
+
+ } elseif (($chrs{$c} == ']') && ($top['what'] == JSON_IN_ARR)) {
+ // found a right-bracket, and we're in an array
+ array_pop($stk);
+ //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ } elseif (($chrs{$c} == '{') &&
+ in_array($top['what'], array(JSON_SLICE, JSON_IN_ARR, JSON_IN_OBJ))) {
+ // found a left-brace, and we are in an array, object, or slice
+ array_push($stk, array('what' => JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+ //print("Found start of object at {$c}\n");
+
+ } elseif (($chrs{$c} == '}') && ($top['what'] == JSON_IN_OBJ)) {
+ // found a right-brace, and we're in an object
+ array_pop($stk);
+ //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ } elseif (($substr_chrs_c_2 == '/*') &&
+ in_array($top['what'], array(JSON_SLICE, JSON_IN_ARR, JSON_IN_OBJ))) {
+ // found a comment start, and we are in an array, object, or slice
+ array_push($stk, array('what' => JSON_IN_CMT, 'where' => $c, 'delim' => false));
+ $c++;
+ //print("Found start of comment at {$c}\n");
+
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == JSON_IN_CMT)) {
+ // found a comment end, and we're in one now
+ array_pop($stk);
+ $c++;
+
+ for ($i = $top['where']; $i <= $c; ++$i)
+ $chrs = substr_replace($chrs, ' ', $i, 1);
+
+ //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
+
+ }
+
+ }
+
+ if (reset($stk) == JSON_IN_ARR) {
+ return $arr;
+
+ } elseif (reset($stk) == JSON_IN_OBJ) {
+ return $obj;
+
+ }
+
+ }
+ }
+ }
+
+ /**
+ * decodes a JSON string into appropriate variable; alias for decode()
+ */
+ function dec($var) {
+ return $this->decode($var);
+ }
+}
+
diff --git a/inc/JpegMeta.php b/inc/JpegMeta.php
new file mode 100644
index 000000000..5c043fb6b
--- /dev/null
+++ b/inc/JpegMeta.php
@@ -0,0 +1,3008 @@
+<?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 $_type = 'unknown';
+
+ var $_markers;
+ var $_info;
+
+
+ /**
+ * Constructor
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ */
+ function JpegMeta($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>
+ */
+ 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 = $alt;
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function getTitle($max=80){
+ $cap = '';
+
+ // 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>
+ */
+ function getDates() {
+ $this->_parseAll();
+ if ($this->_markers == null) {
+ if (@isset($this->_info['file']['UnixTime'])) {
+ $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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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() {
+ $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();
+ }
+ }
+
+ /*************************************************************/
+ 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;
+ }
+
+ /*************************************************************/
+ 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'] = 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://www.php.net/manual/en/function.getimagesize.php
+ // http://www.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'] = 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;
+ }
+
+ $pos = 0;
+ $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;
+ break;
+ }
+
+ $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>
+ */
+ 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;
+ }
+
+ /*************************************************************/
+ 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;
+ }
+
+ /*************************************************************/
+ 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;
+ }
+
+ /*************************************************************/
+ function & _getIFDEntries($isBigEndian, $mode) {
+ $EXIFNames = $this->_exifTagNames($mode);
+ $EXIFTags = $this->_exifNameTags($mode);
+ $EXIFTypeInfo = $this->_exifTagTypes($mode);
+
+ $ifdEntries = array();
+ $entryCount = 0;
+
+ reset($EXIFNames);
+ while (list($tag, $name) = each($EXIFNames)) {
+ $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) {
+ $this->_putString($value, $j * 4, "\0\0\0\0");
+ $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) {
+ $this->_putString($value, $j * 8, "\0\0\0\0\0\0\0\0");
+ $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']);
+ while (list($key) = each($this->_info['adobe']['raw'])) {
+ $pos = $this->_write8BIM(
+ $data,
+ $pos,
+ $this->_info['adobe']['raw'][$key]['type'],
+ $this->_info['adobe']['raw'][$key]['header'],
+ $this->_info['adobe']['raw'][$key]['data'] );
+ }
+ }
+
+ return $data;
+ }
+
+ /*************************************************************/
+ 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();
+
+ reset($this->_info['iptc']);
+
+ while (list($label) = each($this->_info['iptc'])) {
+ $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;
+ }
+
+ /*************************************************************/
+ 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();
+ reset($tags2Names);
+ while (list($tag, $name) = each($tags2Names)) {
+ $names2Tags[$name] = $tag;
+ }
+
+ return $names2Tags;
+ }
+
+ /*************************************************************/
+ function _getByte(&$data, $pos) {
+ return ord($data{$pos});
+ }
+
+ /*************************************************************/
+ 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;
+ }
+
+ /*************************************************************/
+ 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);
+ }
+ }
+
+ /*************************************************************/
+ 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;
+ }
+
+ return substr($data, $pos, $length);
+ }
+
+ /*************************************************************/
+ 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 .= '&nbsp;';
+ 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/inc/PassHash.class.php b/inc/PassHash.class.php
new file mode 100644
index 000000000..2558f37c6
--- /dev/null
+++ b/inc/PassHash.class.php
@@ -0,0 +1,433 @@
+<?php
+/**
+ * Password Hashing Class
+ *
+ * This class implements various mechanisms used to hash passwords
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @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>
+ * @return bool
+ */
+ function verify_hash($clear,$hash){
+ $method='';
+ $salt='';
+ $magic='';
+
+ //determine the used method and salt
+ $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('/^\$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('/^sha1\$(.{5})\$/',$hash,$m)){
+ $method = 'djangosha1';
+ $salt = $m[1];
+ }elseif(preg_match('/^md5\$(.{5})\$/',$hash,$m)){
+ $method = 'djangomd5';
+ $salt = $m[1];
+ }elseif(preg_match('/^\$2a\$(.{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($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;
+ if($this->$call($clear,$salt,$magic) === $hash){
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Create a random salt
+ *
+ * @param int $len - The length of the salt
+ */
+ public function gen_salt($len=32){
+ $salt = '';
+ $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ for($i=0;$i<$len;$i++) $salt .= $chars[mt_rand(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.
+ *
+ * @param stringref $salt - The salt, pass null if you want one generated
+ * @param int $len - The length of the salt
+ */
+ public function init_salt(&$salt,$len=32){
+ if(is_null($salt)) $salt = $this->gen_salt($len);
+ if(strlen($salt) > $len) $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://de.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)
+ * @returns string - hashed password
+ */
+ public function hash_smd5($clear, $salt=null){
+ $this->init_salt($salt,8);
+
+ if(defined('CRYPT_MD5') && CRYPT_MD5){
+ 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.
+ */
+ 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://de.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)
+ * @returns 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
+ * @returns 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
+ * @returns 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
+ * @returns 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
+ * @returns 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://www.php.net/mysql
+ * @author <soren at byu dot edu>
+ * @param string $clear - the clear text to hash
+ * @returns 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
+ * @returns string - hashed password
+ */
+ public function hash_my411($clear){
+ return '*'.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
+ * @returns 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 hashing method 'pmd5'
+ *
+ * Uses salted MD5 hashs. Salt is 1+8 bytes long, 1st byte is the
+ * iteration count when given, for null salts $compute is 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
+ * @returns string - hashed password
+ */
+ public function hash_pmd5($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 iteration count
+ $iter = strpos($itoa64,$iterc);
+ $iter = 1 << $iter;
+ $salt = substr($salt,1,8);
+
+ // iterate
+ $hash = md5($salt . $clear, true);
+ do {
+ $hash = md5($hash . $clear, true);
+ } while (--$iter);
+
+ // encode
+ $output = '';
+ $count = 16;
+ $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;
+ }
+
+ /**
+ * Alias for hash_pmd5
+ */
+ 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
+ * @returns 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
+ * @returns string - hashed password
+ */
+ public function hash_djangomd5($clear, $salt=null){
+ $this->init_salt($salt,5);
+ return 'md5$'.$salt.'$'.md5($salt.$clear);
+ }
+
+
+ /**
+ * 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)
+ * @returns string - hashed password
+ */
+ public function hash_bcrypt($clear, $salt=null, $compute=8){
+ 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 = '$2a$'.str_pad($compute, 2, '0', STR_PAD_LEFT).'$'.
+ $this->gen_salt(22);
+ }
+
+ return crypt($password, $salt);
+ }
+
+}
diff --git a/inc/SafeFN.class.php b/inc/SafeFN.class.php
new file mode 100644
index 000000000..43b19e9ab
--- /dev/null
+++ b/inc/SafeFN.class.php
@@ -0,0 +1,157 @@
+<?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
+ * @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 function encode($filename) {
+ return self::unicode_to_safe(utf8_to_unicode($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 function decode($filename) {
+ return unicode_to_utf8(self::safe_to_unicode(strtolower($filename)));
+ }
+
+ public function validate_printable_utf8($printable_utf8) {
+ return !preg_match('#[\x01-\x1f]#',$printable_utf8);
+ }
+
+ public function validate_safe($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 function unicode_to_safe($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 function safe_to_unicode($safe) {
+
+ $unicode = array();
+ $split = preg_split('#(?=['.self::$post_indicator.self::$pre_indicator.'])#',$safe,-1,PREG_SPLIT_NO_EMPTY);
+
+ $converted = false;
+ foreach ($split as $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 < strlen($sub); $i++) {
+ $unicode[] = ord($sub[$i]);
+ }
+ $converted = false;
+ } else if (strlen($sub)==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/inc/SimplePie.php b/inc/SimplePie.php
new file mode 100644
index 000000000..10d8141bd
--- /dev/null
+++ b/inc/SimplePie.php
@@ -0,0 +1,15299 @@
+<?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-2011, Ryan Parman, Geoffrey 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.2.1
+ * @copyright 2004-2011 Ryan Parman, Geoffrey Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Geoffrey Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @todo phpDoc comments
+ */
+
+/**
+ * SimplePie Name
+ */
+define('SIMPLEPIE_NAME', 'SimplePie');
+
+/**
+ * SimplePie Version
+ */
+define('SIMPLEPIE_VERSION', '1.2.1-dev');
+
+/**
+ * SimplePie Build
+ */
+define('SIMPLEPIE_BUILD', '20111015034325');
+
+/**
+ * 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
+ */
+define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
+
+/**
+ * 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/');
+
+/**
+ * Whether we're running on PHP5
+ */
+define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
+
+/**
+ * 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
+ */
+class SimplePie
+{
+ /**
+ * @var array Raw data
+ * @access private
+ */
+ var $data = array();
+
+ /**
+ * @var mixed Error string
+ * @access private
+ */
+ var $error;
+
+ /**
+ * @var object Instance of SimplePie_Sanitize (or other class)
+ * @see SimplePie::set_sanitize_class()
+ * @access private
+ */
+ var $sanitize;
+
+ /**
+ * @var string SimplePie Useragent
+ * @see SimplePie::set_useragent()
+ * @access private
+ */
+ var $useragent = SIMPLEPIE_USERAGENT;
+
+ /**
+ * @var string Feed URL
+ * @see SimplePie::set_feed_url()
+ * @access private
+ */
+ var $feed_url;
+
+ /**
+ * @var object Instance of SimplePie_File to use as a feed
+ * @see SimplePie::set_file()
+ * @access private
+ */
+ var $file;
+
+ /**
+ * @var string Raw feed data
+ * @see SimplePie::set_raw_data()
+ * @access private
+ */
+ var $raw_data;
+
+ /**
+ * @var int Timeout for fetching remote files
+ * @see SimplePie::set_timeout()
+ * @access private
+ */
+ var $timeout = 10;
+
+ /**
+ * @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
+ */
+ var $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
+ */
+ var $force_feed = false;
+
+ /**
+ * @var bool Enable/Disable XML dump
+ * @see SimplePie::enable_xml_dump()
+ * @access private
+ */
+ var $xml_dump = false;
+
+ /**
+ * @var bool Enable/Disable Caching
+ * @see SimplePie::enable_cache()
+ * @access private
+ */
+ var $cache = true;
+
+ /**
+ * @var int Cache duration (in seconds)
+ * @see SimplePie::set_cache_duration()
+ * @access private
+ */
+ var $cache_duration = 3600;
+
+ /**
+ * @var int Auto-discovery cache duration (in seconds)
+ * @see SimplePie::set_autodiscovery_cache_duration()
+ * @access private
+ */
+ var $autodiscovery_cache_duration = 604800; // 7 Days.
+
+ /**
+ * @var string Cache location (relative to executing script)
+ * @see SimplePie::set_cache_location()
+ * @access private
+ */
+ var $cache_location = './cache';
+
+ /**
+ * @var string Function that creates the cache filename
+ * @see SimplePie::set_cache_name_function()
+ * @access private
+ */
+ var $cache_name_function = 'md5';
+
+ /**
+ * @var bool Reorder feed by date descending
+ * @see SimplePie::enable_order_by_date()
+ * @access private
+ */
+ var $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
+ */
+ var $input_encoding = false;
+
+ /**
+ * @var int Feed Autodiscovery Level
+ * @see SimplePie::set_autodiscovery_level()
+ * @access private
+ */
+ var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
+
+ /**
+ * @var string Class used for caching feeds
+ * @see SimplePie::set_cache_class()
+ * @access private
+ */
+ var $cache_class = 'SimplePie_Cache';
+
+ /**
+ * @var string Class used for locating feeds
+ * @see SimplePie::set_locator_class()
+ * @access private
+ */
+ var $locator_class = 'SimplePie_Locator';
+
+ /**
+ * @var string Class used for parsing feeds
+ * @see SimplePie::set_parser_class()
+ * @access private
+ */
+ var $parser_class = 'SimplePie_Parser';
+
+ /**
+ * @var string Class used for fetching feeds
+ * @see SimplePie::set_file_class()
+ * @access private
+ */
+ var $file_class = 'SimplePie_File';
+
+ /**
+ * @var string Class used for items
+ * @see SimplePie::set_item_class()
+ * @access private
+ */
+ var $item_class = 'SimplePie_Item';
+
+ /**
+ * @var string Class used for authors
+ * @see SimplePie::set_author_class()
+ * @access private
+ */
+ var $author_class = 'SimplePie_Author';
+
+ /**
+ * @var string Class used for categories
+ * @see SimplePie::set_category_class()
+ * @access private
+ */
+ var $category_class = 'SimplePie_Category';
+
+ /**
+ * @var string Class used for enclosures
+ * @see SimplePie::set_enclosures_class()
+ * @access private
+ */
+ var $enclosure_class = 'SimplePie_Enclosure';
+
+ /**
+ * @var string Class used for Media RSS <media:text> captions
+ * @see SimplePie::set_caption_class()
+ * @access private
+ */
+ var $caption_class = 'SimplePie_Caption';
+
+ /**
+ * @var string Class used for Media RSS <media:copyright>
+ * @see SimplePie::set_copyright_class()
+ * @access private
+ */
+ var $copyright_class = 'SimplePie_Copyright';
+
+ /**
+ * @var string Class used for Media RSS <media:credit>
+ * @see SimplePie::set_credit_class()
+ * @access private
+ */
+ var $credit_class = 'SimplePie_Credit';
+
+ /**
+ * @var string Class used for Media RSS <media:rating>
+ * @see SimplePie::set_rating_class()
+ * @access private
+ */
+ var $rating_class = 'SimplePie_Rating';
+
+ /**
+ * @var string Class used for Media RSS <media:restriction>
+ * @see SimplePie::set_restriction_class()
+ * @access private
+ */
+ var $restriction_class = 'SimplePie_Restriction';
+
+ /**
+ * @var string Class used for content-type sniffing
+ * @see SimplePie::set_content_type_sniffer_class()
+ * @access private
+ */
+ var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
+
+ /**
+ * @var string Class used for item sources.
+ * @see SimplePie::set_source_class()
+ * @access private
+ */
+ var $source_class = 'SimplePie_Source';
+
+ /**
+ * @var mixed Set javascript query string parameter (false, or
+ * anything type-cast to false, disables this feature)
+ * @see SimplePie::set_javascript()
+ * @access private
+ */
+ var $javascript = 'js';
+
+ /**
+ * @var int Maximum number of feeds to check with autodiscovery
+ * @see SimplePie::set_max_checked_feeds()
+ * @access private
+ */
+ var $max_checked_feeds = 10;
+
+ /**
+ * @var array All the feeds found during the autodiscovery process
+ * @see SimplePie::get_all_discovered_feeds()
+ * @access private
+ */
+ var $all_discovered_feeds = array();
+
+ /**
+ * @var string Web-accessible path to the handler_favicon.php file.
+ * @see SimplePie::set_favicon_handler()
+ * @access private
+ */
+ var $favicon_handler = '';
+
+ /**
+ * @var string Web-accessible path to the handler_image.php file.
+ * @see SimplePie::set_image_handler()
+ * @access private
+ */
+ var $image_handler = '';
+
+ /**
+ * @var array Stores the URLs when multiple feeds are being initialized.
+ * @see SimplePie::set_feed_url()
+ * @access private
+ */
+ var $multifeed_url = array();
+
+ /**
+ * @var array Stores SimplePie objects when multiple feeds initialized.
+ * @access private
+ */
+ var $multifeed_objects = array();
+
+ /**
+ * @var array Stores the get_object_vars() array for use with multifeeds.
+ * @see SimplePie::set_feed_url()
+ * @access private
+ */
+ var $config_settings = null;
+
+ /**
+ * @var integer Stores the number of items to return per-feed with multifeeds.
+ * @see SimplePie::set_item_limit()
+ * @access private
+ */
+ var $item_limit = 0;
+
+ /**
+ * @var array Stores the default attributes to be stripped by strip_attributes().
+ * @see SimplePie::strip_attributes()
+ * @access private
+ */
+ var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
+
+ /**
+ * @var array Stores the default tags to be stripped by strip_htmltags().
+ * @see SimplePie::strip_htmltags()
+ * @access private
+ */
+ var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
+
+ /**
+ * The SimplePie class contains feed level data and options
+ *
+ * There are two ways that you can create a new SimplePie object. The first
+ * is by passing a feed URL as a parameter to the SimplePie constructor
+ * (as well as optionally setting the cache location and cache expiry). This
+ * will initialise the whole feed with all of the default settings, and you
+ * can begin accessing methods and properties immediately.
+ *
+ * The second way is to create the SimplePie object with no parameters
+ * at all. This will enable you to set configuration options. 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. This format is
+ * what is used throughout this documentation.
+ *
+ * @access public
+ * @since 1.0 Preview Release
+ * @param string $feed_url This is the URL you want to parse.
+ * @param string $cache_location This is where you want the cache to be stored.
+ * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
+ */
+ function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
+ {
+ // Other objects, instances created here so we can set options on them
+ $this->sanitize = new SimplePie_Sanitize;
+
+ // Set options if they're passed to the constructor
+ if ($cache_location !== null)
+ {
+ $this->set_cache_location($cache_location);
+ }
+
+ if ($cache_duration !== null)
+ {
+ $this->set_cache_duration($cache_duration);
+ }
+
+ // Only init the script if we're passed a feed URL
+ if ($feed_url !== null)
+ {
+ $this->set_feed_url($feed_url);
+ $this->init();
+ }
+ }
+
+ /**
+ * Used for converting object to a string
+ */
+ function __toString()
+ {
+ return md5(serialize($this->data));
+ }
+
+ /**
+ * Remove items that link back to this before destroying this object
+ */
+ function __destruct()
+ {
+ if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
+ {
+ 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 no matter what it
+ * appears like
+ *
+ * @access public
+ * @since 1.1
+ * @param bool $enable Force the given data/URL to be treated as a feed
+ */
+ function force_feed($enable = false)
+ {
+ $this->force_feed = (bool) $enable;
+ }
+
+ /**
+ * This is 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.
+ *
+ * @access public
+ * @since 1.0 Preview Release
+ * @param mixed $url This is the URL (or array of URLs) that you want to parse.
+ * @see SimplePie::set_raw_data()
+ */
+ function set_feed_url($url)
+ {
+ if (is_array($url))
+ {
+ $this->multifeed_url = array();
+ foreach ($url as $value)
+ {
+ $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
+ }
+ }
+ else
+ {
+ $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
+ }
+ }
+
+ /**
+ * Provides an instance of SimplePie_File to use as a feed
+ *
+ * @access public
+ * @param object &$file Instance of SimplePie_File (or subclass)
+ * @return bool True on success, false on failure
+ */
+ function set_file(&$file)
+ {
+ if (is_a($file, 'SimplePie_File'))
+ {
+ $this->feed_url = $file->url;
+ $this->file =& $file;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 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.
+ *
+ * @access public
+ * @since 1.0 Beta 3
+ * @param string $data RSS or Atom data as a string.
+ * @see SimplePie::set_feed_url()
+ */
+ function set_raw_data($data)
+ {
+ $this->raw_data = $data;
+ }
+
+ /**
+ * Allows you to override 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.
+ *
+ * @access public
+ * @since 1.0 Beta 3
+ * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
+ */
+ function set_timeout($timeout = 10)
+ {
+ $this->timeout = (int) $timeout;
+ }
+
+ /**
+ * Forces SimplePie to use fsockopen() instead of the preferred cURL
+ * functions.
+ *
+ * @access public
+ * @since 1.0 Beta 3
+ * @param bool $enable Force fsockopen() to be used
+ */
+ function force_fsockopen($enable = false)
+ {
+ $this->force_fsockopen = (bool) $enable;
+ }
+
+ /**
+ * Outputs the raw XML content of the feed, after it has gone through
+ * SimplePie's filters.
+ *
+ * Used only for debugging, this function will output the XML content as
+ * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
+ * before trying to parse it. Many parts of the feed are re-written in
+ * memory, and in the end, you have a parsable feed. XML dump shows you the
+ * actual XML that SimplePie tries to parse, which may or may not be very
+ * different from the original feed.
+ *
+ * @access public
+ * @since 1.0 Preview Release
+ * @param bool $enable Enable XML dump
+ */
+ function enable_xml_dump($enable = false)
+ {
+ $this->xml_dump = (bool) $enable;
+ }
+
+ /**
+ * Enables/disables caching in SimplePie.
+ *
+ * This option allows you to disable caching all-together in SimplePie.
+ * However, disabling the cache can lead to longer load times.
+ *
+ * @access public
+ * @since 1.0 Preview Release
+ * @param bool $enable Enable caching
+ */
+ function enable_cache($enable = true)
+ {
+ $this->cache = (bool) $enable;
+ }
+
+ /**
+ * Set the length of time (in seconds) that the contents of a feed
+ * will be cached.
+ *
+ * @access public
+ * @param int $seconds The feed content cache duration.
+ */
+ 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.
+ *
+ * @access public
+ * @param int $seconds The autodiscovered feed URL cache duration.
+ */
+ 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.
+ *
+ * @access public
+ * @param string $location The file system location.
+ */
+ function set_cache_location($location = './cache')
+ {
+ $this->cache_location = (string) $location;
+ }
+
+ /**
+ * Determines whether feed items should be sorted into reverse chronological order.
+ *
+ * @access public
+ * @param bool $enable Sort as reverse chronological order.
+ */
+ function enable_order_by_date($enable = true)
+ {
+ $this->order_by_date = (bool) $enable;
+ }
+
+ /**
+ * Allows you to override the character encoding reported by the feed.
+ *
+ * @access public
+ * @param string $encoding Character encoding.
+ */
+ 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
+ *
+ * @access public
+ * @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)
+ */
+ function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
+ {
+ $this->autodiscovery = (int) $level;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for caching.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_cache_class($class = 'SimplePie_Cache')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
+ {
+ $this->cache_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for auto-discovery.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_locator_class($class = 'SimplePie_Locator')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
+ {
+ $this->locator_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for XML parsing.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_parser_class($class = 'SimplePie_Parser')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
+ {
+ $this->parser_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for remote file fetching.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_file_class($class = 'SimplePie_File')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
+ {
+ $this->file_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for data sanitization.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_sanitize_class($class = 'SimplePie_Sanitize')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
+ {
+ $this->sanitize = new $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for handling feed items.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_item_class($class = 'SimplePie_Item')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
+ {
+ $this->item_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for handling author data.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_author_class($class = 'SimplePie_Author')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
+ {
+ $this->author_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for handling category data.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_category_class($class = 'SimplePie_Category')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
+ {
+ $this->category_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for feed enclosures.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_enclosure_class($class = 'SimplePie_Enclosure')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
+ {
+ $this->enclosure_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for <media:text> captions
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_caption_class($class = 'SimplePie_Caption')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
+ {
+ $this->caption_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for <media:copyright>
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_copyright_class($class = 'SimplePie_Copyright')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
+ {
+ $this->copyright_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for <media:credit>
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_credit_class($class = 'SimplePie_Credit')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
+ {
+ $this->credit_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for <media:rating>
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_rating_class($class = 'SimplePie_Rating')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
+ {
+ $this->rating_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for <media:restriction>
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_restriction_class($class = 'SimplePie_Restriction')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
+ {
+ $this->restriction_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses for content-type sniffing.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
+ {
+ $this->content_type_sniffer_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to change which class SimplePie uses item sources.
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @access public
+ * @param string $class Name of custom class.
+ * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ */
+ function set_source_class($class = 'SimplePie_Source')
+ {
+ if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
+ {
+ $this->source_class = $class;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allows you to override the default user agent string.
+ *
+ * @access public
+ * @param string $ua New user agent string.
+ */
+ function set_useragent($ua = SIMPLEPIE_USERAGENT)
+ {
+ $this->useragent = (string) $ua;
+ }
+
+ /**
+ * Set callback function to create cache filename with
+ *
+ * @access public
+ * @param mixed $function Callback function
+ */
+ function set_cache_name_function($function = 'md5')
+ {
+ if (is_callable($function))
+ {
+ $this->cache_name_function = $function;
+ }
+ }
+
+ /**
+ * Set javascript query string parameter
+ *
+ * @access public
+ * @param mixed $get Javascript query string parameter
+ */
+ function set_javascript($get = 'js')
+ {
+ if ($get)
+ {
+ $this->javascript = (string) $get;
+ }
+ else
+ {
+ $this->javascript = false;
+ }
+ }
+
+ /**
+ * Set options to make SP as fast as possible. Forgoes a
+ * substantial amount of data sanitization in favor of speed.
+ *
+ * @access public
+ * @param bool $set Whether to set them or not
+ */
+ 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->set_image_handler(false);
+ }
+ }
+
+ /**
+ * Set maximum number of feeds to check with autodiscovery
+ *
+ * @access public
+ * @param int $max Maximum number of feeds to check
+ */
+ function set_max_checked_feeds($max = 10)
+ {
+ $this->max_checked_feeds = (int) $max;
+ }
+
+ function remove_div($enable = true)
+ {
+ $this->sanitize->remove_div($enable);
+ }
+
+ 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);
+ }
+ }
+
+ function encode_instead_of_strip($enable = true)
+ {
+ $this->sanitize->encode_instead_of_strip($enable);
+ }
+
+ function strip_attributes($attribs = '')
+ {
+ if ($attribs === '')
+ {
+ $attribs = $this->strip_attributes;
+ }
+ $this->sanitize->strip_attributes($attribs);
+ }
+
+ function set_output_encoding($encoding = 'UTF-8')
+ {
+ $this->sanitize->set_output_encoding($encoding);
+ }
+
+ 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
+ *
+ * @access public
+ * @since 1.0
+ * @param array $element_attribute Element/attribute key/value pairs
+ */
+ function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
+ {
+ $this->sanitize->set_url_replacements($element_attribute);
+ }
+
+ /**
+ * Set the handler to enable the display of cached favicons.
+ *
+ * @access public
+ * @param str $page Web-accessible path to the handler_favicon.php file.
+ * @param str $qs The query string that the value should be passed to.
+ */
+ function set_favicon_handler($page = false, $qs = 'i')
+ {
+ if ($page !== false)
+ {
+ $this->favicon_handler = $page . '?' . $qs . '=';
+ }
+ else
+ {
+ $this->favicon_handler = '';
+ }
+ }
+
+ /**
+ * Set the handler to enable the display of cached images.
+ *
+ * @access public
+ * @param str $page Web-accessible path to the handler_image.php file.
+ * @param str $qs The query string that the value should be passed to.
+ */
+ 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.
+ *
+ * @access public
+ * @param integer $limit The maximum number of items to return.
+ */
+ function set_item_limit($limit = 0)
+ {
+ $this->item_limit = (int) $limit;
+ }
+
+ function init()
+ {
+ // Check absolute bare minimum requirements.
+ if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
+ {
+ 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;
+ }
+ }
+
+ if (isset($_GET[$this->javascript]))
+ {
+ SimplePie_Misc::output_javascript();
+ exit;
+ }
+
+ // Pass whatever was set with config options over to the sanitizer.
+ $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
+ $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
+
+ if ($this->feed_url !== null || $this->raw_data !== null)
+ {
+ $this->data = array();
+ $this->multifeed_objects = array();
+ $cache = false;
+
+ if ($this->feed_url !== null)
+ {
+ $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
+ // Decide whether to enable caching
+ if ($this->cache && $parsed_feed_url['scheme'] !== '')
+ {
+ $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
+ }
+ // If it's enabled and we don't want an XML dump, use the cache
+ if ($cache && !$this->xml_dump)
+ {
+ // 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'])
+ {
+ $cache->unlink();
+ $this->data = array();
+ }
+ else
+ {
+ $this->set_feed_url($this->data['feed_url']);
+ return $this->init();
+ }
+ }
+ }
+ // Check if the cache has been updated
+ elseif ($cache->mtime() + $this->cache_duration < time())
+ {
+ // If we have last-modified and/or etag set
+ if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
+ {
+ $headers = array();
+ 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 = new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
+ if ($file->success)
+ {
+ if ($file->status_code === 304)
+ {
+ $cache->touch();
+ return true;
+ }
+ else
+ {
+ $headers = $file->headers;
+ }
+ }
+ else
+ {
+ unset($file);
+ }
+ }
+ }
+ // If the cache is still valid, just return true
+ else
+ {
+ 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 (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
+ {
+ $file =& $this->file;
+ }
+ else
+ {
+ $file = new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
+ }
+ }
+ // 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;
+ if (!empty($this->data))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (!$this->force_feed)
+ {
+ // Check if the supplied URL is a feed, if it isn't, look for it.
+ $locate = new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
+ if (!$locate->is_feed($file))
+ {
+ // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
+ unset($file);
+ if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
+ {
+ 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 writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
+ }
+ $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
+ }
+ $this->feed_url = $file->url;
+ }
+ else
+ {
+ $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
+ SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
+ return false;
+ }
+ }
+ $locate = null;
+ }
+
+ $headers = $file->headers;
+ $data = $file->body;
+ $sniffer = new $this->content_type_sniffer_class($file);
+ $sniffed = $sniffer->get_type();
+ }
+ else
+ {
+ $data = $this->raw_data;
+ }
+
+ // Set up array of possible encodings
+ $encodings = array();
+
+ // First check to see if input has been overridden.
+ if ($this->input_encoding !== false)
+ {
+ $encodings[] = $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, SimplePie_Misc::xml_encoding($data));
+ $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[] = $charset[1];
+ }
+ $encodings[] = 'US-ASCII';
+ }
+ // Text MIME-type default
+ elseif (substr($sniffed, 0, 5) === 'text/')
+ {
+ $encodings[] = 'US-ASCII';
+ }
+ }
+
+ // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
+ $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
+ $encodings[] = 'UTF-8';
+ $encodings[] = 'ISO-8859-1';
+
+ // There's no point in trying an encoding twice
+ $encodings = array_unique($encodings);
+
+ // If we want the XML, just output that with the most likely encoding and quit
+ if ($this->xml_dump)
+ {
+ header('Content-type: text/xml; charset=' . $encodings[0]);
+ echo $data;
+ exit;
+ }
+
+ // 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 = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
+ {
+ // Create new parser
+ $parser = new $this->parser_class();
+
+ // If it's parsed fine
+ if ($parser->parse($utf8_data, 'UTF-8'))
+ {
+ $this->data = $parser->get_data();
+ if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
+ {
+ 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 writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
+ }
+ return true;
+ }
+ else
+ {
+ $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
+ SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
+ return false;
+ }
+ }
+ }
+ }
+ if (isset($parser))
+ {
+ // We have an error, just set SimplePie_Misc::error to it and quit
+ $this->error = sprintf('This XML document is invalid, 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. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
+ }
+ SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
+ return false;
+ }
+ elseif (!empty($this->multifeed_url))
+ {
+ $i = 0;
+ $success = 0;
+ $this->multifeed_objects = array();
+ foreach ($this->multifeed_url as $url)
+ {
+ if (SIMPLEPIE_PHP5)
+ {
+ // This keyword needs to defy coding standards for PHP4 compatibility
+ $this->multifeed_objects[$i] = clone($this);
+ }
+ else
+ {
+ $this->multifeed_objects[$i] = $this;
+ }
+ $this->multifeed_objects[$i]->set_feed_url($url);
+ $success |= $this->multifeed_objects[$i]->init();
+ $i++;
+ }
+ return (bool) $success;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Return the error message for the occured error
+ *
+ * @access public
+ * @return string Error message
+ */
+ function error()
+ {
+ return $this->error;
+ }
+
+ function get_encoding()
+ {
+ return $this->sanitize->output_encoding;
+ }
+
+ 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);
+ }
+ }
+
+ 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'];
+ }
+
+ /**
+ * Returns the URL for the favicon of the feed's website.
+ *
+ * @todo Cache atom:icon
+ * @access public
+ * @since 1.0
+ */
+ function get_favicon()
+ {
+ if ($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 (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
+ {
+ $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
+
+ if ($this->cache && $this->favicon_handler)
+ {
+ $favicon_filename = call_user_func($this->cache_name_function, $favicon);
+ $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
+
+ if ($cache->load())
+ {
+ return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ $file = new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
+
+ if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
+ {
+ $sniffer = new $this->content_type_sniffer_class($file);
+ if (substr($sniffer->get_type(), 0, 6) === 'image/')
+ {
+ if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
+ {
+ return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ trigger_error("$cache->name is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
+ return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ // not an image
+ else
+ {
+ return false;
+ }
+ }
+ }
+ }
+ else
+ {
+ return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @todo If we have a perm redirect we should return the new URL
+ * @todo When we make the above change, let's support <itunes:new-feed-url> as well
+ * @todo Also, |atom:link|@rel=self
+ */
+ function subscribe_url()
+ {
+ if ($this->feed_url !== null)
+ {
+ return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_feed()
+ {
+ if ($this->feed_url !== null)
+ {
+ return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_outlook()
+ {
+ if ($this->feed_url !== null)
+ {
+ return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_podcast()
+ {
+ if ($this->feed_url !== null)
+ {
+ return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_itunes()
+ {
+ if ($this->feed_url !== null)
+ {
+ return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Creates the subscribe_* methods' return data
+ *
+ * @access private
+ * @param string $feed_url String to prefix to the feed URL
+ * @param string $site_url String to prefix to the site URL (and
+ * suffix to the feed URL)
+ * @return mixed URL if feed exists, false otherwise
+ */
+ function subscribe_service($feed_url, $site_url = null)
+ {
+ if ($this->subscribe_url())
+ {
+ $return = $feed_url . rawurlencode($this->feed_url);
+ if ($site_url !== null && $this->get_link() !== null)
+ {
+ $return .= $site_url . rawurlencode($this->get_link());
+ }
+ return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function subscribe_aol()
+ {
+ return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
+ }
+
+ function subscribe_bloglines()
+ {
+ return $this->subscribe_service('http://www.bloglines.com/sub/');
+ }
+
+ function subscribe_eskobo()
+ {
+ return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
+ }
+
+ function subscribe_feedfeeds()
+ {
+ return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
+ }
+
+ function subscribe_feedster()
+ {
+ return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
+ }
+
+ function subscribe_google()
+ {
+ return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
+ }
+
+ function subscribe_gritwire()
+ {
+ return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
+ }
+
+ function subscribe_msn()
+ {
+ return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
+ }
+
+ function subscribe_netvibes()
+ {
+ return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
+ }
+
+ function subscribe_newsburst()
+ {
+ return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
+ }
+
+ function subscribe_newsgator()
+ {
+ return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
+ }
+
+ function subscribe_odeo()
+ {
+ return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
+ }
+
+ function subscribe_podnova()
+ {
+ return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
+ }
+
+ function subscribe_rojo()
+ {
+ return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
+ }
+
+ function subscribe_yahoo()
+ {
+ return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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();
+ }
+ else
+ {
+ return $this->subscribe_url();
+ }
+ }
+
+ function sanitize($data, $type, $base = '')
+ {
+ return $this->sanitize->sanitize($data, $type, $base);
+ }
+
+ function get_title()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($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'], SimplePie_Misc::atom_03_construct_type($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);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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[] = new $this->category_class($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[] = new $this->category_class($term, $scheme, null);
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
+ {
+ $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
+ {
+ $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($categories))
+ {
+ return SimplePie_Misc::array_unique($categories);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_author($key = 0)
+ {
+ $authors = $this->get_authors();
+ if (isset($authors[$key]))
+ {
+ return $authors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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[] = new $this->author_class($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[] = new $this->author_class($name, $url, $email);
+ }
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
+ {
+ $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
+ {
+ $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
+ {
+ $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($authors))
+ {
+ return SimplePie_Misc::array_unique($authors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_contributor($key = 0)
+ {
+ $contributors = $this->get_contributors();
+ if (isset($contributors[$key]))
+ {
+ return $contributors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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[] = new $this->author_class($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[] = new $this->author_class($name, $url, $email);
+ }
+ }
+
+ if (!empty($contributors))
+ {
+ return SimplePie_Misc::array_unique($contributors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link($key = 0, $rel = 'alternate')
+ {
+ $links = $this->get_links($rel);
+ if (isset($links[$key]))
+ {
+ return $links[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Added for parity between the parent-level and the item/entry-level.
+ */
+ function get_permalink()
+ {
+ return $this->get_link(0);
+ }
+
+ 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 (SimplePie_Misc::is_isegment_nz_nc($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];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_all_discovered_feeds()
+ {
+ return $this->all_discovered_feeds;
+ }
+
+ function get_description()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($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'], SimplePie_Misc::atom_03_construct_type($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]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_copyright()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($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'], SimplePie_Misc::atom_03_construct_type($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);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_item_quantity($max = 0)
+ {
+ $max = (int) $max;
+ $qty = count($this->get_items());
+ if ($max === 0)
+ {
+ return $qty;
+ }
+ else
+ {
+ return ($qty > $max) ? $max : $qty;
+ }
+ }
+
+ function get_item($key = 0)
+ {
+ $items = $this->get_items();
+ if (isset($items[$key]))
+ {
+ return $items[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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);
+ }
+ else
+ {
+ $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'][] = new $this->item_class($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'][] = new $this->item_class($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'][] = new $this->item_class($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'][] = new $this->item_class($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'][] = new $this->item_class($this, $items[$key]);
+ }
+ }
+ }
+ }
+
+ if (!empty($this->data['items']))
+ {
+ // If we want to order it by date, check if all items have a date, and then sort it
+ if ($this->order_by_date && empty($this->multifeed_objects))
+ {
+ if (!isset($this->data['ordered_items']))
+ {
+ $do_sort = true;
+ foreach ($this->data['items'] as $item)
+ {
+ if (!$item->get_date('U'))
+ {
+ $do_sort = false;
+ break;
+ }
+ }
+ $item = null;
+ $this->data['ordered_items'] = $this->data['items'];
+ if ($do_sort)
+ {
+ usort($this->data['ordered_items'], array(&$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);
+ }
+ else
+ {
+ return array_slice($items, $start, $end);
+ }
+ }
+ else
+ {
+ return array();
+ }
+ }
+
+ /**
+ * @static
+ */
+ function sort_items($a, $b)
+ {
+ return $a->get_date('U') <= $b->get_date('U');
+ }
+
+ /**
+ * @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 (is_a($arg, 'SimplePie'))
+ {
+ $items = array_merge($items, $arg->get_items(0, $limit));
+ }
+ else
+ {
+ trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
+ }
+ }
+
+ $do_sort = true;
+ foreach ($items as $item)
+ {
+ if (!$item->get_date('U'))
+ {
+ $do_sort = false;
+ break;
+ }
+ }
+ $item = null;
+ if ($do_sort)
+ {
+ usort($items, array('SimplePie', 'sort_items'));
+ }
+
+ if ($end === 0)
+ {
+ return array_slice($items, $start);
+ }
+ else
+ {
+ return array_slice($items, $start, $end);
+ }
+ }
+ else
+ {
+ trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
+ return array();
+ }
+ }
+}
+
+class SimplePie_Item
+{
+ var $feed;
+ var $data = array();
+
+ function SimplePie_Item($feed, $data)
+ {
+ $this->feed = $feed;
+ $this->data = $data;
+ }
+
+ function __toString()
+ {
+ return md5(serialize($this->data));
+ }
+
+ /**
+ * Remove items that link back to this before destroying this object
+ */
+ function __destruct()
+ {
+ if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
+ {
+ unset($this->feed);
+ }
+ }
+
+ function get_item_tags($namespace, $tag)
+ {
+ if (isset($this->data['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][$namespace][$tag];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_base($element = array())
+ {
+ return $this->feed->get_base($element);
+ }
+
+ function sanitize($data, $type, $base = '')
+ {
+ return $this->feed->sanitize($data, $type, $base);
+ }
+
+ function get_feed()
+ {
+ return $this->feed;
+ }
+
+ function get_id($hash = false)
+ {
+ 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 (($return = $this->get_permalink()) !== null)
+ {
+ return $return;
+ }
+ elseif (($return = $this->get_title()) !== null)
+ {
+ return $return;
+ }
+ }
+ if ($this->get_permalink() !== null || $this->get_title() !== null)
+ {
+ return md5($this->get_permalink() . $this->get_title());
+ }
+ else
+ {
+ return md5(serialize($this->data));
+ }
+ }
+
+ 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'], SimplePie_Misc::atom_10_construct_type($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'], SimplePie_Misc::atom_03_construct_type($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'];
+ }
+
+ function get_description($description_only = false)
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_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_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
+ }
+
+ elseif (!$description_only)
+ {
+ return $this->get_content(true);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_content($content_only = false)
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif (!$content_only)
+ {
+ return $this->get_description(true);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_categories()
+ {
+ $categories = array();
+
+ foreach ((array) $this->get_item_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[] = new $this->feed->category_class($term, $scheme, $label);
+ }
+ foreach ((array) $this->get_item_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[] = new $this->feed->category_class($term, $scheme, null);
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
+ {
+ $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
+ {
+ $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($categories))
+ {
+ return SimplePie_Misc::array_unique($categories);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_author($key = 0)
+ {
+ $authors = $this->get_authors();
+ if (isset($authors[$key]))
+ {
+ return $authors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_contributor($key = 0)
+ {
+ $contributors = $this->get_contributors();
+ if (isset($contributors[$key]))
+ {
+ return $contributors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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[] = new $this->feed->author_class($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[] = new $this->feed->author_class($name, $url, $email);
+ }
+ }
+
+ if (!empty($contributors))
+ {
+ return SimplePie_Misc::array_unique($contributors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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[] = new $this->feed->author_class($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[] = new $this->feed->author_class($name, $url, $email);
+ }
+ }
+ if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
+ {
+ $authors[] = new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
+ {
+ $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
+ {
+ $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
+ {
+ $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($authors))
+ {
+ return SimplePie_Misc::array_unique($authors);
+ }
+ elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
+ {
+ return $authors;
+ }
+ elseif ($authors = $this->feed->get_authors())
+ {
+ return $authors;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_copyright()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($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);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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_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'];
+ }
+ 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'];
+ }
+
+ if (!empty($this->data['date']['raw']))
+ {
+ $parser = SimplePie_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']);
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_permalink()
+ {
+ $link = $this->get_link();
+ $enclosure = $this->get_enclosure(0);
+ if ($link !== null)
+ {
+ return $link;
+ }
+ elseif ($enclosure !== null)
+ {
+ return $enclosure->get_link();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link($key = 0, $rel = 'alternate')
+ {
+ $links = $this->get_links($rel);
+ if ($links[$key] !== null)
+ {
+ return $links[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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 (SimplePie_Misc::is_isegment_nz_nc($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];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * @todo Add ability to prefer one type of content over another (in a media group).
+ */
+ function get_enclosure($key = 0, $prefer = null)
+ {
+ $enclosures = $this->get_enclosures();
+ if (isset($enclosures[$key]))
+ {
+ return $enclosures[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Grabs 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.
+ *
+ * @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 it's value is empty, we should fall back to the value from the parent (if it exists).
+ */
+ 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[] = new $this->feed->caption_class($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[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
+ }
+ }
+ if (is_array($captions_parent))
+ {
+ $captions_parent = array_values(SimplePie_Misc::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[] = new $this->feed->category_class($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[] = new $this->feed->category_class($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[] = new $this->feed->category_class($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[] = new $this->feed->category_class($term, $scheme, $label);
+ }
+ }
+ }
+ if (is_array($categories_parent))
+ {
+ $categories_parent = array_values(SimplePie_Misc::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 = new $this->feed->copyright_class($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 = new $this->feed->copyright_class($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[] = new $this->feed->credit_class($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[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
+ }
+ }
+ if (is_array($credits_parent))
+ {
+ $credits_parent = array_values(SimplePie_Misc::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(SimplePie_Misc::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(SimplePie_Misc::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[] = new $this->feed->rating_class($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[] = new $this->feed->rating_class($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[] = new $this->feed->rating_class($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[] = new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ }
+ if (is_array($ratings_parent))
+ {
+ $ratings_parent = array_values(SimplePie_Misc::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[] = new $this->feed->restriction_class($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[] = new $this->feed->restriction_class($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[] = new $this->feed->restriction_class($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[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ }
+ if (is_array($restrictions_parent))
+ {
+ $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
+ }
+
+ // 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[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
+ }
+ if (is_array($captions))
+ {
+ $captions = array_values(SimplePie_Misc::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[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
+ }
+ if (is_array($captions))
+ {
+ $captions = array_values(SimplePie_Misc::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[] = new $this->feed->category_class($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[] = new $this->feed->category_class($term, $scheme, $label);
+ }
+ }
+ if (is_array($categories) && is_array($categories_parent))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
+ }
+ elseif (is_array($categories))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique($categories));
+ }
+ elseif (is_array($categories_parent))
+ {
+ $categories = array_values(SimplePie_Misc::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 = new $this->feed->copyright_class($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 = new $this->feed->copyright_class($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[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
+ }
+ if (is_array($credits))
+ {
+ $credits = array_values(SimplePie_Misc::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[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
+ }
+ if (is_array($credits))
+ {
+ $credits = array_values(SimplePie_Misc::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(SimplePie_Misc::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(SimplePie_Misc::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(SimplePie_Misc::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(SimplePie_Misc::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[] = new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ if (is_array($ratings))
+ {
+ $ratings = array_values(SimplePie_Misc::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[] = new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ if (is_array($ratings))
+ {
+ $ratings = array_values(SimplePie_Misc::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[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ if (is_array($restrictions))
+ {
+ $restrictions = array_values(SimplePie_Misc::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[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ if (is_array($restrictions))
+ {
+ $restrictions = array_values(SimplePie_Misc::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(SimplePie_Misc::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(SimplePie_Misc::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'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
+ }
+ if (is_array($captions))
+ {
+ $captions = array_values(SimplePie_Misc::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[] = new $this->feed->category_class($term, $scheme, $label);
+ }
+ }
+ if (is_array($categories) && is_array($categories_parent))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
+ }
+ elseif (is_array($categories))
+ {
+ $categories = array_values(SimplePie_Misc::array_unique($categories));
+ }
+ elseif (is_array($categories_parent))
+ {
+ $categories = array_values(SimplePie_Misc::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 = new $this->feed->copyright_class($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[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
+ }
+ if (is_array($credits))
+ {
+ $credits = array_values(SimplePie_Misc::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(SimplePie_Misc::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(SimplePie_Misc::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);
+ }
+ 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[] = new $this->feed->rating_class($rating_scheme, $rating_value);
+ }
+ if (is_array($ratings))
+ {
+ $ratings = array_values(SimplePie_Misc::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[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
+ }
+ if (is_array($restrictions))
+ {
+ $restrictions = array_values(SimplePie_Misc::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(SimplePie_Misc::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'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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']);
+ }
+
+ // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
+ $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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);
+ }
+ }
+
+ 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'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $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(SimplePie_Misc::array_unique($this->data['enclosures']));
+ }
+ if (!empty($this->data['enclosures']))
+ {
+ return $this->data['enclosures'];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_source()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
+ {
+ return new $this->feed->source_class($this, $return[0]);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Creates the add_to_* methods' return data
+ *
+ * @access private
+ * @param string $item_url String to prefix to the item permalink
+ * @param string $title_url String to prefix to the item title
+ * (and suffix to the item permalink)
+ * @return mixed URL if feed exists, false otherwise
+ */
+ function add_to_service($item_url, $title_url = null, $summary_url = null)
+ {
+ if ($this->get_permalink() !== null)
+ {
+ $return = $item_url . rawurlencode($this->get_permalink());
+ if ($title_url !== null && $this->get_title() !== null)
+ {
+ $return .= $title_url . rawurlencode($this->get_title());
+ }
+ if ($summary_url !== null && $this->get_description() !== null)
+ {
+ $return .= $summary_url . rawurlencode($this->get_description());
+ }
+ return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function add_to_blinklist()
+ {
+ return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
+ }
+
+ function add_to_blogmarks()
+ {
+ return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
+ }
+
+ function add_to_delicious()
+ {
+ return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
+ }
+
+ function add_to_digg()
+ {
+ return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
+ }
+
+ function add_to_furl()
+ {
+ return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
+ }
+
+ function add_to_magnolia()
+ {
+ return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
+ }
+
+ function add_to_myweb20()
+ {
+ return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
+ }
+
+ function add_to_newsvine()
+ {
+ return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
+ }
+
+ function add_to_reddit()
+ {
+ return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
+ }
+
+ function add_to_segnalo()
+ {
+ return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
+ }
+
+ function add_to_simpy()
+ {
+ return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
+ }
+
+ function add_to_spurl()
+ {
+ return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
+ }
+
+ function add_to_wists()
+ {
+ return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
+ }
+
+ function search_technorati()
+ {
+ return $this->add_to_service('http://www.technorati.com/search/');
+ }
+}
+
+class SimplePie_Source
+{
+ var $item;
+ var $data = array();
+
+ function SimplePie_Source($item, $data)
+ {
+ $this->item = $item;
+ $this->data = $data;
+ }
+
+ function __toString()
+ {
+ return md5(serialize($this->data));
+ }
+
+ function get_source_tags($namespace, $tag)
+ {
+ if (isset($this->data['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][$namespace][$tag];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_base($element = array())
+ {
+ return $this->item->get_base($element);
+ }
+
+ function sanitize($data, $type, $base = '')
+ {
+ return $this->item->sanitize($data, $type, $base);
+ }
+
+ function get_item()
+ {
+ return $this->item;
+ }
+
+ function get_title()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($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'], SimplePie_Misc::atom_03_construct_type($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);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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[] = new $this->item->feed->category_class($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[] = new $this->item->feed->category_class($term, $scheme, null);
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
+ {
+ $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
+ {
+ $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($categories))
+ {
+ return SimplePie_Misc::array_unique($categories);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_author($key = 0)
+ {
+ $authors = $this->get_authors();
+ if (isset($authors[$key]))
+ {
+ return $authors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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[] = new $this->item->feed->author_class($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[] = new $this->item->feed->author_class($name, $url, $email);
+ }
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
+ {
+ $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
+ {
+ $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
+ {
+ $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
+ }
+
+ if (!empty($authors))
+ {
+ return SimplePie_Misc::array_unique($authors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_contributor($key = 0)
+ {
+ $contributors = $this->get_contributors();
+ if (isset($contributors[$key]))
+ {
+ return $contributors[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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[] = new $this->item->feed->author_class($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[] = new $this->item->feed->author_class($name, $url, $email);
+ }
+ }
+
+ if (!empty($contributors))
+ {
+ return SimplePie_Misc::array_unique($contributors);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link($key = 0, $rel = 'alternate')
+ {
+ $links = $this->get_links($rel);
+ if (isset($links[$key]))
+ {
+ return $links[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Added for parity between the parent-level and the item/entry-level.
+ */
+ function get_permalink()
+ {
+ return $this->get_link(0);
+ }
+
+ 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 (SimplePie_Misc::is_isegment_nz_nc($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];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_description()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($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'], SimplePie_Misc::atom_03_construct_type($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]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_copyright()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($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'], SimplePie_Misc::atom_03_construct_type($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);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ 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]));
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Author
+{
+ var $name;
+ var $link;
+ var $email;
+
+ // Constructor, used to input the data
+ function SimplePie_Author($name = null, $link = null, $email = null)
+ {
+ $this->name = $name;
+ $this->link = $link;
+ $this->email = $email;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_name()
+ {
+ if ($this->name !== null)
+ {
+ return $this->name;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link()
+ {
+ if ($this->link !== null)
+ {
+ return $this->link;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_email()
+ {
+ if ($this->email !== null)
+ {
+ return $this->email;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Category
+{
+ var $term;
+ var $scheme;
+ var $label;
+
+ // Constructor, used to input the data
+ function SimplePie_Category($term = null, $scheme = null, $label = null)
+ {
+ $this->term = $term;
+ $this->scheme = $scheme;
+ $this->label = $label;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_term()
+ {
+ if ($this->term !== null)
+ {
+ return $this->term;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_label()
+ {
+ if ($this->label !== null)
+ {
+ return $this->label;
+ }
+ else
+ {
+ return $this->get_term();
+ }
+ }
+}
+
+class SimplePie_Enclosure
+{
+ var $bitrate;
+ var $captions;
+ var $categories;
+ var $channels;
+ var $copyright;
+ var $credits;
+ var $description;
+ var $duration;
+ var $expression;
+ var $framerate;
+ var $handler;
+ var $hashes;
+ var $height;
+ var $javascript;
+ var $keywords;
+ var $lang;
+ var $length;
+ var $link;
+ var $medium;
+ var $player;
+ var $ratings;
+ var $restrictions;
+ var $samplingrate;
+ var $thumbnails;
+ var $title;
+ var $type;
+ var $width;
+
+ // Constructor, used to input the data
+ function SimplePie_Enclosure($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->javascript = $javascript;
+ $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
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_bitrate()
+ {
+ if ($this->bitrate !== null)
+ {
+ return $this->bitrate;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_caption($key = 0)
+ {
+ $captions = $this->get_captions();
+ if (isset($captions[$key]))
+ {
+ return $captions[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_captions()
+ {
+ if ($this->captions !== null)
+ {
+ return $this->captions;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_categories()
+ {
+ if ($this->categories !== null)
+ {
+ return $this->categories;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_channels()
+ {
+ if ($this->channels !== null)
+ {
+ return $this->channels;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_copyright()
+ {
+ if ($this->copyright !== null)
+ {
+ return $this->copyright;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_credit($key = 0)
+ {
+ $credits = $this->get_credits();
+ if (isset($credits[$key]))
+ {
+ return $credits[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_credits()
+ {
+ if ($this->credits !== null)
+ {
+ return $this->credits;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_description()
+ {
+ if ($this->description !== null)
+ {
+ return $this->description;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_duration($convert = false)
+ {
+ if ($this->duration !== null)
+ {
+ if ($convert)
+ {
+ $time = SimplePie_Misc::time_hms($this->duration);
+ return $time;
+ }
+ else
+ {
+ return $this->duration;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_expression()
+ {
+ if ($this->expression !== null)
+ {
+ return $this->expression;
+ }
+ else
+ {
+ return 'full';
+ }
+ }
+
+ 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;
+ }
+
+ function get_framerate()
+ {
+ if ($this->framerate !== null)
+ {
+ return $this->framerate;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_handler()
+ {
+ return $this->get_real_type(true);
+ }
+
+ function get_hash($key = 0)
+ {
+ $hashes = $this->get_hashes();
+ if (isset($hashes[$key]))
+ {
+ return $hashes[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_hashes()
+ {
+ if ($this->hashes !== null)
+ {
+ return $this->hashes;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_height()
+ {
+ if ($this->height !== null)
+ {
+ return $this->height;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_language()
+ {
+ if ($this->lang !== null)
+ {
+ return $this->lang;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_keyword($key = 0)
+ {
+ $keywords = $this->get_keywords();
+ if (isset($keywords[$key]))
+ {
+ return $keywords[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_keywords()
+ {
+ if ($this->keywords !== null)
+ {
+ return $this->keywords;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_length()
+ {
+ if ($this->length !== null)
+ {
+ return $this->length;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_link()
+ {
+ if ($this->link !== null)
+ {
+ return urldecode($this->link);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_medium()
+ {
+ if ($this->medium !== null)
+ {
+ return $this->medium;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_player()
+ {
+ if ($this->player !== null)
+ {
+ return $this->player;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_rating($key = 0)
+ {
+ $ratings = $this->get_ratings();
+ if (isset($ratings[$key]))
+ {
+ return $ratings[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_ratings()
+ {
+ if ($this->ratings !== null)
+ {
+ return $this->ratings;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_restriction($key = 0)
+ {
+ $restrictions = $this->get_restrictions();
+ if (isset($restrictions[$key]))
+ {
+ return $restrictions[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_restrictions()
+ {
+ if ($this->restrictions !== null)
+ {
+ return $this->restrictions;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_sampling_rate()
+ {
+ if ($this->samplingrate !== null)
+ {
+ return $this->samplingrate;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_size()
+ {
+ $length = $this->get_length();
+ if ($length !== null)
+ {
+ return round($length/1048576, 2);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_thumbnail($key = 0)
+ {
+ $thumbnails = $this->get_thumbnails();
+ if (isset($thumbnails[$key]))
+ {
+ return $thumbnails[$key];
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_thumbnails()
+ {
+ if ($this->thumbnails !== null)
+ {
+ return $this->thumbnails;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_title()
+ {
+ if ($this->title !== null)
+ {
+ return $this->title;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_width()
+ {
+ if ($this->width !== null)
+ {
+ return $this->width;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function native_embed($options='')
+ {
+ return $this->embed($options, true);
+ }
+
+ /**
+ * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
+ */
+ 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 = '';
+
+ // Make sure the JS library is included
+ if (!$native)
+ {
+ static $javascript_outputted = null;
+ if (!$javascript_outputted && $this->javascript)
+ {
+ $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
+ $javascript_outputted = true;
+ }
+ }
+
+ // Odeo Feed MP3's
+ if ($handler === 'odeo')
+ {
+ if ($native)
+ {
+ $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url=' . $this->get_link() . '"></embed>';
+ }
+ else
+ {
+ $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
+ }
+ }
+
+ // Flash
+ elseif ($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;
+ }
+
+ function get_real_type($find_handler = false)
+ {
+ // If it's Odeo, let's get it out of the way.
+ if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
+ {
+ return 'odeo';
+ }
+
+ // 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';
+ }
+ else
+ {
+ return null;
+ }
+ }
+ else
+ {
+ return $type;
+ }
+ }
+}
+
+class SimplePie_Caption
+{
+ var $type;
+ var $lang;
+ var $startTime;
+ var $endTime;
+ var $text;
+
+ // Constructor, used to input the data
+ function SimplePie_Caption($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;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_endtime()
+ {
+ if ($this->endTime !== null)
+ {
+ return $this->endTime;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_language()
+ {
+ if ($this->lang !== null)
+ {
+ return $this->lang;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_starttime()
+ {
+ if ($this->startTime !== null)
+ {
+ return $this->startTime;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_text()
+ {
+ if ($this->text !== null)
+ {
+ return $this->text;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Credit
+{
+ var $role;
+ var $scheme;
+ var $name;
+
+ // Constructor, used to input the data
+ function SimplePie_Credit($role = null, $scheme = null, $name = null)
+ {
+ $this->role = $role;
+ $this->scheme = $scheme;
+ $this->name = $name;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_role()
+ {
+ if ($this->role !== null)
+ {
+ return $this->role;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_name()
+ {
+ if ($this->name !== null)
+ {
+ return $this->name;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Copyright
+{
+ var $url;
+ var $label;
+
+ // Constructor, used to input the data
+ function SimplePie_Copyright($url = null, $label = null)
+ {
+ $this->url = $url;
+ $this->label = $label;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_url()
+ {
+ if ($this->url !== null)
+ {
+ return $this->url;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_attribution()
+ {
+ if ($this->label !== null)
+ {
+ return $this->label;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Rating
+{
+ var $scheme;
+ var $value;
+
+ // Constructor, used to input the data
+ function SimplePie_Rating($scheme = null, $value = null)
+ {
+ $this->scheme = $scheme;
+ $this->value = $value;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_value()
+ {
+ if ($this->value !== null)
+ {
+ return $this->value;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+class SimplePie_Restriction
+{
+ var $relationship;
+ var $type;
+ var $value;
+
+ // Constructor, used to input the data
+ function SimplePie_Restriction($relationship = null, $type = null, $value = null)
+ {
+ $this->relationship = $relationship;
+ $this->type = $type;
+ $this->value = $value;
+ }
+
+ function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ function get_relationship()
+ {
+ if ($this->relationship !== null)
+ {
+ return $this->relationship;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ function get_value()
+ {
+ if ($this->value !== null)
+ {
+ return $this->value;
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
+
+/**
+ * @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;
+
+ function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
+ {
+ 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'], $parsed['fragment']);
+ }
+ $this->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_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') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
+ {
+ curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
+ curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
+ }
+
+ $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
+ {
+ $info = curl_getinfo($fp);
+ curl_close($fp);
+ $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
+ $this->headers = array_pop($this->headers);
+ $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);
+ return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
+ }
+ }
+ }
+ }
+ 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.0\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);
+ return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
+ }
+ 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 = $decoder->data;
+ }
+ break;
+
+ case 'deflate':
+ if (($body = gzuncompress($this->body)) === false)
+ {
+ if (($body = gzinflate($this->body)) === false)
+ {
+ $this->error = 'Unable to decode HTTP "deflate" stream';
+ $this->success = false;
+ }
+ }
+ $this->body = $body;
+ 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 (!$this->body = file_get_contents($url))
+ {
+ $this->error = 'file_get_contents could not read the file';
+ $this->success = false;
+ }
+ }
+ }
+}
+
+/**
+ * HTTP Response Parser
+ *
+ * @package SimplePie
+ */
+class SimplePie_HTTP_Parser
+{
+ /**
+ * HTTP Version
+ *
+ * @access public
+ * @var float
+ */
+ var $http_version = 0.0;
+
+ /**
+ * Status code
+ *
+ * @access public
+ * @var int
+ */
+ var $status_code = 0;
+
+ /**
+ * Reason phrase
+ *
+ * @access public
+ * @var string
+ */
+ var $reason = '';
+
+ /**
+ * Key/value pairs of the headers
+ *
+ * @access public
+ * @var array
+ */
+ var $headers = array();
+
+ /**
+ * Body of the response
+ *
+ * @access public
+ * @var string
+ */
+ var $body = '';
+
+ /**
+ * Current state of the state machine
+ *
+ * @access private
+ * @var string
+ */
+ var $state = 'http_version';
+
+ /**
+ * 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;
+
+ /**
+ * Name of the hedaer currently being parsed
+ *
+ * @access private
+ * @var string
+ */
+ var $name = '';
+
+ /**
+ * Value of the hedaer currently being parsed
+ *
+ * @access private
+ * @var string
+ */
+ var $value = '';
+
+ /**
+ * Create an instance of the class with the input data
+ *
+ * @access public
+ * @param string $data Input data
+ */
+ function SimplePie_HTTP_Parser($data)
+ {
+ $this->data = $data;
+ $this->data_length = strlen($this->data);
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @access public
+ * @return bool true on success, false on failure
+ */
+ 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;
+ }
+ else
+ {
+ $this->http_version = '';
+ $this->status_code = '';
+ $this->reason = '';
+ $this->headers = array();
+ $this->body = '';
+ return false;
+ }
+ }
+
+ /**
+ * Check whether there is data beyond the pointer
+ *
+ * @access private
+ * @return bool true if there is further data, false if not
+ */
+ function has_data()
+ {
+ return (bool) ($this->position < $this->data_length);
+ }
+
+ /**
+ * See if the next character is LWS
+ *
+ * @access private
+ * @return bool true if the next character is LWS, false if not
+ */
+ 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
+ *
+ * @access private
+ */
+ 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
+ *
+ * @access private
+ */
+ 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
+ *
+ * @access private
+ */
+ 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
+ *
+ * @access private
+ */
+ function new_line()
+ {
+ $this->value = trim($this->value, "\x0D\x20");
+ if ($this->name !== '' && $this->value !== '')
+ {
+ $this->name = strtolower($this->name);
+ if (isset($this->headers[$this->name]))
+ {
+ $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
+ *
+ * @access private
+ */
+ 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
+ *
+ * @access private
+ */
+ 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
+ *
+ * @access private
+ */
+ function value()
+ {
+ if ($this->is_linear_whitespace())
+ {
+ $this->linear_whitespace();
+ }
+ else
+ {
+ switch ($this->data[$this->position])
+ {
+ case '"':
+ $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
+ *
+ * @access private
+ */
+ 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
+ *
+ * @access private
+ */
+ 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
+ *
+ * @access private
+ */
+ 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
+ *
+ * @access private
+ */
+ function quote_escaped()
+ {
+ $this->value .= $this->data[$this->position];
+ $this->position++;
+ $this->state = 'quote';
+ }
+
+ /**
+ * Parse the body
+ *
+ * @access private
+ */
+ function body()
+ {
+ $this->body = substr($this->data, $this->position);
+ $this->state = 'emit';
+ }
+}
+
+/**
+ * gzdecode
+ *
+ * @package SimplePie
+ */
+class SimplePie_gzdecode
+{
+ /**
+ * Compressed data
+ *
+ * @access private
+ * @see gzdecode::$data
+ */
+ var $compressed_data;
+
+ /**
+ * Size of compressed data
+ *
+ * @access private
+ */
+ var $compressed_size;
+
+ /**
+ * Minimum size of a valid gzip string
+ *
+ * @access private
+ */
+ var $min_compressed_size = 18;
+
+ /**
+ * Current position of pointer
+ *
+ * @access private
+ */
+ var $position = 0;
+
+ /**
+ * Flags (FLG)
+ *
+ * @access private
+ */
+ var $flags;
+
+ /**
+ * Uncompressed data
+ *
+ * @access public
+ * @see gzdecode::$compressed_data
+ */
+ var $data;
+
+ /**
+ * Modified time
+ *
+ * @access public
+ */
+ var $MTIME;
+
+ /**
+ * Extra Flags
+ *
+ * @access public
+ */
+ var $XFL;
+
+ /**
+ * Operating System
+ *
+ * @access public
+ */
+ var $OS;
+
+ /**
+ * Subfield ID 1
+ *
+ * @access public
+ * @see gzdecode::$extra_field
+ * @see gzdecode::$SI2
+ */
+ var $SI1;
+
+ /**
+ * Subfield ID 2
+ *
+ * @access public
+ * @see gzdecode::$extra_field
+ * @see gzdecode::$SI1
+ */
+ var $SI2;
+
+ /**
+ * Extra field content
+ *
+ * @access public
+ * @see gzdecode::$SI1
+ * @see gzdecode::$SI2
+ */
+ var $extra_field;
+
+ /**
+ * Original filename
+ *
+ * @access public
+ */
+ var $filename;
+
+ /**
+ * Human readable comment
+ *
+ * @access public
+ */
+ var $comment;
+
+ /**
+ * Don't allow anything to be set
+ *
+ * @access public
+ */
+ function __set($name, $value)
+ {
+ trigger_error("Cannot write property $name", E_USER_ERROR);
+ }
+
+ /**
+ * Set the compressed string and related properties
+ *
+ * @access public
+ */
+ function SimplePie_gzdecode($data)
+ {
+ $this->compressed_data = $data;
+ $this->compressed_size = strlen($data);
+ }
+
+ /**
+ * Decode the GZIP stream
+ *
+ * @access 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;
+ }
+ else
+ {
+ $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;
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
+
+class SimplePie_Cache
+{
+ /**
+ * Don't call the constructor. Please.
+ *
+ * @access private
+ */
+ function SimplePie_Cache()
+ {
+ trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
+ }
+
+ /**
+ * Create a new SimplePie_Cache object
+ *
+ * @static
+ * @access public
+ */
+ function create($location, $filename, $extension)
+ {
+ $location_iri = new SimplePie_IRI($location);
+ switch ($location_iri->get_scheme())
+ {
+ case 'mysql':
+ if (extension_loaded('mysql'))
+ {
+ return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
+ }
+ break;
+
+ default:
+ return new SimplePie_Cache_File($location, $filename, $extension);
+ }
+ }
+}
+
+class SimplePie_Cache_File
+{
+ var $location;
+ var $filename;
+ var $extension;
+ var $name;
+
+ function SimplePie_Cache_File($location, $filename, $extension)
+ {
+ $this->location = $location;
+ $this->filename = $filename;
+ $this->extension = $extension;
+ $this->name = "$this->location/$this->filename.$this->extension";
+ }
+
+ function save($data)
+ {
+ if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
+ {
+ if (is_a($data, 'SimplePie'))
+ {
+ $data = $data->data;
+ }
+
+ $data = serialize($data);
+
+ if (function_exists('file_put_contents'))
+ {
+ return (bool) file_put_contents($this->name, $data);
+ }
+ else
+ {
+ $fp = fopen($this->name, 'wb');
+ if ($fp)
+ {
+ fwrite($fp, $data);
+ fclose($fp);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ function load()
+ {
+ if (file_exists($this->name) && is_readable($this->name))
+ {
+ return unserialize(file_get_contents($this->name));
+ }
+ return false;
+ }
+
+ function mtime()
+ {
+ if (file_exists($this->name))
+ {
+ return filemtime($this->name);
+ }
+ return false;
+ }
+
+ function touch()
+ {
+ if (file_exists($this->name))
+ {
+ return touch($this->name);
+ }
+ return false;
+ }
+
+ function unlink()
+ {
+ if (file_exists($this->name))
+ {
+ return unlink($this->name);
+ }
+ return false;
+ }
+}
+
+class SimplePie_Cache_DB
+{
+ 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);
+ }
+}
+
+class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
+{
+ var $mysql;
+ var $options;
+ var $id;
+
+ function SimplePie_Cache_MySQL($mysql_location, $name, $extension)
+ {
+ $host = $mysql_location->get_host();
+ if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
+ {
+ $server = ':' . substr($host, 5, -1);
+ }
+ else
+ {
+ $server = $host;
+ if ($mysql_location->get_port() !== null)
+ {
+ $server .= ':' . $mysql_location->get_port();
+ }
+ }
+
+ if (strpos($mysql_location->get_userinfo(), ':') !== false)
+ {
+ list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
+ }
+ else
+ {
+ $username = $mysql_location->get_userinfo();
+ $password = null;
+ }
+
+ if ($this->mysql = mysql_connect($server, $username, $password))
+ {
+ $this->id = $name . $extension;
+ $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());
+ if (!isset($this->options['prefix'][0]))
+ {
+ $this->options['prefix'][0] = '';
+ }
+
+ if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
+ && mysql_query('SET NAMES utf8')
+ && ($query = mysql_unbuffered_query('SHOW TABLES')))
+ {
+ $db = array();
+ while ($row = mysql_fetch_row($query))
+ {
+ $db[] = $row[0];
+ }
+
+ if (!in_array($this->options['prefix'][0] . 'cache_data', $db))
+ {
+ if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . '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)))'))
+ {
+ $this->mysql = null;
+ }
+ }
+
+ if (!in_array($this->options['prefix'][0] . 'items', $db))
+ {
+ if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'))
+ {
+ $this->mysql = null;
+ }
+ }
+ }
+ else
+ {
+ $this->mysql = null;
+ }
+ }
+ }
+
+ function save($data)
+ {
+ if ($this->mysql)
+ {
+ $feed_id = "'" . mysql_real_escape_string($this->id) . "'";
+
+ if (is_a($data, 'SimplePie'))
+ {
+ if (SIMPLEPIE_PHP5)
+ {
+ // This keyword needs to defy coding standards for PHP4 compatibility
+ $data = clone($data);
+ }
+
+ $prepared = $this->prepare_simplepie_object_for_cache($data);
+
+ if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
+ {
+ if (mysql_num_rows($query))
+ {
+ $items = count($prepared[1]);
+ if ($items)
+ {
+ $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
+ }
+ else
+ {
+ $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
+ }
+
+ if (!mysql_query($sql, $this->mysql))
+ {
+ return false;
+ }
+ }
+ elseif (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql))
+ {
+ return false;
+ }
+
+ $ids = array_keys($prepared[1]);
+ if (!empty($ids))
+ {
+ foreach ($ids as $id)
+ {
+ $database_ids[] = mysql_real_escape_string($id);
+ }
+
+ if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql))
+ {
+ $existing_ids = array();
+ while ($row = mysql_fetch_row($query))
+ {
+ $existing_ids[] = $row[0];
+ }
+
+ $new_ids = array_diff($ids, $existing_ids);
+
+ foreach ($new_ids as $new_id)
+ {
+ if (!($date = $prepared[1][$new_id]->get_date('U')))
+ {
+ $date = time();
+ }
+
+ if (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data)) . '\', ' . $date . ')', $this->mysql))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+ }
+ elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
+ {
+ if (mysql_num_rows($query))
+ {
+ if (mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql))
+ {
+ return true;
+ }
+ }
+ elseif (mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ function load()
+ {
+ if ($this->mysql && ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
+ {
+ $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['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';
+ if ($items > 0)
+ {
+ $sql .= ' LIMIT ' . $items;
+ }
+
+ if ($query = mysql_unbuffered_query($sql, $this->mysql))
+ {
+ while ($row = mysql_fetch_row($query))
+ {
+ $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ return $data;
+ }
+ return false;
+ }
+
+ function mtime()
+ {
+ if ($this->mysql && ($query = mysql_query('SELECT `mtime` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
+ {
+ return $row[0];
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function touch()
+ {
+ if ($this->mysql && ($query = mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && mysql_affected_rows($this->mysql))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function unlink()
+ {
+ if ($this->mysql && ($query = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($query2 = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
+
+class SimplePie_Misc
+{
+ 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;
+ }
+
+ function absolutize_url($relative, $base)
+ {
+ $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
+ return $iri->get_iri();
+ }
+
+ 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_replace($input, '/', 0, 3);
+ }
+ 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_replace($input, '/', 0, 4);
+ $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;
+ }
+
+ 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]), 'UTF-8');
+ }
+ }
+ }
+ }
+ return $return;
+ }
+
+ function element_implode($element)
+ {
+ $full = "<$element[tag]";
+ foreach ($element['attribs'] as $key => $value)
+ {
+ $key = strtolower($key);
+ $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
+ }
+ if ($element['self_closing'])
+ {
+ $full .= ' />';
+ }
+ else
+ {
+ $full .= ">$element[content]</$element[tag]>";
+ }
+ return $full;
+ }
+
+ 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;
+ }
+
+ /**
+ * If a file has been cached, retrieve and display it.
+ *
+ * This is most useful for caching images (get_favicon(), etc.),
+ * however it works for all cached files. This WILL NOT display ANY
+ * file/image/page/whatever, but rather only display what has already
+ * been cached by SimplePie.
+ *
+ * @access public
+ * @see SimplePie::get_favicon()
+ * @param str $identifier_url URL that is used to identify the content.
+ * This may or may not be the actual URL of the live content.
+ * @param str $cache_location Location of SimplePie's cache. Defaults
+ * to './cache'.
+ * @param str $cache_extension The file extension that the file was
+ * cached with. Defaults to 'spc'.
+ * @param str $cache_class Name of the cache-handling class being used
+ * in SimplePie. Defaults to 'SimplePie_Cache', and should be left
+ * as-is unless you've overloaded the class.
+ * @param str $cache_name_function Obsolete. Exists for backwards
+ * compatibility reasons only.
+ */
+ function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
+ {
+ $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
+
+ if ($file = $cache->load())
+ {
+ if (isset($file['headers']['content-type']))
+ {
+ header('Content-type:' . $file['headers']['content-type']);
+ }
+ else
+ {
+ header('Content-type: application/octet-stream');
+ }
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
+ echo $file['body'];
+ exit;
+ }
+
+ die('Cached file for ' . $identifier_url . ' cannot be found.');
+ }
+
+ 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);
+ }
+ else
+ {
+ return $url;
+ }
+ }
+
+ function parse_url($url)
+ {
+ $iri = new SimplePie_IRI($url);
+ return array(
+ 'scheme' => (string) $iri->get_scheme(),
+ 'authority' => (string) $iri->get_authority(),
+ 'path' => (string) $iri->get_path(),
+ 'query' => (string) $iri->get_query(),
+ 'fragment' => (string) $iri->get_fragment()
+ );
+ }
+
+ function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
+ {
+ $iri = new SimplePie_IRI('');
+ $iri->set_scheme($scheme);
+ $iri->set_authority($authority);
+ $iri->set_path($path);
+ $iri->set_query($query);
+ $iri->set_fragment($fragment);
+ return $iri->get_iri();
+ }
+
+ function normalize_url($url)
+ {
+ $iri = new SimplePie_IRI($url);
+ return $iri->get_iri();
+ }
+
+ 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);
+ }
+ else
+ {
+ return strtoupper($match[0]);
+ }
+ }
+
+ /**
+ * Remove bad UTF-8 bytes
+ *
+ * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
+ * FAQ: Multilingual Forms (modified to include full ASCII range)
+ *
+ * @author Geoffrey Sneddon
+ * @see http://www.w3.org/International/questions/qa-forms-utf-8
+ * @param string $str String to remove bad UTF-8 bytes from
+ * @return string UTF-8 string
+ */
+ function utf8_bad_replace($str)
+ {
+ if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
+ {
+ return $return;
+ }
+ elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
+ {
+ return $return;
+ }
+ elseif (preg_match_all('/(?:[\x00-\x7F]|[\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})+/', $str, $matches))
+ {
+ return implode("\xEF\xBF\xBD", $matches[0]);
+ }
+ elseif ($str !== '')
+ {
+ return "\xEF\xBF\xBD";
+ }
+ else
+ {
+ return '';
+ }
+ }
+
+ /**
+ * Converts a Windows-1252 encoded string to a UTF-8 encoded string
+ *
+ * @static
+ * @access public
+ * @param string $string Windows-1252 encoded string
+ * @return string UTF-8 encoded string
+ */
+ 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);
+ }
+
+ 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') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && in_array($input, mb_list_encodings()) && ($return = @mb_convert_encoding($data, $output, $input)))
+ {
+ return $return;
+ }
+ // This is last, as behaviour of this varies with OS userland and PHP version
+ elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
+ {
+ return $return;
+ }
+ // If we can't do anything, just fail
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * 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
+ */
+ 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;
+ }
+ }
+
+ 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;
+ }
+
+ function is_subclass_of($class1, $class2)
+ {
+ if (func_num_args() !== 2)
+ {
+ trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
+ }
+ elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
+ {
+ return is_subclass_of($class1, $class2);
+ }
+ elseif (is_string($class1) && is_string($class2))
+ {
+ if (class_exists($class1))
+ {
+ if (class_exists($class2))
+ {
+ $class2 = strtolower($class2);
+ while ($class1 = strtolower(get_parent_class($class1)))
+ {
+ if ($class1 === $class2)
+ {
+ return true;
+ }
+ }
+ }
+ }
+ else
+ {
+ trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Strip HTML comments
+ *
+ * @access public
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ 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;
+ }
+
+ function parse_date($dt)
+ {
+ $parser = SimplePie_Parse_Date::get();
+ return $parser->parse($dt);
+ }
+
+ /**
+ * Decode HTML entities
+ *
+ * @static
+ * @access public
+ * @param string $data Input data
+ * @return string Output data
+ */
+ function entities_decode($data)
+ {
+ $decoder = new SimplePie_Decode_HTML_Entities($data);
+ return $decoder->parse();
+ }
+
+ /**
+ * Remove RFC822 comments
+ *
+ * @access public
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ 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;
+ }
+
+ function parse_mime($mime)
+ {
+ if (($pos = strpos($mime, ';')) === false)
+ {
+ return trim($mime);
+ }
+ else
+ {
+ return trim(substr($mime, 0, $pos));
+ }
+ }
+
+ function htmlspecialchars_decode($string, $quote_style)
+ {
+ if (function_exists('htmlspecialchars_decode'))
+ {
+ return htmlspecialchars_decode($string, $quote_style);
+ }
+ else
+ {
+ return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
+ }
+ }
+
+ 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;
+ }
+ }
+ else
+ {
+ return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
+ }
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+ }
+ else
+ {
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+ }
+ }
+
+ 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);
+ }
+
+ function space_seperated_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;
+ }
+
+ function array_unique($array)
+ {
+ if (version_compare(PHP_VERSION, '5.2', '>='))
+ {
+ return array_unique($array);
+ }
+ else
+ {
+ $array = (array) $array;
+ $new_array = array();
+ $new_array_strings = array();
+ foreach ($array as $key => $value)
+ {
+ if (is_object($value))
+ {
+ if (method_exists($value, '__toString'))
+ {
+ $cmp = $value->__toString();
+ }
+ else
+ {
+ trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
+ }
+ }
+ elseif (is_array($value))
+ {
+ $cmp = (string) reset($value);
+ }
+ else
+ {
+ $cmp = (string) $value;
+ }
+ if (!in_array($cmp, $new_array_strings))
+ {
+ $new_array[$key] = $value;
+ $new_array_strings[] = $cmp;
+ }
+ }
+ return $new_array;
+ }
+ }
+
+ /**
+ * Converts a unicode codepoint to a UTF-8 character
+ *
+ * @static
+ * @access public
+ * @param int $codepoint Unicode codepoint
+ * @return string UTF-8 character
+ */
+ 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));
+ }
+ else
+ {
+ // U+FFFD REPLACEMENT CHARACTER
+ return "\xEF\xBF\xBD";
+ }
+ }
+
+ /**
+ * Re-implementation of PHP 5's stripos()
+ *
+ * Returns the numeric position of the first occurrence of needle in the
+ * haystack string.
+ *
+ * @static
+ * @access string
+ * @param object $haystack
+ * @param string $needle Note that the needle may be a string of one or more
+ * characters. If needle is not a string, it is converted to an integer
+ * and applied as the ordinal value of a character.
+ * @param int $offset The optional offset parameter allows you to specify which
+ * character in haystack to start searching. The position returned is still
+ * relative to the beginning of haystack.
+ * @return bool If needle is not found, stripos() will return boolean false.
+ */
+ function stripos($haystack, $needle, $offset = 0)
+ {
+ if (function_exists('stripos'))
+ {
+ return stripos($haystack, $needle, $offset);
+ }
+ else
+ {
+ if (is_string($needle))
+ {
+ $needle = strtolower($needle);
+ }
+ elseif (is_int($needle) || is_bool($needle) || is_double($needle))
+ {
+ $needle = strtolower(chr($needle));
+ }
+ else
+ {
+ trigger_error('needle is not a string or an integer', E_USER_WARNING);
+ return false;
+ }
+
+ return strpos(strtolower($haystack), $needle, $offset);
+ }
+ }
+
+ /**
+ * 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
+ * @access string
+ * @param string $str The input string.
+ * @return array
+ */
+ 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
+ * @return array Possible encodings
+ */
+ function xml_encoding($data)
+ {
+ // 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 = new SimplePie_XML_Declaration_Parser(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 = new SimplePie_XML_Declaration_Parser(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 = new SimplePie_XML_Declaration_Parser(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 = new SimplePie_XML_Declaration_Parser(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 = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-8';
+ }
+ // Fallback to UTF-8
+ else
+ {
+ $encoding[] = 'UTF-8';
+ }
+ return $encoding;
+ }
+
+ 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_odeo(link) {
+ document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');
+}
+
+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
+ }
+
+
+
+ /**
+ * Format debugging information
+ */
+ 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;
+ }
+}
+
+/**
+ * Decode HTML Entities
+ *
+ * This implements HTML5 as of revision 967 (2007-06-28)
+ *
+ * @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
+ */
+ function SimplePie_Decode_HTML_Entities($data)
+ {
+ $this->data = $data;
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @access public
+ * @return string Output data
+ */
+ 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
+ */
+ function consume()
+ {
+ if (isset($this->data[$this->position]))
+ {
+ $this->consumed .= $this->data[$this->position];
+ return $this->data[$this->position++];
+ }
+ else
+ {
+ 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
+ */
+ 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;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Unconsume one byte
+ *
+ * @access private
+ */
+ function unconsume()
+ {
+ $this->consumed = substr($this->consumed, 0, -1);
+ $this->position--;
+ }
+
+ /**
+ * Decode an entity
+ *
+ * @access private
+ */
+ function entity()
+ {
+ switch ($this->consume())
+ {
+ case "\x09":
+ case "\x0A":
+ case "\x0B":
+ 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;
+ }
+ }
+}
+
+/**
+ * IRI parser/serialiser
+ *
+ * @package SimplePie
+ */
+class SimplePie_IRI
+{
+ /**
+ * Scheme
+ *
+ * @access private
+ * @var string
+ */
+ var $scheme;
+
+ /**
+ * User Information
+ *
+ * @access private
+ * @var string
+ */
+ var $userinfo;
+
+ /**
+ * Host
+ *
+ * @access private
+ * @var string
+ */
+ var $host;
+
+ /**
+ * Port
+ *
+ * @access private
+ * @var string
+ */
+ var $port;
+
+ /**
+ * Path
+ *
+ * @access private
+ * @var string
+ */
+ var $path;
+
+ /**
+ * Query
+ *
+ * @access private
+ * @var string
+ */
+ var $query;
+
+ /**
+ * Fragment
+ *
+ * @access private
+ * @var string
+ */
+ var $fragment;
+
+ /**
+ * Whether the object represents a valid IRI
+ *
+ * @access private
+ * @var array
+ */
+ var $valid = array();
+
+ /**
+ * Return the entire IRI when you try and read the object as a string
+ *
+ * @access public
+ * @return string
+ */
+ function __toString()
+ {
+ return $this->get_iri();
+ }
+
+ /**
+ * Create a new IRI object, from a specified string
+ *
+ * @access public
+ * @param string $iri
+ * @return SimplePie_IRI
+ */
+ function SimplePie_IRI($iri)
+ {
+ $iri = (string) $iri;
+ if ($iri !== '')
+ {
+ $parsed = $this->parse_iri($iri);
+ $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']);
+ }
+ }
+
+ /**
+ * Create a new IRI object by resolving a relative IRI
+ *
+ * @static
+ * @access public
+ * @param SimplePie_IRI $base Base IRI
+ * @param string $relative Relative IRI
+ * @return SimplePie_IRI
+ */
+ function absolutize($base, $relative)
+ {
+ $relative = (string) $relative;
+ if ($relative !== '')
+ {
+ $relative = new SimplePie_IRI($relative);
+ if ($relative->get_scheme() !== null)
+ {
+ $target = $relative;
+ }
+ elseif ($base->get_iri() !== null)
+ {
+ if ($relative->get_authority() !== null)
+ {
+ $target = $relative;
+ $target->set_scheme($base->get_scheme());
+ }
+ else
+ {
+ $target = new SimplePie_IRI('');
+ $target->set_scheme($base->get_scheme());
+ $target->set_userinfo($base->get_userinfo());
+ $target->set_host($base->get_host());
+ $target->set_port($base->get_port());
+ if ($relative->get_path() !== null)
+ {
+ if (strpos($relative->get_path(), '/') === 0)
+ {
+ $target->set_path($relative->get_path());
+ }
+ elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
+ {
+ $target->set_path('/' . $relative->get_path());
+ }
+ elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
+ {
+ $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
+ }
+ else
+ {
+ $target->set_path($relative->get_path());
+ }
+ $target->set_query($relative->get_query());
+ }
+ else
+ {
+ $target->set_path($base->get_path());
+ if ($relative->get_query() !== null)
+ {
+ $target->set_query($relative->get_query());
+ }
+ elseif ($base->get_query() !== null)
+ {
+ $target->set_query($base->get_query());
+ }
+ }
+ }
+ $target->set_fragment($relative->get_fragment());
+ }
+ else
+ {
+ // No base URL, just return the relative URL
+ $target = $relative;
+ }
+ }
+ else
+ {
+ $target = $base;
+ }
+ return $target;
+ }
+
+ /**
+ * Parse an IRI into scheme/authority/path/query/fragment segments
+ *
+ * @access private
+ * @param string $iri
+ * @return array
+ */
+ function parse_iri($iri)
+ {
+ preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
+ for ($i = count($match); $i <= 9; $i++)
+ {
+ $match[$i] = '';
+ }
+ return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
+ }
+
+ /**
+ * Remove dot segments from a path
+ *
+ * @access private
+ * @param string $input
+ * @return string
+ */
+ 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_replace($input, '/', 0, 3);
+ }
+ 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_replace($input, '/', 0, 4);
+ $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 $valid_chars Valid characters
+ * @param int $case Normalise case
+ * @return string
+ */
+ function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE, $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 $valid_chars (the latter is safe because all
+ // pct-encoded sections are now valid).
+ $valid_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
+
+ // Now replace any bytes that aren't allowed with their pct-encoded versions
+ $position = 0;
+ $strlen = strlen($string);
+ while (($position += strspn($string, $valid_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;
+ }
+ }
+ }
+
+ // Normalise case
+ if ($case & SIMPLEPIE_LOWERCASE)
+ {
+ $string = strtolower($string);
+ }
+ elseif ($case & SIMPLEPIE_UPPERCASE)
+ {
+ $string = strtoupper($string);
+ }
+
+ return $string;
+ }
+
+ /**
+ * Callback function for preg_replace_callback.
+ *
+ * Removes sequences of percent encoded bytes that represent UTF-8
+ * encoded characters in iunreserved
+ *
+ * @access private
+ * @param array $match PCRE match
+ * @return string Replacement
+ */
+ 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;
+ }
+
+ /**
+ * Check if the object represents a valid IRI
+ *
+ * @access public
+ * @return bool
+ */
+ function is_valid()
+ {
+ return array_sum($this->valid) === count($this->valid);
+ }
+
+ /**
+ * Set the scheme. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @access public
+ * @param string $scheme
+ * @return bool
+ */
+ function set_scheme($scheme)
+ {
+ if ($scheme === null || $scheme === '')
+ {
+ $this->scheme = null;
+ }
+ else
+ {
+ $len = strlen($scheme);
+ switch (true)
+ {
+ case $len > 1:
+ if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
+ {
+ $this->scheme = null;
+ $this->valid[__FUNCTION__] = false;
+ return false;
+ }
+
+ case $len > 0:
+ if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
+ {
+ $this->scheme = null;
+ $this->valid[__FUNCTION__] = false;
+ return false;
+ }
+ }
+ $this->scheme = strtolower($scheme);
+ }
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+
+ /**
+ * Set the authority. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @access public
+ * @param string $authority
+ * @return bool
+ */
+ function set_authority($authority)
+ {
+ if (($userinfo_end = strrpos($authority, '@')) !== false)
+ {
+ $userinfo = substr($authority, 0, $userinfo_end);
+ $authority = substr($authority, $userinfo_end + 1);
+ }
+ else
+ {
+ $userinfo = null;
+ }
+
+ if (($port_start = strpos($authority, ':')) !== false)
+ {
+ $port = substr($authority, $port_start + 1);
+ $authority = substr($authority, 0, $port_start);
+ }
+ else
+ {
+ $port = null;
+ }
+
+ return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
+ }
+
+ /**
+ * Set the userinfo.
+ *
+ * @access public
+ * @param string $userinfo
+ * @return bool
+ */
+ function set_userinfo($userinfo)
+ {
+ if ($userinfo === null || $userinfo === '')
+ {
+ $this->userinfo = null;
+ }
+ else
+ {
+ $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
+ }
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+
+ /**
+ * Set the host. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @access public
+ * @param string $host
+ * @return bool
+ */
+ function set_host($host)
+ {
+ if ($host === null || $host === '')
+ {
+ $this->host = null;
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+ elseif ($host[0] === '[' && substr($host, -1) === ']')
+ {
+ if (Net_IPv6::checkIPv6(substr($host, 1, -1)))
+ {
+ $this->host = $host;
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+ else
+ {
+ $this->host = null;
+ $this->valid[__FUNCTION__] = false;
+ return false;
+ }
+ }
+ else
+ {
+ $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+ }
+
+ /**
+ * Set the port. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @access public
+ * @param string $port
+ * @return bool
+ */
+ function set_port($port)
+ {
+ if ($port === null || $port === '')
+ {
+ $this->port = null;
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+ elseif (strspn($port, '0123456789') === strlen($port))
+ {
+ $this->port = (int) $port;
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+ else
+ {
+ $this->port = null;
+ $this->valid[__FUNCTION__] = false;
+ return false;
+ }
+ }
+
+ /**
+ * Set the path.
+ *
+ * @access public
+ * @param string $path
+ * @return bool
+ */
+ function set_path($path)
+ {
+ if ($path === null || $path === '')
+ {
+ $this->path = null;
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+ elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
+ {
+ $this->path = null;
+ $this->valid[__FUNCTION__] = false;
+ return false;
+ }
+ else
+ {
+ $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
+ if ($this->scheme !== null)
+ {
+ $this->path = $this->remove_dot_segments($this->path);
+ }
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+ }
+
+ /**
+ * Set the query.
+ *
+ * @access public
+ * @param string $query
+ * @return bool
+ */
+ function set_query($query)
+ {
+ if ($query === null || $query === '')
+ {
+ $this->query = null;
+ }
+ else
+ {
+ $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?&=');
+ }
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+
+ /**
+ * Set the fragment.
+ *
+ * @access public
+ * @param string $fragment
+ * @return bool
+ */
+ function set_fragment($fragment)
+ {
+ if ($fragment === null || $fragment === '')
+ {
+ $this->fragment = null;
+ }
+ else
+ {
+ $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
+ }
+ $this->valid[__FUNCTION__] = true;
+ return true;
+ }
+
+ /**
+ * Get the complete IRI
+ *
+ * @access public
+ * @return string
+ */
+ function get_iri()
+ {
+ $iri = '';
+ if ($this->scheme !== null)
+ {
+ $iri .= $this->scheme . ':';
+ }
+ if (($authority = $this->get_authority()) !== null)
+ {
+ $iri .= '//' . $authority;
+ }
+ if ($this->path !== null)
+ {
+ $iri .= $this->path;
+ }
+ if ($this->query !== null)
+ {
+ $iri .= '?' . $this->query;
+ }
+ if ($this->fragment !== null)
+ {
+ $iri .= '#' . $this->fragment;
+ }
+
+ if ($iri !== '')
+ {
+ return $iri;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Get the scheme
+ *
+ * @access public
+ * @return string
+ */
+ function get_scheme()
+ {
+ return $this->scheme;
+ }
+
+ /**
+ * Get the complete authority
+ *
+ * @access public
+ * @return string
+ */
+ function get_authority()
+ {
+ $authority = '';
+ if ($this->userinfo !== null)
+ {
+ $authority .= $this->userinfo . '@';
+ }
+ if ($this->host !== null)
+ {
+ $authority .= $this->host;
+ }
+ if ($this->port !== null)
+ {
+ $authority .= ':' . $this->port;
+ }
+
+ if ($authority !== '')
+ {
+ return $authority;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Get the user information
+ *
+ * @access public
+ * @return string
+ */
+ function get_userinfo()
+ {
+ return $this->userinfo;
+ }
+
+ /**
+ * Get the host
+ *
+ * @access public
+ * @return string
+ */
+ function get_host()
+ {
+ return $this->host;
+ }
+
+ /**
+ * Get the port
+ *
+ * @access public
+ * @return string
+ */
+ function get_port()
+ {
+ return $this->port;
+ }
+
+ /**
+ * Get the path
+ *
+ * @access public
+ * @return string
+ */
+ function get_path()
+ {
+ return $this->path;
+ }
+
+ /**
+ * Get the query
+ *
+ * @access public
+ * @return string
+ */
+ function get_query()
+ {
+ return $this->query;
+ }
+
+ /**
+ * Get the fragment
+ *
+ * @access public
+ * @return string
+ */
+ function get_fragment()
+ {
+ return $this->fragment;
+ }
+}
+
+/**
+ * Class to validate and to work with IPv6 addresses.
+ *
+ * @package SimplePie
+ * @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 Geoffrey Sneddon <geoffers@gmail.com>
+ */
+class SimplePie_Net_IPv6
+{
+ /**
+ * Removes a possible existing netmask specification of an IP address.
+ *
+ * @param string $ip the (compressed) IP as Hex representation
+ * @return string the IP the without netmask
+ * @since 1.1.0
+ * @access public
+ * @static
+ */
+ function removeNetmaskSpec($ip)
+ {
+ if (strpos($ip, '/') !== false)
+ {
+ list($addr, $nm) = explode('/', $ip);
+ }
+ else
+ {
+ $addr = $ip;
+ }
+ return $addr;
+ }
+
+ /**
+ * Uncompresses an IPv6 address
+ *
+ * RFC 2373 allows you to compress zeros in an address to '::'. This
+ * function expects an valid IPv6 address and expands the '::' to
+ * the required zeros.
+ *
+ * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
+ * ::1 -> 0:0:0:0:0:0:0:1
+ *
+ * @access public
+ * @static
+ * @param string $ip a valid IPv6-address (hex format)
+ * @return string the uncompressed IPv6-address (hex format)
+ */
+ function Uncompress($ip)
+ {
+ $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
+ $c1 = -1;
+ $c2 = -1;
+ if (strpos($ip, '::') !== false)
+ {
+ list($ip1, $ip2) = explode('::', $ip);
+ if ($ip1 === '')
+ {
+ $c1 = -1;
+ }
+ else
+ {
+ $pos = 0;
+ if (($pos = substr_count($ip1, ':')) > 0)
+ {
+ $c1 = $pos;
+ }
+ else
+ {
+ $c1 = 0;
+ }
+ }
+ if ($ip2 === '')
+ {
+ $c2 = -1;
+ }
+ else
+ {
+ $pos = 0;
+ if (($pos = substr_count($ip2, ':')) > 0)
+ {
+ $c2 = $pos;
+ }
+ else
+ {
+ $c2 = 0;
+ }
+ }
+ if (strstr($ip2, '.'))
+ {
+ $c2++;
+ }
+ // ::
+ if ($c1 === -1 && $c2 === -1)
+ {
+ $uip = '0:0:0:0:0:0:0:0';
+ }
+ // ::xxx
+ else if ($c1 === -1)
+ {
+ $fill = str_repeat('0:', 7 - $c2);
+ $uip = str_replace('::', $fill, $uip);
+ }
+ // xxx::
+ else if ($c2 === -1)
+ {
+ $fill = str_repeat(':0', 7 - $c1);
+ $uip = str_replace('::', $fill, $uip);
+ }
+ // xxx::xxx
+ else
+ {
+ $fill = str_repeat(':0:', 6 - $c2 - $c1);
+ $uip = str_replace('::', $fill, $uip);
+ $uip = str_replace('::', ':', $uip);
+ }
+ }
+ return $uip;
+ }
+
+ /**
+ * Splits an IPv6 address into the IPv6 and a possible IPv4 part
+ *
+ * RFC 2373 allows you to note the last two parts of an IPv6 address as
+ * an IPv4 compatible address
+ *
+ * Example: 0:0:0:0:0:0:13.1.68.3
+ * 0:0:0:0:0:FFFF:129.144.52.38
+ *
+ * @access public
+ * @static
+ * @param string $ip a valid IPv6-address (hex format)
+ * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
+ */
+ function SplitV64($ip)
+ {
+ $ip = SimplePie_Net_IPv6::Uncompress($ip);
+ if (strstr($ip, '.'))
+ {
+ $pos = strrpos($ip, ':');
+ $ip[$pos] = '_';
+ $ipPart = explode('_', $ip);
+ return $ipPart;
+ }
+ else
+ {
+ return array($ip, '');
+ }
+ }
+
+ /**
+ * Checks an IPv6 address
+ *
+ * Checks if the given IP is IPv6-compatible
+ *
+ * @access public
+ * @static
+ * @param string $ip a valid IPv6-address
+ * @return bool true if $ip is an IPv6 address
+ */
+ function checkIPv6($ip)
+ {
+ $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
+ $count = 0;
+ if (!empty($ipPart[0]))
+ {
+ $ipv6 = explode(':', $ipPart[0]);
+ for ($i = 0; $i < count($ipv6); $i++)
+ {
+ $dec = hexdec($ipv6[$i]);
+ $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
+ if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
+ {
+ $count++;
+ }
+ }
+ if ($count === 8)
+ {
+ return true;
+ }
+ elseif ($count === 6 && !empty($ipPart[1]))
+ {
+ $ipv4 = explode('.', $ipPart[1]);
+ $count = 0;
+ foreach ($ipv4 as $ipv4_part)
+ {
+ if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
+ {
+ $count++;
+ }
+ }
+ if ($count === 4)
+ {
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
+
+/**
+ * Date Parser
+ *
+ * @package SimplePie
+ */
+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,
+ 'dienstag' => 2,
+ 'mittwoch' => 3,
+ 'donnerstag' => 4,
+ 'freitag' => 5,
+ 'samstag' => 6,
+ 'sonnabend' => 6,
+ '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,
+ );
+
+ /**
+ * 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' => 8,
+ '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,
+ 'februar' => 2,
+ 'märz' => 3,
+ 'april' => 4,
+ 'mai' => 5,
+ 'juni' => 6,
+ 'juli' => 7,
+ 'august' => 8,
+ 'september' => 9,
+ 'oktober' => 10,
+ 'november' => 11,
+ 'dezember' => 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,
+ );
+
+ /**
+ * 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,
+ '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
+ */
+ function SimplePie_Parse_Date()
+ {
+ $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
+ */
+ 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
+ */
+ 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
+ */
+ 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 seperator (including more than one))
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ 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($match[6] + $match[7] / pow(10, strlen($match[7])));
+
+ return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Remove RFC822 comments
+ *
+ * @access protected
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ 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 ($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
+ */
+ 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;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Parse RFC850's date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ 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;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Parse C99's asctime()'s date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ 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]);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Parse dates using strtotime()
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ function date_strtotime($date)
+ {
+ $strtotime = strtotime($date);
+ if ($strtotime === -1 || $strtotime === false)
+ {
+ return false;
+ }
+ else
+ {
+ return $strtotime;
+ }
+ }
+}
+
+/**
+ * Content-type sniffing
+ *
+ * @package SimplePie
+ */
+class SimplePie_Content_Type_Sniffer
+{
+ /**
+ * File object
+ *
+ * @var SimplePie_File
+ * @access private
+ */
+ var $file;
+
+ /**
+ * Create an instance of the class with the input file
+ *
+ * @access public
+ * @param SimplePie_Content_Type_Sniffer $file Input file
+ */
+ function SimplePie_Content_Type_Sniffer($file)
+ {
+ $this->file = $file;
+ }
+
+ /**
+ * Get the Content-Type of the specified file
+ *
+ * @access public
+ * @return string Actual Content-Type
+ */
+ 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'))
+ {
+ 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 = 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;
+ }
+ else
+ {
+ return $official;
+ }
+ }
+ elseif ($official === 'text/html')
+ {
+ return $this->feed_or_html();
+ }
+ else
+ {
+ return $official;
+ }
+ }
+ else
+ {
+ return $this->unknown();
+ }
+ }
+
+ /**
+ * Sniff text or binary
+ *
+ * @access private
+ * @return string Actual Content-Type
+ */
+ 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';
+ }
+ else
+ {
+ return 'text/plain';
+ }
+ }
+
+ /**
+ * Sniff unknown
+ *
+ * @access private
+ * @return string Actual Content-Type
+ */
+ 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';
+ }
+ else
+ {
+ return $this->text_or_binary();
+ }
+ }
+
+ /**
+ * Sniff images
+ *
+ * @access private
+ * @return string Actual Content-Type
+ */
+ 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';
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Sniff HTML
+ *
+ * @access private
+ * @return string Actual Content-Type
+ */
+ function feed_or_html()
+ {
+ $len = strlen($this->file->body);
+ $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
+
+ 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';
+ }
+}
+
+/**
+ * Parses the XML Declaration
+ *
+ * @package SimplePie
+ */
+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
+ */
+ function SimplePie_XML_Declaration_Parser($data)
+ {
+ $this->data = $data;
+ $this->data_length = strlen($this->data);
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @access public
+ * @return bool true on success, false on failure
+ */
+ function parse()
+ {
+ while ($this->state && $this->state !== 'emit' && $this->has_data())
+ {
+ $state = $this->state;
+ $this->$state();
+ }
+ $this->data = '';
+ if ($this->state === 'emit')
+ {
+ return true;
+ }
+ else
+ {
+ $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
+ */
+ function has_data()
+ {
+ return (bool) ($this->position < $this->data_length);
+ }
+
+ /**
+ * Advance past any whitespace
+ *
+ * @return int Number of whitespace characters passed
+ */
+ function skip_whitespace()
+ {
+ $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
+ $this->position += $whitespace;
+ return $whitespace;
+ }
+
+ /**
+ * Read value
+ */
+ 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;
+ }
+
+ function before_version_name()
+ {
+ if ($this->skip_whitespace())
+ {
+ $this->state = 'version_name';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ function version_equals()
+ {
+ if (substr($this->data, $this->position, 1) === '=')
+ {
+ $this->position++;
+ $this->skip_whitespace();
+ $this->state = 'version_value';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ 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';
+ }
+ }
+
+ function encoding_equals()
+ {
+ if (substr($this->data, $this->position, 1) === '=')
+ {
+ $this->position++;
+ $this->skip_whitespace();
+ $this->state = 'encoding_value';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ function standalone_equals()
+ {
+ if (substr($this->data, $this->position, 1) === '=')
+ {
+ $this->position++;
+ $this->skip_whitespace();
+ $this->state = 'standalone_value';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ 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;
+ }
+ }
+}
+
+class SimplePie_Locator
+{
+ var $useragent;
+ var $timeout;
+ var $file;
+ var $local = array();
+ var $elsewhere = array();
+ var $file_class = 'SimplePie_File';
+ var $cached_entities = array();
+ var $http_base;
+ var $base;
+ var $base_location = 0;
+ var $checked_feeds = 0;
+ var $max_checked_feeds = 10;
+ var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
+
+ function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
+ {
+ $this->file =& $file;
+ $this->file_class = $file_class;
+ $this->useragent = $useragent;
+ $this->timeout = $timeout;
+ $this->max_checked_feeds = $max_checked_feeds;
+ $this->content_type_sniffer_class = $content_type_sniffer_class;
+ }
+
+ 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 = new $this->content_type_sniffer_class($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;
+ }
+
+ if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
+ {
+ return $working;
+ }
+
+ if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
+ {
+ return $working;
+ }
+
+ if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
+ {
+ return $working;
+ }
+ }
+ return null;
+ }
+
+ function is_feed(&$file)
+ {
+ if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
+ {
+ $sniffer = new $this->content_type_sniffer_class($file);
+ $sniffed = $sniffer->get_type();
+ if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ function get_base()
+ {
+ $this->http_base = $this->file->url;
+ $this->base = $this->http_base;
+ $elements = SimplePie_Misc::get_element('base', $this->file->body);
+ foreach ($elements as $element)
+ {
+ if ($element['attribs']['href']['data'] !== '')
+ {
+ $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
+ $this->base_location = $element['offset'];
+ break;
+ }
+ }
+ }
+
+ function autodiscovery()
+ {
+ $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body));
+ $done = array();
+ $feeds = array();
+ foreach ($links as $link)
+ {
+ if ($this->checked_feeds === $this->max_checked_feeds)
+ {
+ break;
+ }
+ if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
+ {
+ $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
+
+ if ($this->base_location < $link['offset'])
+ {
+ $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
+ }
+ else
+ {
+ $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
+ }
+
+ if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
+ {
+ $this->checked_feeds++;
+ $feed = new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
+ 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))
+ {
+ $feeds[$href] = $feed;
+ }
+ }
+ $done[] = $href;
+ }
+ }
+
+ if (!empty($feeds))
+ {
+ return array_values($feeds);
+ }
+ else {
+ return null;
+ }
+ }
+
+ function get_links()
+ {
+ $links = SimplePie_Misc::get_element('a', $this->file->body);
+ foreach ($links as $link)
+ {
+ if (isset($link['attribs']['href']['data']))
+ {
+ $href = trim($link['attribs']['href']['data']);
+ $parsed = SimplePie_Misc::parse_url($href);
+ if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
+ {
+ if ($this->base_location < $link['offset'])
+ {
+ $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
+ }
+ else
+ {
+ $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
+ }
+
+ $current = SimplePie_Misc::parse_url($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;
+ }
+
+ 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++;
+ $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
+ 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 $feed;
+ }
+ else
+ {
+ unset($array[$key]);
+ }
+ }
+ }
+ return null;
+ }
+
+ function body(&$array)
+ {
+ foreach ($array as $key => $value)
+ {
+ if ($this->checked_feeds === $this->max_checked_feeds)
+ {
+ break;
+ }
+ if (preg_match('/(rss|rdf|atom|xml)/i', $value))
+ {
+ $this->checked_feeds++;
+ $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
+ 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 $feed;
+ }
+ else
+ {
+ unset($array[$key]);
+ }
+ }
+ }
+ return null;
+ }
+}
+
+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;
+
+ function parse(&$data, $encoding)
+ {
+ // 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 = new SimplePie_XML_Declaration_Parser(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') . '"?>' . $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;
+ }
+ else
+ {
+ 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;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ }
+
+ function get_error_code()
+ {
+ return $this->error_code;
+ }
+
+ function get_error_string()
+ {
+ return $this->error_string;
+ }
+
+ function get_current_line()
+ {
+ return $this->current_line;
+ }
+
+ function get_current_column()
+ {
+ return $this->current_column;
+ }
+
+ function get_current_byte()
+ {
+ return $this->current_byte;
+ }
+
+ function get_data()
+ {
+ return $this->data;
+ }
+
+ 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']))
+ {
+ $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_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'))
+ {
+ $this->current_xhtml_construct = 0;
+ }
+ }
+ }
+
+ function cdata($parser, $cdata)
+ {
+ if ($this->current_xhtml_construct >= 0)
+ {
+ $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
+ }
+ else
+ {
+ $this->data['data'] .= $cdata;
+ }
+ }
+
+ 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);
+ }
+
+ 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;
+ }
+ $cache[$string] = array($namespace, $local_name);
+ }
+ else
+ {
+ $cache[$string] = array('', $string);
+ }
+ }
+ return $cache[$string];
+ }
+}
+
+/**
+ * @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', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
+ var $strip_comments = false;
+ var $output_encoding = 'UTF-8';
+ var $enable_cache = true;
+ var $cache_location = './cache';
+ var $cache_name_function = 'md5';
+ var $cache_class = 'SimplePie_Cache';
+ var $file_class = 'SimplePie_File';
+ var $timeout = 10;
+ var $useragent = '';
+ var $force_fsockopen = false;
+
+ var $replace_url_attributes = array(
+ 'a' => 'href',
+ 'area' => 'href',
+ 'blockquote' => 'cite',
+ 'del' => 'cite',
+ 'form' => 'action',
+ 'img' => array('longdesc', 'src'),
+ 'input' => 'src',
+ 'ins' => 'cite',
+ 'q' => 'cite'
+ );
+
+ function remove_div($enable = true)
+ {
+ $this->remove_div = (bool) $enable;
+ }
+
+ function set_image_handler($page = false)
+ {
+ if ($page)
+ {
+ $this->image_handler = (string) $page;
+ }
+ else
+ {
+ $this->image_handler = false;
+ }
+ }
+
+ 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;
+ }
+
+ if ($cache_class)
+ {
+ $this->cache_class = (string) $cache_class;
+ }
+ }
+
+ function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
+ {
+ if ($file_class)
+ {
+ $this->file_class = (string) $file_class;
+ }
+
+ if ($timeout)
+ {
+ $this->timeout = (string) $timeout;
+ }
+
+ if ($useragent)
+ {
+ $this->useragent = (string) $useragent;
+ }
+
+ if ($force_fsockopen)
+ {
+ $this->force_fsockopen = (string) $force_fsockopen;
+ }
+ }
+
+ 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;
+ }
+ }
+
+ function encode_instead_of_strip($encode = false)
+ {
+ $this->encode_instead_of_strip = (bool) $encode;
+ }
+
+ function strip_attributes($attribs = array('bgsound', 'class', '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;
+ }
+ }
+
+ function strip_comments($strip = false)
+ {
+ $this->strip_comments = (bool) $strip;
+ }
+
+ 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
+ *
+ * @access public
+ * @since 1.0
+ * @param array $element_attribute Element/attribute key/value pairs
+ */
+ function set_url_replacements($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;
+ }
+
+ 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_XHTML)
+ {
+ 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_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
+ {
+ // Strip comments
+ if ($this->strip_comments)
+ {
+ $data = SimplePie_Misc::strip_comments($data);
+ }
+
+ // 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)
+ {
+ $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
+ while (preg_match($pcre, $data))
+ {
+ $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
+ }
+ }
+ }
+
+ if ($this->strip_attributes)
+ {
+ foreach ($this->strip_attributes as $attrib)
+ {
+ $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);
+ }
+ }
+
+ // Replace relative URLs
+ $this->base = $base;
+ foreach ($this->replace_url_attributes as $element => $attributes)
+ {
+ $data = $this->replace_urls($data, $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 = SimplePie_Misc::get_element('img', $data);
+ foreach ($images as $img)
+ {
+ if (isset($img['attribs']['src']['data']))
+ {
+ $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
+ $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
+
+ if ($cache->load())
+ {
+ $img['attribs']['src']['data'] = $this->image_handler . $image_url;
+ $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
+ }
+ else
+ {
+ $file = new $this->file_class($img['attribs']['src']['data'], $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['attribs']['src']['data'] = $this->image_handler . $image_url;
+ $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
+ }
+ else
+ {
+ trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
+ $data = trim($data);
+ }
+
+ if ($type & SIMPLEPIE_CONSTRUCT_IRI)
+ {
+ $data = SimplePie_Misc::absolutize_url($data, $base);
+ }
+
+ if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
+ {
+ $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
+ }
+
+ if ($this->output_encoding !== 'UTF-8')
+ {
+ $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
+ }
+ }
+ return $data;
+ }
+
+ function replace_urls($data, $tag, $attributes)
+ {
+ if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
+ {
+ $elements = SimplePie_Misc::get_element($tag, $data);
+ foreach ($elements as $element)
+ {
+ if (is_array($attributes))
+ {
+ foreach ($attributes as $attribute)
+ {
+ if (isset($element['attribs'][$attribute]['data']))
+ {
+ $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
+ $new_element = SimplePie_Misc::element_implode($element);
+ $data = str_replace($element['full'], $new_element, $data);
+ $element['full'] = $new_element;
+ }
+ }
+ }
+ elseif (isset($element['attribs'][$attributes]['data']))
+ {
+ $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
+ $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
+ }
+ }
+ }
+ return $data;
+ }
+
+ 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 '';
+ }
+ }
+}
+
+?>
diff --git a/inc/Sitemapper.php b/inc/Sitemapper.php
new file mode 100644
index 000000000..4689b04a6
--- /dev/null
+++ b/inc/Sitemapper.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Sitemap handling functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Michael Hamann <michael@content-space.de>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * A class for building sitemaps and pinging search engines with the sitemap URL.
+ *
+ * @author Michael Hamann
+ */
+class Sitemapper {
+ /**
+ * 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/
+ */
+ public static function generate(){
+ global $conf;
+ if($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) return false;
+
+ $sitemap = Sitemapper::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,'','') < AUTH_READ) continue;
+ $item = SitemapItem::createFromID($id);
+ if ($item !== NULL)
+ $items[] = $item;
+ }
+
+ $eventData = array('items' => &$items, 'sitemap' => &$sitemap);
+ $event = new Doku_Event('SITEMAP_GENERATE', $eventData);
+ if ($event->advise_before(true)) {
+ //save the new sitemap
+ $result = io_saveFile($sitemap, Sitemapper::getXML($items));
+ }
+ $event->advise_after();
+
+ return $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) {
+ 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 The path to the sitemap file.
+ * @author Michael Hamann
+ */
+ public static function getFilePath() {
+ global $conf;
+
+ $sitemap = $conf['cachedir'].'/sitemap.xml';
+ if($conf['compression'] === 'bz2' || $conf['compression'] === 'gz'){
+ $sitemap .= '.gz';
+ }
+
+ return $sitemap;
+ }
+
+ /**
+ * Pings search engines with the sitemap url. Plugins can add or remove
+ * urls to ping using the SITEMAP_PING event.
+ *
+ * @author Michael Hamann
+ */
+ 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,
+ 'yahoo' => 'http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=dokuwiki&url='.$encoded_sitemap_url,
+ 'microsoft' => 'http://www.bing.com/webmaster/ping.aspx?siteMap='.$encoded_sitemap_url,
+ );
+
+ $data = array('ping_urls' => $ping_urls,
+ 'encoded_sitemap_url' => $encoded_sitemap_url
+ );
+ $event = new Doku_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;
+ }
+}
+
+/**
+ * An item of a sitemap.
+ *
+ * @author Michael Hamann
+ */
+class SitemapItem {
+ public $url;
+ public $lastmod;
+ public $changefreq;
+ public $priority;
+
+ /**
+ * Create a new item.
+ *
+ * @param $url string The url of the item
+ * @param $lastmod int Timestamp of the last modification
+ * @param $changefreq string 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 $id string A wikipage id.
+ * @param $changefreq string 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.
+ * @return 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 SitemapItem(wl($id, '', true), $date, $changefreq, $priority);
+ }
+
+ /**
+ * Get the XML representation of the sitemap item.
+ *
+ * @return 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/inc/TarLib.class.php b/inc/TarLib.class.php
new file mode 100644
index 000000000..12418c48d
--- /dev/null
+++ b/inc/TarLib.class.php
@@ -0,0 +1,795 @@
+<?php
+/**
+ * TAR format class - Creates TAR archives
+ *
+ * This class is part or the MaxgComp suite and originally named
+ * MaxgTar class.
+ *
+ * Modified for Dokuwiki
+ *
+ * @license LGPL-2.1
+ * @link http://docs.maxg.info
+ * @author Bouchon <tarlib@bouchon.org> (Maxg)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+
+
+/**
+ * Those constants represent the compression method to use.
+ * COMPRESS_GZIP is used for the GZIP compression; COMPRESS_BZIP for
+ * BZIP2 and COMPRESS_NONE for no compression.
+ *
+ * On the other hand, COMPRESS_AUTO is a bit harder. It will first check
+ * if the zlib extensions are loaded.
+ * If it is, GZIP will be used. Else it will check if the bz2 extensions
+ * are loaded. If it is, BZIP2 will be used. Else no compression will be
+ * performed.
+ *
+ * You can then use getCompression() to know the compression chosen.
+ *
+ * If you selected a compression which can't be used (i.e extension not
+ * present), it will be just disabled, and won't produce any error !
+ * As a consequence, getCompression() will return COMPRESS_NONE
+ *
+ * ARCHIVE_DYNAMIC can be passed as the first argument of the constructor, to
+ * create an archive in memory instead of a file. See also: MaxgTar(),
+ * getDynamicArchive() and writeArchive()
+ *
+ * ARCHIVE_RENAMECOMP is a flag that can be multiplied by the compression method
+ * (i.e COMPRESS_AUTO * ARCHIVE_RENAMECOMP). This will add the correct extension
+ * to the archive name, which is useful with COMPRESS_AUTO, ie .bz2 if you gave
+ * COMPRESS_BZIP. See also getCompression(TRUE) which does exactly the
+ * same
+ *
+ * COMPRESS_DETECT does exactly the opposite and try to detect the
+ * compression to use to read the archive depending on its extension. (i.e if
+ * the archive ends with .tar.gz TarLib will try to decompress it with
+ * GZIP). See also setCompression()
+ *
+ * FULL_ARCHIVE is a -1 constant that means "the complete archive" when
+ * extracting. This is explained in Extract()
+ */
+#define('COMPRESS_GZIP',1);
+#define('COMPRESS_BZIP',2);
+#define('COMPRESS_AUTO',3);
+#define('COMPRESS_NONE',0);
+#define('TARLIB_VERSION','1.2');
+#define('FULL_ARCHIVE',-1);
+#define('ARCHIVE_DYNAMIC',0);
+#define('ARCHIVE_RENAMECOMP',5);
+#define('COMPRESS_DETECT',-1);
+
+class TarLib {
+ var $_comptype;
+ var $_compzlevel;
+ var $_fp;
+ var $_memdat;
+ var $_nomf;
+ var $_result;
+ var $_initerror;
+
+ const COMPRESS_GZIP = 1;
+ const COMPRESS_BZIP = 2;
+ const COMPRESS_AUTO = 3;
+ const COMPRESS_NONE = 0;
+ const TARLIB_VERSION = '1.2';
+ const FULL_ARCHIVE = -1;
+ const ARCHIVE_DYNAMIC = 0;
+ const ARCHIVE_RENAMECOMP = 5;
+ const COMPRESS_DETECT = -1;
+
+ /**
+ * constructor, initialize the class
+ *
+ * The constructor initialize the variables and prepare the class for the
+ * archive, and return the object created. Note that you can use multiple
+ * instances of the MaxgTar class, if you call this function another time and
+ * store the object in an other variable.
+ *
+ * In fact, MaxgTar accepts the following arguments (all are optional) :
+ *
+ * filename can be either a file name (absolute or relative). In this
+ * case, it can be used both for reading and writing. You can also open
+ * remote archive if you add a protocole name at the beginning of the file
+ * (ie https://host.dom/archive.tar.gz), but for reading only and if the
+ * directive allow_url_fopen is enabled in PHP.INI (this can be checked with
+ * TarInfo()). If you pass a file that doesn't exist, the script
+ * will try to create it. If the archive already exists and contains files,
+ * you can use Add() to append files.But by default this parameter
+ * is ARCHIVE_DYNAMIC (write only) so the archive is created in memory and
+ * can be sent to a file [writeArchive()] or to the client
+ * [sendClient()]
+ *
+ * compression_type should be a constant that represents a type of
+ * compression, or its integer value. The different values are described in
+ * the constants.
+ *
+ * compression_level is an integer between 1 and 9 (by default) an
+ * represent the GZIP or BZIP compression level. 1 produce fast compression,
+ * and 9 produce smaller files. See the RFC 1952 for more infos.
+ */
+ function tarlib($p_filen = TarLib::ARCHIVE_DYNAMIC , $p_comptype = TarLib::COMPRESS_AUTO, $p_complevel = 9) {
+ $this->_initerror = 0;
+ $this->_nomf = $p_filen;
+ $flag=0;
+ if($p_comptype && $p_comptype % 5 == 0){
+ $p_comptype /= TarLib::ARCHIVE_RENAMECOMP;
+ $flag=1;
+ }
+
+ if($p_complevel > 0 && $p_complevel <= 9) $this->_compzlevel = $p_complevel;
+ else $p_complevel = 9;
+
+ if($p_comptype == TarLib::COMPRESS_DETECT) {
+ if(strtolower(substr($p_filen,-3)) == '.gz') $p_comptype = TarLib::COMPRESS_GZIP;
+ elseif(strtolower(substr($p_filen,-4)) == '.bz2') $p_comptype = TarLib::COMPRESS_BZIP;
+ else $p_comptype = TarLib::COMPRESS_NONE;
+ }
+
+ switch($p_comptype) {
+ case TarLib::COMPRESS_GZIP:
+ if(!extension_loaded('zlib')) $this->_initerror = -1;
+ $this->_comptype = TarLib::COMPRESS_GZIP;
+ break;
+
+ case TarLib::COMPRESS_BZIP:
+ if(!extension_loaded('bz2')) $this->_initerror = -2;
+ $this->_comptype = TarLib::COMPRESS_BZIP;
+ break;
+
+ case TarLib::COMPRESS_AUTO:
+ if(extension_loaded('zlib'))
+ $this->_comptype = TarLib::COMPRESS_GZIP;
+ elseif(extension_loaded('bz2'))
+ $this->_comptype = TarLib::COMPRESS_BZIP;
+ else
+ $this->_comptype = TarLib::COMPRESS_NONE;
+ break;
+
+ default:
+ $this->_comptype = TarLib::COMPRESS_NONE;
+ }
+
+ if($this->_initerror < 0) $this->_comptype = TarLib::COMPRESS_NONE;
+
+ if($flag) $this->_nomf.= '.'.$this->getCompression(1);
+ $this->_result = true;
+ }
+
+ /**
+ * Recycle a TAR object.
+ *
+ * This function does exactly the same as TarLib (constructor), except it
+ * returns a status code.
+ */
+ function setArchive($p_name='', $p_comp = TarLib::COMPRESS_AUTO, $p_level=9) {
+ $this->_CompTar();
+ $this->TarLib($p_name, $p_comp, $p_level);
+ return $this->_result;
+ }
+
+ /**
+ * Get the compression used to generate the archive
+ *
+ * This is a very useful function when you're using dynamical archives.
+ * Besides, if you let the script chose which compression to use, you'll have
+ * a problem when you'll want to send it to the client if you don't know
+ * which compression was used.
+ *
+ * There are two ways to call this function : if you call it without argument
+ * or with FALSE, it will return the compression constants, explained on the
+ * MaxgTar Constants. If you call it with GetExtension on TRUE it will
+ * return the extension without starting dot (ie "tar" or "tar.bz2" or
+ * "tar.gz")
+ *
+ * NOTE: This can be done with the flag ARCHIVE_RENAMECOMP, see the
+ * MaxgTar Constants
+ */
+ function getCompression($ext = false) {
+ $exts = Array('tar','tar.gz','tar.bz2');
+ if($ext) return $exts[$this->_comptype];
+ return $this->_comptype;
+ }
+
+ /**
+ * Change the compression mode.
+ *
+ * This function will change the compression methode to read or write
+ * the archive. See the MaxgTar Constants to see which constants you can use.
+ * It may look strange, but it returns the GZIP compression level.
+ */
+ function setCompression($p_comp = TarLib::COMPRESS_AUTO) {
+ $this->setArchive($this->_nomf, $p_comp, $this->_compzlevel);
+ return $this->_compzlevel;
+ }
+
+ /**
+ * Returns the compressed dynamic archive.
+ *
+ * When you're working with dynamic archives, use this function to grab
+ * the final compressed archive in a string ready to be put in a SQL table or
+ * in a file.
+ */
+ function getDynamicArchive() {
+ return $this->_encode($this->_memdat);
+ }
+
+ /**
+ * Write a dynamical archive into a file
+ *
+ * This function attempts to write a dynamicaly-genrated archive into
+ * TargetFile on the webserver. It returns a TarErrorStr() status
+ * code.
+ *
+ * To know the extension to add to the file if you're using AUTO_DETECT
+ * compression, you can use getCompression().
+ */
+ function writeArchive($p_archive) {
+ if(!$this->_memdat) return -7;
+ $fp = @fopen($p_archive, 'wb');
+ if(!$fp) return -6;
+
+ fwrite($fp, $this->_memdat);
+ fclose($fp);
+
+ return true;
+ }
+
+ /**
+ * Send a TAR archive to the client browser.
+ *
+ * This function will send an archive to the client, and return a status
+ * code, but can behave differently depending on the arguments you give. All
+ * arguments are optional.
+ *
+ * ClientName is used to specify the archive name to give to the browser. If
+ * you don't give one, it will send the constructor filename or return an
+ * error code in case of dynamical archive.
+ *
+ * FileName is optional and used to send a specific archive. Leave it blank
+ * to send dynamical archives or the current working archive.
+ *
+ * If SendHeaders is enabled (by default), the library will send the HTTP
+ * headers itself before it sends the contents. This headers are :
+ * Content-Type, Content-Disposition, Content-Length and Accept-Range.
+ *
+ * Please note that this function DOES NOT stops the script so don't forget
+ * to exit() to avoid your script sending other data and corrupt the archive.
+ * Another note : for AUTO_DETECT dynamical archives you can know the
+ * extension to add to the name with getCompression()
+ */
+ function sendClient($name = '', $archive = '', $headers = true) {
+ if(!$name && !$this->_nomf) return -9;
+ if(!$archive && !$this->_memdat) return -10;
+ if(!$name) $name = basename($this->_nomf);
+
+ if($archive){ if(!file_exists($archive)) return -11; }
+ else $decoded = $this->getDynamicArchive();
+
+ if($headers) {
+ header('Content-Type: application/x-gtar');
+ header('Content-Disposition: attachment; filename='.basename($name));
+ header('Accept-Ranges: bytes');
+ header('Content-Length: '.($archive ? filesize($archive) : strlen($decoded)));
+ }
+
+ if($archive) {
+ $fp = @fopen($archive,'rb');
+ if(!$fp) return -4;
+
+ while(!feof($fp)) echo fread($fp,2048);
+ } else {
+ echo $decoded;
+ }
+
+ return true;
+ }
+
+ /**
+ * Extract part or totality of the archive.
+ *
+ * This function can extract files from an archive, and returns then a
+ * status codes that can be converted with TarErrorStr() into a
+ * human readable message.
+ *
+ * Only the first argument is required, What and it can be either the
+ * constant FULL_ARCHIVE or an indexed array containing each file you want to
+ * extract.
+ *
+ * To contains the target folder to extract the archive. It is optional and
+ * the default value is '.' which means the current folder. If the target
+ * folder doesn't exist, the script attempts to create it and give it
+ * permissions 0777 by default.
+ *
+ * RemovePath is very usefull when you want to extract files from a subfoler
+ * in the archive to a root folder. For instance, if you have a file in the
+ * archive called some/sub/folder/test.txt and you want to extract it to the
+ * script folder, you can call Extract with To = '.' and RemovePath =
+ * 'some/sub/folder/'
+ *
+ * FileMode is optional and its default value is 0755. It is in fact the UNIX
+ * permission in octal mode (prefixed with a 0) that will be given on each
+ * extracted file.
+ */
+ function Extract($p_what = TarLib::FULL_ARCHIVE, $p_to = '.', $p_remdir='', $p_mode = 0755) {
+ if(!$this->_OpenRead()) return -4;
+ // if(!@is_dir($p_to)) if(!@mkdir($p_to, 0777)) return -8; --CS
+ if(!@is_dir($p_to)) if(!$this->_dirApp($p_to)) return -8; //--CS (route through correct dir fn)
+
+ $ok = $this->_extractList($p_to, $p_what, $p_remdir, $p_mode);
+ $this->_CompTar();
+
+ return $ok;
+ }
+
+ /**
+ * Create a new package with the given files
+ *
+ * This function will attempt to create a new archive with global headers
+ * then add the given files into. If the archive is a real file, the
+ * contents are written directly into the file, if it is a dynamic archive
+ * contents are only stored in memory. This function should not be used to
+ * add files to an existing archive, you should use Add() instead.
+ *
+ * The FileList actually supports three different modes :
+ *
+ * - You can pass a string containing filenames separated by pipes '|'.
+ * In this case the file are read from the webserver filesystem and the
+ * root folder is the folder where the script using the MaxgTar is called.
+ *
+ * - You can also give a unidimensional indexed array containing the
+ * filenames. The behaviour for the content reading is the same that a
+ * '|'ed string.
+ *
+ * - The more useful usage is to pass bidimensional arrays, where the
+ * first element contains the filename and the second contains the file
+ * contents. You can even add empty folders to the package if the filename
+ * has a leading '/'. Once again, have a look at the exemples to understand
+ * better.
+ *
+ * Note you can also give arrays with both dynamic contents and static files.
+ *
+ * The optional parameter RemovePath can be used to delete a part of the tree
+ * of the filename you're adding, for instance if you're adding in the root
+ * of a package a file that is stored somewhere in the server tree.
+ *
+ * On the contrary the parameter AddPath can be used to add a prefix folder
+ * to the file you store. Note also that the RemovePath is applied before the
+ * AddPath is added, so it HAS a sense to use both parameters together.
+ */
+ function Create($p_filelist,$p_add='',$p_rem='') {
+ if(!$fl = $this->_fetchFilelist($p_filelist)) return -5;
+ if(!$this->_OpenWrite()) return -6;
+
+ $ok = $this->_addFileList($fl,$p_add,$p_rem);
+
+ if($ok){
+ $this->_writeFooter();
+ }else{
+ $this->_CompTar();
+ @unlink($this->_nomf);
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Add files to an existing package.
+ *
+ * This function does exactly the same than Create() exept it
+ * will append the given files at the end of the archive. Please not the is
+ * safe to call Add() on a newly created archive whereas the
+ * contrary will fail !
+ *
+ * This function returns a status code, you can use TarErrorStr() on
+ * it to get the human-readable description of the error.
+ */
+ function Add($p_filelist, $p_add = '', $p_rem = '') {
+ if (($this->_nomf != TarLib::ARCHIVE_DYNAMIC && @is_file($this->_nomf)) ||
+ ($this->_nomf == TarLib::ARCHIVE_DYNAMIC && !$this->_memdat)){
+ return $this->Create($p_filelist, $p_add, $p_rem);
+ }
+
+ if(!$fl = $this->_fetchFilelist($p_filelist)) return -5;
+ return $this->_append($fl, $p_add, $p_rem);
+ }
+
+ /**
+ * Read the contents of a TAR archive
+ *
+ * This function attempts to get the list of the files stored in the
+ * archive, and return either an error code or an indexed array of
+ * associative array containing for each file the following information :
+ *
+ * checksum Tar Checksum of the file
+ * filename The full name of the stored file (up to 100 c.)
+ * mode UNIX permissions in DECIMAL, not octal
+ * uid The Owner ID
+ * gid The Group ID
+ * size Uncompressed filesize
+ * mtime Timestamp of last modification
+ * typeflag Empty for files, set for folders
+ * link For the links, did you guess it ?
+ * uname Owner name
+ * gname Group name
+ */
+ function ListContents() {
+ if(!$this->_nomf) return -3;
+ if(!$this->_OpenRead()) return -4;
+
+ $result = Array();
+
+ while ($dat = $this->_read(512)) {
+ $dat = $this->_readHeader($dat);
+ if(!is_array($dat)) continue;
+
+ $this->_seek(ceil($dat['size']/512)*512,1);
+ $result[] = $dat;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Convert a status code into a human readable message
+ *
+ * Some MaxgTar functions like Create(), Add() ... return numerical
+ * status code. You can pass them to this function to grab their english
+ * equivalent.
+ */
+ function TarErrorStr($i) {
+ $ecodes = Array(
+ 1 => true,
+ 0 => "Undocumented error",
+ -1 => "Can't use COMPRESS_GZIP compression : ZLIB extensions are not loaded !",
+ -2 => "Can't use COMPRESS_BZIP compression : BZ2 extensions are not loaded !",
+ -3 => "You must set a archive file to read the contents !",
+ -4 => "Can't open the archive file for read !",
+ -5 => "Invalide file list !",
+ -6 => "Can't open the archive in write mode !",
+ -7 => "There is no ARCHIVE_DYNAMIC to write !",
+ -8 => "Can't create the directory to extract files !",
+ -9 => "Please pass a archive name to send if you made created an ARCHIVE_DYNAMIC !",
+ -10 => "You didn't pass an archive filename and there is no stored ARCHIVE_DYNAMIC !",
+ -11 => "Given archive doesn't exist !"
+ );
+
+ return isset($ecodes[$i]) ? $ecodes[$i] : $ecodes[0];
+ }
+
+ function _seek($p_flen, $tell=0) {
+ if($this->_nomf === TarLib::ARCHIVE_DYNAMIC)
+ $this->_memdat=substr($this->_memdat,0,($tell ? strlen($this->_memdat) : 0) + $p_flen);
+ elseif($this->_comptype == TarLib::COMPRESS_GZIP)
+ @gzseek($this->_fp, ($tell ? @gztell($this->_fp) : 0)+$p_flen);
+ elseif($this->_comptype == TarLib::COMPRESS_BZIP)
+ @fseek($this->_fp, ($tell ? @ftell($this->_fp) : 0)+$p_flen);
+ else
+ @fseek($this->_fp, ($tell ? @ftell($this->_fp) : 0)+$p_flen);
+ }
+
+ function _OpenRead() {
+ if($this->_comptype == TarLib::COMPRESS_GZIP)
+ $this->_fp = @gzopen($this->_nomf, 'rb');
+ elseif($this->_comptype == TarLib::COMPRESS_BZIP)
+ $this->_fp = @bzopen($this->_nomf, 'rb');
+ else
+ $this->_fp = @fopen($this->_nomf, 'rb');
+
+ return ($this->_fp ? true : false);
+ }
+
+ function _OpenWrite($add = 'w') {
+ if($this->_nomf === TarLib::ARCHIVE_DYNAMIC) return true;
+
+ if($this->_comptype == TarLib::COMPRESS_GZIP)
+ $this->_fp = @gzopen($this->_nomf, $add.'b'.$this->_compzlevel);
+ elseif($this->_comptype == TarLib::COMPRESS_BZIP)
+ $this->_fp = @bzopen($this->_nomf, $add.'b');
+ else
+ $this->_fp = @fopen($this->_nomf, $add.'b');
+
+ return ($this->_fp ? true : false);
+ }
+
+ function _CompTar() {
+ if($this->_nomf === TarLib::ARCHIVE_DYNAMIC || !$this->_fp) return;
+
+ if($this->_comptype == TarLib::COMPRESS_GZIP) @gzclose($this->_fp);
+ elseif($this->_comptype == TarLib::COMPRESS_BZIP) @bzclose($this->_fp);
+ else @fclose($this->_fp);
+ }
+
+ function _read($p_len) {
+ if($this->_comptype == TarLib::COMPRESS_GZIP)
+ return @gzread($this->_fp,$p_len);
+ elseif($this->_comptype == TarLib::COMPRESS_BZIP)
+ return @bzread($this->_fp,$p_len);
+ else
+ return @fread($this->_fp,$p_len);
+ }
+
+ function _write($p_data) {
+ if($this->_nomf === TarLib::ARCHIVE_DYNAMIC) $this->_memdat .= $p_data;
+ elseif($this->_comptype == TarLib::COMPRESS_GZIP)
+ return @gzwrite($this->_fp,$p_data);
+
+ elseif($this->_comptype == TarLib::COMPRESS_BZIP)
+ return @bzwrite($this->_fp,$p_data);
+
+ else
+ return @fwrite($this->_fp,$p_data);
+ }
+
+ function _encode($p_dat) {
+ if($this->_comptype == TarLib::COMPRESS_GZIP)
+ return gzencode($p_dat, $this->_compzlevel);
+ elseif($this->_comptype == TarLib::COMPRESS_BZIP)
+ return bzcompress($p_dat, $this->_compzlevel);
+ else return $p_dat;
+ }
+
+ function _readHeader($p_dat) {
+ if (!$p_dat || strlen($p_dat) != 512) return false;
+
+ for ($i=0, $chks=0; $i<148; $i++)
+ $chks += ord($p_dat[$i]);
+
+ for ($i=156,$chks+=256; $i<512; $i++)
+ $chks += ord($p_dat[$i]);
+
+ $headers = @unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $p_dat);
+ if(!$headers) return false;
+
+ $return['checksum'] = OctDec(trim($headers['checksum']));
+ if ($return['checksum'] != $chks) return false;
+
+ $return['filename'] = trim($headers['filename']);
+ $return['mode'] = OctDec(trim($headers['mode']));
+ $return['uid'] = OctDec(trim($headers['uid']));
+ $return['gid'] = OctDec(trim($headers['gid']));
+ $return['size'] = OctDec(trim($headers['size']));
+ $return['mtime'] = OctDec(trim($headers['mtime']));
+ $return['typeflag'] = $headers['typeflag'];
+ $return['link'] = trim($headers['link']);
+ $return['uname'] = trim($headers['uname']);
+ $return['gname'] = trim($headers['gname']);
+
+ return $return;
+ }
+
+ function _fetchFilelist($p_filelist) {
+ if(!$p_filelist || (is_array($p_filelist) && !@count($p_filelist))) return false;
+
+ if(is_string($p_filelist)) {
+ $p_filelist = explode('|',$p_filelist);
+ if(!is_array($p_filelist)) $p_filelist = Array($p_filelist);
+ }
+
+ return $p_filelist;
+ }
+
+ function _addFileList($p_fl, $p_addir, $p_remdir) {
+ foreach($p_fl as $file) {
+ if(($file == $this->_nomf && $this->_nomf != TarLib::ARCHIVE_DYNAMIC) || !$file || (!file_exists($file) && !is_array($file)))
+ continue;
+
+ if (!$this->_addFile($file, $p_addir, $p_remdir))
+ continue;
+
+ if (@is_dir($file)) {
+ $d = @opendir($file);
+
+ if(!$d) continue;
+ readdir($d);
+ readdir($d);
+
+ while($f = readdir($d)) {
+ if($file != ".") $tmplist[0] = "$file/$f";
+ else $tmplist[0] = $d;
+
+ $this->_addFileList($tmplist, $p_addir, $p_remdir);
+ }
+
+ closedir($d);
+ unset($tmplist,$f);
+ }
+ }
+ return true;
+ }
+
+ function _addFile($p_fn, $p_addir = '', $p_remdir = '') {
+ if(is_array($p_fn)) list($p_fn, $data) = $p_fn;
+ $sname = $p_fn;
+
+ if($p_remdir) {
+ if(substr($p_remdir,-1) != '/') $p_remdir .= "/";
+
+ if(substr($sname, 0, strlen($p_remdir)) == $p_remdir)
+ $sname = substr($sname, strlen($p_remdir));
+ }
+
+ if($p_addir) $sname = $p_addir.(substr($p_addir,-1) == '/' ? '' : "/").$sname;
+
+ if(strlen($sname) > 99) return;
+
+ if(@is_dir($p_fn)) {
+ if(!$this->_writeFileHeader($p_fn, $sname)) return false;
+ } else {
+ if(!$data) {
+ $fp = fopen($p_fn, 'rb');
+ if(!$fp) return false;
+ }
+
+ if(!$this->_writeFileHeader($p_fn, $sname, ($data ? strlen($data) : false))) return false;
+
+ if(!$data) {
+ while(!feof($fp)) {
+ $packed = pack("a512", fread($fp,512));
+ $this->_write($packed);
+ }
+ fclose($fp);
+ } else {
+ $len = strlen($data);
+ for($s = 0; $s < $len; $s += 512){
+ $this->_write(pack("a512",substr($data,$s,512)));
+ }
+ }
+ }
+
+ return true;
+ }
+
+ function _writeFileHeader($p_file, $p_sname, $p_data=false) {
+ if(!$p_data) {
+ if (!$p_sname) $p_sname = $p_file;
+ $p_sname = $this->_pathTrans($p_sname);
+
+ $h_info = stat($p_file);
+ $h[0] = sprintf("%6s ", DecOct($h_info[4]));
+ $h[] = sprintf("%6s ", DecOct($h_info[5]));
+ $h[] = sprintf("%6s ", DecOct(fileperms($p_file)));
+ clearstatcache();
+ $h[] = sprintf("%11s ", DecOct(filesize($p_file)));
+ $h[] = sprintf("%11s", DecOct(filemtime($p_file)));
+
+ $dir = @is_dir($p_file) ? '5' : '';
+ } else {
+ $dir = '';
+ $p_data = sprintf("%11s ", DecOct($p_data));
+ $time = sprintf("%11s ", DecOct(time()));
+ $h = Array(" 0 "," 0 "," 40777 ",$p_data,$time);
+ }
+
+ $data_first = pack("a100a8a8a8a12A12", $p_sname, $h[2], $h[0], $h[1], $h[3], $h[4]);
+ $data_last = pack("a1a100a6a2a32a32a8a8a155a12", $dir, '', '', '', '', '', '', '', '', "");
+
+ 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->_write($data_first);
+
+ $chks = pack("a8",sprintf("%6s ", DecOct($chks)));
+ $this->_write($chks.$data_last);
+
+ return true;
+ }
+
+ function _append($p_filelist, $p_addir="", $p_remdir="") {
+ if(!$this->_fp) if(!$this->_OpenWrite('a')) return -6;
+
+ if($this->_nomf == TarLib::ARCHIVE_DYNAMIC) {
+ $s = strlen($this->_memdat);
+ $this->_memdat = substr($this->_memdat,0,-512);
+ } else {
+ $s = filesize($this->_nomf);
+ $this->_seek($s-512);
+ }
+
+ $ok = $this->_addFileList($p_filelist, $p_addir, $p_remdir);
+ $this->_writeFooter();
+
+ return $ok;
+ }
+
+ function _pathTrans($p_dir) {
+ if ($p_dir) {
+ $subf = explode("/", $p_dir);
+ $r='';
+
+ for ($i=count($subf)-1; $i>=0; $i--) {
+ if ($subf[$i] == ".") {
+ # do nothing
+ } elseif ($subf[$i] == "..") {
+ $i--;
+ } elseif (!$subf[$i] && $i!=count($subf)-1 && $i) {
+ # do nothing
+ } else {
+ $r = $subf[$i].($i!=(count($subf)-1) ? "/".$r : "");
+ }
+ }
+ }
+ return $r;
+ }
+
+ function _writeFooter() {
+ $this->_write(pack("a512", ""));
+ }
+
+ function _extractList($p_to, $p_files, $p_remdir, $p_mode = 0755) {
+ if (!$p_to || ($p_to[0]!="/"&&substr($p_to,0,3)!="../"&&substr($p_to,1,3)!=":\\"&&substr($p_to,1,2)!=":/")) /*" // <- PHP Coder bug */
+ $p_to = "./$p_to";
+
+ if ($p_remdir && substr($p_remdir,-1)!='/') $p_remdir .= '/';
+ $p_remdirs = strlen($p_remdir);
+ while($dat = $this->_read(512)) {
+ $headers = $this->_readHeader($dat);
+ if(!$headers['filename']) continue;
+
+ if($p_files == -1 || $p_files[0] == -1){
+ $extract = true;
+ } else {
+ $extract = false;
+
+ foreach($p_files as $f) {
+ if(substr($f,-1) == "/") {
+ if((strlen($headers['filename']) > strlen($f)) && (substr($headers['filename'],0,strlen($f))==$f)) {
+ $extract = true;
+ break;
+ }
+ } elseif($f == $headers['filename']) {
+ $extract = true;
+ break;
+ }
+ }
+ }
+
+ if ($extract) {
+ $det[] = $headers;
+ if ($p_remdir && substr($headers['filename'],0,$p_remdirs)==$p_remdir)
+ $headers['filename'] = substr($headers['filename'],$p_remdirs);
+
+ if($headers['filename'].'/' == $p_remdir && $headers['typeflag']=='5') continue;
+
+ if ($p_to != "./" && $p_to != "/") {
+ while($p_to{-1}=="/") $p_to = substr($p_to,0,-1);
+
+ if($headers['filename']{0} == "/")
+ $headers['filename'] = $p_to.$headers['filename'];
+ else
+ $headers['filename'] = $p_to."/".$headers['filename'];
+ }
+
+ $ok = $this->_dirApp($headers['typeflag']=="5" ? $headers['filename'] : dirname($headers['filename']));
+ if($ok < 0) return $ok;
+
+ if (!$headers['typeflag']) {
+ if (!$fp = @fopen($headers['filename'], "wb")) return -6;
+ $n = floor($headers['size']/512);
+
+ for ($i=0; $i<$n; $i++){
+ fwrite($fp, $this->_read(512),512);
+ }
+ if (($headers['size'] % 512) != 0) fwrite($fp, $this->_read(512), $headers['size'] % 512);
+
+ fclose($fp);
+ touch($headers['filename'], $headers['mtime']);
+ chmod($headers['filename'], $p_mode);
+ } else {
+ $this->_seek(ceil($headers['size']/512)*512,1);
+ }
+ }else $this->_seek(ceil($headers['size']/512)*512,1);
+ }
+ return $det;
+ }
+
+ function _dirApp($d) {
+ // map to dokuwiki function (its more robust)
+ return io_mkdir_p($d);
+ }
+
+}
+
diff --git a/inc/ZipLib.class.php b/inc/ZipLib.class.php
new file mode 100644
index 000000000..cf89a40a4
--- /dev/null
+++ b/inc/ZipLib.class.php
@@ -0,0 +1,504 @@
+<?php
+
+/**
+ * @author bouchon
+ * @link http://dev.maxg.info
+ * @link http://forum.maxg.info
+ *
+ * Modified for Dokuwiki
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+class ZipLib {
+
+ var $datasec;
+ var $ctrl_dir = array();
+ var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
+ var $old_offset = 0;
+ var $dirs = Array(".");
+
+ function get_List($zip_name) {
+ $zip = @fopen($zip_name, 'rb');
+ if(!$zip) return(0);
+ $centd = $this->ReadCentralDir($zip,$zip_name);
+
+ @rewind($zip);
+ @fseek($zip, $centd['offset']);
+
+ for ($i=0; $i<$centd['entries']; $i++) {
+ $header = $this->ReadCentralFileHeaders($zip);
+ $header['index'] = $i;
+
+ $info['filename'] = $header['filename'];
+ $info['stored_filename'] = $header['stored_filename'];
+ $info['size'] = $header['size'];
+ $info['compressed_size'] = $header['compressed_size'];
+ $info['crc'] = strtoupper(dechex( $header['crc'] ));
+ $info['mtime'] = $header['mtime'];
+ $info['comment'] = $header['comment'];
+ $info['folder'] = ($header['external']==0x41FF0010||$header['external']==16)?1:0;
+ $info['index'] = $header['index'];
+ $info['status'] = $header['status'];
+ $ret[]=$info;
+
+ unset($header);
+ }
+ return $ret;
+ }
+
+ function Add($files,$compact) {
+ if(!is_array($files[0])) $files=Array($files);
+
+ for($i=0;$files[$i];$i++){
+ $fn = $files[$i];
+ if(!in_Array(dirname($fn[0]),$this->dirs))
+ $this->add_Dir(dirname($fn[0]));
+ if(basename($fn[0]))
+ $ret[basename($fn[0])]=$this->add_File($fn[1],$fn[0],$compact);
+ }
+ return $ret;
+ }
+
+ /**
+ * Zips recursively the $folder directory, from the $basedir directory
+ */
+ function Compress($folder, $basedir=null, $parent=null) {
+ $full_path = $basedir."/".$parent.$folder;
+ $zip_path = $parent.$folder;
+ if ($zip_path) {
+ $zip_path .= "/";
+ $this->add_dir($zip_path);
+ }
+ $dir = new DirectoryIterator($full_path);
+ foreach($dir as $file) {
+ if(!$file->isDot()) {
+ $filename = $file->getFilename();
+ if($file->isDir()) {
+ $this->Compress($filename, $basedir, $zip_path);
+ } else {
+ $content = join('', file($full_path.'/'.$filename));
+ $this->add_File($content, $zip_path.$filename);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the Zip file
+ */
+ function get_file() {
+ $data = implode('', $this -> datasec);
+ $ctrldir = implode('', $this -> ctrl_dir);
+
+ return $data . $ctrldir . $this -> eof_ctrl_dir .
+ pack('v', count($this->ctrl_dir)).pack('v', count($this->ctrl_dir)).
+ pack('V', strlen($ctrldir)) . pack('V', strlen($data)) . "\x00\x00";
+ }
+
+ function add_dir($name) {
+ $name = str_replace("\\", "/", $name);
+ $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+
+ $fr .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) );
+ $fr .= pack("v", 0 ).$name.pack("V", 0).pack("V", 0).pack("V", 0);
+ $this -> datasec[] = $fr;
+
+ $new_offset = strlen(implode("", $this->datasec));
+
+ $cdrec = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00";
+ $cdrec .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) );
+ $cdrec .= pack("v", 0 ).pack("v", 0 ).pack("v", 0 ).pack("v", 0 );
+ $ext = "\xff\xff\xff\xff";
+ $cdrec .= pack("V", 16 ).pack("V", $this -> old_offset ).$name;
+
+ $this -> ctrl_dir[] = $cdrec;
+ $this -> old_offset = $new_offset;
+ $this -> dirs[] = $name;
+ }
+
+ /**
+ * Add a file named $name from a string $data
+ */
+ function add_File($data, $name, $compact = 1) {
+ $name = str_replace('\\', '/', $name);
+ $dtime = dechex($this->DosTime());
+
+ $hexdtime = pack('H*',$dtime[6].$dtime[7].
+ $dtime[4].$dtime[5].
+ $dtime[2].$dtime[3].
+ $dtime[0].$dtime[1]);
+
+ if($compact){
+ $fr = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$hexdtime;
+ }else{
+ $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00".$hexdtime;
+ }
+ $unc_len = strlen($data);
+ $crc = crc32($data);
+
+ if($compact){
+ $zdata = gzcompress($data);
+ $c_len = strlen($zdata);
+ $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
+ }else{
+ $zdata = $data;
+ }
+ $c_len=strlen($zdata);
+ $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);
+ $fr .= pack('v', strlen($name)).pack('v', 0).$name.$zdata;
+
+ $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);
+
+ $this -> datasec[] = $fr;
+ $new_offset = strlen(implode('', $this->datasec));
+ if($compact) {
+ $cdrec = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00";
+ } else {
+ $cdrec = "\x50\x4b\x01\x02\x14\x00\x0a\x00\x00\x00\x00\x00";
+ }
+ $cdrec .= $hexdtime.pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);
+ $cdrec .= pack('v', strlen($name) ).pack('v', 0 ).pack('v', 0 );
+ $cdrec .= pack('v', 0 ).pack('v', 0 ).pack('V', 32 );
+ $cdrec .= pack('V', $this -> old_offset );
+
+ $this -> old_offset = $new_offset;
+ $cdrec .= $name;
+ $this -> ctrl_dir[] = $cdrec;
+ return true;
+ }
+
+ function DosTime() {
+ $timearray = getdate();
+ 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);
+ }
+
+ /**
+ * Extract a zip file $zn to the $to directory
+ */
+ function Extract ( $zn, $to, $index = Array(-1) ) {
+ if(!@is_dir($to)) $this->_mkdir($to);
+ $ok = 0;
+ $zip = @fopen($zn,'rb');
+ if(!$zip) return(-1);
+ $cdir = $this->ReadCentralDir($zip,$zn);
+ $pos_entry = $cdir['offset'];
+
+ if(!is_array($index)){
+ $index = array($index);
+ }
+ for($i=0; isset($index[$i]);$i++){
+ if(intval($index[$i])!=$index[$i]||$index[$i]>$cdir['entries'])
+ return(-1);
+ }
+
+ for ($i=0; $i<$cdir['entries']; $i++) {
+ @fseek($zip, $pos_entry);
+ $header = $this->ReadCentralFileHeaders($zip);
+ $header['index'] = $i;
+ $pos_entry = ftell($zip);
+ @rewind($zip);
+ fseek($zip, $header['offset']);
+ if(in_array("-1",$index)||in_array($i,$index)){
+ $stat[$header['filename']]=$this->ExtractFile($header, $to, $zip);
+ }
+ }
+ fclose($zip);
+ return $stat;
+ }
+
+ function ReadFileHeader($zip, $header) {
+ $binary_data = fread($zip, 30);
+ $data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data);
+
+ $header['filename'] = fread($zip, $data['filename_len']);
+ if ($data['extra_len'] != 0) {
+ $header['extra'] = fread($zip, $data['extra_len']);
+ } else {
+ $header['extra'] = '';
+ }
+
+ $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['mdate'] = $data['mdate'];
+ $header['mtime'] = $data['mtime'];
+
+ if ($header['mdate'] && $header['mtime']){
+ $hour = ($header['mtime']&0xF800)>>11;
+ $minute = ($header['mtime']&0x07E0)>>5;
+ $seconde = ($header['mtime']&0x001F)*2;
+ $year = (($header['mdate']&0xFE00)>>9)+1980;
+ $month = ($header['mdate']&0x01E0)>>5;
+ $day = $header['mdate']&0x001F;
+ $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
+ } else {
+ $header['mtime'] = time();
+ }
+
+ $header['stored_filename'] = $header['filename'];
+ $header['status'] = "ok";
+ return $header;
+ }
+
+ function ReadCentralFileHeaders($zip){
+ $binary_data = fread($zip, 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($zip,$header['filename_len']);
+ }else{
+ $header['filename'] = '';
+ }
+
+ if ($header['extra_len'] != 0){
+ $header['extra'] = fread($zip, $header['extra_len']);
+ }else{
+ $header['extra'] = '';
+ }
+
+ if ($header['comment_len'] != 0){
+ $header['comment'] = fread($zip, $header['comment_len']);
+ }else{
+ $header['comment'] = '';
+ }
+
+ if ($header['mdate'] && $header['mtime']) {
+ $hour = ($header['mtime'] & 0xF800) >> 11;
+ $minute = ($header['mtime'] & 0x07E0) >> 5;
+ $seconde = ($header['mtime'] & 0x001F)*2;
+ $year = (($header['mdate'] & 0xFE00) >> 9) + 1980;
+ $month = ($header['mdate'] & 0x01E0) >> 5;
+ $day = $header['mdate'] & 0x001F;
+ $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
+ } else {
+ $header['mtime'] = time();
+ }
+
+ $header['stored_filename'] = $header['filename'];
+ $header['status'] = 'ok';
+ if (substr($header['filename'], -1) == '/') $header['external'] = 0x41FF0010;
+
+ return $header;
+ }
+
+ function ReadCentralDir($zip,$zip_name) {
+ $size = filesize($zip_name);
+ if ($size < 277){
+ $maximum_size = $size;
+ } else {
+ $maximum_size=277;
+ }
+
+ @fseek($zip, $size-$maximum_size);
+ $pos = ftell($zip);
+ $bytes = 0x00000000;
+
+ while ($pos < $size) {
+ $byte = @fread($zip, 1);
+ $bytes=(($bytes << 8) & 0xFFFFFFFF) | Ord($byte);
+ if ($bytes == 0x504b0506){
+ $pos++;
+ break;
+ }
+ $pos++;
+ }
+
+ $data=unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size',
+ fread($zip, 18));
+
+ if ($data['comment_size'] != 0){
+ $centd['comment'] = fread($zip, $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;
+ }
+
+ function ExtractFile($header,$to,$zip) {
+ $header = $this->readfileheader($zip, $header);
+
+ if(substr($to,-1)!="/") $to.="/";
+ if(substr($header['filename'],-1)=="/") {
+ $this->_mkdir($to.$header['filename']);
+ return +2;
+ }
+
+ if (!$this->_mkdir($to.dirname($header['filename']))) return (-1);
+
+ if (!array_key_exists("external", $header) || (!($header['external']==0x41FF0010)&&!($header['external']==16))) {
+ if ($header['compression']==0) {
+ $fp = @fopen($to.$header['filename'], 'wb');
+ if(!$fp) return(-1);
+ $size = $header['compressed_size'];
+
+ while ($size != 0) {
+ $read_size = ($size < 2048 ? $size : 2048);
+ $buffer = fread($zip, $read_size);
+ $binary_data = pack('a'.$read_size, $buffer);
+ @fwrite($fp, $binary_data, $read_size);
+ $size -= $read_size;
+ }
+ fclose($fp);
+ touch($to.$header['filename'], $header['mtime']);
+
+ }else{
+ if (!is_dir(dirname($to.$header['filename']))) $this->_mkdir(dirname($to.$header['filename']));
+ $fp = fopen($to.$header['filename'].'.gz','wb');
+ if(!$fp) return(-1);
+ $binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($header['compression']),
+ Chr(0x00), time(), Chr(0x00), Chr(3));
+
+ fwrite($fp, $binary_data, 10);
+ $size = $header['compressed_size'];
+
+ while ($size != 0) {
+ $read_size = ($size < 1024 ? $size : 1024);
+ $buffer = fread($zip, $read_size);
+ $binary_data = pack('a'.$read_size, $buffer);
+ @fwrite($fp, $binary_data, $read_size);
+ $size -= $read_size;
+ }
+
+ $binary_data = pack('VV', $header['crc'], $header['size']);
+ fwrite($fp, $binary_data,8);
+ fclose($fp);
+
+ $gzp = @gzopen($to.$header['filename'].'.gz','rb');
+ if(!$gzp){
+ @gzclose($gzp);
+ @unlink($to.$header['filename']);
+ die("Archive is compressed whereas ZLIB is not enabled.");
+ }
+ $fp = @fopen($to.$header['filename'],'wb');
+ if(!$fp) return(-1);
+ $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);
+
+ touch($to.$header['filename'], $header['mtime']);
+ @unlink($to.$header['filename'].'.gz');
+ }
+ }
+ return true;
+ }
+
+ /**
+ * centralize mkdir calls and use dokuwiki io functions
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ function _mkdir($d) {
+ return io_mkdir_p($d);
+ }
+
+
+ function ExtractStr($zn, $name) {
+ $ok = 0;
+ $zip = @fopen($zn,'rb');
+ if(!$zip) return(null);
+ $cdir = $this->ReadCentralDir($zip,$zn);
+ $pos_entry = $cdir['offset'];
+
+ for ($i=0; $i<$cdir['entries']; $i++) {
+ @fseek($zip, $pos_entry);
+ $header = $this->ReadCentralFileHeaders($zip);
+ $header['index'] = $i;
+ $pos_entry = ftell($zip);
+ @rewind($zip);
+ fseek($zip, $header['offset']);
+ if ($name == $header['stored_filename'] || $name == $header['filename']) {
+ $str = $this->ExtractStrFile($header, $zip);
+ fclose($zip);
+ return $str;
+ }
+
+ }
+ fclose($zip);
+ return null;
+ }
+
+ function ExtractStrFile($header,$zip) {
+ $hdr = $this->readfileheader($zip);
+ $binary_data = '';
+ if (!($header['external']==0x41FF0010) && !($header['external']==16)) {
+ if ($header['compression']==0) {
+ while ($size != 0) {
+ $read_size = ($size < 2048 ? $size : 2048);
+ $buffer = fread($zip, $read_size);
+ $binary_data .= pack('a'.$read_size, $buffer);
+ $size -= $read_size;
+ }
+ return $binary_data;
+ } else {
+ $size = $header['compressed_size'];
+ if ($size == 0) {
+ return '';
+ }
+ //Just in case
+ if ($size > ($this->_ret_bytes(ini_get('memory_limit'))/2)) {
+ die("Compressed file is to huge to be uncompress in memory.");
+ }
+ while ($size != 0)
+ {
+ $read_size = ($size < 2048 ? $size : 2048);
+ $buffer = fread($zip, $read_size);
+ $binary_data .= pack('a'.$read_size, $buffer);
+ $size -= $read_size;
+ }
+ $str = gzinflate($binary_data, $header['size']);
+ if ($header['crc'] == crc32($str)) {
+ return $str;
+ } else {
+ die("Crc Error");
+ }
+ }
+ }
+ return null;
+ }
+
+ function _ret_bytes($val) {
+ $val = trim($val);
+ $last = $val{strlen($val)-1};
+ switch($last) {
+ case 'k':
+ case 'K':
+ return (int) $val * 1024;
+ break;
+ case 'm':
+ case 'M':
+ return (int) $val * 1048576;
+ break;
+ default:
+ return $val;
+ }
+ }
+}
+
diff --git a/inc/actions.php b/inc/actions.php
new file mode 100644
index 000000000..4a2e200ae
--- /dev/null
+++ b/inc/actions.php
@@ -0,0 +1,762 @@
+<?php
+/**
+ * DokuWiki Actions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * Call the needed action handlers
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @triggers ACTION_ACT_PREPROCESS
+ * @triggers ACTION_HEADERS_SEND
+ */
+function act_dispatch(){
+ global $ACT;
+ global $ID;
+ global $INFO;
+ global $QUERY;
+ global $lang;
+ global $conf;
+
+ $preact = $ACT;
+
+ // give plugins an opportunity to process the action
+ $evt = new Doku_Event('ACTION_ACT_PREPROCESS',$ACT);
+ if ($evt->advise_before()) {
+
+ //sanitize $ACT
+ $ACT = act_clean($ACT);
+
+ //check if searchword was given - else just show
+ $s = cleanID($QUERY);
+ if($ACT == 'search' && empty($s)){
+ $ACT = 'show';
+ }
+
+ //login stuff
+ if(in_array($ACT,array('login','logout'))){
+ $ACT = act_auth($ACT);
+ }
+
+ //check if user is asking to (un)subscribe a page
+ if($ACT == 'subscribe') {
+ try {
+ $ACT = act_subscription($ACT);
+ } catch (Exception $e) {
+ msg($e->getMessage(), -1);
+ }
+ }
+
+ //display some infos
+ if($ACT == 'check'){
+ check();
+ $ACT = 'show';
+ }
+
+ //check permissions
+ $ACT = act_permcheck($ACT);
+
+ //sitemap
+ if ($ACT == 'sitemap'){
+ $ACT = act_sitemap($ACT);
+ }
+
+ //register
+ if($ACT == 'register' && $_POST['save'] && register()){
+ $ACT = 'login';
+ }
+
+ if ($ACT == 'resendpwd' && act_resendpwd()) {
+ $ACT = 'login';
+ }
+
+ //update user profile
+ if ($ACT == 'profile') {
+ if(!$_SERVER['REMOTE_USER']) {
+ $ACT = 'login';
+ } else {
+ if(updateprofile()) {
+ msg($lang['profchanged'],1);
+ $ACT = 'show';
+ }
+ }
+ }
+
+ //revert
+ if($ACT == 'revert'){
+ if(checkSecurityToken()){
+ $ACT = act_revert($ACT);
+ }else{
+ $ACT = 'show';
+ }
+ }
+
+ //save
+ if($ACT == 'save'){
+ if(checkSecurityToken()){
+ $ACT = act_save($ACT);
+ }else{
+ $ACT = 'preview';
+ }
+ }
+
+ //cancel conflicting edit
+ if($ACT == 'cancel')
+ $ACT = 'show';
+
+ //draft deletion
+ if($ACT == 'draftdel')
+ $ACT = act_draftdel($ACT);
+
+ //draft saving on preview
+ if($ACT == 'preview')
+ $ACT = act_draftsave($ACT);
+
+ //edit
+ if(in_array($ACT, array('edit', 'preview', 'recover'))) {
+ $ACT = act_edit($ACT);
+ }else{
+ unlock($ID); //try to unlock
+ }
+
+ //handle export
+ if(substr($ACT,0,7) == 'export_')
+ $ACT = act_export($ACT);
+
+ //handle admin tasks
+ if($ACT == 'admin'){
+ // retrieve admin plugin name from $_REQUEST['page']
+ if (!empty($_REQUEST['page'])) {
+ $pluginlist = plugin_list('admin');
+ if (in_array($_REQUEST['page'], $pluginlist)) {
+ // attempt to load the plugin
+ if ($plugin =& plugin_load('admin',$_REQUEST['page']) !== null){
+ if($plugin->forAdminOnly() && !$INFO['isadmin']){
+ // a manager tried to load a plugin that's for admins only
+ unset($_REQUEST['page']);
+ msg('For admins only',-1);
+ }else{
+ $plugin->handle();
+ }
+ }
+ }
+ }
+ }
+
+ // check permissions again - the action may have changed
+ $ACT = act_permcheck($ACT);
+ } // end event ACTION_ACT_PREPROCESS default action
+ $evt->advise_after();
+ // Make sure plugs can handle 'denied'
+ if($conf['send404'] && $ACT == 'denied') {
+ header('HTTP/1.0 403 Forbidden');
+ }
+ unset($evt);
+
+ // when action 'show', the intial not 'show' and POST, do a redirect
+ if($ACT == 'show' && $preact != 'show' && strtolower($_SERVER['REQUEST_METHOD']) == 'post'){
+ act_redirect($ID,$preact);
+ }
+
+ global $INFO;
+ global $conf;
+ global $license;
+
+ //call template FIXME: all needed vars available?
+ $headers[] = 'Content-Type: text/html; charset=utf-8';
+ trigger_event('ACTION_HEADERS_SEND',$headers,'act_sendheaders');
+
+ include(template('main.php'));
+ // output for the commands is now handled in inc/templates.php
+ // in function tpl_content()
+}
+
+function act_sendheaders($headers) {
+ foreach ($headers as $hdr) header($hdr);
+}
+
+/**
+ * Sanitize the action command
+ *
+ * Add all allowed commands here.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function act_clean($act){
+ global $lang;
+ global $conf;
+ global $INFO;
+
+ // 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';
+
+ // check if action is disabled
+ if(!actionOK($act)){
+ msg('Command disabled: '.htmlspecialchars($act),-1);
+ return 'show';
+ }
+
+ //disable all acl related commands if ACL is disabled
+ if(!$conf['useacl'] && in_array($act,array('login','logout','register','admin',
+ 'subscribe','unsubscribe','profile','revert',
+ 'resendpwd'))){
+ msg('Command unavailable: '.htmlspecialchars($act),-1);
+ return 'show';
+ }
+
+ //is there really a draft?
+ if($act == 'draft' && !file_exists($INFO['draft'])) return 'edit';
+
+ if(!in_array($act,array('login','logout','register','save','cancel','edit','draft',
+ 'preview','search','show','check','index','revisions',
+ 'diff','recent','backlink','admin','subscribe','revert',
+ 'unsubscribe','profile','resendpwd','recover',
+ 'draftdel','sitemap','media')) && substr($act,0,7) != 'export_' ) {
+ msg('Command unknown: '.htmlspecialchars($act),-1);
+ return 'show';
+ }
+ return $act;
+}
+
+/**
+ * Run permissionchecks
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function act_permcheck($act){
+ global $INFO;
+ global $conf;
+
+ if(in_array($act,array('save','preview','edit','recover'))){
+ if($INFO['exists']){
+ if($act == 'edit'){
+ //the edit function will check again and do a source show
+ //when no AUTH_EDIT available
+ $permneed = AUTH_READ;
+ }else{
+ $permneed = AUTH_EDIT;
+ }
+ }else{
+ $permneed = AUTH_CREATE;
+ }
+ }elseif(in_array($act,array('login','search','recent','profile','index', 'sitemap'))){
+ $permneed = AUTH_NONE;
+ }elseif($act == 'revert'){
+ $permneed = AUTH_ADMIN;
+ if($INFO['ismanager']) $permneed = AUTH_EDIT;
+ }elseif($act == 'register'){
+ $permneed = AUTH_NONE;
+ }elseif($act == 'resendpwd'){
+ $permneed = AUTH_NONE;
+ }elseif($act == 'admin'){
+ if($INFO['ismanager']){
+ // if the manager has the needed permissions for a certain admin
+ // action is checked later
+ $permneed = AUTH_READ;
+ }else{
+ $permneed = AUTH_ADMIN;
+ }
+ }else{
+ $permneed = AUTH_READ;
+ }
+ if($INFO['perm'] >= $permneed) return $act;
+
+ return 'denied';
+}
+
+/**
+ * Handle 'draftdel'
+ *
+ * Deletes the draft for the current page and user
+ */
+function act_draftdel($act){
+ global $INFO;
+ @unlink($INFO['draft']);
+ $INFO['draft'] = null;
+ return 'show';
+}
+
+/**
+ * Saves a draft on preview
+ *
+ * @todo this currently duplicates code from ajax.php :-/
+ */
+function act_draftsave($act){
+ global $INFO;
+ global $ID;
+ global $conf;
+ if($conf['usedraft'] && $_POST['wikitext']){
+ $draft = array('id' => $ID,
+ 'prefix' => substr($_POST['prefix'], 0, -1),
+ 'text' => $_POST['wikitext'],
+ 'suffix' => $_POST['suffix'],
+ 'date' => (int) $_POST['date'],
+ 'client' => $INFO['client'],
+ );
+ $cname = getCacheName($draft['client'].$ID,'.draft');
+ if(io_saveFile($cname,serialize($draft))){
+ $INFO['draft'] = $cname;
+ }
+ }
+ return $act;
+}
+
+/**
+ * Handle 'save'
+ *
+ * Checks for spam and conflicts and saves the page.
+ * Does a redirect to show the page afterwards or
+ * returns a new action.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function act_save($act){
+ global $ID;
+ global $DATE;
+ global $PRE;
+ global $TEXT;
+ global $SUF;
+ global $SUM;
+ global $lang;
+ global $INFO;
+
+ //spam check
+ if(checkwordblock()) {
+ msg($lang['wordblock'], -1);
+ return 'edit';
+ }
+ //conflict check
+ if($DATE != 0 && $INFO['meta']['date']['modified'] > $DATE )
+ return 'conflict';
+
+ //save it
+ saveWikiText($ID,con($PRE,$TEXT,$SUF,1),$SUM,$_REQUEST['minor']); //use pretty mode for con
+ //unlock it
+ unlock($ID);
+
+ //delete draft
+ act_draftdel($act);
+ session_write_close();
+
+ // when done, show page
+ return 'show';
+}
+
+/**
+ * Revert to a certain revision
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function act_revert($act){
+ global $ID;
+ global $REV;
+ global $lang;
+ // FIXME $INFO['writable'] currently refers to the attic version
+ // global $INFO;
+ // if (!$INFO['writable']) {
+ // return 'show';
+ // }
+
+ // 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) return 'show'; //something went wrong
+ $sum = $lang['restored'];
+ }
+
+ // spam check
+
+ if (checkwordblock($text)) {
+ msg($lang['wordblock'], -1);
+ return 'edit';
+ }
+
+ saveWikiText($ID,$text,$sum,false);
+ msg($sum,1);
+
+ //delete any draft
+ act_draftdel($act);
+ session_write_close();
+
+ // when done, show current page
+ $_SERVER['REQUEST_METHOD'] = 'post'; //should force a redirect
+ $REV = '';
+ return 'show';
+}
+
+/**
+ * Do a redirect after receiving post data
+ *
+ * Tries to add the section id as hash mark after section editing
+ */
+function act_redirect($id,$preact){
+ global $PRE;
+ global $TEXT;
+
+ $opts = array(
+ 'id' => $id,
+ 'preact' => $preact
+ );
+ //get section name when coming from section edit
+ if($PRE && preg_match('/^\s*==+([^=\n]+)/',$TEXT,$match)){
+ $check = false; //Byref
+ $opts['fragment'] = sectionID($match[0], $check);
+ }
+
+ trigger_event('ACTION_SHOW_REDIRECT',$opts,'act_redirect_execute');
+}
+
+function act_redirect_execute($opts){
+ $go = wl($opts['id'],'',true);
+ if(isset($opts['fragment'])) $go .= '#'.$opts['fragment'];
+
+ //show it
+ send_redirect($go);
+}
+
+/**
+ * Handle 'login', 'logout'
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function act_auth($act){
+ global $ID;
+ global $INFO;
+
+ //already logged in?
+ if(isset($_SERVER['REMOTE_USER']) && $act=='login'){
+ return 'show';
+ }
+
+ //handle logout
+ if($act=='logout'){
+ $lockedby = checklock($ID); //page still locked?
+ if($lockedby == $_SERVER['REMOTE_USER'])
+ unlock($ID); //try to unlock
+
+ // do the logout stuff
+ auth_logoff();
+
+ // rebuild info array
+ $INFO = pageinfo();
+
+ act_redirect($ID,'login');
+ }
+
+ return $act;
+}
+
+/**
+ * Handle 'edit', 'preview', 'recover'
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function act_edit($act){
+ 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 = $lang['restored'];
+ }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 = $INFO['meta']['date']['modified'];
+
+ //check if locked by anyone - if not lock for my self
+ //do not lock when the user can't edit anyway
+ if ($INFO['writable']) {
+ $lockedby = checklock($ID);
+ if($lockedby) return 'locked';
+
+ lock($ID);
+ }
+
+ return $act;
+}
+
+/**
+ * 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>
+ */
+function act_export($act){
+ global $ID;
+ global $REV;
+ global $conf;
+ global $lang;
+
+ $pre = '';
+ $post = '';
+ $output = '';
+ $headers = array();
+
+ // search engines: never cache exported docs! (Google only currently)
+ $headers['X-Robots-Tag'] = 'noindex';
+
+ $mode = substr($act,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 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' . DOKU_LF;
+ $pre .= ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . DOKU_LF;
+ $pre .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$conf['lang'].'"' . DOKU_LF;
+ $pre .= ' lang="'.$conf['lang'].'" dir="'.$lang['direction'].'">' . DOKU_LF;
+ $pre .= '<head>' . DOKU_LF;
+ $pre .= ' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . DOKU_LF;
+ $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);
+ $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;
+
+ trigger_event('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;
+ }
+ return 'show';
+}
+
+/**
+ * Handle sitemap delivery
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ */
+function act_sitemap($act) {
+ global $conf;
+
+ if ($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) {
+ header("HTTP/1.0 404 Not Found");
+ print "Sitemap generation is disabled.";
+ exit;
+ }
+
+ $sitemap = Sitemapper::getFilePath();
+ if(strrchr($sitemap, '.') === '.gz'){
+ $mime = 'application/x-gzip';
+ }else{
+ $mime = 'application/xml; charset=utf-8';
+ }
+
+ // Check if sitemap file exists, otherwise create it
+ if (!is_readable($sitemap)) {
+ Sitemapper::generate();
+ }
+
+ if (is_readable($sitemap)) {
+ // Send headers
+ header('Content-Type: '.$mime);
+ header('Content-Disposition: attachment; filename='.basename($sitemap));
+
+ http_conditionalRequest(filemtime($sitemap));
+
+ // Send file
+ //use x-sendfile header to pass the delivery to compatible webservers
+ if (http_sendfile($sitemap)) exit;
+
+ readfile($sitemap);
+ exit;
+ }
+
+ header("HTTP/1.0 500 Internal Server Error");
+ print "Could not read the sitemap file - bad permissions?";
+ exit;
+}
+
+/**
+ * Handle page 'subscribe'
+ *
+ * Throws exception on error.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function act_subscription($act){
+ global $lang;
+ global $INFO;
+ global $ID;
+
+ // subcriptions work for logged in users only
+ if(!$_SERVER['REMOTE_USER']) return 'show';
+
+ // get and preprocess data.
+ $params = array();
+ foreach(array('target', 'style', 'action') as $param) {
+ if (isset($_REQUEST["sub_$param"])) {
+ $params[$param] = $_REQUEST["sub_$param"];
+ }
+ }
+
+ // any action given? if not just return and show the subscription page
+ if(!$params['action'] || !checkSecurityToken()) return $act;
+
+ // Handle POST data, may throw exception.
+ trigger_event('ACTION_HANDLE_SUBSCRIBE', $params, 'subscription_handle_post');
+
+ $target = $params['target'];
+ $style = $params['style'];
+ $data = $params['data'];
+ $action = $params['action'];
+
+ // Perform action.
+ if (!subscription_set($_SERVER['REMOTE_USER'], $target, $style, $data)) {
+ throw new Exception(sprintf($lang["subscr_{$action}_error"],
+ hsc($INFO['userinfo']['name']),
+ prettyprint_id($target)));
+ }
+ msg(sprintf($lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']),
+ prettyprint_id($target)), 1);
+ act_redirect($ID, $act);
+
+ // Assure that we have valid data if act_redirect somehow fails.
+ $INFO['subscribed'] = get_info_subscribed();
+ return 'show';
+}
+
+/**
+ * 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>
+ */
+function subscription_handle_post(&$params) {
+ global $INFO;
+ global $lang;
+
+ // 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'],
+ $_SERVER['REMOTE_USER'],
+ prettyprint_id($target)));
+ }
+ // subscription_set deletes a subscription if style = null.
+ $style = null;
+ }
+
+ $data = in_array($style, array('list', 'digest')) ? time() : null;
+ $params = compact('target', 'style', 'data', 'action');
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/adLDAP.php b/inc/adLDAP.php
new file mode 100644
index 000000000..a64096b85
--- /dev/null
+++ b/inc/adLDAP.php
@@ -0,0 +1,2422 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 3.3.2
+ *
+ * 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-2010 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-2010 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 91 $
+ * @version 3.3.2
+ * @link http://adldap.sourceforge.net/
+ */
+
+/**
+ * Define the different types of account in AD
+ */
+define ('ADLDAP_NORMAL_ACCOUNT', 805306368);
+define ('ADLDAP_WORKSTATION_TRUST', 805306369);
+define ('ADLDAP_INTERDOMAIN_TRUST', 805306370);
+define ('ADLDAP_SECURITY_GLOBAL_GROUP', 268435456);
+define ('ADLDAP_DISTRIBUTION_GROUP', 268435457);
+define ('ADLDAP_SECURITY_LOCAL_GROUP', 536870912);
+define ('ADLDAP_DISTRIBUTION_LOCAL_GROUP', 536870913);
+define ('ADLDAP_FOLDER', 'OU');
+define ('ADLDAP_CONTAINER', 'CN');
+
+/**
+* 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
+*/
+class adLDAP {
+ /**
+ * The account suffix for your domain, can be set when the class is invoked
+ *
+ * @var string
+ */
+ protected $_account_suffix = "@mydomain.local";
+
+ /**
+ * The base dn for your domain
+ *
+ * @var string
+ */
+ protected $_base_dn = "DC=mydomain,DC=local";
+
+ /**
+ * Array of domain controllers. Specifiy multiple controllers if you
+ * would like the class to balance the LDAP queries amongst multiple servers
+ *
+ * @var array
+ */
+ protected $_domain_controllers = 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 $_ad_username=NULL;
+ protected $_ad_password=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 $_real_primarygroup=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 $_use_ssl=false;
+
+ /**
+ * Use TLS
+ * If you wish to use TLS you should ensure that $_use_ssl is set to false and vice-versa
+ *
+ * @var bool
+ */
+ protected $_use_tls=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 $_recursive_groups=true;
+
+ // You should not need to edit anything below this line
+ //******************************************************************************************
+
+ /**
+ * Connection and bind default variables
+ *
+ * @var mixed
+ * @var mixed
+ */
+ protected $_conn;
+ protected $_bind;
+
+ /**
+ * Getters and Setters
+ */
+
+ /**
+ * Set the account suffix
+ *
+ * @param string $_account_suffix
+ * @return void
+ */
+ public function set_account_suffix($_account_suffix)
+ {
+ $this->_account_suffix = $_account_suffix;
+ }
+
+ /**
+ * Get the account suffix
+ *
+ * @return string
+ */
+ public function get_account_suffix()
+ {
+ return $this->_account_suffix;
+ }
+
+ /**
+ * Set the domain controllers array
+ *
+ * @param array $_domain_controllers
+ * @return void
+ */
+ public function set_domain_controllers(array $_domain_controllers)
+ {
+ $this->_domain_controllers = $_domain_controllers;
+ }
+
+ /**
+ * Get the list of domain controllers
+ *
+ * @return void
+ */
+ public function get_domain_controllers()
+ {
+ return $this->_domain_controllers;
+ }
+
+ /**
+ * Set the username of an account with higher priviledges
+ *
+ * @param string $_ad_username
+ * @return void
+ */
+ public function set_ad_username($_ad_username)
+ {
+ $this->_ad_username = $_ad_username;
+ }
+
+ /**
+ * Get the username of the account with higher priviledges
+ *
+ * This will throw an exception for security reasons
+ */
+ public function get_ad_username()
+ {
+ 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 $_ad_password
+ * @return void
+ */
+ public function set_ad_password($_ad_password)
+ {
+ $this->_ad_password = $_ad_password;
+ }
+
+ /**
+ * Get the password of the account with higher priviledges
+ *
+ * This will throw an exception for security reasons
+ */
+ public function get_ad_password()
+ {
+ throw new adLDAPException('For security reasons you cannot access the domain administrator account details');
+ }
+
+ /**
+ * Set whether to detect the true primary group
+ *
+ * @param bool $_real_primary_group
+ * @return void
+ */
+ public function set_real_primarygroup($_real_primarygroup)
+ {
+ $this->_real_primarygroup = $_real_primarygroup;
+ }
+
+ /**
+ * Get the real primary group setting
+ *
+ * @return bool
+ */
+ public function get_real_primarygroup()
+ {
+ return $this->_real_primarygroup;
+ }
+
+ /**
+ * Set whether to use SSL
+ *
+ * @param bool $_use_ssl
+ * @return void
+ */
+ public function set_use_ssl($_use_ssl)
+ {
+ $this->_use_ssl = $_use_ssl;
+ }
+
+ /**
+ * Get the SSL setting
+ *
+ * @return bool
+ */
+ public function get_use_ssl()
+ {
+ return $this->_use_ssl;
+ }
+
+ /**
+ * Set whether to use TLS
+ *
+ * @param bool $_use_tls
+ * @return void
+ */
+ public function set_use_tls($_use_tls)
+ {
+ $this->_use_tls = $_use_tls;
+ }
+
+ /**
+ * Get the TLS setting
+ *
+ * @return bool
+ */
+ public function get_use_tls()
+ {
+ return $this->_use_tls;
+ }
+
+ /**
+ * Set whether to lookup recursive groups
+ *
+ * @param bool $_recursive_groups
+ * @return void
+ */
+ public function set_recursive_groups($_recursive_groups)
+ {
+ $this->_recursive_groups = $_recursive_groups;
+ }
+
+ /**
+ * Get the recursive groups setting
+ *
+ * @return bool
+ */
+ public function get_recursive_groups()
+ {
+ return $this->_recursive_groups;
+ }
+
+ /**
+ * 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->_account_suffix=$options["account_suffix"]; }
+ if (array_key_exists("base_dn",$options)){ $this->_base_dn=$options["base_dn"]; }
+ if (array_key_exists("domain_controllers",$options)){ $this->_domain_controllers=$options["domain_controllers"]; }
+ if (array_key_exists("ad_username",$options)){ $this->_ad_username=$options["ad_username"]; }
+ if (array_key_exists("ad_password",$options)){ $this->_ad_password=$options["ad_password"]; }
+ if (array_key_exists("real_primarygroup",$options)){ $this->_real_primarygroup=$options["real_primarygroup"]; }
+ if (array_key_exists("use_ssl",$options)){ $this->_use_ssl=$options["use_ssl"]; }
+ if (array_key_exists("use_tls",$options)){ $this->_use_tls=$options["use_tls"]; }
+ if (array_key_exists("recursive_groups",$options)){ $this->_recursive_groups=$options["recursive_groups"]; }
+ }
+
+ if ($this->ldap_supported() === false) {
+ throw new adLDAPException('No LDAP support for PHP. See: http://www.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
+ $dc=$this->random_controller();
+ if ($this->_use_ssl){
+ $this->_conn = ldap_connect("ldaps://".$dc, 636);
+ } else {
+ $this->_conn = ldap_connect($dc);
+ }
+
+ // Set some ldap options for talking to AD
+ ldap_set_option($this->_conn, LDAP_OPT_PROTOCOL_VERSION, 3);
+ ldap_set_option($this->_conn, LDAP_OPT_REFERRALS, 0);
+
+ if ($this->_use_tls) {
+ ldap_start_tls($this->_conn);
+ }
+
+ // Bind as a domain admin if they've set it up
+ if ($this->_ad_username!=NULL && $this->_ad_password!=NULL){
+ $this->_bind = @ldap_bind($this->_conn,$this->_ad_username.$this->_account_suffix,$this->_ad_password);
+ if (!$this->_bind){
+ if ($this->_use_ssl && !$this->_use_tls){
+ // If you have problems troubleshooting, remove the @ character from the ldap_bind 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->get_last_error());
+ } else {
+ throw new adLDAPException('Bind to Active Directory failed. Check the login credentials and/or server details. AD said: ' . $this->get_last_error());
+ }
+ }
+ }
+
+ if ($this->_base_dn == NULL) {
+ $this->_base_dn = $this->find_base_dn();
+ }
+
+ return (true);
+ }
+
+ /**
+ * Closes the LDAP connection
+ *
+ * @return void
+ */
+ public function close() {
+ ldap_close ($this->_conn);
+ }
+
+ /**
+ * 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, $prevent_rebind = false) {
+ // Prevent null binding
+ if ($username === NULL || $password === NULL) { return false; }
+ if (empty($username) || empty($password)) { return false; }
+
+ // Bind as the user
+ $ret = true;
+ $this->_bind = @ldap_bind($this->_conn, $username . $this->_account_suffix, $password);
+ if (!$this->_bind){ $ret = false; }
+
+ // Cnce we've checked their details, kick back into admin mode if we have it
+ if ($this->_ad_username !== NULL && !$prevent_rebind) {
+ $this->_bind = @ldap_bind($this->_conn, $this->_ad_username . $this->_account_suffix , $this->_ad_password);
+ if (!$this->_bind){
+ // This should never happen in theory
+ throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->get_last_error());
+ }
+ }
+
+ return $ret;
+ }
+
+ //*****************************************************************************************************************
+ // GROUP FUNCTIONS
+
+ /**
+ * Add a group to a group
+ *
+ * @param string $parent The parent group name
+ * @param string $child The child group name
+ * @return bool
+ */
+ public function group_add_group($parent,$child){
+
+ // Find the parent group's dn
+ $parent_group=$this->group_info($parent,array("cn"));
+ if ($parent_group[0]["dn"]===NULL){ return (false); }
+ $parent_dn=$parent_group[0]["dn"];
+
+ // Find the child group's dn
+ $child_group=$this->group_info($child,array("cn"));
+ if ($child_group[0]["dn"]===NULL){ return (false); }
+ $child_dn=$child_group[0]["dn"];
+
+ $add=array();
+ $add["member"] = $child_dn;
+
+ $result=@ldap_mod_add($this->_conn,$parent_dn,$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 group_add_user($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
+ $user_dn=$this->user_dn($user,$isGUID);
+ if ($user_dn===false){ return (false); }
+
+ // Find the group's dn
+ $group_info=$this->group_info($group,array("cn"));
+ if ($group_info[0]["dn"]===NULL){ return (false); }
+ $group_dn=$group_info[0]["dn"];
+
+ $add=array();
+ $add["member"] = $user_dn;
+
+ $result=@ldap_mod_add($this->_conn,$group_dn,$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 $contact_dn The DN of the contact to add
+ * @return bool
+ */
+ public function group_add_contact($group,$contact_dn){
+ // 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
+ $group_info=$this->group_info($group,array("cn"));
+ if ($group_info[0]["dn"]===NULL){ return (false); }
+ $group_dn=$group_info[0]["dn"];
+
+ $add=array();
+ $add["member"] = $contact_dn;
+
+ $result=@ldap_mod_add($this->_conn,$group_dn,$add);
+ if ($result==false){ return (false); }
+ return (true);
+ }
+
+ /**
+ * Create a group
+ *
+ * @param array $attributes Default attributes of the group
+ * @return bool
+ */
+ public function group_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->_conn,"CN=".$add["cn"].", ".$container.",".$this->_base_dn,$add);
+ 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 group_del_group($parent,$child){
+
+ // Find the parent dn
+ $parent_group=$this->group_info($parent,array("cn"));
+ if ($parent_group[0]["dn"]===NULL){ return (false); }
+ $parent_dn=$parent_group[0]["dn"];
+
+ // Find the child dn
+ $child_group=$this->group_info($child,array("cn"));
+ if ($child_group[0]["dn"]===NULL){ return (false); }
+ $child_dn=$child_group[0]["dn"];
+
+ $del=array();
+ $del["member"] = $child_dn;
+
+ $result=@ldap_mod_del($this->_conn,$parent_dn,$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 group_del_user($group,$user,$isGUID=false){
+
+ // Find the parent dn
+ $group_info=$this->group_info($group,array("cn"));
+ if ($group_info[0]["dn"]===NULL){ return (false); }
+ $group_dn=$group_info[0]["dn"];
+
+ // Find the users dn
+ $user_dn=$this->user_dn($user,$isGUID);
+ if ($user_dn===false){ return (false); }
+
+ $del=array();
+ $del["member"] = $user_dn;
+
+ $result=@ldap_mod_del($this->_conn,$group_dn,$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 $contact_dn The DN of a contact to remove from the group
+ * @return bool
+ */
+ public function group_del_contact($group,$contact_dn){
+
+ // Find the parent dn
+ $group_info=$this->group_info($group,array("cn"));
+ if ($group_info[0]["dn"]===NULL){ return (false); }
+ $group_dn=$group_info[0]["dn"];
+
+ $del=array();
+ $del["member"] = $contact_dn;
+
+ $result=@ldap_mod_del($this->_conn,$group_dn,$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 groups_in_group($group, $recursive = NULL){
+ if (!$this->_bind){ return (false); }
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; } // Use the default option if they haven't set it
+
+ // Search the directory for the members of a group
+ $info=$this->group_info($group,array("member","cn"));
+ $groups=$info[0]["member"];
+ if (!is_array($groups)) {
+ return (false);
+ }
+
+ $group_array=array();
+
+ for ($i=0; $i<$groups["count"]; $i++){
+ $filter="(&(objectCategory=group)(distinguishedName=".$this->ldap_slashes($groups[$i])."))";
+ $fields = array("samaccountname", "distinguishedname", "objectClass");
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+
+ // not a person, look for a group
+ if ($entries['count'] == 0 && $recursive == true) {
+ $filter="(&(objectCategory=group)(distinguishedName=".$this->ldap_slashes($groups[$i])."))";
+ $fields = array("distinguishedname");
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+ if (!isset($entries[0]['distinguishedname'][0])) {
+ continue;
+ }
+ $sub_groups = $this->groups_in_group($entries[0]['distinguishedname'][0], $recursive);
+ if (is_array($sub_groups)) {
+ $group_array = array_merge($group_array, $sub_groups);
+ $group_array = array_unique($group_array);
+ }
+ continue;
+ }
+
+ $group_array[] = $entries[0]['distinguishedname'][0];
+ }
+ return ($group_array);
+ }
+
+ /**
+ * 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 group_members($group, $recursive = NULL){
+ if (!$this->_bind){ return (false); }
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; } // Use the default option if they haven't set it
+ // Search the directory for the members of a group
+ $info=$this->group_info($group,array("member","cn"));
+ $users=$info[0]["member"];
+ if (!is_array($users)) {
+ return (false);
+ }
+
+ $user_array=array();
+
+ for ($i=0; $i<$users["count"]; $i++){
+ $filter="(&(objectCategory=person)(distinguishedName=".$this->ldap_slashes($users[$i])."))";
+ $fields = array("samaccountname", "distinguishedname", "objectClass");
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+
+ // not a person, look for a group
+ if ($entries['count'] == 0 && $recursive == true) {
+ $filter="(&(objectCategory=group)(distinguishedName=".$this->ldap_slashes($users[$i])."))";
+ $fields = array("samaccountname");
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+ if (!isset($entries[0]['samaccountname'][0])) {
+ continue;
+ }
+ $sub_users = $this->group_members($entries[0]['samaccountname'][0], $recursive);
+ if (is_array($sub_users)) {
+ $user_array = array_merge($user_array, $sub_users);
+ $user_array = array_unique($user_array);
+ }
+ continue;
+ }
+
+ if ($entries[0]['samaccountname'][0] === NULL && $entries[0]['distinguishedname'][0] !== NULL) {
+ $user_array[] = $entries[0]['distinguishedname'][0];
+ }
+ elseif ($entries[0]['samaccountname'][0] !== NULL) {
+ $user_array[] = $entries[0]['samaccountname'][0];
+ }
+ }
+ return ($user_array);
+ }
+
+ /**
+ * Group Information. Returns an array of information about a group.
+ * The group name is case sensitive
+ *
+ * @param string $group_name The group name to retrieve info about
+ * @param array $fields Fields to retrieve
+ * @return array
+ */
+ public function group_info($group_name,$fields=NULL){
+ if ($group_name===NULL){ return (false); }
+ if (!$this->_bind){ return (false); }
+
+ if (stristr($group_name, '+')) {
+ $group_name=stripslashes($group_name);
+ }
+
+ $filter="(&(objectCategory=group)(name=".$this->ldap_slashes($group_name)."))";
+ //echo ($filter."!!!<br>");
+ if ($fields===NULL){ $fields=array("member","memberof","cn","description","distinguishedname","objectcategory","samaccountname"); }
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+ //print_r($entries);
+ return ($entries);
+ }
+
+ /**
+ * Return a complete list of "groups in groups"
+ *
+ * @param string $group The group to get the list from
+ * @return array
+ */
+ public function recursive_groups($group){
+ if ($group===NULL){ return (false); }
+
+ $ret_groups=array();
+
+ $groups=$this->group_info($group,array("memberof"));
+ if (isset($groups[0]["memberof"]) && is_array($groups[0]["memberof"])) {
+ $groups=$groups[0]["memberof"];
+
+ if ($groups){
+ $group_names=$this->nice_names($groups);
+ $ret_groups=array_merge($ret_groups,$group_names); //final groups to return
+
+ foreach ($group_names as $id => $group_name){
+ $child_groups=$this->recursive_groups($group_name);
+ $ret_groups=array_merge($ret_groups,$child_groups);
+ }
+ }
+ }
+
+ return ($ret_groups);
+ }
+
+ /**
+ * Returns a complete list of the groups in AD based on a SAM Account Type
+ *
+ * @param string $samaccounttype The account type to return
+ * @param bool $include_desc Whether to return a description
+ * @param string $search Search parameters
+ * @param bool $sorted Whether to sort the results
+ * @return array
+ */
+ public function search_groups($samaccounttype = ADLDAP_SECURITY_GLOBAL_GROUP, $include_desc = false, $search = "*", $sorted = true) {
+ if (!$this->_bind){ return (false); }
+
+ $filter = '(&(objectCategory=group)';
+ if ($samaccounttype !== null) {
+ $filter .= '(samaccounttype='. $samaccounttype .')';
+ }
+ $filter .= '(cn='.$search.'))';
+ // Perform the search and grab all their details
+ $fields=array("samaccountname","description");
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+
+ $groups_array = array();
+ for ($i=0; $i<$entries["count"]; $i++){
+ if ($include_desc && strlen($entries[$i]["description"][0]) > 0 ){
+ $groups_array[ $entries[$i]["samaccountname"][0] ] = $entries[$i]["description"][0];
+ } elseif ($include_desc){
+ $groups_array[ $entries[$i]["samaccountname"][0] ] = $entries[$i]["samaccountname"][0];
+ } else {
+ array_push($groups_array, $entries[$i]["samaccountname"][0]);
+ }
+ }
+ if( $sorted ){ asort($groups_array); }
+ return ($groups_array);
+ }
+
+ /**
+ * Returns a complete list of all groups in AD
+ *
+ * @param bool $include_desc Whether to return a description
+ * @param string $search Search parameters
+ * @param bool $sorted Whether to sort the results
+ * @return array
+ */
+ public function all_groups($include_desc = false, $search = "*", $sorted = true){
+ $groups_array = $this->search_groups(null, $include_desc, $search, $sorted);
+ return ($groups_array);
+ }
+
+ /**
+ * Returns a complete list of security groups in AD
+ *
+ * @param bool $include_desc Whether to return a description
+ * @param string $search Search parameters
+ * @param bool $sorted Whether to sort the results
+ * @return array
+ */
+ public function all_security_groups($include_desc = false, $search = "*", $sorted = true){
+ $groups_array = $this->search_groups(ADLDAP_SECURITY_GLOBAL_GROUP, $include_desc, $search, $sorted);
+ return ($groups_array);
+ }
+
+ /**
+ * Returns a complete list of distribution lists in AD
+ *
+ * @param bool $include_desc Whether to return a description
+ * @param string $search Search parameters
+ * @param bool $sorted Whether to sort the results
+ * @return array
+ */
+ public function all_distribution_groups($include_desc = false, $search = "*", $sorted = true){
+ $groups_array = $this->search_groups(ADLDAP_DISTRIBUTION_GROUP, $include_desc, $search, $sorted);
+ return ($groups_array);
+ }
+
+ //*****************************************************************************************************************
+ // USER FUNCTIONS
+
+ /**
+ * 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 user_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->_use_ssl && !$this->_use_tls)){
+ 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_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->account_control($control_options);
+ //echo ("<pre>"); print_r($add);
+
+ // Determine the container
+ $attributes["container"]=array_reverse($attributes["container"]);
+ $container="OU=".implode(",OU=",$attributes["container"]);
+
+ // Add the entry
+ $result=@ldap_add($this->_conn, "CN=".$add["cn"][0].", ".$container.",".$this->_base_dn, $add);
+ if ($result!=true){ return (false); }
+
+ return (true);
+ }
+
+ /**
+ * 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 user_delete($username,$isGUID=false) {
+ $userinfo = $this->user_info($username, array("*"),$isGUID);
+ $dn = $userinfo[0]['distinguishedname'][0];
+ $result=$this->dn_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 user_groups($username,$recursive=NULL,$isGUID=false){
+ if ($username===NULL){ return (false); }
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; } // Use the default option if they haven't set it
+ if (!$this->_bind){ return (false); }
+
+ // Search the directory for their information
+ $info=@$this->user_info($username,array("memberof","primarygroupid"),$isGUID);
+ $groups=$this->nice_names($info[0]["memberof"]); // Presuming the entry returned is our guy (unique usernames)
+
+ if ($recursive === true){
+ foreach ($groups as $id => $group_name){
+ $extra_groups=$this->recursive_groups($group_name);
+ $groups=array_merge($groups,$extra_groups);
+ }
+ }
+
+ return ($groups);
+ }
+
+ /**
+ * Find information about the users
+ *
+ * @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 user_info($username,$fields=NULL,$isGUID=false){
+ if ($username===NULL){ return (false); }
+ if (!$this->_bind){ return (false); }
+
+ if ($isGUID === true) {
+ $username = $this->strguid2hex($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->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $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->_real_primarygroup && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["objectsid"][0])){
+ //$entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]);
+ $entries[0]["memberof"][]=$this->get_primary_group($entries[0]["primarygroupid"][0], $entries[0]["objectsid"][0]);
+ } else {
+ $entries[0]["memberof"][]="CN=Domain Users,CN=Users,".$this->_base_dn;
+ }
+ $entries[0]["memberof"]["count"]++;
+ }
+ }
+ return $entries;
+ }
+ 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 user_ingroup($username,$group,$recursive=NULL,$isGUID=false){
+ if ($username===NULL){ return (false); }
+ if ($group===NULL){ return (false); }
+ if (!$this->_bind){ return (false); }
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; } // Use the default option if they haven't set it
+
+ // Get a list of the groups
+ $groups=$this->user_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://www.php.net/manual/en/book.bc.php
+ * @return array
+ */
+ public function user_password_expiry($username,$isGUID=false) {
+ if ($username===NULL){ return ("Missing compulsory field [username]"); }
+ if (!$this->_bind){ return (false); }
+ if (!function_exists('bcmod')) { return ("Missing function support [bcmod] http://www.php.net/manual/en/book.bc.php"); };
+
+ $userinfo = $this->user_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->_conn, $this->_base_dn, 'objectclass=*', array('maxPwdAge'));
+ if (!$sr) {
+ return false;
+ }
+ $info = ldap_get_entries($this->_conn, $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 user_modify($username,$attributes,$isGUID=false){
+ if ($username===NULL){ return ("Missing compulsory field [username]"); }
+ if (array_key_exists("password",$attributes) && !$this->_use_ssl){
+ throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.');
+ }
+
+ // Find the dn of the user
+ $user_dn=$this->user_dn($username,$isGUID);
+ if ($user_dn===false){ return (false); }
+
+ // Translate the update to the LDAP schema
+ $mod=$this->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"]){ $control_options=array("NORMAL_ACCOUNT"); }
+ else { $control_options=array("NORMAL_ACCOUNT","ACCOUNTDISABLE"); }
+ $mod["userAccountControl"][0]=$this->account_control($control_options);
+ }
+
+ // Do the update
+ $result=@ldap_modify($this->_conn,$user_dn,$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 user_disable($username,$isGUID=false){
+ if ($username===NULL){ return ("Missing compulsory field [username]"); }
+ $attributes=array("enabled"=>0);
+ $result = $this->user_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 user_enable($username,$isGUID=false){
+ if ($username===NULL){ return ("Missing compulsory field [username]"); }
+ $attributes=array("enabled"=>1);
+ $result = $this->user_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 user_password($username,$password,$isGUID=false){
+ if ($username===NULL){ return (false); }
+ if ($password===NULL){ return (false); }
+ if (!$this->_bind){ return (false); }
+ if (!$this->_use_ssl && !$this->_use_tls){
+ throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.');
+ }
+
+ $user_dn=$this->user_dn($username,$isGUID);
+ if ($user_dn===false){ return (false); }
+
+ $add=array();
+ $add["unicodePwd"][0]=$this->encode_password($password);
+
+ $result=@ldap_mod_replace($this->_conn,$user_dn,$add);
+ if ($result==false){
+ $err = ldap_errno($this->_conn);
+ 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);
+ }
+
+ /**
+ * Return a list of all users in AD
+ *
+ * @param bool $include_desc Return a description of the user
+ * @param string $search Search parameter
+ * @param bool $sorted Sort the user accounts
+ * @return array
+ */
+ public function all_users($include_desc = false, $search = "*", $sorted = true){
+ if (!$this->_bind){ return (false); }
+
+ // Perform the search and grab all their details
+ $filter = "(&(objectClass=user)(samaccounttype=". ADLDAP_NORMAL_ACCOUNT .")(objectCategory=person)(cn=".$search."))";
+ $fields=array("samaccountname","displayname");
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+
+ $users_array = array();
+ for ($i=0; $i<$entries["count"]; $i++){
+ if ($include_desc && strlen($entries[$i]["displayname"][0])>0){
+ $users_array[ $entries[$i]["samaccountname"][0] ] = $entries[$i]["displayname"][0];
+ } elseif ($include_desc){
+ $users_array[ $entries[$i]["samaccountname"][0] ] = $entries[$i]["samaccountname"][0];
+ } else {
+ array_push($users_array, $entries[$i]["samaccountname"][0]);
+ }
+ }
+ if ($sorted){ asort($users_array); }
+ return ($users_array);
+ }
+
+ /**
+ * Converts a username (samAccountName) to a GUID
+ *
+ * @param string $username The username to query
+ * @return string
+ */
+ public function username2guid($username) {
+ if (!$this->_bind){ return (false); }
+ if ($username === null){ return ("Missing compulsory field [username]"); }
+
+ $filter = "samaccountname=" . $username;
+ $fields = array("objectGUID");
+ $sr = @ldap_search($this->_conn, $this->_base_dn, $filter, $fields);
+ if (ldap_count_entries($this->_conn, $sr) > 0) {
+ $entry = @ldap_first_entry($this->_conn, $sr);
+ $guid = @ldap_get_values_len($this->_conn, $entry, 'objectGUID');
+ $strGUID = $this->binary2text($guid[0]);
+ return ($strGUID);
+ }
+ else {
+ return (false);
+ }
+ }
+
+ /**
+ * 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 user_move($username, $container) {
+ if (!$this->_bind){ 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->user_info($username, array("*"));
+ $dn = $userinfo[0]['distinguishedname'][0];
+ $newrdn = "cn=" . $username;
+ $container = array_reverse($container);
+ $newcontainer = "ou=" . implode(",ou=",$container);
+ $newbasedn = strtolower($newcontainer) . "," . $this->_base_dn;
+ $result=@ldap_rename($this->_conn,$dn,$newrdn,$newbasedn,true);
+ if ($result !== true) {
+ return (false);
+ }
+ return (true);
+ }
+
+ //*****************************************************************************************************************
+ // 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 contact_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_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->_conn, "CN=".$add["cn"][0].", ".$container.",".$this->_base_dn, $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 contact_groups($distinguishedname,$recursive=NULL){
+ if ($distinguishedname===NULL){ return (false); }
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; } //use the default option if they haven't set it
+ if (!$this->_bind){ return (false); }
+
+ // Search the directory for their information
+ $info=@$this->contact_info($distinguishedname,array("memberof","primarygroupid"));
+ $groups=$this->nice_names($info[0]["memberof"]); //presuming the entry returned is our contact
+
+ if ($recursive === true){
+ foreach ($groups as $id => $group_name){
+ $extra_groups=$this->recursive_groups($group_name);
+ $groups=array_merge($groups,$extra_groups);
+ }
+ }
+
+ return ($groups);
+ }
+
+ /**
+ * Get contact information
+ *
+ * @param string $distinguisedname The full DN of a contact
+ * @param array $fields Attributes to be returned
+ * @return array
+ */
+ public function contact_info($distinguishedname,$fields=NULL){
+ if ($distinguishedname===NULL){ return (false); }
+ if (!$this->_bind){ return (false); }
+
+ $filter="distinguishedName=".$distinguishedname;
+ if ($fields===NULL){ $fields=array("distinguishedname","mail","memberof","department","displayname","telephonenumber","primarygroupid","objectsid"); }
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $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->_real_primarygroup && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["primarygroupid"][0])){
+ //$entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]);
+ $entries[0]["memberof"][]=$this->get_primary_group($entries[0]["primarygroupid"][0], $entries[0]["objectsid"][0]);
+ } else {
+ $entries[0]["memberof"][]="CN=Domain Users,CN=Users,".$this->_base_dn;
+ }
+ }
+
+ $entries[0]["memberof"]["count"]++;
+ return ($entries);
+ }
+
+ /**
+ * 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 contact_ingroup($distinguisedname,$group,$recursive=NULL){
+ if ($distinguisedname===NULL){ return (false); }
+ if ($group===NULL){ return (false); }
+ if (!$this->_bind){ return (false); }
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; } //use the default option if they haven't set it
+
+ // Get a list of the groups
+ $groups=$this->contact_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 contact_modify($distinguishedname,$attributes){
+ if ($distinguishedname===NULL){ return ("Missing compulsory field [distinguishedname]"); }
+
+ // Translate the update to the LDAP schema
+ $mod=$this->adldap_schema($attributes);
+
+ // Check to see if this is an enabled status update
+ if (!$mod){ return (false); }
+
+ // Do the update
+ $result=ldap_modify($this->_conn,$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 contact_delete($distinguishedname) {
+ $result = $this->dn_delete($distinguishedname);
+ if ($result!=true){ return (false); }
+ return (true);
+ }
+
+ /**
+ * Return a list of all contacts
+ *
+ * @param bool $include_desc 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_contacts($include_desc = false, $search = "*", $sorted = true){
+ if (!$this->_bind){ return (false); }
+
+ // Perform the search and grab all their details
+ $filter = "(&(objectClass=contact)(cn=".$search."))";
+ $fields=array("displayname","distinguishedname");
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+
+ $users_array = array();
+ for ($i=0; $i<$entries["count"]; $i++){
+ if ($include_desc && strlen($entries[$i]["displayname"][0])>0){
+ $users_array[ $entries[$i]["distinguishedname"][0] ] = $entries[$i]["displayname"][0];
+ } elseif ($include_desc){
+ $users_array[ $entries[$i]["distinguishedname"][0] ] = $entries[$i]["distinguishedname"][0];
+ } else {
+ array_push($users_array, $entries[$i]["distinguishedname"][0]);
+ }
+ }
+ if ($sorted){ asort($users_array); }
+ return ($users_array);
+ }
+
+ //*****************************************************************************************************************
+ // FOLDER FUNCTIONS
+
+ /**
+ * Returns a folder listing for a specific OU
+ * See http://adldap.sourceforge.net/wiki/doku.php?id=api_folder_functions
+ *
+ * @param array $folder_name 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 $dn_type 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 folder_list($folder_name = NULL, $dn_type = ADLDAP_FOLDER, $recursive = NULL, $type = NULL) {
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; } //use the default option if they haven't set it
+ if (!$this->_bind){ 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->_base_dn;
+ if (is_array($folder_name)) {
+ $ou = $dn_type . "=".implode("," . $dn_type . "=",$folder_name);
+ $filter .= '(!(distinguishedname=' . $ou . ',' . $this->_base_dn . ')))';
+ $searchou = $ou . ',' . $this->_base_dn;
+ }
+ else {
+ $filter .= '(!(distinguishedname=' . $this->_base_dn . ')))';
+ }
+
+ if ($recursive === true) {
+ $sr=ldap_search($this->_conn, $searchou, $filter, array('objectclass', 'distinguishedname', 'samaccountname'));
+ $entries = @ldap_get_entries($this->_conn, $sr);
+ if (is_array($entries)) {
+ return $entries;
+ }
+ }
+ else {
+ $sr=ldap_list($this->_conn, $searchou, $filter, array('objectclass', 'distinguishedname', 'samaccountname'));
+ $entries = @ldap_get_entries($this->_conn, $sr);
+ if (is_array($entries)) {
+ return $entries;
+ }
+ }
+
+ return false;
+ }
+
+ //*****************************************************************************************************************
+ // COMPUTER FUNCTIONS
+
+ /**
+ * Get information about a specific computer
+ *
+ * @param string $computer_name The name of the computer
+ * @param array $fields Attributes to return
+ * @return array
+ */
+ public function computer_info($computer_name,$fields=NULL){
+ if ($computer_name===NULL){ return (false); }
+ if (!$this->_bind){ return (false); }
+
+ $filter="(&(objectClass=computer)(cn=".$computer_name."))";
+ if ($fields===NULL){ $fields=array("memberof","cn","displayname","dnshostname","distinguishedname","objectcategory","operatingsystem","operatingsystemservicepack","operatingsystemversion"); }
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+
+ return ($entries);
+ }
+
+ /**
+ * Check if a computer is in a group
+ *
+ * @param string $computer_name The name of the computer
+ * @param string $group The group to check
+ * @param bool $recursive Whether to check recursively
+ * @return array
+ */
+ public function computer_ingroup($computer_name,$group,$recursive=NULL){
+ if ($computer_name===NULL){ return (false); }
+ if ($group===NULL){ return (false); }
+ if (!$this->_bind){ return (false); }
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; } // use the default option if they haven't set it
+
+ //get a list of the groups
+ $groups=$this->computer_groups($computer_name,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 $computer_name The name of the computer
+ * @param bool $recursive Whether to check recursively
+ * @return array
+ */
+ public function computer_groups($computer_name,$recursive=NULL){
+ if ($computer_name===NULL){ return (false); }
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; } //use the default option if they haven't set it
+ if (!$this->_bind){ return (false); }
+
+ //search the directory for their information
+ $info=@$this->computer_info($computer_name,array("memberof","primarygroupid"));
+ $groups=$this->nice_names($info[0]["memberof"]); //presuming the entry returned is our guy (unique usernames)
+
+ if ($recursive === true){
+ foreach ($groups as $id => $group_name){
+ $extra_groups=$this->recursive_groups($group_name);
+ $groups=array_merge($groups,$extra_groups);
+ }
+ }
+
+ return ($groups);
+ }
+
+ //************************************************************************************************************
+ // ORGANIZATIONAL UNIT FUNCTIONS
+
+ /**
+ * Create an organizational unit
+ *
+ * @param array $attributes Default attributes of the ou
+ * @return bool
+ */
+ public function ou_create($attributes){
+ if (!is_array($attributes)){ return ("Attributes 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]"); }
+ if (!is_array($attributes["container"])){ return ("Container attribute must be an array."); }
+ $attributes["container"]=array_reverse($attributes["container"]);
+
+ $add=array();
+ $add["objectClass"] = "organizationalUnit";
+
+ $container="OU=".implode(",OU=",$attributes["container"]);
+ $result=ldap_add($this->_conn,"CN=".$add["cn"].", ".$container.",".$this->_base_dn,$add);
+ if ($result!=true){ return (false); }
+
+ return (true);
+ }
+
+ //************************************************************************************************************
+ // EXCHANGE FUNCTIONS
+
+ /**
+ * 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 $usedefaults Indicates whether the store should use the default quota, rather than the per-mailbox quota.
+ * @param string $base_dn 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 exchange_create_mailbox($username, $storagegroup, $emailaddress, $mailnickname=NULL, $usedefaults=TRUE, $base_dn=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 ($base_dn===NULL) {
+ $base_dn = $this->_base_dn;
+ }
+
+ $container="CN=".implode(",CN=",$storagegroup);
+
+ if ($mailnickname===NULL) { $mailnickname=$username; }
+ $mdbUseDefaults = $this->bool2str($usedefaults);
+
+ $attributes = array(
+ 'exchange_homemdb'=>$container.",".$base_dn,
+ 'exchange_proxyaddress'=>'SMTP:' . $emailaddress,
+ 'exchange_mailnickname'=>$mailnickname,
+ 'exchange_usedefaults'=>$mdbUseDefaults
+ );
+ $result = $this->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 exchange_add_X400($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->user_info($username,array("cn","proxyaddresses"), $isGUID);
+ if ($user[0]["dn"]===NULL){ return (false); }
+ $user_dn=$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_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->_conn,$user_dn,$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 exchange_add_address($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->user_info($username,array("cn","proxyaddresses"),$isGUID);
+ if ($user[0]["dn"]===NULL){ return (false); }
+ $user_dn=$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->_conn,$user_dn,$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_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->_conn,$user_dn,$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 exchange_del_address($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->user_info($username,array("cn","proxyaddresses"),$isGUID);
+ if ($user[0]["dn"]===NULL){ return (false); }
+ $user_dn=$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->_conn,$user_dn,$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 exchange_primary_address($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->user_info($username,array("cn","proxyaddresses"), $isGUID);
+ if ($user[0]["dn"]===NULL){ return (false); }
+ $user_dn=$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->_conn,$user_dn,$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 exchange_contact_mailenable($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->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_schema($attributes);
+
+ // Check to see if this is an enabled status update
+ if (!$mod){ return (false); }
+
+ // Do the update
+ $result=ldap_modify($this->_conn,$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 exchange_servers($attributes = array('cn','distinguishedname','serialnumber')) {
+ if (!$this->_bind){ return (false); }
+
+ $configurationNamingContext = $this->get_root_dse(array('configurationnamingcontext'));
+ $sr = @ldap_search($this->_conn,$configurationNamingContext[0]['configurationnamingcontext'][0],'(&(objectCategory=msExchExchangeServer))',$attributes);
+ $entries = @ldap_get_entries($this->_conn, $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 exchange_storage_groups($exchangeServer, $attributes = array('cn','distinguishedname'), $recursive = NULL) {
+ if (!$this->_bind){ return (false); }
+ if ($exchangeServer===NULL){ return ("Missing compulsory field [exchangeServer]"); }
+ if ($recursive===NULL){ $recursive=$this->_recursive_groups; }
+
+ $filter = '(&(objectCategory=msExchStorageGroup))';
+ $sr=@ldap_search($this->_conn, $exchangeServer, $filter, $attributes);
+ $entries = @ldap_get_entries($this->_conn, $sr);
+
+ if ($recursive === true) {
+ for ($i=0; $i<$entries['count']; $i++) {
+ $entries[$i]['msexchprivatemdb'] = $this->exchange_storage_databases($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 exchange_storage_databases($storageGroup, $attributes = array('cn','distinguishedname','displayname')) {
+ if (!$this->_bind){ return (false); }
+ if ($storageGroup===NULL){ return ("Missing compulsory field [storageGroup]"); }
+
+ $filter = '(&(objectCategory=msExchPrivateMDB))';
+ $sr=@ldap_search($this->_conn, $storageGroup, $filter, $attributes);
+ $entries = @ldap_get_entries($this->_conn, $sr);
+ return $entries;
+ }
+
+ //************************************************************************************************************
+ // SERVER FUNCTIONS
+
+ /**
+ * Find the Base DN of your domain controller
+ *
+ * @return string
+ */
+ public function find_base_dn() {
+ $namingContext = $this->get_root_dse(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 get_root_dse($attributes = array("*", "+")) {
+ if (!$this->_bind){ return (false); }
+
+ $sr = @ldap_read($this->_conn, NULL, 'objectClass=*', $attributes);
+ $entries = @ldap_get_entries($this->_conn, $sr);
+ return $entries;
+ }
+
+ //************************************************************************************************************
+ // UTILITY FUNCTIONS (Many of these functions are protected and can only be called from within the class)
+
+ /**
+ * 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 get_last_error() {
+ return @ldap_error($this->_conn);
+ }
+
+ /**
+ * Detect LDAP support in php
+ *
+ * @return bool
+ */
+ protected function ldap_supported() {
+ if (!function_exists('ldap_connect')) {
+ return (false);
+ }
+ return (true);
+ }
+
+ /**
+ * Schema
+ *
+ * @param array $attributes Attributes to be queried
+ * @return array
+ */
+ protected 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->encode_password($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"]; }
+
+ // 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"]; }
+
+ // 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);
+ }
+
+ /**
+ * 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
+ */
+ protected function group_cn($gid){
+ if ($gid===NULL){ return (false); }
+ $r=false;
+
+ $filter="(&(objectCategory=group)(samaccounttype=". ADLDAP_SECURITY_GLOBAL_GROUP ."))";
+ $fields=array("primarygrouptoken","samaccountname","distinguishedname");
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+
+ for ($i=0; $i<$entries["count"]; $i++){
+ if ($entries[$i]["primarygrouptoken"][0]==$gid){
+ $r=$entries[$i]["distinguishedname"][0];
+ $i=$entries["count"];
+ }
+ }
+
+ return ($r);
+ }
+
+ /**
+ * 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 string
+ */
+ protected function get_primary_group($gid, $usersid){
+ if ($gid===NULL || $usersid===NULL){ return (false); }
+ $r=false;
+
+ $gsid = substr_replace($usersid,pack('V',$gid),strlen($usersid)-4,4);
+ $filter='(objectsid='.$this->getTextSID($gsid).')';
+ $fields=array("samaccountname","distinguishedname");
+ $sr=ldap_search($this->_conn,$this->_base_dn,$filter,$fields);
+ $entries = ldap_get_entries($this->_conn, $sr);
+
+ return $entries[0]['distinguishedname'][0];
+ }
+
+ /**
+ * Convert a binary SID to a text SID
+ *
+ * @param string $binsid A Binary SID
+ * @return string
+ */
+ protected 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->little_endian(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
+ */
+ protected function little_endian($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
+ */
+ protected function binary2text($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->binary2text($binaryGuid);
+ return ($strGUID);
+ }
+
+ /**
+ * Converts a string GUID to a hexdecimal value so it can be queried
+ *
+ * @param string $strGUID A string representation of a GUID
+ * @return string
+ */
+ protected function strguid2hex($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;
+ }
+
+ /**
+ * 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
+ */
+ protected function user_dn($username,$isGUID=false){
+ $user=$this->user_info($username,array("cn"),$isGUID);
+ if ($user[0]["dn"]===NULL){ return (false); }
+ $user_dn=$user[0]["dn"];
+ return ($user_dn);
+ }
+
+ /**
+ * Encode a password for transmission over LDAP
+ *
+ * @param string $password The password to encode
+ * @return string
+ */
+ protected function encode_password($password){
+ $password="\"".$password."\"";
+ $encoded="";
+ for ($i=0; $i <strlen($password); $i++){ $encoded.="{$password{$i}}\000"; }
+ return ($encoded);
+ }
+
+ /**
+ * 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
+ */
+ protected function ldap_slashes($str){
+ return preg_replace('/([\x00-\x1F\*\(\)\\\\])/e',
+ '"\\\\\".join("",unpack("H2","$1"))',
+ $str);
+ }
+
+ /**
+ * Select a random domain controller from your domain controller array
+ *
+ * @return string
+ */
+ protected function random_controller(){
+ mt_srand(doubleval(microtime()) * 100000000); // For older PHP versions
+ return ($this->_domain_controllers[array_rand($this->_domain_controllers)]);
+ }
+
+ /**
+ * Account control options
+ *
+ * @param array $options The options to convert to int
+ * @return int
+ */
+ protected function account_control($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);
+ }
+
+ /**
+ * Take an LDAP query and return the nice names, without all the LDAP prefixes (eg. CN, DN)
+ *
+ * @param array $groups
+ * @return array
+ */
+ protected function nice_names($groups){
+
+ $group_array=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);
+ $group_array[]=substr($bits[0],3,(strlen($bits[0])-3));
+ }
+ }
+ return ($group_array);
+ }
+
+ /**
+ * 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
+ */
+ protected function dn_delete($dn){
+ $result=ldap_delete($this->_conn, $dn);
+ if ($result!=true){ return (false); }
+ return (true);
+ }
+
+ /**
+ * Convert a boolean value to a string
+ * You should never need to call this yourself
+ *
+ * @param bool $bool Boolean value
+ * @return string
+ */
+ protected function bool2str($bool) {
+ return ($bool) ? 'TRUE' : 'FALSE';
+ }
+
+ /**
+ * 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);
+ }
+ }
+}
+
+/**
+* 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/inc/auth.php b/inc/auth.php
new file mode 100644
index 000000000..941dcb8d6
--- /dev/null
+++ b/inc/auth.php
@@ -0,0 +1,1026 @@
+<?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>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+// some ACL level defines
+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);
+
+/**
+ * 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
+ */
+function auth_setup(){
+ global $conf;
+ global $auth;
+ global $AUTH_ACL;
+ global $lang;
+ global $config_cascade;
+ $AUTH_ACL = array();
+
+ if(!$conf['useacl']) return false;
+
+ // load the the backend auth functions and instantiate the auth object XXX
+ if (@file_exists(DOKU_INC.'inc/auth/'.$conf['authtype'].'.class.php')) {
+ require_once(DOKU_INC.'inc/auth/basic.class.php');
+ require_once(DOKU_INC.'inc/auth/'.$conf['authtype'].'.class.php');
+
+ $auth_class = "auth_".$conf['authtype'];
+ if (class_exists($auth_class)) {
+ $auth = new $auth_class();
+ if ($auth->success == false) {
+ // degrade to unauthenticated user
+ unset($auth);
+ auth_logoff();
+ msg($lang['authtempfail'], -1);
+ }
+ } else {
+ nice_die($lang['authmodfailed']);
+ }
+ } else {
+ nice_die($lang['authmodfailed']);
+ }
+
+ if(!$auth) return;
+
+ // do the login either by cookie or provided credentials XXX
+ if (!isset($_REQUEST['u'])) $_REQUEST['u'] = '';
+ if (!isset($_REQUEST['p'])) $_REQUEST['p'] = '';
+ if (!isset($_REQUEST['r'])) $_REQUEST['r'] = '';
+ $_REQUEST['http_credentials'] = false;
+ if (!$conf['rememberme']) $_REQUEST['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(empty($_REQUEST['u']) && empty($_COOKIE[DOKU_COOKIE]) && !empty($_SERVER['PHP_AUTH_USER'])){
+ $_REQUEST['u'] = $_SERVER['PHP_AUTH_USER'];
+ $_REQUEST['p'] = $_SERVER['PHP_AUTH_PW'];
+ $_REQUEST['http_credentials'] = true;
+ }
+
+ // apply cleaning
+ $_REQUEST['u'] = $auth->cleanUser($_REQUEST['u']);
+
+ if(isset($_REQUEST['authtok'])){
+ // when an authentication token is given, trust the session
+ auth_validateToken($_REQUEST['authtok']);
+ }elseif(!is_null($auth) && $auth->canDo('external')){
+ // external trust mechanism in place
+ $auth->trustExternal($_REQUEST['u'],$_REQUEST['p'],$_REQUEST['r']);
+ }else{
+ $evdata = array(
+ 'user' => $_REQUEST['u'],
+ 'password' => $_REQUEST['p'],
+ 'sticky' => $_REQUEST['r'],
+ 'silent' => $_REQUEST['http_credentials'],
+ );
+ trigger_event('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper');
+ }
+
+ //load ACL into a global array XXX
+ $AUTH_ACL = auth_loadACL();
+}
+
+/**
+ * Loads the ACL setup and handle user wildcards
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @returns array
+ */
+function auth_loadACL(){
+ global $config_cascade;
+
+ if(!is_readable($config_cascade['acl']['default'])) return array();
+
+ $acl = file($config_cascade['acl']['default']);
+
+ //support user wildcard
+ if(isset($_SERVER['REMOTE_USER'])){
+ $len = count($acl);
+ for($i=0; $i<$len; $i++){
+ if($acl[$i]{0} == '#') continue;
+ list($id,$rest) = preg_split('/\s+/',$acl[$i],2);
+ $id = str_replace('%USER%',cleanID($_SERVER['REMOTE_USER']),$id);
+ $rest = str_replace('%USER%',auth_nameencode($_SERVER['REMOTE_USER']),$rest);
+ $acl[$i] = "$id\t$rest";
+ }
+ }
+ return $acl;
+}
+
+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;
+ global $auth;
+ $sticky ? $sticky = true : $sticky = false; //sanity check
+
+ if (!$auth) return false;
+
+ if(!empty($user)){
+ //usual login
+ if ($auth->checkPass($user,$pass)){
+ // make logininfo globally available
+ $_SERVER['REMOTE_USER'] = $user;
+ $secret = auth_cookiesalt(!$sticky); //bind non-sticky to session
+ auth_setCookie($user,PMA_blowfish_encrypt($pass,$secret),$sticky);
+ return true;
+ }else{
+ //invalid credentials - log off
+ if(!$silent) 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
+ $_SERVER['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); //bind non-sticky to session
+ $pass = PMA_blowfish_decrypt($pass,$secret);
+ return auth_login($user,$pass,$sticky,true);
+ }
+ }
+ //just to be sure
+ auth_logoff(true);
+ return false;
+}
+
+/**
+ * Checks if a given authentication token was stored in the session
+ *
+ * Will setup authentication data using data from the session if the
+ * token is correct. Will exit with a 401 Status if not.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $token The authentication token
+ * @return boolean true (or will exit on failure)
+ */
+function auth_validateToken($token){
+ if(!$token || $token != $_SESSION[DOKU_COOKIE]['auth']['token']){
+ // bad token
+ header("HTTP/1.0 401 Unauthorized");
+ print 'Invalid auth token - maybe the session timed out';
+ unset($_SESSION[DOKU_COOKIE]['auth']['token']); // no second chance
+ exit;
+ }
+ // still here? trust the session data
+ global $USERINFO;
+ $_SERVER['REMOTE_USER'] = $_SESSION[DOKU_COOKIE]['auth']['user'];
+ $USERINFO = $_SESSION[DOKU_COOKIE]['auth']['info'];
+ return true;
+}
+
+/**
+ * Create an auth token and store it in the session
+ *
+ * NOTE: this is completely unrelated to the getSecurityToken() function
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return string The auth token
+ */
+function auth_createToken(){
+ $token = md5(mt_rand());
+ @session_start(); // reopen the session if needed
+ $_SESSION[DOKU_COOKIE]['auth']['token'] = $token;
+ session_write_close();
+ return $token;
+}
+
+/**
+ * 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 stil okay.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return string a MD5 sum of various browser headers
+ */
+function auth_browseruid(){
+ $ip = clientIP(true);
+ $uid = '';
+ $uid .= $_SERVER['HTTP_USER_AGENT'];
+ $uid .= $_SERVER['HTTP_ACCEPT_ENCODING'];
+ $uid .= $_SERVER['HTTP_ACCEPT_LANGUAGE'];
+ $uid .= $_SERVER['HTTP_ACCEPT_CHARSET'];
+ $uid .= substr($ip,0,strpos($ip,'.'));
+ 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
+ * @return string
+ */
+function auth_cookiesalt($addsession=false){
+ global $conf;
+ $file = $conf['metadir'].'/_htcookiesalt';
+ $salt = io_readFile($file);
+ if(empty($salt)){
+ $salt = uniqid(rand(),true);
+ io_saveFile($file,$salt);
+ }
+ if($addsession){
+ $salt .= session_id();
+ }
+ return $salt;
+}
+
+/**
+ * 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;
+ global $INFO, $ID;
+ global $auth;
+
+ // 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']);
+ if(isset($_SERVER['REMOTE_USER']))
+ unset($_SERVER['REMOTE_USER']);
+ $USERINFO=null; //FIXME
+
+ $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
+ if (version_compare(PHP_VERSION, '5.2.0', '>')) {
+ setcookie(DOKU_COOKIE,'',time()-600000,$cookieDir,'',($conf['securecookie'] && is_ssl()),true);
+ }else{
+ setcookie(DOKU_COOKIE,'',time()-600000,$cookieDir,'',($conf['securecookie'] && is_ssl()));
+ }
+
+ 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
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see auth_isadmin
+ * @param string user - Username
+ * @param array groups - List of groups the user is in
+ * @param bool adminonly - when true checks if user is admin
+ */
+function auth_ismanager($user=null,$groups=null,$adminonly=false){
+ global $conf;
+ global $USERINFO;
+ global $auth;
+
+ if (!$auth) return false;
+ if(is_null($user)) {
+ if (!isset($_SERVER['REMOTE_USER'])) {
+ return false;
+ } else {
+ $user = $_SERVER['REMOTE_USER'];
+ }
+ }
+ if(is_null($groups)){
+ $groups = (array) $USERINFO['grps'];
+ }
+
+ // check superuser match
+ if(auth_isMember($conf['superuser'],$user, $groups)) return true;
+ if($adminonly) return false;
+ // check managers
+ if(auth_isMember($conf['manager'],$user, $groups)) return true;
+
+ return false;
+}
+
+/**
+ * Check if a user is admin
+ *
+ * Alias to auth_ismanager with adminonly=true
+ *
+ * The info is available through $INFO['isadmin'], too
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see auth_ismanager
+ */
+function auth_isadmin($user=null,$groups=null){
+ return auth_ismanager($user,$groups,true);
+}
+
+
+/**
+ * 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 $memberlist string commaseparated list of allowed users and groups
+ * @param $user string user to match against
+ * @param $groups array groups the user is member of
+ * @returns bool true for membership acknowledged
+ */
+function auth_isMember($memberlist,$user,array $groups){
+ global $auth;
+ if (!$auth) return false;
+
+ // clean user and groups
+ if(!$auth->isCaseSensitive()){
+ $user = utf8_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(!$auth->isCaseSensitive()) $member = utf8_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;
+ # if no ACL is used always return upload rights
+ if(!$conf['useacl']) return AUTH_UPLOAD;
+ return auth_aclcheck($id,$_SERVER['REMOTE_USER'],$USERINFO['grps']);
+}
+
+/**
+ * Returns the maximum rights a user has for
+ * the given ID or its namespace
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page ID (needs to be resolved and cleaned)
+ * @param string $user Username
+ * @param array $groups Array of groups the user is in
+ * @return int permission level
+ */
+function auth_aclcheck($id,$user,$groups){
+ global $conf;
+ global $AUTH_ACL;
+ 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; }
+
+ $ci = '';
+ if(!$auth->isCaseSensitive()) $ci = 'ui';
+
+ $user = $auth->cleanUser($user);
+ $groups = array_map(array($auth,'cleanGroup'),(array)$groups);
+ $user = auth_nameencode($user);
+
+ //prepend groups with @ and nameencode
+ $cnt = count($groups);
+ for($i=0; $i<$cnt; $i++){
+ $groups[$i] = '@'.auth_nameencode($groups[$i]);
+ }
+
+ $ns = getNS($id);
+ $perm = -1;
+
+ if($user || count($groups)){
+ //add ALL group
+ $groups[] = '@ALL';
+ //add User
+ if($user) $groups[] = $user;
+ }else{
+ $groups[] = '@ALL';
+ }
+
+ //check exact match first
+ $matches = preg_grep('/^'.preg_quote($id,'/').'\s+(\S+)\s+/'.$ci,$AUTH_ACL);
+ if(count($matches)){
+ foreach($matches as $match){
+ $match = preg_replace('/#.*$/','',$match); //ignore comments
+ $acl = preg_split('/\s+/',$match);
+ 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 $perm;
+ }
+ }
+
+ //still here? do the namespace checks
+ if($ns){
+ $path = $ns.':*';
+ }else{
+ $path = '*'; //root document
+ }
+
+ do{
+ $matches = preg_grep('/^'.preg_quote($path,'/').'\s+(\S+)\s+/'.$ci,$AUTH_ACL);
+ if(count($matches)){
+ foreach($matches as $match){
+ $match = preg_replace('/#.*$/','',$match); //ignore comments
+ $acl = preg_split('/\s+/',$match);
+ 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 $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
+}
+
+/**
+ * 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()
+ */
+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 (!isset($cache[$name][$skip_group])) {
+ if($skip_group && $name{0} =='@'){
+ $cache[$name][$skip_group] = '@'.preg_replace('/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/e',
+ "'%'.dechex(ord(substr('\\1',-1)))",substr($name,1));
+ }else{
+ $cache[$name][$skip_group] = preg_replace('/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/e',
+ "'%'.dechex(ord(substr('\\1',-1)))",$name);
+ }
+ }
+
+ return $cache[$name][$skip_group];
+}
+
+/**
+ * Create a pronouncable password
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://www.phpbuilder.com/annotate/message.php3?id=1014451
+ *
+ * @return string pronouncable password
+ */
+function auth_pwgen(){
+ $pw = '';
+ $c = 'bcdfghjklmnprstvwz'; //consonants except hard to speak ones
+ $v = 'aeiou'; //vowels
+ $a = $c.$v; //both
+
+ //use two syllables...
+ for($i=0;$i < 2; $i++){
+ $pw .= $c[rand(0, strlen($c)-1)];
+ $pw .= $v[rand(0, strlen($v)-1)];
+ $pw .= $a[rand(0, strlen($a)-1)];
+ }
+ //... and add a nice number
+ $pw .= rand(10,99);
+
+ return $pw;
+}
+
+/**
+ * Sends a password to the given user
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return bool true on success
+ */
+function auth_sendPassword($user,$password){
+ global $conf;
+ global $lang;
+ global $auth;
+ if (!$auth) return false;
+
+ $hdrs = '';
+ $user = $auth->cleanUser($user);
+ $userinfo = $auth->getUserData($user);
+
+ if(!$userinfo['mail']) return false;
+
+ $text = rawLocale('password');
+ $text = str_replace('@DOKUWIKIURL@',DOKU_URL,$text);
+ $text = str_replace('@FULLNAME@',$userinfo['name'],$text);
+ $text = str_replace('@LOGIN@',$user,$text);
+ $text = str_replace('@PASSWORD@',$password,$text);
+ $text = str_replace('@TITLE@',$conf['title'],$text);
+
+ if(empty($conf['mailprefix'])) {
+ $subject = $lang['regpwmail'];
+ } else {
+ $subject = '['.$conf['mailprefix'].'] '.$lang['regpwmail'];
+ }
+
+ return mail_send($userinfo['name'].' <'.$userinfo['mail'].'>',
+ $subject,
+ $text,
+ $conf['mailfrom']);
+}
+
+/**
+ * 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;
+ global $auth;
+
+ if(!$_POST['save']) return false;
+ if(!actionOK('register')) return false;
+
+ //clean username
+ $_POST['login'] = trim($auth->cleanUser($_POST['login']));
+
+ //clean fullname and email
+ $_POST['fullname'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['fullname']));
+ $_POST['email'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['email']));
+
+ if( empty($_POST['login']) ||
+ empty($_POST['fullname']) ||
+ empty($_POST['email']) ){
+ msg($lang['regmissing'],-1);
+ return false;
+ }
+
+ if ($conf['autopasswd']) {
+ $pass = auth_pwgen(); // automatically generate password
+ } elseif (empty($_POST['pass']) ||
+ empty($_POST['passchk'])) {
+ msg($lang['regmissing'], -1); // complain about missing passwords
+ return false;
+ } elseif ($_POST['pass'] != $_POST['passchk']) {
+ msg($lang['regbadpass'], -1); // complain about misspelled passwords
+ return false;
+ } else {
+ $pass = $_POST['pass']; // accept checked and valid password
+ }
+
+ //check mail
+ if(!mail_isvalid($_POST['email'])){
+ msg($lang['regbadmail'],-1);
+ return false;
+ }
+
+ //okay try to create the user
+ if(!$auth->triggerUserMod('create', array($_POST['login'],$pass,$_POST['fullname'],$_POST['email']))){
+ msg($lang['reguexists'],-1);
+ return false;
+ }
+
+ // create substitutions for use in notification email
+ $substitutions = array(
+ 'NEWUSER' => $_POST['login'],
+ 'NEWNAME' => $_POST['fullname'],
+ 'NEWEMAIL' => $_POST['email'],
+ );
+
+ if (!$conf['autopasswd']) {
+ msg($lang['regsuccess2'],1);
+ notify('', 'register', '', $_POST['login'], false, $substitutions);
+ return true;
+ }
+
+ // autogenerated password? then send him the password
+ if (auth_sendPassword($_POST['login'],$pass)){
+ msg($lang['regsuccess'],1);
+ notify('', 'register', '', $_POST['login'], false, $substitutions);
+ return true;
+ }else{
+ msg($lang['regmailfail'],-1);
+ return false;
+ }
+}
+
+/**
+ * Update user profile
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+function updateprofile() {
+ global $conf;
+ global $INFO;
+ global $lang;
+ global $auth;
+
+ if(empty($_POST['save'])) return false;
+ if(!checkSecurityToken()) return false;
+
+ if(!actionOK('profile')) {
+ msg($lang['profna'],-1);
+ return false;
+ }
+
+ if ($_POST['newpass'] != $_POST['passchk']) {
+ msg($lang['regbadpass'], -1); // complain about misspelled passwords
+ return false;
+ }
+
+ //clean fullname and email
+ $_POST['fullname'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['fullname']));
+ $_POST['email'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/','',$_POST['email']));
+
+ if ((empty($_POST['fullname']) && $auth->canDo('modName')) ||
+ (empty($_POST['email']) && $auth->canDo('modMail'))) {
+ msg($lang['profnoempty'],-1);
+ return false;
+ }
+
+ if (!mail_isvalid($_POST['email']) && $auth->canDo('modMail')){
+ msg($lang['regbadmail'],-1);
+ return false;
+ }
+
+ if ($_POST['fullname'] != $INFO['userinfo']['name'] && $auth->canDo('modName')) $changes['name'] = $_POST['fullname'];
+ if ($_POST['email'] != $INFO['userinfo']['mail'] && $auth->canDo('modMail')) $changes['mail'] = $_POST['email'];
+ if (!empty($_POST['newpass']) && $auth->canDo('modPass')) $changes['pass'] = $_POST['newpass'];
+
+ if (!count($changes)) {
+ msg($lang['profnochange'], -1);
+ return false;
+ }
+
+ if ($conf['profileconfirm']) {
+ if (!$auth->checkPass($_SERVER['REMOTE_USER'], $_POST['oldpass'])) {
+ msg($lang['badlogin'],-1);
+ return false;
+ }
+ }
+
+ if ($result = $auth->triggerUserMod('modify', array($_SERVER['REMOTE_USER'], $changes))) {
+ // update cookie and session with the changed data
+ if ($changes['pass']){
+ list($user,$sticky,$pass) = auth_getCookie();
+ $pass = PMA_blowfish_encrypt($changes['pass'],auth_cookiesalt(!$sticky));
+ auth_setCookie($_SERVER['REMOTE_USER'],$pass,(bool)$sticky);
+ }
+ return true;
+ }
+}
+
+/**
+ * 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;
+ global $auth;
+
+ if(!actionOK('resendpwd')) {
+ msg($lang['resendna'],-1);
+ return false;
+ }
+
+ $token = preg_replace('/[^a-f0-9]+/','',$_REQUEST['pwauth']);
+
+ if($token){
+ // we're in token phase
+
+ $tfile = $conf['cachedir'].'/'.$token{0}.'/'.$token.'.pwauth';
+ if(!@file_exists($tfile)){
+ msg($lang['resendpwdbadauth'],-1);
+ return false;
+ }
+ $user = io_readfile($tfile);
+ @unlink($tfile);
+ $userinfo = $auth->getUserData($user);
+ if(!$userinfo['mail']) {
+ msg($lang['resendpwdnouser'], -1);
+ return false;
+ }
+
+ $pass = auth_pwgen();
+ if (!$auth->triggerUserMod('modify', array($user,array('pass' => $pass)))) {
+ msg('error modifying user data',-1);
+ return false;
+ }
+
+ if (auth_sendPassword($user,$pass)) {
+ msg($lang['resendpwdsuccess'],1);
+ } else {
+ msg($lang['regmailfail'],-1);
+ }
+ return true;
+
+ } else {
+ // we're in request phase
+
+ if(!$_POST['save']) return false;
+
+ if (empty($_POST['login'])) {
+ msg($lang['resendpwdmissing'], -1);
+ return false;
+ } else {
+ $user = trim($auth->cleanUser($_POST['login']));
+ }
+
+ $userinfo = $auth->getUserData($user);
+ if(!$userinfo['mail']) {
+ msg($lang['resendpwdnouser'], -1);
+ return false;
+ }
+
+ // generate auth token
+ $token = md5(auth_cookiesalt().$user); //secret but user based
+ $tfile = $conf['cachedir'].'/'.$token{0}.'/'.$token.'.pwauth';
+ $url = wl('',array('do'=>'resendpwd','pwauth'=>$token),true,'&');
+
+ io_saveFile($tfile,$user);
+
+ $text = rawLocale('pwconfirm');
+ $text = str_replace('@DOKUWIKIURL@',DOKU_URL,$text);
+ $text = str_replace('@FULLNAME@',$userinfo['name'],$text);
+ $text = str_replace('@LOGIN@',$user,$text);
+ $text = str_replace('@TITLE@',$conf['title'],$text);
+ $text = str_replace('@CONFIRM@',$url,$text);
+
+ if(empty($conf['mailprefix'])) {
+ $subject = $lang['regpwmail'];
+ } else {
+ $subject = '['.$conf['mailprefix'].'] '.$lang['regpwmail'];
+ }
+
+ if(mail_send($userinfo['name'].' <'.$userinfo['mail'].'>',
+ $subject,
+ $text,
+ $conf['mailfrom'])){
+ msg($lang['resendpwdconfirm'],1);
+ }else{
+ msg($lang['regmailfail'],-1);
+ }
+ return true;
+ }
+
+ return false; // 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>
+ * @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>
+ * @return bool
+ */
+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
+ */
+function auth_setCookie($user,$pass,$sticky) {
+ global $conf;
+ 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
+ if (version_compare(PHP_VERSION, '5.2.0', '>')) {
+ setcookie(DOKU_COOKIE,$cookie,$time,$cookieDir,'',($conf['securecookie'] && is_ssl()),true);
+ }else{
+ setcookie(DOKU_COOKIE,$cookie,$time,$cookieDir,'',($conf['securecookie'] && is_ssl()));
+ }
+ // 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();
+}
+
+/**
+ * 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/inc/auth/ad.class.php b/inc/auth/ad.class.php
new file mode 100644
index 000000000..1fddad243
--- /dev/null
+++ b/inc/auth/ad.class.php
@@ -0,0 +1,351 @@
+<?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['useacl'] = 1;
+ * $conf['disableactions'] = 'register';
+ * $conf['autopasswd'] = 0;
+ * $conf['authtype'] = 'ad';
+ * $conf['passcrypt'] = 'ssha';
+ *
+ * $conf['auth']['ad']['account_suffix'] = '@my.domain.org';
+ * $conf['auth']['ad']['base_dn'] = 'DC=my,DC=domain,DC=org';
+ * $conf['auth']['ad']['domain_controllers'] = 'srv1.domain.org,srv2.domain.org';
+ *
+ * //optional:
+ * $conf['auth']['ad']['sso'] = 1;
+ * $conf['auth']['ad']['ad_username'] = 'root';
+ * $conf['auth']['ad']['ad_password'] = 'pass';
+ * $conf['auth']['ad']['real_primarygroup'] = 1;
+ * $conf['auth']['ad']['use_ssl'] = 1;
+ * $conf['auth']['ad']['use_tls'] = 1;
+ * $conf['auth']['ad']['debug'] = 1;
+ *
+ * // get additional information to the userinfo array
+ * // add a list of comma separated ldap contact fields.
+ * $conf['auth']['ad']['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>
+ */
+
+require_once(DOKU_INC.'inc/adLDAP.php');
+
+class auth_ad extends auth_basic {
+ var $cnf = null;
+ var $opts = null;
+ var $adldap = null;
+ var $users = null;
+
+ /**
+ * Constructor
+ */
+ function auth_ad() {
+ global $conf;
+ $this->cnf = $conf['auth']['ad'];
+
+
+ // additional information fields
+ if (isset($this->cnf['additional'])) {
+ $this->cnf['additional'] = str_replace(' ', '', $this->cnf['additional']);
+ $this->cnf['additional'] = explode(',', $this->cnf['additional']);
+ } else $this->cnf['additional'] = array();
+
+ // ldap extension is needed
+ if (!function_exists('ldap_connect')) {
+ if ($this->cnf['debug'])
+ msg("AD Auth: PHP LDAP extension not found.",-1);
+ $this->success = false;
+ return;
+ }
+
+ // Prepare SSO
+ if($_SERVER['REMOTE_USER'] && $this->cnf['sso']){
+ // remove possible NTLM domain
+ list($dom,$usr) = explode('\\',$_SERVER['REMOTE_USER'],2);
+ if(!$usr) $usr = $dom;
+
+ // remove possible Kerberos domain
+ list($usr,$dom) = explode('@',$usr);
+
+ $dom = strtolower($dom);
+ $_SERVER['REMOTE_USER'] = $usr;
+
+ // we need to simulate a login
+ if(empty($_COOKIE[DOKU_COOKIE])){
+ $_REQUEST['u'] = $_SERVER['REMOTE_USER'];
+ $_REQUEST['p'] = 'sso_only';
+ }
+ }
+
+ // prepare adLDAP standard configuration
+ $this->opts = $this->cnf;
+
+ // add possible domain specific configuration
+ if($dom && is_array($this->cnf[$dom])) foreach($this->cnf[$dom] as $key => $val){
+ $this->opts[$key] = $val;
+ }
+
+ // handle multiple AD servers
+ $this->opts['domain_controllers'] = explode(',',$this->opts['domain_controllers']);
+ $this->opts['domain_controllers'] = array_map('trim',$this->opts['domain_controllers']);
+ $this->opts['domain_controllers'] = array_filter($this->opts['domain_controllers']);
+
+ // we can change the password if SSL is set
+ if($this->opts['use_ssl'] || $this->opts['use_tls']){
+ $this->cando['modPass'] = true;
+ }
+ $this->cando['modName'] = true;
+ $this->cando['modMail'] = true;
+ }
+
+ /**
+ * 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>
+ * @return bool
+ */
+ function checkPass($user, $pass){
+ if($_SERVER['REMOTE_USER'] &&
+ $_SERVER['REMOTE_USER'] == $user &&
+ $this->cnf['sso']) return true;
+
+ if(!$this->_init()) return false;
+ return $this->adldap->authenticate($user, $pass);
+ }
+
+ /**
+ * 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 LDAP specific function returns the following
+ * addional fields:
+ *
+ * dn string distinguished name (DN)
+ * uid string Posix User ID
+ *
+ * @author James Van Lommel <james@nosq.com>
+ */
+ function getUserData($user){
+ global $conf;
+ if(!$this->_init()) return false;
+
+ $fields = array('mail','displayname','samaccountname');
+
+ // add additional fields to read
+ $fields = array_merge($fields, $this->cnf['additional']);
+ $fields = array_unique($fields);
+
+ //get info for given user
+ $result = $this->adldap->user_info($user, $fields);
+ //general user info
+ $info['name'] = $result[0]['displayname'][0];
+ $info['mail'] = $result[0]['mail'][0];
+ $info['uid'] = $result[0]['samaccountname'][0];
+ $info['dn'] = $result[0]['dn'];
+
+ // additional information
+ foreach ($this->cnf['additional'] as $field) {
+ if (isset($result[0][strtolower($field)])) {
+ $info[$field] = $result[0][strtolower($field)][0];
+ }
+ }
+
+ // handle ActiveDirectory memberOf
+ $info['grps'] = $this->adldap->user_groups($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'];
+ }
+
+ 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)
+ */
+ function cleanGroup($name) {
+ $sName = str_replace('\\', '', $name);
+ $sName = str_replace('#', '', $sName);
+ $sName = preg_replace('[\s]', '_', $sName);
+ return $sName;
+ }
+
+ /**
+ * Sanitize user names
+ */
+ function cleanUser($name) {
+ return $this->cleanGroup($name);
+ }
+
+ /**
+ * Most values in LDAP are case-insensitive
+ */
+ function isCaseSensitive(){
+ return false;
+ }
+
+ /**
+ * Bulk retrieval of user data
+ *
+ * @author Dominik Eckelmann <dokuwiki@cosmocode.de>
+ * @param start index of first user to be returned
+ * @param limit max number of users to be returned
+ * @param filter array of field/pattern pairs, null for no filter
+ * @return array of userinfo (refer getUserData for internal userinfo details)
+ */
+ function retrieveUsers($start=0,$limit=-1,$filter=array()) {
+ if(!$this->_init()) return false;
+
+ if ($this->users === null) {
+ //get info for given user
+ $result = $this->adldap->all_users();
+ 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;
+ }
+
+ /**
+ * Modify user data
+ *
+ * @param $user nick of the user to be changed
+ * @param $changes array of field/value pairs to be changed
+ * @return bool
+ */
+ function modifyUser($user, $changes) {
+ $return = true;
+
+ // password changing
+ if(isset($changes['pass'])){
+ try {
+ $return = $this->adldap->user_password($user,$changes['pass']);
+ } catch (adLDAPException $e) {
+ if ($this->cnf['debug']) msg('AD Auth: '.$e->getMessage(), -1);
+ $return = false;
+ }
+ if(!$return) msg('AD Auth: failed to change the password. Maybe the password policy was not met?',-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 & $this->adldap->user_modify($user,$adchanges);
+ } catch (adLDAPException $e) {
+ if ($this->cnf['debug']) msg('AD Auth: '.$e->getMessage(), -1);
+ $return = false;
+ }
+ }
+
+ return $return;
+ }
+
+ /**
+ * Initialize the AdLDAP library and connect to the server
+ */
+ function _init(){
+ if(!is_null($this->adldap)) return true;
+
+ // connect
+ try {
+ $this->adldap = new adLDAP($this->opts);
+ if (isset($this->opts['ad_username']) && isset($this->opts['ad_password'])) {
+ $this->canDo['getUsers'] = true;
+ }
+ return true;
+ } catch (adLDAPException $e) {
+ if ($this->cnf['debug']) {
+ msg('AD Auth: '.$e->getMessage(), -1);
+ }
+ $this->success = false;
+ $this->adldap = null;
+ }
+ return false;
+ }
+
+ /**
+ * return 1 if $user + $info match $filter criteria, 0 otherwise
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+ function _filter($user, $info) {
+ foreach ($this->_pattern as $item => $pattern) {
+ if ($item == 'user') {
+ if (!preg_match($pattern, $user)) return 0;
+ } else if ($item == 'grps') {
+ if (!count(preg_grep($pattern, $info['grps']))) return 0;
+ } else {
+ if (!preg_match($pattern, $info[$item])) return 0;
+ }
+ }
+ return 1;
+ }
+
+ function _constructPattern($filter) {
+ $this->_pattern = array();
+ foreach ($filter as $item => $pattern) {
+// $this->_pattern[$item] = '/'.preg_quote($pattern,"/").'/i'; // don't allow regex characters
+ $this->_pattern[$item] = '/'.str_replace('/','\/',$pattern).'/i'; // allow regex characters
+ }
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/auth/basic.class.php b/inc/auth/basic.class.php
new file mode 100644
index 000000000..c7e7031bf
--- /dev/null
+++ b/inc/auth/basic.class.php
@@ -0,0 +1,403 @@
+<?php
+/**
+ * auth/basic.class.php
+ *
+ * foundation authorisation class
+ * all auth classes should inherit from this class
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+class auth_basic {
+
+ var $success = true;
+
+
+ /**
+ * Posible 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.
+ */
+ var $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
+ *
+ * Set $this->success to false if checks fail
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ function auth_basic() {
+ // the base class constructor does nothing, derived class
+ // constructors do the real work
+ }
+
+ /**
+ * 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>
+ * @return bool
+ */
+ 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 mixed Result from the modification function or false if an event handler has canceled the action
+ */
+ function triggerUserMod($type, $params)
+ {
+ $validTypes = array(
+ 'create' => 'createUser',
+ 'modify' => 'modifyUser',
+ 'delete' => 'deleteUsers'
+ );
+ if(empty($validTypes[$type]))
+ return false;
+ $eventdata = array('type' => $type, 'params' => $params, 'modification_result' => null);
+ $evt = new Doku_Event('AUTH_USER_CHANGE', $eventdata);
+ if ($evt->advise_before(true)) {
+ $result = call_user_func_array(array($this, $validTypes[$type]), $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>
+ */
+ 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, thus
+ * implementing the checkPass() function is not needed
+ * 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
+ */
+ 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>
+ * @return bool
+ */
+ 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 addres of the user
+ * grps array list of groups the user is in
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return array containing user data or false
+ */
+ function getUserData($user) {
+ 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>
+ */
+ 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 $user nick of the user to be changed
+ * @param $changes array of field/value pairs to be changed (password will be clear text)
+ * @return bool
+ */
+ 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
+ */
+ function deleteUsers($users) {
+ msg("authorisation method does not allow deleting of users", -1);
+ return false;
+ }
+
+ /**
+ * 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>
+ */
+ 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 start index of first user to be returned
+ * @param limit max number of users to be returned
+ * @param filter array of field/pattern pairs, null for no filter
+ * @return array of userinfo (refer getUserData for internal userinfo details)
+ */
+ function retrieveUsers($start=0,$limit=-1,$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>
+ * @return bool
+ */
+ 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>
+ * @return array
+ */
+ 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
+ */
+ 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
+ * @param string - the cleaned username
+ */
+ 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
+ * @param string - the cleaned groupname
+ */
+ 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
+ */
+ function useSessionCache($user){
+ global $conf;
+ return ($_SESSION[DOKU_COOKIE]['auth']['time'] >= @filemtime($conf['cachedir'].'/sessionpurge'));
+ }
+
+}
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/auth/ldap.class.php b/inc/auth/ldap.class.php
new file mode 100644
index 000000000..8eb411995
--- /dev/null
+++ b/inc/auth/ldap.class.php
@@ -0,0 +1,463 @@
+<?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>
+ */
+
+class auth_ldap extends auth_basic {
+ var $cnf = null;
+ var $con = null;
+ var $bound = 0; // 0: anonymous, 1: user, 2: superuser
+
+ /**
+ * Constructor
+ */
+ function auth_ldap(){
+ global $conf;
+ $this->cnf = $conf['auth']['ldap'];
+
+ // ldap extension is needed
+ if(!function_exists('ldap_connect')) {
+ if ($this->cnf['debug'])
+ msg("LDAP err: PHP LDAP extension not found.",-1,__LINE__,__FILE__);
+ $this->success = false;
+ return;
+ }
+
+ if(empty($this->cnf['groupkey'])) $this->cnf['groupkey'] = 'cn';
+ if(empty($this->cnf['userscope'])) $this->cnf['userscope'] = 'sub';
+ if(empty($this->cnf['groupscope'])) $this->cnf['groupscope'] = 'sub';
+
+ // auth_ldap currently just handles authentication, so no
+ // capabilities are set
+ }
+
+ /**
+ * Check user+password
+ *
+ * Checks if the given user exists and the given
+ * plaintext password is correct by trying to bind
+ * to the LDAP server
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return bool
+ */
+ function checkPass($user,$pass){
+ // reject empty password
+ if(empty($pass)) return false;
+ if(!$this->_openLDAP()) return false;
+
+ // indirect user bind
+ if($this->cnf['binddn'] && $this->cnf['bindpw']){
+ // use superuser credentials
+ if(!@ldap_bind($this->con,$this->cnf['binddn'],$this->cnf['bindpw'])){
+ if($this->cnf['debug'])
+ msg('LDAP bind as superuser: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
+ return false;
+ }
+ $this->bound = 2;
+ }else if($this->cnf['binddn'] &&
+ $this->cnf['usertree'] &&
+ $this->cnf['userfilter']) {
+ // special bind string
+ $dn = $this->_makeFilter($this->cnf['binddn'],
+ array('user'=>$user,'server'=>$this->cnf['server']));
+
+ }else if(strpos($this->cnf['usertree'], '%{user}')) {
+ // direct user bind
+ $dn = $this->_makeFilter($this->cnf['usertree'],
+ array('user'=>$user,'server'=>$this->cnf['server']));
+
+ }else{
+ // Anonymous bind
+ if(!@ldap_bind($this->con)){
+ msg("LDAP: can not bind anonymously",-1);
+ if($this->cnf['debug'])
+ msg('LDAP anonymous bind: '.htmlspecialchars(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)){
+ if($this->cnf['debug']){
+ msg("LDAP: bind with $dn failed", -1,__LINE__,__FILE__);
+ msg('LDAP user dn bind: '.htmlspecialchars(ldap_error($this->con)),0);
+ }
+ return false;
+ }
+ $this->bound = 1;
+ return true;
+ }else{
+ // See if we can find the user
+ $info = $this->getUserData($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)){
+ if($this->cnf['debug']){
+ msg("LDAP: bind with $dn failed", -1,__LINE__,__FILE__);
+ msg('LDAP user bind: '.htmlspecialchars(ldap_error($this->con)),0);
+ }
+ return false;
+ }
+ $this->bound = 1;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * 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
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Trouble
+ * @author Dan Allen <dan.j.allen@gmail.com>
+ * @author <evaldas.auryla@pheur.org>
+ * @author Stephane Chazelas <stephane.chazelas@emerson.com>
+ * @return array containing user data or false
+ */
+ function getUserData($user,$inbind=false) {
+ global $conf;
+ if(!$this->_openLDAP()) return false;
+
+ // force superuser bind if wanted and not bound as superuser yet
+ if($this->cnf['binddn'] && $this->cnf['bindpw'] && $this->bound < 2){
+ // use superuser credentials
+ if(!@ldap_bind($this->con,$this->cnf['binddn'],$this->cnf['bindpw'])){
+ if($this->cnf['debug'])
+ msg('LDAP bind as superuser: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
+ return false;
+ }
+ $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 = PMA_blowfish_decrypt($loginpass, auth_cookiesalt(!$loginsticky));
+ $this->checkPass($loginuser, $loginpass);
+ }
+ }
+
+ $info['user'] = $user;
+ $info['server'] = $this->cnf['server'];
+
+ //get info for given user
+ $base = $this->_makeFilter($this->cnf['usertree'], $info);
+ if(!empty($this->cnf['userfilter'])) {
+ $filter = $this->_makeFilter($this->cnf['userfilter'], $info);
+ } else {
+ $filter = "(ObjectClass=*)";
+ }
+
+ $sr = $this->_ldapsearch($this->con, $base, $filter, $this->cnf['userscope']);
+ $result = @ldap_get_entries($this->con, $sr);
+ if($this->cnf['debug']){
+ msg('LDAP user search: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
+ msg('LDAP search at: '.htmlspecialchars($base.' '.$filter),0,__LINE__,__FILE__);
+ }
+
+ // Don't accept more or less than one response
+ if(!is_array($result) || $result['count'] != 1){
+ return false; //user not found
+ }
+
+ $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->cnf['mapping'])){
+ foreach($this->cnf['mapping'] as $localkey => $key) {
+ if(is_array($key)) {
+ // use regexp to clean up user_result
+ list($key, $regexp) = each($key);
+ if($user_result[$key]) foreach($user_result[$key] as $grp){
+ if (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->cnf['grouptree'] || $this->cnf['groupfilter']) {
+ $base = $this->_makeFilter($this->cnf['grouptree'], $user_result);
+ $filter = $this->_makeFilter($this->cnf['groupfilter'], $user_result);
+ $sr = $this->_ldapsearch($this->con, $base, $filter, $this->cnf['groupscope'], array($this->cnf['groupkey']));
+ if($this->cnf['debug']){
+ msg('LDAP group search: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
+ msg('LDAP search at: '.htmlspecialchars($base.' '.$filter),0,__LINE__,__FILE__);
+ }
+ if(!$sr){
+ msg("LDAP: Reading group memberships failed",-1);
+ return false;
+ }
+ $result = ldap_get_entries($this->con, $sr);
+ ldap_free_result($sr);
+
+ if(is_array($result)) foreach($result as $grp){
+ if(!empty($grp[$this->cnf['groupkey']][0])){
+ if($this->cnf['debug'])
+ msg('LDAP usergroup: '.htmlspecialchars($grp[$this->cnf['groupkey']][0]),0,__LINE__,__FILE__);
+ $info['grps'][] = $grp[$this->cnf['groupkey']][0];
+ }
+ }
+ }
+
+ // always add the default group to the list of groups
+ if(!in_array($conf['defaultgroup'],$info['grps'])){
+ $info['grps'][] = $conf['defaultgroup'];
+ }
+ return $info;
+ }
+
+ /**
+ * Most values in LDAP are case-insensitive
+ */
+ function isCaseSensitive(){
+ return false;
+ }
+
+ /**
+ * Bulk retrieval of user data
+ *
+ * @author Dominik Eckelmann <dokuwiki@cosmocode.de>
+ * @param start index of first user to be returned
+ * @param limit max number of users to be returned
+ * @param filter array of field/pattern pairs, null for no filter
+ * @return array of userinfo (refer getUserData for internal userinfo details)
+ */
+ function retrieveUsers($start=0,$limit=-1,$filter=array()) {
+ if(!$this->_openLDAP()) return false;
+
+ if (!isset($this->users)) {
+ // Perform the search and grab all their details
+ if(!empty($this->cnf['userfilter'])) {
+ $all_filter = str_replace('%{user}', '*', $this->cnf['userfilter']);
+ } else {
+ $all_filter = "(ObjectClass=*)";
+ }
+ $sr=ldap_search($this->con,$this->cnf['usertree'],$all_filter);
+ $entries = ldap_get_entries($this->con, $sr);
+ $users_array = array();
+ for ($i=0; $i<$entries["count"]; $i++){
+ array_push($users_array, $entries[$i]["uid"][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
+ *
+ * filter string ldap search filter with placeholders
+ * placeholders array array with the placeholders
+ *
+ * @author Troels Liebe Bentsen <tlb@rapanden.dk>
+ * @return string
+ */
+ 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 1 if $user + $info match $filter criteria, 0 otherwise
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+ function _filter($user, $info) {
+ foreach ($this->_pattern as $item => $pattern) {
+ if ($item == 'user') {
+ if (!preg_match($pattern, $user)) return 0;
+ } else if ($item == 'grps') {
+ if (!count(preg_grep($pattern, $info['grps']))) return 0;
+ } else {
+ if (!preg_match($pattern, $info[$item])) return 0;
+ }
+ }
+ return 1;
+ }
+
+ function _constructPattern($filter) {
+ $this->_pattern = array();
+ foreach ($filter as $item => $pattern) {
+// $this->_pattern[$item] = '/'.preg_quote($pattern,"/").'/i'; // don't allow regex characters
+ $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
+ *
+ * @author Andreas Gohr
+ */
+ function _filterEscape($string){
+ return preg_replace('/([\x00-\x1F\*\(\)\\\\])/e',
+ '"\\\\\".join("",unpack("H2","$1"))',
+ $string);
+ }
+
+ /**
+ * Opens a connection to the configured LDAP server and sets the wanted
+ * option on the connection
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _openLDAP(){
+ if($this->con) return true; // connection already established
+
+ $this->bound = 0;
+
+ $port = ($this->cnf['port']) ? $this->cnf['port'] : 389;
+ $this->con = @ldap_connect($this->cnf['server'],$port);
+ if(!$this->con){
+ msg("LDAP: couldn't connect to LDAP server",-1);
+ return false;
+ }
+
+ //set protocol version and dependend options
+ if($this->cnf['version']){
+ if(!@ldap_set_option($this->con, LDAP_OPT_PROTOCOL_VERSION,
+ $this->cnf['version'])){
+ msg('Setting LDAP Protocol version '.$this->cnf['version'].' failed',-1);
+ if($this->cnf['debug'])
+ msg('LDAP version set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
+ }else{
+ //use TLS (needs version 3)
+ if($this->cnf['starttls']) {
+ if (!@ldap_start_tls($this->con)){
+ msg('Starting TLS failed',-1);
+ if($this->cnf['debug'])
+ msg('LDAP TLS set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
+ }
+ }
+ // needs version 3
+ if(isset($this->cnf['referrals'])) {
+ if(!@ldap_set_option($this->con, LDAP_OPT_REFERRALS,
+ $this->cnf['referrals'])){
+ msg('Setting LDAP referrals to off failed',-1);
+ if($this->cnf['debug'])
+ msg('LDAP referal set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
+ }
+ }
+ }
+ }
+
+ //set deref mode
+ if($this->cnf['deref']){
+ if(!@ldap_set_option($this->con, LDAP_OPT_DEREF, $this->cnf['deref'])){
+ msg('Setting LDAP Deref mode '.$this->cnf['deref'].' failed',-1);
+ if($this->cnf['debug'])
+ msg('LDAP deref set: '.htmlspecialchars(ldap_error($this->con)),0,__LINE__,__FILE__);
+ }
+ }
+
+ $this->canDo['getUsers'] = true;
+ return true;
+ }
+
+ /**
+ * Wraps around ldap_search, ldap_list or ldap_read depending on $scope
+ *
+ * @param $scope string - can be 'base', 'one' or 'sub'
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _ldapsearch($link_identifier, $base_dn, $filter, $scope='sub', $attributes=null,
+ $attrsonly=0, $sizelimit=0, $timelimit=0, $deref=LDAP_DEREF_NEVER){
+ if(is_null($attributes)) $attributes = array();
+
+ if($scope == 'base'){
+ return @ldap_read($link_identifier, $base_dn, $filter, $attributes,
+ $attrsonly, $sizelimit, $timelimit, $deref);
+ }elseif($scope == 'one'){
+ return @ldap_list($link_identifier, $base_dn, $filter, $attributes,
+ $attrsonly, $sizelimit, $timelimit, $deref);
+ }else{
+ return @ldap_search($link_identifier, $base_dn, $filter, $attributes,
+ $attrsonly, $sizelimit, $timelimit, $deref);
+ }
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/auth/mysql.class.php b/inc/auth/mysql.class.php
new file mode 100644
index 000000000..653c725a3
--- /dev/null
+++ b/inc/auth/mysql.class.php
@@ -0,0 +1,939 @@
+<?php
+/**
+ * MySQLP 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 Matthias Grimm <matthias.grimmm@sourceforge.net>
+*/
+
+class auth_mysql extends auth_basic {
+
+ var $dbcon = 0;
+ var $dbver = 0; // database version
+ var $dbrev = 0; // database revision
+ var $dbsub = 0; // database subrevision
+ var $cnf = null;
+ var $defaultgroup = "";
+
+ /**
+ * Constructor
+ *
+ * checks if the mysql interface is available, otherwise it will
+ * set the variable $success of the basis class to false
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function auth_mysql() {
+ global $conf;
+ $this->cnf = $conf['auth']['mysql'];
+
+ if (method_exists($this, 'auth_basic'))
+ parent::auth_basic();
+
+ if(!function_exists('mysql_connect')) {
+ if ($this->cnf['debug'])
+ msg("MySQL err: PHP MySQL extension not found.",-1,__LINE__,__FILE__);
+ $this->success = false;
+ return;
+ }
+
+ // default to UTF-8, you rarely want something else
+ if(!isset($this->cnf['charset'])) $this->cnf['charset'] = 'utf8';
+
+ $this->defaultgroup = $conf['defaultgroup'];
+
+ // set capabilities based upon config strings set
+ if (empty($this->cnf['server']) || empty($this->cnf['user']) ||
+ !isset($this->cnf['password']) || empty($this->cnf['database'])){
+ if ($this->cnf['debug'])
+ msg("MySQL err: insufficient configuration.",-1,__LINE__,__FILE__);
+ $this->success = false;
+ return;
+ }
+
+ $this->cando['addUser'] = $this->_chkcnf(array('getUserInfo',
+ 'getGroups',
+ 'addUser',
+ 'getUserID',
+ 'getGroupID',
+ 'addGroup',
+ 'addUserGroup'),true);
+ $this->cando['delUser'] = $this->_chkcnf(array('getUserID',
+ 'delUser',
+ 'delUserRefs'),true);
+ $this->cando['modLogin'] = $this->_chkcnf(array('getUserID',
+ 'updateUser',
+ 'UpdateTarget'),true);
+ $this->cando['modPass'] = $this->cando['modLogin'];
+ $this->cando['modName'] = $this->cando['modLogin'];
+ $this->cando['modMail'] = $this->cando['modLogin'];
+ $this->cando['modGroups'] = $this->_chkcnf(array('getUserID',
+ 'getGroups',
+ 'getGroupID',
+ 'addGroup',
+ 'addUserGroup',
+ 'delGroup',
+ 'getGroupID',
+ 'delUserGroup'),true);
+ /* getGroups is not yet supported
+ $this->cando['getGroups'] = $this->_chkcnf(array('getGroups',
+ 'getGroupID'),false); */
+ $this->cando['getUsers'] = $this->_chkcnf(array('getUsers',
+ 'getUserInfo',
+ 'getGroups'),false);
+ $this->cando['getUserCount'] = $this->_chkcnf(array('getUsers'),false);
+ }
+
+ /**
+ * Check if the given config strings are set
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @return bool
+ */
+ function _chkcnf($keys, $wop=false){
+ foreach ($keys as $key){
+ if (empty($this->cnf[$key])) return false;
+ }
+
+ /* write operation and lock array filled with tables names? */
+ if ($wop && (!is_array($this->cnf['TablesToLock']) ||
+ !count($this->cnf['TablesToLock']))){
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks if the given user exists and the given plaintext password
+ * is correct. Furtheron it might be checked wether the user is
+ * member of the right group
+ *
+ * Depending on which SQL string is defined in the config, password
+ * checking is done here (getpass) or by the database (passcheck)
+ *
+ * @param $user user who would like access
+ * @param $pass user's clear text password to check
+ * @return bool
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function checkPass($user,$pass){
+ $rc = false;
+
+ if($this->_openDB()) {
+ $sql = str_replace('%{user}',$this->_escape($user),$this->cnf['checkPass']);
+ $sql = str_replace('%{pass}',$this->_escape($pass),$sql);
+ $sql = str_replace('%{dgroup}',$this->_escape($this->defaultgroup),$sql);
+ $result = $this->_queryDB($sql);
+
+ if($result !== false && count($result) == 1) {
+ if($this->cnf['forwardClearPass'] == 1)
+ $rc = true;
+ else
+ $rc = auth_verifyPassword($pass,$result[0]['pass']);
+ }
+ $this->_closeDB();
+ }
+ return $rc;
+ }
+
+ /**
+ * [public function]
+ *
+ * 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 $user user's nick to get data for
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function getUserData($user){
+ if($this->_openDB()) {
+ $this->_lockTables("READ");
+ $info = $this->_getUserInfo($user);
+ $this->_unlockTables();
+ $this->_closeDB();
+ } else
+ $info = false;
+ return $info;
+ }
+
+ /**
+ * [public function]
+ *
+ * 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).
+ *
+ * @param $user nick of the user
+ * @param $pwd clear text password
+ * @param $name full name of the user
+ * @param $mail email address
+ * @param $grps array of groups the user should become member of
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function createUser($user,$pwd,$name,$mail,$grps=null){
+ if($this->_openDB()) {
+ if (($info = $this->_getUserInfo($user)) !== false)
+ return false; // user already exists
+
+ // set defaultgroup if no groups were given
+ if ($grps == null)
+ $grps = array($this->defaultgroup);
+
+ $this->_lockTables("WRITE");
+ $pwd = $this->cnf['forwardClearPass'] ? $pwd : auth_cryptPassword($pwd);
+ $rc = $this->_addUser($user,$pwd,$name,$mail,$grps);
+ $this->_unlockTables();
+ $this->_closeDB();
+ if ($rc) return true;
+ }
+ return null; // return error
+ }
+
+ /**
+ * Modify user data [public function]
+ *
+ * An existing user dataset will be modified. Changes are given in an array.
+ *
+ * The dataset update will be rejected if the user name should be changed
+ * to an already existing one.
+ *
+ * The password must be provides unencrypted. Pasword cryption is done
+ * automatically if configured.
+ *
+ * If one or more groups could't be updated, an error would be set. In
+ * this case the dataset might already be changed and we can't rollback
+ * the changes. Transactions would be really usefull here.
+ *
+ * modifyUser() may be called without SQL statements defined that are
+ * needed to change group membership (for example if only the user profile
+ * should be modified). In this case we asure that we don't touch groups
+ * even $changes['grps'] is set by mistake.
+ *
+ * @param $user nick of the user to be changed
+ * @param $changes array of field/value pairs to be changed (password
+ * will be clear text)
+ * @return bool true on success, false on error
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function modifyUser($user, $changes) {
+ $rc = false;
+
+ if (!is_array($changes) || !count($changes))
+ return true; // nothing to change
+
+ if($this->_openDB()) {
+ $this->_lockTables("WRITE");
+
+ if (($uid = $this->_getUserID($user))) {
+ $rc = $this->_updateUserInfo($changes, $uid);
+
+ if ($rc && isset($changes['grps']) && $this->cando['modGroups']) {
+ $groups = $this->_getGroups($user);
+ $grpadd = array_diff($changes['grps'], $groups);
+ $grpdel = array_diff($groups, $changes['grps']);
+
+ foreach($grpadd as $group)
+ if (($this->_addUserToGroup($user, $group, 1)) == false)
+ $rc = false;
+
+ foreach($grpdel as $group)
+ if (($this->_delUserFromGroup($user, $group)) == false)
+ $rc = false;
+ }
+ }
+
+ $this->_unlockTables();
+ $this->_closeDB();
+ }
+ return $rc;
+ }
+
+ /**
+ * [public function]
+ *
+ * Remove one or more users from the list of registered users
+ *
+ * @param array $users array of users to be deleted
+ * @return int the number of users deleted
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function deleteUsers($users) {
+ $count = 0;
+
+ if($this->_openDB()) {
+ if (is_array($users) && count($users)) {
+ $this->_lockTables("WRITE");
+ foreach ($users as $user) {
+ if ($this->_delUser($user))
+ $count++;
+ }
+ $this->_unlockTables();
+ }
+ $this->_closeDB();
+ }
+ return $count;
+ }
+
+ /**
+ * [public function]
+ *
+ * Counts users which meet certain $filter criteria.
+ *
+ * @param array $filter filter criteria in item/pattern pairs
+ * @return count of found users.
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function getUserCount($filter=array()) {
+ $rc = 0;
+
+ if($this->_openDB()) {
+ $sql = $this->_createSQLFilter($this->cnf['getUsers'], $filter);
+
+ if ($this->dbver >= 4) {
+ $sql = substr($sql, 6); /* remove 'SELECT' or 'select' */
+ $sql = "SELECT SQL_CALC_FOUND_ROWS".$sql." LIMIT 1";
+ $this->_queryDB($sql);
+ $result = $this->_queryDB("SELECT FOUND_ROWS()");
+ $rc = $result[0]['FOUND_ROWS()'];
+ } else if (($result = $this->_queryDB($sql)))
+ $rc = count($result);
+
+ $this->_closeDB();
+ }
+ return $rc;
+ }
+
+ /**
+ * Bulk retrieval of user data. [public function]
+ *
+ * @param first index of first user to be returned
+ * @param limit max number of users to be returned
+ * @param filter array of field/pattern pairs
+ * @return array of userinfo (refer getUserData for internal userinfo details)
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function retrieveUsers($first=0,$limit=10,$filter=array()) {
+ $out = array();
+
+ if($this->_openDB()) {
+ $this->_lockTables("READ");
+ $sql = $this->_createSQLFilter($this->cnf['getUsers'], $filter);
+ $sql .= " ".$this->cnf['SortOrder']." LIMIT $first, $limit";
+ $result = $this->_queryDB($sql);
+
+ if (!empty($result)) {
+ foreach ($result as $user)
+ if (($info = $this->_getUserInfo($user['user'])))
+ $out[$user['user']] = $info;
+ }
+
+ $this->_unlockTables();
+ $this->_closeDB();
+ }
+ return $out;
+ }
+
+ /**
+ * Give user membership of a group [public function]
+ *
+ * @param $user
+ * @param $group
+ * @return bool true on success, false on error
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function joinGroup($user, $group) {
+ $rc = false;
+
+ if ($this->_openDB()) {
+ $this->_lockTables("WRITE");
+ $rc = $this->_addUserToGroup($user, $group);
+ $this->_unlockTables();
+ $this->_closeDB();
+ }
+ return $rc;
+ }
+
+ /**
+ * Remove user from a group [public function]
+ *
+ * @param $user user that leaves a group
+ * @param $group group to leave
+ * @return bool
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function leaveGroup($user, $group) {
+ $rc = false;
+
+ if ($this->_openDB()) {
+ $this->_lockTables("WRITE");
+ $uid = $this->_getUserID($user);
+ $rc = $this->_delUserFromGroup($user, $group);
+ $this->_unlockTables();
+ $this->_closeDB();
+ }
+ return $rc;
+ }
+
+ /**
+ * MySQL is case-insensitive
+ */
+ function isCaseSensitive(){
+ return false;
+ }
+
+ /**
+ * Adds a user to a group.
+ *
+ * If $force is set to '1' non existing groups would be created.
+ *
+ * The database connection must already be established. Otherwise
+ * this function does nothing and returns 'false'. It is strongly
+ * recommended to call this function only after all participating
+ * tables (group and usergroup) have been locked.
+ *
+ * @param $user user to add to a group
+ * @param $group name of the group
+ * @param $force '1' create missing groups
+ * @return bool 'true' on success, 'false' on error
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _addUserToGroup($user, $group, $force=0) {
+ $newgroup = 0;
+
+ if (($this->dbcon) && ($user)) {
+ $gid = $this->_getGroupID($group);
+ if (!$gid) {
+ if ($force) { // create missing groups
+ $sql = str_replace('%{group}',$this->_escape($group),$this->cnf['addGroup']);
+ $gid = $this->_modifyDB($sql);
+ $newgroup = 1; // group newly created
+ }
+ if (!$gid) return false; // group didn't exist and can't be created
+ }
+
+ $sql = $this->cnf['addUserGroup'];
+ if(strpos($sql,'%{uid}') !== false){
+ $uid = $this->_getUserID($user);
+ $sql = str_replace('%{uid}', $this->_escape($uid),$sql);
+ }
+ $sql = str_replace('%{user}', $this->_escape($user),$sql);
+ $sql = str_replace('%{gid}', $this->_escape($gid),$sql);
+ $sql = str_replace('%{group}',$this->_escape($group),$sql);
+ if ($this->_modifyDB($sql) !== false) return true;
+
+ if ($newgroup) { // remove previously created group on error
+ $sql = str_replace('%{gid}', $this->_escape($gid),$this->cnf['delGroup']);
+ $sql = str_replace('%{group}',$this->_escape($group),$sql);
+ $this->_modifyDB($sql);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Remove user from a group
+ *
+ * @param $user user that leaves a group
+ * @param $group group to leave
+ * @return bool true on success, false on error
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _delUserFromGroup($user, $group) {
+ $rc = false;
+
+
+ if (($this->dbcon) && ($user)) {
+ $sql = $this->cnf['delUserGroup'];
+ if(strpos($sql,'%{uid}') !== false){
+ $uid = $this->_getUserID($user);
+ $sql = str_replace('%{uid}', $this->_escape($uid),$sql);
+ }
+ $gid = $this->_getGroupID($group);
+ if ($gid) {
+ $sql = str_replace('%{user}', $this->_escape($user),$sql);
+ $sql = str_replace('%{gid}', $this->_escape($gid),$sql);
+ $sql = str_replace('%{group}',$this->_escape($group),$sql);
+ $rc = $this->_modifyDB($sql) == 0 ? true : false;
+ }
+ }
+ return $rc;
+ }
+
+ /**
+ * Retrieves a list of groups the user is a member off.
+ *
+ * The database connection must already be established
+ * for this function to work. Otherwise it will return
+ * 'false'.
+ *
+ * @param $user user whose groups should be listed
+ * @return bool false on error
+ * @return array array containing all groups on success
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _getGroups($user) {
+ $groups = array();
+
+ if($this->dbcon) {
+ $sql = str_replace('%{user}',$this->_escape($user),$this->cnf['getGroups']);
+ $result = $this->_queryDB($sql);
+
+ if($result !== false && count($result)) {
+ foreach($result as $row)
+ $groups[] = $row['group'];
+ }
+ return $groups;
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves the user id of a given user name
+ *
+ * The database connection must already be established
+ * for this function to work. Otherwise it will return
+ * 'false'.
+ *
+ * @param $user user whose id is desired
+ * @return user id
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _getUserID($user) {
+ if($this->dbcon) {
+ $sql = str_replace('%{user}',$this->_escape($user),$this->cnf['getUserID']);
+ $result = $this->_queryDB($sql);
+ return $result === false ? false : $result[0]['id'];
+ }
+ return false;
+ }
+
+ /**
+ * Adds a new User to the database.
+ *
+ * The database connection must already be established
+ * for this function to work. Otherwise it will return
+ * 'false'.
+ *
+ * @param $user login of the user
+ * @param $pwd encrypted password
+ * @param $name full name of the user
+ * @param $mail email address
+ * @param $grps array of groups the user should become member of
+ * @return bool
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _addUser($user,$pwd,$name,$mail,$grps){
+ if($this->dbcon && is_array($grps)) {
+ $sql = str_replace('%{user}', $this->_escape($user),$this->cnf['addUser']);
+ $sql = str_replace('%{pass}', $this->_escape($pwd),$sql);
+ $sql = str_replace('%{name}', $this->_escape($name),$sql);
+ $sql = str_replace('%{email}',$this->_escape($mail),$sql);
+ $uid = $this->_modifyDB($sql);
+
+ if ($uid) {
+ foreach($grps as $group) {
+ $gid = $this->_addUserToGroup($user, $group, 1);
+ if ($gid === false) break;
+ }
+
+ if ($gid) return true;
+ else {
+ /* remove the new user and all group relations if a group can't
+ * be assigned. Newly created groups will remain in the database
+ * and won't be removed. This might create orphaned groups but
+ * is not a big issue so we ignore this problem here.
+ */
+ $this->_delUser($user);
+ if ($this->cnf['debug'])
+ msg ("MySQL err: Adding user '$user' to group '$group' failed.",-1,__LINE__,__FILE__);
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Deletes a given user and all his group references.
+ *
+ * The database connection must already be established
+ * for this function to work. Otherwise it will return
+ * 'false'.
+ *
+ * @param $user user whose id is desired
+ * @return bool
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _delUser($user) {
+ if($this->dbcon) {
+ $uid = $this->_getUserID($user);
+ if ($uid) {
+ $sql = str_replace('%{uid}',$this->_escape($uid),$this->cnf['delUserRefs']);
+ $this->_modifyDB($sql);
+ $sql = str_replace('%{uid}',$this->_escape($uid),$this->cnf['delUser']);
+ $sql = str_replace('%{user}', $this->_escape($user),$sql);
+ $this->_modifyDB($sql);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * getUserInfo
+ *
+ * Gets the data for a specific user The database connection
+ * must already be established for this function to work.
+ * Otherwise it will return 'false'.
+ *
+ * @param $user user's nick to get data for
+ * @return bool false on error
+ * @return array user info on success
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _getUserInfo($user){
+ $sql = str_replace('%{user}',$this->_escape($user),$this->cnf['getUserInfo']);
+ $result = $this->_queryDB($sql);
+ if($result !== false && count($result)) {
+ $info = $result[0];
+ $info['grps'] = $this->_getGroups($user);
+ return $info;
+ }
+ return false;
+ }
+
+ /**
+ * Updates the user info in the database
+ *
+ * Update a user data structure in the database according changes
+ * given in an array. The user name can only be changes if it didn't
+ * exists already. If the new user name exists the update procedure
+ * will be aborted. The database keeps unchanged.
+ *
+ * The database connection has already to be established for this
+ * function to work. Otherwise it will return 'false'.
+ *
+ * The password will be crypted if necessary.
+ *
+ * @param $changes array of items to change as pairs of item and value
+ * @param $uid user id of dataset to change, must be unique in DB
+ * @return true on success or false on error
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _updateUserInfo($changes, $uid) {
+ $sql = $this->cnf['updateUser']." ";
+ $cnt = 0;
+ $err = 0;
+
+ if($this->dbcon) {
+ foreach ($changes as $item => $value) {
+ if ($item == 'user') {
+ if (($this->_getUserID($changes['user']))) {
+ $err = 1; /* new username already exists */
+ break; /* abort update */
+ }
+ if ($cnt++ > 0) $sql .= ", ";
+ $sql .= str_replace('%{user}',$value,$this->cnf['UpdateLogin']);
+ } else if ($item == 'name') {
+ if ($cnt++ > 0) $sql .= ", ";
+ $sql .= str_replace('%{name}',$value,$this->cnf['UpdateName']);
+ } else if ($item == 'pass') {
+ if (!$this->cnf['forwardClearPass'])
+ $value = auth_cryptPassword($value);
+ if ($cnt++ > 0) $sql .= ", ";
+ $sql .= str_replace('%{pass}',$value,$this->cnf['UpdatePass']);
+ } else if ($item == 'mail') {
+ if ($cnt++ > 0) $sql .= ", ";
+ $sql .= str_replace('%{email}',$value,$this->cnf['UpdateEmail']);
+ }
+ }
+
+ if ($err == 0) {
+ if ($cnt > 0) {
+ $sql .= " ".str_replace('%{uid}', $uid, $this->cnf['UpdateTarget']);
+ if(get_class($this) == 'auth_mysql') $sql .= " LIMIT 1"; //some PgSQL inheritance comp.
+ $this->_modifyDB($sql);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves the group id of a given group name
+ *
+ * The database connection must already be established
+ * for this function to work. Otherwise it will return
+ * 'false'.
+ *
+ * @param $group group name which id is desired
+ * @return group id
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _getGroupID($group) {
+ if($this->dbcon) {
+ $sql = str_replace('%{group}',$this->_escape($group),$this->cnf['getGroupID']);
+ $result = $this->_queryDB($sql);
+ return $result === false ? false : $result[0]['id'];
+ }
+ return false;
+ }
+
+ /**
+ * Opens a connection to a database and saves the handle for further
+ * usage in the object. The successful call to this functions is
+ * essential for most functions in this object.
+ *
+ * @return bool
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _openDB() {
+ if (!$this->dbcon) {
+ $con = @mysql_connect ($this->cnf['server'], $this->cnf['user'], $this->cnf['password']);
+ if ($con) {
+ if ((mysql_select_db($this->cnf['database'], $con))) {
+ if ((preg_match("/^(\d+)\.(\d+)\.(\d+).*/", mysql_get_server_info ($con), $result)) == 1) {
+ $this->dbver = $result[1];
+ $this->dbrev = $result[2];
+ $this->dbsub = $result[3];
+ }
+ $this->dbcon = $con;
+ if(!empty($this->cnf['charset'])){
+ mysql_query('SET CHARACTER SET "' . $this->cnf['charset'] . '"', $con);
+ }
+ return true; // connection and database successfully opened
+ } else {
+ mysql_close ($con);
+ if ($this->cnf['debug'])
+ msg("MySQL err: No access to database {$this->cnf['database']}.",-1,__LINE__,__FILE__);
+ }
+ } else if ($this->cnf['debug'])
+ msg ("MySQL err: Connection to {$this->cnf['user']}@{$this->cnf['server']} not possible.",
+ -1,__LINE__,__FILE__);
+
+ return false; // connection failed
+ }
+ return true; // connection already open
+ }
+
+ /**
+ * Closes a database connection.
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _closeDB() {
+ if ($this->dbcon) {
+ mysql_close ($this->dbcon);
+ $this->dbcon = 0;
+ }
+ }
+
+ /**
+ * Sends a SQL query to the database and transforms the result into
+ * an associative array.
+ *
+ * This function is only able to handle queries that returns a
+ * table such as SELECT.
+ *
+ * @param $query SQL string that contains the query
+ * @return array with the result table
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _queryDB($query) {
+ if($this->cnf['debug'] >= 2){
+ msg('MySQL query: '.hsc($query),0,__LINE__,__FILE__);
+ }
+
+ $resultarray = array();
+ if ($this->dbcon) {
+ $result = @mysql_query($query,$this->dbcon);
+ if ($result) {
+ while (($t = mysql_fetch_assoc($result)) !== false)
+ $resultarray[]=$t;
+ mysql_free_result ($result);
+ return $resultarray;
+ }
+ if ($this->cnf['debug'])
+ msg('MySQL err: '.mysql_error($this->dbcon),-1,__LINE__,__FILE__);
+ }
+ return false;
+ }
+
+ /**
+ * Sends a SQL query to the database
+ *
+ * This function is only able to handle queries that returns
+ * either nothing or an id value such as INPUT, DELETE, UPDATE, etc.
+ *
+ * @param $query SQL string that contains the query
+ * @return insert id or 0, false on error
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _modifyDB($query) {
+ if ($this->dbcon) {
+ $result = @mysql_query($query,$this->dbcon);
+ if ($result) {
+ $rc = mysql_insert_id($this->dbcon); //give back ID on insert
+ if ($rc !== false) return $rc;
+ }
+ if ($this->cnf['debug'])
+ msg('MySQL err: '.mysql_error($this->dbcon),-1,__LINE__,__FILE__);
+ }
+ return false;
+ }
+
+ /**
+ * Locked a list of tables for exclusive access so that modifications
+ * to the database can't be disturbed by other threads. The list
+ * could be set with $conf['auth']['mysql']['TablesToLock'] = array()
+ *
+ * If aliases for tables are used in SQL statements, also this aliases
+ * must be locked. For eg. you use a table 'user' and the alias 'u' in
+ * some sql queries, the array must looks like this (order is important):
+ * array("user", "user AS u");
+ *
+ * MySQL V3 is not able to handle transactions with COMMIT/ROLLBACK
+ * so that this functionality is simulated by this function. Nevertheless
+ * it is not as powerful as transactions, it is a good compromise in safty.
+ *
+ * @param $mode could be 'READ' or 'WRITE'
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _lockTables($mode) {
+ if ($this->dbcon) {
+ if (is_array($this->cnf['TablesToLock']) && !empty($this->cnf['TablesToLock'])) {
+ if ($mode == "READ" || $mode == "WRITE") {
+ $sql = "LOCK TABLES ";
+ $cnt = 0;
+ foreach ($this->cnf['TablesToLock'] as $table) {
+ if ($cnt++ != 0) $sql .= ", ";
+ $sql .= "$table $mode";
+ }
+ $this->_modifyDB($sql);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Unlock locked tables. All existing locks of this thread will be
+ * abrogated.
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _unlockTables() {
+ if ($this->dbcon) {
+ $this->_modifyDB("UNLOCK TABLES");
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Transforms the filter settings in an filter string for a SQL database
+ * The database connection must already be established, otherwise the
+ * original SQL string without filter criteria will be returned.
+ *
+ * @param $sql SQL string to which the $filter criteria should be added
+ * @param $filter array of filter criteria as pairs of item and pattern
+ * @return SQL string with attached $filter criteria on success
+ * @return the original SQL string on error.
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _createSQLFilter($sql, $filter) {
+ $SQLfilter = "";
+ $cnt = 0;
+
+ if ($this->dbcon) {
+ foreach ($filter as $item => $pattern) {
+ $tmp = '%'.$this->_escape($pattern).'%';
+ if ($item == 'user') {
+ if ($cnt++ > 0) $SQLfilter .= " AND ";
+ $SQLfilter .= str_replace('%{user}',$tmp,$this->cnf['FilterLogin']);
+ } else if ($item == 'name') {
+ if ($cnt++ > 0) $SQLfilter .= " AND ";
+ $SQLfilter .= str_replace('%{name}',$tmp,$this->cnf['FilterName']);
+ } else if ($item == 'mail') {
+ if ($cnt++ > 0) $SQLfilter .= " AND ";
+ $SQLfilter .= str_replace('%{email}',$tmp,$this->cnf['FilterEmail']);
+ } else if ($item == 'grps') {
+ if ($cnt++ > 0) $SQLfilter .= " AND ";
+ $SQLfilter .= str_replace('%{group}',$tmp,$this->cnf['FilterGroup']);
+ }
+ }
+
+ // we have to check SQLfilter here and must not use $cnt because if
+ // any of cnf['Filter????'] is not defined, a malformed SQL string
+ // would be generated.
+
+ if (strlen($SQLfilter)) {
+ $glue = strpos(strtolower($sql),"where") ? " AND " : " WHERE ";
+ $sql = $sql.$glue.$SQLfilter;
+ }
+ }
+
+ return $sql;
+ }
+
+ /**
+ * Escape a string for insertion into the database
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $string The string to escape
+ * @param boolean $like Escape wildcard chars as well?
+ */
+ function _escape($string,$like=false){
+ if($this->dbcon){
+ $string = mysql_real_escape_string($string, $this->dbcon);
+ }else{
+ $string = addslashes($string);
+ }
+ if($like){
+ $string = addcslashes($string,'%_');
+ }
+ return $string;
+ }
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/auth/pgsql.class.php b/inc/auth/pgsql.class.php
new file mode 100644
index 000000000..cf8bf7600
--- /dev/null
+++ b/inc/auth/pgsql.class.php
@@ -0,0 +1,410 @@
+<?php
+/**
+ * PgSQL authentication backend
+ *
+ * This class inherits much functionality from the MySQL class
+ * and just reimplements the Postgres specific parts.
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Matthias Grimm <matthias.grimmm@sourceforge.net>
+*/
+
+require_once(DOKU_INC.'inc/auth/mysql.class.php');
+
+class auth_pgsql extends auth_mysql {
+
+ /**
+ * Constructor
+ *
+ * checks if the pgsql interface is available, otherwise it will
+ * set the variable $success of the basis class to false
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function auth_pgsql() {
+ global $conf;
+ $this->cnf = $conf['auth']['pgsql'];
+ if(!$this->cnf['port']) $this->cnf['port'] = 5432;
+
+ if (method_exists($this, 'auth_basic'))
+ parent::auth_basic();
+
+ if(!function_exists('pg_connect')) {
+ if ($this->cnf['debug'])
+ msg("PgSQL err: PHP Postgres extension not found.",-1);
+ $this->success = false;
+ return;
+ }
+
+ $this->defaultgroup = $conf['defaultgroup'];
+
+ // set capabilities based upon config strings set
+ if (empty($this->cnf['user']) ||
+ empty($this->cnf['password']) || empty($this->cnf['database'])){
+ if ($this->cnf['debug'])
+ msg("PgSQL err: insufficient configuration.",-1,__LINE__,__FILE__);
+ $this->success = false;
+ return;
+ }
+
+ $this->cando['addUser'] = $this->_chkcnf(array('getUserInfo',
+ 'getGroups',
+ 'addUser',
+ 'getUserID',
+ 'getGroupID',
+ 'addGroup',
+ 'addUserGroup'));
+ $this->cando['delUser'] = $this->_chkcnf(array('getUserID',
+ 'delUser',
+ 'delUserRefs'));
+ $this->cando['modLogin'] = $this->_chkcnf(array('getUserID',
+ 'updateUser',
+ 'UpdateTarget'));
+ $this->cando['modPass'] = $this->cando['modLogin'];
+ $this->cando['modName'] = $this->cando['modLogin'];
+ $this->cando['modMail'] = $this->cando['modLogin'];
+ $this->cando['modGroups'] = $this->_chkcnf(array('getUserID',
+ 'getGroups',
+ 'getGroupID',
+ 'addGroup',
+ 'addUserGroup',
+ 'delGroup',
+ 'getGroupID',
+ 'delUserGroup'));
+ /* getGroups is not yet supported
+ $this->cando['getGroups'] = $this->_chkcnf(array('getGroups',
+ 'getGroupID')); */
+ $this->cando['getUsers'] = $this->_chkcnf(array('getUsers',
+ 'getUserInfo',
+ 'getGroups'));
+ $this->cando['getUserCount'] = $this->_chkcnf(array('getUsers'));
+ }
+
+ /**
+ * Check if the given config strings are set
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @return bool
+ */
+ function _chkcnf($keys, $wop=false){
+ foreach ($keys as $key){
+ if (empty($this->cnf[$key])) return false;
+ }
+ return true;
+ }
+
+ // @inherit function checkPass($user,$pass)
+ // @inherit function getUserData($user)
+ // @inherit function createUser($user,$pwd,$name,$mail,$grps=null)
+ // @inherit function modifyUser($user, $changes)
+ // @inherit function deleteUsers($users)
+
+
+ /**
+ * [public function]
+ *
+ * Counts users which meet certain $filter criteria.
+ *
+ * @param array $filter filter criteria in item/pattern pairs
+ * @return count of found users.
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function getUserCount($filter=array()) {
+ $rc = 0;
+
+ if($this->_openDB()) {
+ $sql = $this->_createSQLFilter($this->cnf['getUsers'], $filter);
+
+ // no equivalent of SQL_CALC_FOUND_ROWS in pgsql?
+ if (($result = $this->_queryDB($sql))){
+ $rc = count($result);
+ }
+ $this->_closeDB();
+ }
+ return $rc;
+ }
+
+ /**
+ * Bulk retrieval of user data. [public function]
+ *
+ * @param first index of first user to be returned
+ * @param limit max number of users to be returned
+ * @param filter array of field/pattern pairs
+ * @return array of userinfo (refer getUserData for internal userinfo details)
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function retrieveUsers($first=0,$limit=10,$filter=array()) {
+ $out = array();
+
+ if($this->_openDB()) {
+ $this->_lockTables("READ");
+ $sql = $this->_createSQLFilter($this->cnf['getUsers'], $filter);
+ $sql .= " ".$this->cnf['SortOrder']." LIMIT $limit OFFSET $first";
+ $result = $this->_queryDB($sql);
+
+ foreach ($result as $user)
+ if (($info = $this->_getUserInfo($user['user'])))
+ $out[$user['user']] = $info;
+
+ $this->_unlockTables();
+ $this->_closeDB();
+ }
+ return $out;
+ }
+
+ // @inherit function joinGroup($user, $group)
+ // @inherit function leaveGroup($user, $group) {
+
+ /**
+ * Adds a user to a group.
+ *
+ * If $force is set to '1' non existing groups would be created.
+ *
+ * The database connection must already be established. Otherwise
+ * this function does nothing and returns 'false'.
+ *
+ * @param $user user to add to a group
+ * @param $group name of the group
+ * @param $force '1' create missing groups
+ * @return bool 'true' on success, 'false' on error
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _addUserToGroup($user, $group, $force=0) {
+ $newgroup = 0;
+
+ if (($this->dbcon) && ($user)) {
+ $gid = $this->_getGroupID($group);
+ if (!$gid) {
+ if ($force) { // create missing groups
+ $sql = str_replace('%{group}',addslashes($group),$this->cnf['addGroup']);
+ $this->_modifyDB($sql);
+ //group should now exists try again to fetch it
+ $gid = $this->_getGroupID($group);
+ $newgroup = 1; // group newly created
+ }
+ }
+ if (!$gid) return false; // group didn't exist and can't be created
+
+ $sql = $this->cnf['addUserGroup'];
+ if(strpos($sql,'%{uid}') !== false){
+ $uid = $this->_getUserID($user);
+ $sql = str_replace('%{uid}', addslashes($uid), $sql);
+ }
+ $sql = str_replace('%{user}', addslashes($user),$sql);
+ $sql = str_replace('%{gid}', addslashes($gid),$sql);
+ $sql = str_replace('%{group}',addslashes($group),$sql);
+ if ($this->_modifyDB($sql) !== false) return true;
+
+ if ($newgroup) { // remove previously created group on error
+ $sql = str_replace('%{gid}', addslashes($gid),$this->cnf['delGroup']);
+ $sql = str_replace('%{group}',addslashes($group),$sql);
+ $this->_modifyDB($sql);
+ }
+ }
+ return false;
+ }
+
+ // @inherit function _delUserFromGroup($user $group)
+ // @inherit function _getGroups($user)
+ // @inherit function _getUserID($user)
+
+ /**
+ * Adds a new User to the database.
+ *
+ * The database connection must already be established
+ * for this function to work. Otherwise it will return
+ * 'false'.
+ *
+ * @param $user login of the user
+ * @param $pwd encrypted password
+ * @param $name full name of the user
+ * @param $mail email address
+ * @param $grps array of groups the user should become member of
+ * @return bool
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _addUser($user,$pwd,$name,$mail,$grps){
+ if($this->dbcon && is_array($grps)) {
+ $sql = str_replace('%{user}', addslashes($user),$this->cnf['addUser']);
+ $sql = str_replace('%{pass}', addslashes($pwd),$sql);
+ $sql = str_replace('%{name}', addslashes($name),$sql);
+ $sql = str_replace('%{email}',addslashes($mail),$sql);
+ if($this->_modifyDB($sql)){
+ $uid = $this->_getUserID($user);
+ }else{
+ return false;
+ }
+
+ if ($uid) {
+ foreach($grps as $group) {
+ $gid = $this->_addUserToGroup($user, $group, 1);
+ if ($gid === false) break;
+ }
+
+ if ($gid) return true;
+ else {
+ /* remove the new user and all group relations if a group can't
+ * be assigned. Newly created groups will remain in the database
+ * and won't be removed. This might create orphaned groups but
+ * is not a big issue so we ignore this problem here.
+ */
+ $this->_delUser($user);
+ if ($this->cnf['debug'])
+ msg("PgSQL err: Adding user '$user' to group '$group' failed.",-1,__LINE__,__FILE__);
+ }
+ }
+ }
+ return false;
+ }
+
+ // @inherit function _delUser($user)
+ // @inherit function _getUserInfo($user)
+ // @inherit function _updateUserInfo($changes, $uid)
+ // @inherit function _getGroupID($group)
+
+ /**
+ * Opens a connection to a database and saves the handle for further
+ * usage in the object. The successful call to this functions is
+ * essential for most functions in this object.
+ *
+ * @return bool
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _openDB() {
+ if (!$this->dbcon) {
+ $dsn = $this->cnf['server'] ? 'host='.$this->cnf['server'] : '';
+ $dsn .= ' port='.$this->cnf['port'];
+ $dsn .= ' dbname='.$this->cnf['database'];
+ $dsn .= ' user='.$this->cnf['user'];
+ $dsn .= ' password='.$this->cnf['password'];
+
+ $con = @pg_connect($dsn);
+ if ($con) {
+ $this->dbcon = $con;
+ return true; // connection and database successfully opened
+ } else if ($this->cnf['debug']){
+ msg ("PgSQL err: Connection to {$this->cnf['user']}@{$this->cnf['server']} not possible.",
+ -1,__LINE__,__FILE__);
+ }
+ return false; // connection failed
+ }
+ return true; // connection already open
+ }
+
+ /**
+ * Closes a database connection.
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _closeDB() {
+ if ($this->dbcon) {
+ pg_close ($this->dbcon);
+ $this->dbcon = 0;
+ }
+ }
+
+ /**
+ * Sends a SQL query to the database and transforms the result into
+ * an associative array.
+ *
+ * This function is only able to handle queries that returns a
+ * table such as SELECT.
+ *
+ * @param $query SQL string that contains the query
+ * @return array with the result table
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _queryDB($query) {
+ if ($this->dbcon) {
+ $result = @pg_query($this->dbcon,$query);
+ if ($result) {
+ while (($t = pg_fetch_assoc($result)) !== false)
+ $resultarray[]=$t;
+ pg_free_result ($result);
+ return $resultarray;
+ }elseif ($this->cnf['debug'])
+ msg('PgSQL err: '.pg_last_error($this->dbcon),-1,__LINE__,__FILE__);
+ }
+ return false;
+ }
+
+ /**
+ * Executes an update or insert query. This differs from the
+ * MySQL one because it does NOT return the last insertID
+ *
+ * @author Andreas Gohr
+ */
+ function _modifyDB($query) {
+ if ($this->dbcon) {
+ $result = @pg_query($this->dbcon,$query);
+ if ($result) {
+ pg_free_result ($result);
+ return true;
+ }
+ if ($this->cnf['debug']){
+ msg('PgSQL err: '.pg_last_error($this->dbcon),-1,__LINE__,__FILE__);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Start a transaction
+ *
+ * @param $mode could be 'READ' or 'WRITE'
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _lockTables($mode) {
+ if ($this->dbcon) {
+ $this->_modifyDB('BEGIN');
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Commit a transaction
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+ function _unlockTables() {
+ if ($this->dbcon) {
+ $this->_modifyDB('COMMIT');
+ return true;
+ }
+ return false;
+ }
+
+ // @inherit function _createSQLFilter($sql, $filter)
+
+
+ /**
+ * Escape a string for insertion into the database
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $string The string to escape
+ * @param boolean $like Escape wildcard chars as well?
+ */
+ function _escape($string,$like=false){
+ $string = pg_escape_string($string);
+ if($like){
+ $string = addcslashes($string,'%_');
+ }
+ return $string;
+ }
+
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/auth/plain.class.php b/inc/auth/plain.class.php
new file mode 100644
index 000000000..3941190e9
--- /dev/null
+++ b/inc/auth/plain.class.php
@@ -0,0 +1,328 @@
+<?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>
+ */
+
+class auth_plain extends auth_basic {
+
+ var $users = null;
+ var $_pattern = array();
+
+ /**
+ * Constructor
+ *
+ * Carry out sanity checks to ensure the object is
+ * able to operate. Set capabilities.
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ function auth_plain() {
+ 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;
+ }
+ }
+
+ /**
+ * Check user+password [required auth function]
+ *
+ * Checks if the given user exists and the given
+ * plaintext password is correct
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return bool
+ */
+ 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>
+ */
+ function getUserData($user){
+
+ if($this->users === null) $this->_loadUserData();
+ return isset($this->users[$user]) ? $this->users[$user] : false;
+ }
+
+ /**
+ * 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>
+ */
+ function createUser($user,$pwd,$name,$mail,$grps=null){
+ global $conf;
+ global $config_cascade;
+
+ // user mustn't already exist
+ if ($this->getUserData($user) !== false) return false;
+
+ $pass = auth_cryptPassword($pwd);
+
+ // set default group if no groups specified
+ if (!is_array($grps)) $grps = array($conf['defaultgroup']);
+
+ // prepare user line
+ $groups = join(',',$grps);
+ $userline = join(':',array($user,$pass,$name,$mail,$groups))."\n";
+
+ if (io_saveFile($config_cascade['plainauth.users']['default'],$userline,true)) {
+ $this->users[$user] = compact('pass','name','mail','grps');
+ return $pwd;
+ }
+
+ msg('The '.$config_cascade['plainauth.users']['default'].
+ ' file is not writable. Please inform the Wiki-Admin',-1);
+ return null;
+ }
+
+ /**
+ * Modify user data
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param $user nick of the user to be changed
+ * @param $changes array of field/value pairs to be changed (password will be clear text)
+ * @return bool
+ */
+ function modifyUser($user, $changes) {
+ global $conf;
+ global $ACT;
+ global $INFO;
+ global $config_cascade;
+
+ // sanity checks, user must already exist and there must be something to change
+ if (($userinfo = $this->getUserData($user)) === false) 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;
+ }
+
+ $groups = join(',',$userinfo['grps']);
+ $userline = join(':',array($newuser, $userinfo['pass'], $userinfo['name'], $userinfo['mail'], $groups))."\n";
+
+ if (!$this->deleteUsers(array($user))) {
+ msg('Unable to modify user data. Please inform the Wiki-Admin',-1);
+ return false;
+ }
+
+ if (!io_saveFile($config_cascade['plainauth.users']['default'],$userline,true)) {
+ msg('There was an error modifying your user data. You should register again.',-1);
+ // FIXME, user has been deleted but not recreated, should force a logout and redirect to login page
+ $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
+ */
+ 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) {
+ 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)) {
+ foreach ($deleted as $user) unset($this->users[$user]);
+ return count($deleted);
+ }
+
+ // problem deleting, 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>
+ */
+ 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 start index of first user to be returned
+ * @param limit max number of users to be returned
+ * @param filter array of field/pattern pairs
+ * @return array of userinfo (refer getUserData for internal userinfo details)
+ */
+ 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;
+ }
+
+ /**
+ * Only valid pageid's (no namespaces) for usernames
+ */
+ function cleanUser($user){
+ global $conf;
+ return cleanID(str_replace(':',$conf['sepchar'],$user));
+ }
+
+ /**
+ * Only valid pageid's (no namespaces) for groupnames
+ */
+ 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>
+ */
+ function _loadUserData(){
+ global $config_cascade;
+
+ $this->users = array();
+
+ if(!@file_exists($config_cascade['plainauth.users']['default'])) return;
+
+ $lines = file($config_cascade['plainauth.users']['default']);
+ foreach($lines as $line){
+ $line = preg_replace('/#.*$/','',$line); //ignore comments
+ $line = trim($line);
+ if(empty($line)) continue;
+
+ $row = explode(":",$line,5);
+ $groups = array_values(array_filter(explode(",",$row[4])));
+
+ $this->users[$row[0]]['pass'] = $row[1];
+ $this->users[$row[0]]['name'] = urldecode($row[2]);
+ $this->users[$row[0]]['mail'] = $row[3];
+ $this->users[$row[0]]['grps'] = $groups;
+ }
+ }
+
+ /**
+ * return 1 if $user + $info match $filter criteria, 0 otherwise
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+ function _filter($user, $info) {
+ // FIXME
+ foreach ($this->_pattern as $item => $pattern) {
+ if ($item == 'user') {
+ if (!preg_match($pattern, $user)) return 0;
+ } else if ($item == 'grps') {
+ if (!count(preg_grep($pattern, $info['grps']))) return 0;
+ } else {
+ if (!preg_match($pattern, $info[$item])) return 0;
+ }
+ }
+ return 1;
+ }
+
+ function _constructPattern($filter) {
+ $this->_pattern = array();
+ foreach ($filter as $item => $pattern) {
+// $this->_pattern[$item] = '/'.preg_quote($pattern,"/").'/i'; // don't allow regex characters
+ $this->_pattern[$item] = '/'.str_replace('/','\/',$pattern).'/i'; // allow regex characters
+ }
+ }
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/blowfish.php b/inc/blowfish.php
new file mode 100644
index 000000000..bcf5804a2
--- /dev/null
+++ b/inc/blowfish.php
@@ -0,0 +1,514 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * The Cipher_blowfish:: class implements the Cipher interface enryption data
+ * using the Blowfish algorithm.
+ *
+ * $Horde: horde/lib/Cipher/blowfish.php,v 1.2.2.3 2003/01/03 13:23:22 jan Exp $
+ *
+ * Copyright 2002-2003 Mike Cochrane <mike@graftonhall.co.nz>
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @version $Id: blowfish.php 11081 2008-01-25 09:35:48Z cybot_tm $
+ * @since Horde 2.2
+ * @package horde.cipher
+ */
+
+// Change for phpMyAdmin by lem9:
+//class Horde_Cipher_blowfish extends Horde_Cipher {
+class Horde_Cipher_blowfish
+{
+ /* Pi Array */
+ var $p = array(
+ 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
+ 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
+ 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
+ 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
+ 0x9216D5D9, 0x8979FB1B);
+
+ /* S Boxes */
+ var $s1 = 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);
+ var $s2 = 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);
+ var $s3 = 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);
+ var $s4 = 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);
+
+ /* The number of rounds to do */
+ var $_rounds = 16;
+
+ /**
+ * Set the key to be used for en/decryption
+ *
+ * @param String $key The key to use
+ */
+ function setKey($key) {
+ $key = $this->_formatKey($key);
+ $keyPos = $keyXor = 0;
+
+ $iMax = count($this->p);
+ $keyLen = count($key);
+ for ($i = 0; $i < $iMax; $i++) {
+ for ($t = 0; $t < 4; $t++) {
+ $keyXor = ($keyXor << 8) | (($key[$keyPos]) & 0x0ff);
+ if (++$keyPos == $keyLen) {
+ $keyPos = 0;
+ }
+ }
+ $this->p[$i] = $this->p[$i] ^ $keyXor;
+ }
+
+ $encZero = array('L' => 0, 'R' => 0);
+ for ($i = 0; $i + 1 < $iMax; $i += 2) {
+ $encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
+ $this->p[$i] = $encZero['L'];
+ $this->p[$i + 1] = $encZero['R'];
+ }
+
+ $iMax = count($this->s1);
+ for ($i = 0; $i < $iMax; $i += 2) {
+ $encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
+ $this->s1[$i] = $encZero['L'];
+ $this->s1[$i + 1] = $encZero['R'];
+ }
+
+ $iMax = count($this->s2);
+ for ($i = 0; $i < $iMax; $i += 2) {
+ $encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
+ $this->s2[$i] = $encZero['L'];
+ $this->s2[$i + 1] = $encZero['R'];
+ }
+
+ $iMax = count($this->s3);
+ for ($i = 0; $i < $iMax; $i += 2) {
+ $encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
+ $this->s3[$i] = $encZero['L'];
+ $this->s3[$i + 1] = $encZero['R'];
+ }
+
+ $iMax = count($this->s4);
+ for ($i = 0; $i < $iMax; $i += 2) {
+ $encZero = $this->_encryptBlock($encZero['L'], $encZero['R']);
+ $this->s4[$i] = $encZero['L'];
+ $this->s4[$i + 1] = $encZero['R'];
+ }
+
+ }
+
+ /**
+ * Encrypt a block on data.
+ *
+ * @param String $block The data to encrypt
+ * @param optional String $key The key to use
+ *
+ * @return String the encrypted output
+ */
+ function encryptBlock($block, $key = null) {
+ if (!is_null($key)) {
+ $this->setKey($key);
+ }
+
+ list($L, $R) = array_values(unpack('N*', $block));
+ $parts = $this->_encryptBlock($L, $R);
+ return pack("NN", $parts['L'], $parts['R']);
+ }
+
+ /**
+ * Encrypt a block on data.
+ *
+ * @param String $L The data to encrypt.
+ * @param String $R The data to encrypt.
+ *
+ * @return String The encrypted output.
+ */
+ function _encryptBlock($L, $R) {
+ $L ^= $this->p[0];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[1];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[2];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[3];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[4];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[5];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[6];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[7];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[8];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[9];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[10];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[11];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[12];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[13];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[14];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[15];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[16];
+ $R ^= $this->p[17];
+
+ return array('L' => $R, 'R' => $L);
+ }
+
+ /**
+ * Decrypt a block on data.
+ *
+ * @param String $block The data to decrypt
+ * @param optional String $key The key to use
+ *
+ * @return String the decrypted output
+ */
+ function decryptBlock($block, $key = null) {
+ if (!is_null($key)) {
+ $this->setKey($key);
+ }
+
+ // change for phpMyAdmin
+ $L = null;
+ $R = null;
+
+ $retarray = array_values(unpack('N*', $block));
+ if (isset($retarray[0])) {
+ $L = $retarray[0];
+ }
+ if (isset($retarray[1])) {
+ $R = $retarray[1];
+ }
+ // end change for phpMyAdmin
+
+ $L ^= $this->p[17];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[16];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[15];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[14];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[13];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[12];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[11];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[10];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[9];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[8];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[7];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[6];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[5];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[4];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[3];
+ $R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[2];
+ $L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[1];
+
+ $decrypted = pack("NN", $R ^ $this->p[0], $L);
+ return $decrypted;
+ }
+
+ /**
+ * Converts a text key into an array.
+ *
+ * @return array The key.
+ */
+ function _formatKey($key) {
+ return array_values(unpack('C*', $key));
+ }
+
+}
+
+// higher-level functions:
+/**
+ * Encryption using blowfish algorithm
+ *
+ * @param string original data
+ * @param string the secret
+ *
+ * @return string the encrypted result
+ *
+ * @access public
+ *
+ * @author lem9
+ */
+function PMA_blowfish_encrypt($data, $secret) {
+ $pma_cipher = new Horde_Cipher_blowfish;
+ $encrypt = '';
+
+ $data .= '_'; // triming fixed for DokuWiki FS#1690 FS#1713
+ $mod = strlen($data) % 8;
+
+ if ($mod > 0) {
+ $data .= str_repeat("\0", 8 - $mod);
+ }
+
+ foreach (str_split($data, 8) as $chunk) {
+ $encrypt .= $pma_cipher->encryptBlock($chunk, $secret);
+ }
+ return base64_encode($encrypt);
+}
+
+/**
+ * Decryption using blowfish algorithm
+ *
+ * @param string encrypted data
+ * @param string the secret
+ *
+ * @return string original data
+ *
+ * @access public
+ *
+ * @author lem9
+ */
+function PMA_blowfish_decrypt($encdata, $secret) {
+ $pma_cipher = new Horde_Cipher_blowfish;
+ $decrypt = '';
+ $data = base64_decode($encdata);
+
+ foreach (str_split($data, 8) as $chunk) {
+ $decrypt .= $pma_cipher->decryptBlock($chunk, $secret);
+ }
+ return substr(rtrim($decrypt, "\0"), 0, -1); // triming fixed for DokuWiki FS#1690 FS#1713
+}
diff --git a/inc/cache.php b/inc/cache.php
new file mode 100644
index 000000000..ff78e37ae
--- /dev/null
+++ b/inc/cache.php
@@ -0,0 +1,270 @@
+<?php
+/**
+ * Generic class to handle caching
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+class cache {
+ var $key = ''; // primary identifier for this item
+ var $ext = ''; // file ext for cache data, secondary identifier for this item
+ var $cache = ''; // cache file name
+ var $depends = array(); // array containing cache dependency information,
+ // used by _useCache to determine cache validity
+
+ var $_event = ''; // event to be triggered during useCache
+
+ function cache($key,$ext) {
+ $this->key = $key;
+ $this->ext = $ext;
+ $this->cache = getCacheName($key,$ext);
+ }
+
+ /**
+ * public method to determine whether the cache can be used
+ *
+ * to assist in cetralisation of event triggering and calculation of cache statistics,
+ * don't override this function override _useCache()
+ *
+ * @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
+ */
+ function useCache($depends=array()) {
+ $this->depends = $depends;
+ $this->_addDependencies();
+
+ if ($this->_event) {
+ return $this->_stats(trigger_event($this->_event,$this,array($this,'_useCache')));
+ } else {
+ return $this->_stats($this->_useCache());
+ }
+ }
+
+ /**
+ * private 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
+ *
+ * can be overridden
+ *
+ * @return bool see useCache()
+ */
+ function _useCache() {
+
+ 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
+ */
+ function _addDependencies() {
+ if (isset($_REQUEST['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
+ */
+ 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
+ */
+ function storeCache($data) {
+ return io_savefile($this->cache, $data);
+ }
+
+ /**
+ * remove any cached data associated with this cache instance
+ */
+ 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
+ */
+ 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;
+ }
+}
+
+class cache_parser extends cache {
+
+ var $file = ''; // source file for cache
+ var $mode = ''; // input mode (represents the processing the input file will undergo)
+
+ var $_event = 'PARSER_CACHE_USE';
+
+ function cache_parser($id, $file, $mode) {
+ if ($id) $this->page = $id;
+ $this->file = $file;
+ $this->mode = $mode;
+
+ parent::cache($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'],'.'.$mode);
+ }
+
+ function _useCache() {
+
+ if (!@file_exists($this->file)) return false; // source exists?
+ return parent::_useCache();
+ }
+
+ function _addDependencies() {
+ global $conf, $config_cascade;
+
+ $this->depends['age'] = isset($this->depends['age']) ?
+ min($this->depends['age'],$conf['cachetime']) : $conf['cachetime'];
+
+ // 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();
+ }
+
+}
+
+class cache_renderer extends cache_parser {
+ function _useCache() {
+ global $conf;
+
+ if (!parent::_useCache()) return false;
+
+ if (!isset($this->page)) {
+ return true;
+ }
+
+ // 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;
+ }
+
+ function _addDependencies() {
+
+ // 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)) {
+
+ $metafile = metaFN($this->page,'.meta');
+ $files[] = $metafile; // ... the page's own metadata
+
+ $valid = p_get_metadata($this->page, 'date valid'); // for xhtml this will render the metadata if needed
+ 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();
+ }
+}
+
+class cache_instructions extends cache_parser {
+
+ function cache_instructions($id, $file) {
+ parent::cache_parser($id, $file, 'i');
+ }
+
+ function retrieveCache($clean=true) {
+ $contents = io_readFile($this->cache, false);
+ return !empty($contents) ? unserialize($contents) : array();
+ }
+
+ function storeCache($instructions) {
+ return io_savefile($this->cache,serialize($instructions));
+ }
+}
diff --git a/inc/changelog.php b/inc/changelog.php
new file mode 100644
index 000000000..60f9b8657
--- /dev/null
+++ b/inc/changelog.php
@@ -0,0 +1,539 @@
+<?php
+/**
+ * Changelog handling functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// Constants for known core changelog line types.
+// Use these in place of string literals for more readable code.
+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');
+
+/**
+ * parses a changelog line into it's components
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function parseChangelogLine($line) {
+ $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'] = rtrim($tmp[6], "\n"); // extra data (varies by line type)
+ 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.
+ * Availible flags:
+ * - ExternalEdit - mark as an external edit.
+ *
+ * @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){
+ global $conf, $INFO;
+
+ // 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)?$_SERVER['REMOTE_USER']:'';
+
+ $strip = array("\t", "\n");
+ $logline = array(
+ 'date' => $date,
+ 'ip' => $remote,
+ 'type' => str_replace($strip, '', $type),
+ 'id' => $id,
+ 'user' => $user,
+ 'sum' => utf8_substr(str_replace($strip, '', $summary),0,255),
+ 'extra' => str_replace($strip, '', $extra)
+ );
+
+ // update metadata
+ if (!$wasRemoved) {
+ $oldmeta = p_read_metadata($id);
+ $meta = array();
+ if (!$INFO['exists'] && empty($oldmeta['persistent']['date']['created'])){ // newly created
+ $meta['date']['created'] = $created;
+ if ($user){
+ $meta['creator'] = $INFO['userinfo']['name'];
+ $meta['user'] = $user;
+ }
+ } elseif (!$INFO['exists'] && !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] = $INFO['userinfo']['name'];
+ } elseif (!$minor) { // non-minor modification
+ $meta['date']['modified'] = $date;
+ if ($user) $meta['contributor'][$user] = $INFO['userinfo']['name'];
+ }
+ $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>
+ */
+function addMediaLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extra='', $flags=null){
+ global $conf;
+
+ $id = cleanid($id);
+
+ if(!$date) $date = time(); //use current time if none supplied
+ $remote = clientIP(true);
+ $user = $_SERVER['REMOTE_USER'];
+
+ $strip = array("\t", "\n");
+ $logline = array(
+ 'date' => $date,
+ 'ip' => $remote,
+ 'type' => str_replace($strip, '', $type),
+ 'id' => $id,
+ 'user' => $user,
+ 'sum' => utf8_substr(str_replace($strip, '', $summary),0,255),
+ 'extra' => str_replace($strip, '', $extra)
+ );
+
+ // 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_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 bool $flags see above
+ *
+ * @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']);
+ }
+ $lines_position = count($lines)-1;
+
+ if ($flags & RECENTS_MEDIA_PAGES_MIXED) {
+ $media_lines = @file($conf['media_changelog']);
+ $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 & ~RECENTS_MEDIA_CHANGES, $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_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 bool $flags see above (optional)
+ *
+ * @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']);
+ }
+
+ // 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>
+ */
+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 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
+ $fn = (($flags & RECENTS_MEDIA_CHANGES) ? mediaFN($recent['id']) : wikiFN($recent['id']));
+ if((!@file_exists($fn)) && ($flags & RECENTS_SKIP_DELETED)) return false;
+
+ return $recent;
+}
+
+/**
+ * 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.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function getRevisionInfo($id, $rev, $chunk_size=8192, $media=false) {
+ global $cache_revinfo;
+ $cache =& $cache_revinfo;
+ if (!isset($cache[$id])) { $cache[$id] = array(); }
+ $rev = max($rev, 0);
+
+ // check if it's already in the memory cache
+ if (isset($cache[$id]) && isset($cache[$id][$rev])) {
+ return $cache[$id][$rev];
+ }
+
+ if ($media) {
+ $file = mediaMetaFN($id, '.changes');
+ } else {
+ $file = metaFN($id, '.changes');
+ }
+ if (!@file_exists($file)) { return false; }
+ if (filesize($file)<$chunk_size || $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);
+ $tail = ftell($fp);
+ $finger = 0;
+ $finger_rev = 0;
+
+ // find chunk
+ while ($tail-$head>$chunk_size) {
+ $finger = $head+floor(($tail-$head)/2.0);
+ fseek($fp, $finger);
+ fgets($fp); // slip the finger forward to a new line
+ $finger = ftell($fp);
+ $tmp = fgets($fp); // then read at that location
+ $tmp = parseChangelogLine($tmp);
+ $finger_rev = $tmp['date'];
+ if ($finger==$head || $finger==$tail) { break; }
+ 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;
+ }
+
+ // read chunk
+ $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($chunk_size-$got, 0));
+ if ($tmp===false) { break; } //error state
+ $got += strlen($tmp);
+ $chunk .= $tmp;
+ }
+ $lines = explode("\n", $chunk);
+ array_pop($lines); // remove trailing newline
+ fclose($fp);
+ }
+
+ // parse and cache changelog lines
+ foreach ($lines as $value) {
+ $tmp = parseChangelogLine($value);
+ if ($tmp!==false) {
+ $cache[$id][$tmp['date']] = $tmp;
+ }
+ }
+ if (!isset($cache[$id][$rev])) { return false; }
+ return $cache[$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.
+ *
+ * id: the page of interest
+ * first: skip the first n changelog lines
+ * num: number of revisions to return
+ *
+ * The current revision is automatically skipped when the page exists.
+ * See $INFO['meta']['last_change'] for the current revision.
+ *
+ * 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.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function getRevisions($id, $first, $num, $chunk_size=8192, $media=false) {
+ global $cache_revinfo;
+ $cache =& $cache_revinfo;
+ if (!isset($cache[$id])) { $cache[$id] = array(); }
+
+ $revs = array();
+ $lines = array();
+ $count = 0;
+ if ($media) {
+ $file = mediaMetaFN($id, '.changes');
+ } else {
+ $file = metaFN($id, '.changes');
+ }
+ $num = max($num, 0);
+ $chunk_size = max($chunk_size, 0);
+ if ($first<0) {
+ $first = 0;
+ } else if (!$media && @file_exists(wikiFN($id)) || $media && @file_exists(mediaFN($id))) {
+ // skip current revision if the page exists
+ $first = max($first+1, 0);
+ }
+
+ if (!@file_exists($file)) { return $revs; }
+ if (filesize($file)<$chunk_size || $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-$chunk_size, 0);
+ while ($count<$num+$first) {
+ fseek($fp, $finger);
+ $nl = $finger;
+ if ($finger>0) {
+ fgets($fp); // slip the finger forward to a new line
+ $nl = ftell($fp);
+ }
+
+ // was the chunk big enough? if not, take another bite
+ if($nl > 0 && $tail <= $nl){
+ $finger = max($finger-$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($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; } // already read all the lines
+ else {
+ $tail = $finger;
+ $finger = max($tail-$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)); }
+ else if ($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) {
+ $cache[$id][$tmp['date']] = $tmp;
+ $revs[] = $tmp['date'];
+ }
+ }
+
+ return $revs;
+}
+
+
diff --git a/inc/cliopts.php b/inc/cliopts.php
new file mode 100644
index 000000000..588f0bc6d
--- /dev/null
+++ b/inc/cliopts.php
@@ -0,0 +1,504 @@
+<?php
+/**
+ * Brutally chopped and modified from http://pear.php.net/package/Console_Getopts
+ *
+ * PHP Version 5
+ *
+ * Copyright (c) 1997-2004 The PHP Group
+ *
+ * LICENSE: This source file is subject to the New BSD license that is
+ * available through the world-wide-web at the following URI:
+ * http://www.opensource.org/licenses/bsd-license.php. If you did not receive
+ * a copy of the New BSD License and are unable to obtain it through the web,
+ * please send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category Console
+ * @package Console_Getopt
+ * @author Andrei Zmievski <andrei@php.net>
+ * @modified Harry Fuecks hfuecks gmail.com
+ * @modified Tanguy Ortolo <tanguy+dokuwiki@ortolo.eu>
+ * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/Console_Getopt
+ *
+ */
+
+//------------------------------------------------------------------------------
+/**
+ * Sets up CLI environment based on SAPI and PHP version
+ * Helps resolve some issues between the CGI and CLI SAPIs
+ * as well is inconsistencies between PHP 4.3+ and older versions
+ */
+if (version_compare(phpversion(), '4.3.0', '<') || php_sapi_name() == 'cgi') {
+ // Handle output buffering
+ @ob_end_flush();
+ ob_implicit_flush(true);
+
+ // PHP ini settings
+ set_time_limit(0);
+ ini_set('track_errors', true);
+ ini_set('html_errors', false);
+ ini_set('magic_quotes_runtime', false);
+
+ // Define stream constants
+ define('STDIN', fopen('php://stdin', 'r'));
+ define('STDOUT', fopen('php://stdout', 'w'));
+ define('STDERR', fopen('php://stderr', 'w'));
+
+ // Close the streams on script termination
+ register_shutdown_function(
+ create_function('',
+ 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;')
+ );
+}
+
+//------------------------------------------------------------------------------
+/**
+* Error codes
+*/
+define('DOKU_CLI_OPTS_UNKNOWN_OPT',1); //Unrecognized option
+define('DOKU_CLI_OPTS_OPT_ARG_REQUIRED',2); //Option requires argument
+define('DOKU_CLI_OPTS_OPT_ARG_DENIED',3); //Option not allowed argument
+define('DOKU_CLI_OPTS_OPT_ABIGUOUS',4);//Option abiguous
+define('DOKU_CLI_OPTS_ARG_READ',5);//Could not read argv
+
+//------------------------------------------------------------------------------
+/**
+ * Command-line options parsing class.
+ *
+ * @author Andrei Zmievski <andrei@php.net>
+ *
+ */
+class Doku_Cli_Opts {
+
+ /**
+ * <?php ?>
+ * @see http://www.sitepoint.com/article/php-command-line-1/3
+ * @param string executing file name - this MUST be passed the __FILE__ constant
+ * @param string short options
+ * @param array (optional) long options
+ * @return Doku_Cli_Opts_Container or Doku_Cli_Opts_Error
+ */
+ function & getOptions($bin_file, $short_options, $long_options = null) {
+ $args = Doku_Cli_Opts::readPHPArgv();
+
+ if ( Doku_Cli_Opts::isError($args) ) {
+ return $args;
+ }
+
+ // Compatibility between "php extensions.php" and "./extensions.php"
+ if ( realpath($_SERVER['argv'][0]) == $bin_file ) {
+ $options = Doku_Cli_Opts::getOpt($args,$short_options,$long_options);
+ } else {
+ $options = Doku_Cli_Opts::getOpt2($args,$short_options,$long_options);
+ }
+
+ if ( Doku_Cli_Opts::isError($options) ) {
+ return $options;
+ }
+
+ $container = new Doku_Cli_Opts_Container($options);
+ return $container;
+ }
+
+ /**
+ * Parses the command-line options.
+ *
+ * The first parameter to this function should be the list of command-line
+ * arguments without the leading reference to the running program.
+ *
+ * The second parameter is a string of allowed short options. Each of the
+ * option letters can be followed by a colon ':' to specify that the option
+ * requires an argument, or a double colon '::' to specify that the option
+ * takes an optional argument.
+ *
+ * The third argument is an optional array of allowed long options. The
+ * leading '--' should not be included in the option name. Options that
+ * require an argument should be followed by '=', and options that take an
+ * option argument should be followed by '=='.
+ *
+ * The return value is an array of two elements: the list of parsed
+ * options and the list of non-option command-line arguments. Each entry in
+ * the list of parsed options is a pair of elements - the first one
+ * specifies the option, and the second one specifies the option argument,
+ * if there was one.
+ *
+ * Long and short options can be mixed.
+ *
+ * Most of the semantics of this function are based on GNU getopt_long().
+ *
+ * @param array $args an array of command-line arguments
+ * @param string $short_options specifies the list of allowed short options
+ * @param array $long_options specifies the list of allowed long options
+ *
+ * @return array two-element array containing the list of parsed options and
+ * the non-option arguments
+ * @access public
+ */
+ function getopt2($args, $short_options, $long_options = null) {
+ return Doku_Cli_Opts::doGetopt(
+ 2, $args, $short_options, $long_options
+ );
+ }
+
+ /**
+ * This function expects $args to start with the script name (POSIX-style).
+ * Preserved for backwards compatibility.
+ *
+ * @param array $args an array of command-line arguments
+ * @param string $short_options specifies the list of allowed short options
+ * @param array $long_options specifies the list of allowed long options
+ *
+ * @see getopt2()
+ * @return array two-element array containing the list of parsed options and
+ * the non-option arguments
+ */
+ function getopt($args, $short_options, $long_options = null) {
+ return Doku_Cli_Opts::doGetopt(
+ 1, $args, $short_options, $long_options
+ );
+ }
+
+ /**
+ * The actual implementation of the argument parsing code.
+ *
+ * @param int $version Version to use
+ * @param array $args an array of command-line arguments
+ * @param string $short_options specifies the list of allowed short options
+ * @param array $long_options specifies the list of allowed long options
+ *
+ * @return array
+ */
+ function doGetopt($version, $args, $short_options, $long_options = null) {
+
+ // in case you pass directly readPHPArgv() as the first arg
+ if (Doku_Cli_Opts::isError($args)) {
+ return $args;
+ }
+ if (empty($args)) {
+ return array(array(), array());
+ }
+ $opts = array();
+ $non_opts = array();
+
+ settype($args, 'array');
+
+ if ($long_options && is_array($long_options)) {
+ sort($long_options);
+ }
+
+ /*
+ * Preserve backwards compatibility with callers that relied on
+ * erroneous POSIX fix.
+ */
+ if ($version < 2) {
+ if (isset($args[0]{0}) && $args[0]{0} != '-') {
+ array_shift($args);
+ }
+ }
+
+ reset($args);
+ while (list($i, $arg) = each($args)) {
+
+ /* 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($args, $i + 1));
+ break;
+ }
+
+ if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) {
+ $non_opts = array_merge($non_opts, array_slice($args, $i));
+ break;
+ } elseif (strlen($arg) > 1 && $arg{1} == '-') {
+ $error = Doku_Cli_Opts::_parseLongOption(substr($arg, 2), $long_options, $opts, $args);
+ if (Doku_Cli_Opts::isError($error))
+ return $error;
+ } elseif ($arg == '-') {
+ // - is stdin
+ $non_opts = array_merge($non_opts, array_slice($args, $i));
+ break;
+ } else {
+ $error = Doku_Cli_Opts::_parseShortOption(substr($arg, 1), $short_options, $opts, $args);
+ if (Doku_Cli_Opts::isError($error))
+ return $error;
+ }
+ }
+
+ return array($opts, $non_opts);
+ }
+
+ /**
+ * Parse short option
+ *
+ * @param string $arg Argument
+ * @param string[] $short_options Available short options
+ * @param string[][] &$opts
+ * @param string[] &$args
+ *
+ * @access private
+ * @return void
+ */
+ function _parseShortOption($arg, $short_options, &$opts, &$args) {
+ $len = strlen($arg);
+ for ($i = 0; $i < $len; $i++) {
+ $opt = $arg{$i};
+ $opt_arg = null;
+
+ /* Try to find the short option in the specifier string. */
+ if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':')
+ {
+ return Doku_Cli_Opts::raiseError(
+ DOKU_CLI_OPTS_UNKNOWN_OPT,
+ "Unrecognized option -- $opt"
+ );
+ }
+
+ if (strlen($spec) > 1 && $spec{1} == ':') {
+ if (strlen($spec) > 2 && $spec{2} == ':') {
+ if ($i + 1 < strlen($arg)) {
+ /* Option takes an optional argument. Use the remainder of
+ the arg string if there is anything left. */
+ $opts[] = array($opt, substr($arg, $i + 1));
+ break;
+ }
+ } else {
+ /* Option requires an argument. Use the remainder of the arg
+ string if there is anything left. */
+ if ($i + 1 < strlen($arg)) {
+ $opts[] = array($opt, substr($arg, $i + 1));
+ break;
+ } else if (list(, $opt_arg) = each($args)) {
+ /* Else use the next argument. */;
+ if (Doku_Cli_Opts::_isShortOpt($opt_arg) || Doku_Cli_Opts::_isLongOpt($opt_arg))
+ return Doku_Cli_Opts::raiseError(
+ DOKU_CLI_OPTS_OPT_ARG_REQUIRED,
+ "option requires an argument --$opt"
+ );
+ }
+ else
+ return Doku_Cli_Opts::raiseError(
+ DOKU_CLI_OPTS_OPT_ARG_REQUIRED,
+ "Option requires an argument -- $opt"
+ );
+ }
+ }
+
+ $opts[] = array($opt, $opt_arg);
+ }
+ }
+
+ /**
+ * Checks if an argument is a short option
+ *
+ * @param string $arg Argument to check
+ *
+ * @access private
+ * @return bool
+ */
+ function _isShortOpt($arg)
+ {
+ return strlen($arg) == 2 && $arg[0] == '-'
+ && preg_match('/[a-zA-Z]/', $arg[1]);
+ }
+
+ /**
+ * Checks if an argument is a long option
+ *
+ * @param string $arg Argument to check
+ *
+ * @access private
+ * @return bool
+ */
+ function _isLongOpt($arg)
+ {
+ return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' &&
+ preg_match('/[a-zA-Z]+$/', substr($arg, 2));
+ }
+
+ /**
+ * Parse long option
+ *
+ * @param string $arg Argument
+ * @param string[] $long_options Available long options
+ * @param string[][] &$opts
+ * @param string[] &$args
+ *
+ * @access private
+ * @return void|PEAR_Error
+ */
+ function _parseLongOption($arg, $long_options, &$opts, &$args) {
+ @list($opt, $opt_arg) = explode('=', $arg, 2);
+ $opt_len = strlen($opt);
+ $opt_cnt = count($long_options);
+
+ for ($i = 0; $i < $opt_cnt; $i++) {
+ $long_opt = $long_options[$i];
+ $opt_start = substr($long_opt, 0, $opt_len);
+
+ $long_opt_name = str_replace('=', '', $long_opt);
+
+ /* Option doesn't match. Go on to the next one. */
+ if ($opt_start != $opt)
+ continue;
+
+ $opt_rest = substr($long_opt, $opt_len);
+
+ /* Check that the options uniquely matches one of the allowed
+ options. */
+ if ($i + 1 < count($long_options)) {
+ $next_option_rest = substr($long_options[$i + 1], $opt_len);
+ } else {
+ $next_option_rest = '';
+ }
+
+ if ($opt_rest != '' && $opt{0} != '=' &&
+ $i + 1 < $opt_cnt &&
+ $opt == substr($long_options[$i+1], 0, $opt_len) &&
+ $next_option_rest != '' &&
+ $next_option_rest{0} != '=') {
+ return Doku_Cli_Opts::raiseError(
+ DOKU_CLI_OPTS_OPT_ABIGUOUS,
+ "Option --$opt is ambiguous"
+ );
+ }
+
+ if (substr($long_opt, -1) == '=') {
+ if (substr($long_opt, -2) != '==') {
+ /* Long option requires an argument.
+ Take the next argument if one wasn't specified. */;
+ if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) {
+ return Doku_Cli_Opts::raiseError(
+ DOKU_CLI_OPTS_OPT_ARG_REQUIRED,
+ "Option --$opt requires an argument"
+ );
+ }
+
+ if (Doku_Cli_Opts::_isShortOpt($opt_arg)
+ || Doku_Cli_Opts::_isLongOpt($opt_arg))
+ return Doku_Cli_Opts::raiseError(
+ DOKU_CLI_OPTS_OPT_ARG_REQUIRED,
+ "Option --$opt requires an argument"
+ );
+ }
+ } else if ($opt_arg) {
+ return Doku_Cli_Opts::raiseError(
+ DOKU_CLI_OPTS_OPT_ARG_DENIED,
+ "Option --$opt doesn't allow an argument"
+ );
+ }
+
+ $opts[] = array('--' . $opt, $opt_arg);
+ return;
+ }
+
+ return Doku_Cli_Opts::raiseError(
+ DOKU_CLI_OPTS_UNKNOWN_OPT,
+ "Unrecognized option --$opt"
+ );
+ }
+
+ /**
+ * Safely read the $argv PHP array across different PHP configurations.
+ * Will take care on register_globals and register_argc_argv ini directives
+ *
+ * @access public
+ * @return mixed the $argv PHP array or PEAR error if not registered
+ */
+ function readPHPArgv() {
+ global $argv;
+ if (!is_array($argv)) {
+ if (!@is_array($_SERVER['argv'])) {
+ if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
+ return Doku_Cli_Opts::raiseError(
+ DOKU_CLI_OPTS_ARG_READ,
+ "Could not read cmd args (register_argc_argv=Off?)"
+ );
+ }
+ return $GLOBALS['HTTP_SERVER_VARS']['argv'];
+ }
+ return $_SERVER['argv'];
+ }
+ return $argv;
+ }
+
+ function raiseError($code, $msg) {
+ return new Doku_Cli_Opts_Error($code, $msg);
+ }
+
+ function isError($obj) {
+ return is_a($obj, 'Doku_Cli_Opts_Error');
+ }
+
+}
+
+//------------------------------------------------------------------------------
+class Doku_Cli_Opts_Error {
+
+ var $code;
+ var $msg;
+
+ function Doku_Cli_Opts_Error($code, $msg) {
+ $this->code = $code;
+ $this->msg = $msg;
+ }
+
+ function getMessage() {
+ return $this->msg;
+ }
+
+ function isError() {
+ return true;
+ }
+
+}
+
+//------------------------------------------------------------------------------
+class Doku_Cli_Opts_Container {
+
+ var $options = array();
+ var $args = array();
+
+ function Doku_Cli_Opts_Container($options) {
+ foreach ( $options[0] as $option ) {
+ if ( false !== ( strpos($option[0], '--') ) ) {
+ $opt_name = substr($option[0], 2);
+ } else {
+ $opt_name = $option[0];
+ }
+ $this->options[$opt_name] = $option[1];
+ }
+
+ $this->args = $options[1];
+ }
+
+ function has($option) {
+ return array_key_exists($option, $this->options);
+ }
+
+ function get($option) {
+ if ( isset($this->options[$option]) ) {
+ return ( $this->options[$option] ) ;
+ }
+ }
+
+ function arg($index) {
+ if ( isset($this->args[$index]) ) {
+ return $this->args[$index];
+ }
+ }
+
+ function numArgs() {
+ return count($this->args);
+ }
+
+ function hasArgs() {
+ return count($this->args) !== 0;
+ }
+
+ function isError() {
+ return false;
+ }
+
+}
diff --git a/inc/common.php b/inc/common.php
new file mode 100644
index 000000000..0c769c50d
--- /dev/null
+++ b/inc/common.php
@@ -0,0 +1,1573 @@
+<?php
+/**
+ * Common DokuWiki functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * These constants are used with the recents function
+ */
+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);
+
+/**
+ * Wrapper around htmlspecialchars()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see htmlspecialchars()
+ */
+function hsc($string){
+ return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
+}
+
+/**
+ * print a newline terminated string
+ *
+ * You can give an indention as optional parameter
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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>
+ */
+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(){
+ return md5(auth_cookiesalt().session_id().$_SERVER['REMOTE_USER']);
+}
+
+/**
+ * Check the secret CSRF token
+ */
+function checkSecurityToken($token=null){
+ if(!$_SERVER['REMOTE_USER']) return true; // no logged in user, no need for a check
+
+ if(is_null($token)) $token = $_REQUEST['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>
+ */
+function formSecurityToken($print=true){
+ $ret = '<div class="no"><input type="hidden" name="sectok" value="'.getSecurityToken().'" /></div>'."\n";
+ if($print){
+ echo $ret;
+ }else{
+ return $ret;
+ }
+}
+
+/**
+ * Return info about the current document as associative
+ * array.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function pageinfo(){
+ global $ID;
+ global $REV;
+ global $RANGE;
+ global $USERINFO;
+ global $lang;
+
+ // 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;
+
+ // set info about manager/admin status.
+ $info['isadmin'] = false;
+ $info['ismanager'] = false;
+ if(isset($_SERVER['REMOTE_USER'])){
+ $info['userinfo'] = $USERINFO;
+ $info['perm'] = auth_quickaclcheck($ID);
+ $info['subscribed'] = get_info_subscribed();
+ $info['client'] = $_SERVER['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'] = $_SERVER['REMOTE_USER'];
+ }
+
+ }else{
+ $info['perm'] = auth_aclcheck($ID,'',null);
+ $info['subscribed'] = false;
+ $info['client'] = clientIP(true);
+ }
+
+ $info['namespace'] = getNS($ID);
+ $info['locked'] = checklock($ID);
+ $info['filepath'] = fullpath(wikiFN($ID));
+ $info['exists'] = @file_exists($info['filepath']);
+ if($REV){
+ //check if current revision was meant
+ if($info['exists'] && (@filemtime($info['filepath'])==$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'] = fullpath(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
+ if($REV){
+ $revinfo = getRevisionInfo($ID, $REV, 1024);
+ }else{
+ if (is_array($info['meta']['last_change'])) {
+ $revinfo = $info['meta']['last_change'];
+ } else {
+ $revinfo = getRevisionInfo($ID, $info['lastmod'], 1024);
+ // 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));
+ }
+
+ $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'];
+ }
+
+ // draft
+ $draft = getCacheName($info['client'].$ID,'.draft');
+ if(@file_exists($draft)){
+ if(@filemtime($draft) < @filemtime(wikiFN($ID))){
+ // remove stale draft
+ @unlink($draft);
+ }else{
+ $info['draft'] = $draft;
+ }
+ }
+
+ // mobile detection
+ $info['ismobile'] = clientismobile();
+
+ return $info;
+}
+
+/**
+ * Build an string of URL parameters
+ *
+ * @author Andreas Gohr
+ */
+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
+ */
+function buildAttributes($params,$skipempty=false){
+ $url = '';
+ $white = false;
+ foreach($params as $key => $val){
+ if($key{0} == '_') continue;
+ if($val === '' && $skipempty) 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>
+ */
+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;
+
+ //first visit?
+ $crumbs = isset($_SESSION[DOKU_COOKIE]['bc']) ? $_SESSION[DOKU_COOKIE]['bc'] : array();
+ //we only save on show and existing wiki documents
+ $file = wikiFN($ID);
+ if($ACT != 'show' || !@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 systems and to have proper URL encoding
+ *
+ * Urlencoding is ommitted when the second parameter is false
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function idfilter($id,$ue=true){
+ global $conf;
+ if ($conf['useslash'] && $conf['userewrite']){
+ $id = strtr($id,':','/');
+ }elseif (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' &&
+ $conf['userewrite']) {
+ $id = strtr($id,':',';');
+ }
+ if($ue){
+ $id = rawurlencode($id);
+ $id = str_replace('%3A',':',$id); //keep as colon
+ $id = str_replace('%2F','/',$id); //keep as slash
+ }
+ return $id;
+}
+
+/**
+ * This builds a link to a wikipage
+ *
+ * It handles URL rewriting and adds additional parameter if
+ * given in $more
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function wl($id='',$more='',$abs=false,$sep='&amp;'){
+ global $conf;
+ if(is_array($more)){
+ $more = buildURLparams($more,$sep);
+ }else{
+ $more = str_replace(',',$sep,$more);
+ }
+
+ $id = idfilter($id);
+ if($abs){
+ $xlink = DOKU_URL;
+ }else{
+ $xlink = DOKU_BASE;
+ }
+
+ if($conf['userewrite'] == 2){
+ $xlink .= DOKU_SCRIPT.'/'.$id;
+ if($more) $xlink .= '?'.$more;
+ }elseif($conf['userewrite']){
+ $xlink .= $id;
+ if($more) $xlink .= '?'.$more;
+ }elseif($id){
+ $xlink .= DOKU_SCRIPT.'?id='.$id;
+ if($more) $xlink .= $sep.$more;
+ }else{
+ $xlink .= DOKU_SCRIPT;
+ if($more) $xlink .= '?'.$more;
+ }
+
+ 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>
+ */
+function exportlink($id='',$format='raw',$more='',$abs=false,$sep='&amp;'){
+ global $conf;
+ if(is_array($more)){
+ $more = buildURLparams($more,$sep);
+ }else{
+ $more = str_replace(',',$sep,$more);
+ }
+
+ $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($more) $xlink .= $sep.$more;
+ }elseif($conf['userewrite'] == 1){
+ $xlink .= '_export/'.$format.'/'.$id;
+ if($more) $xlink .= '?'.$more;
+ }else{
+ $xlink .= DOKU_SCRIPT.'?do=export_'.$format.$sep.'id='.$id;
+ if($more) $xlink .= $sep.$more;
+ }
+
+ 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 boolean $direct - link to detail page if false
+ * @param string $sep - URL parameter separator
+ * @param boolean $abs - Create an absolute URL
+ */
+function ml($id='',$more='',$direct=true,$sep='&amp;',$abs=false){
+ global $conf;
+ if(is_array($more)){
+ // strip defaults for shorter URLs
+ if(isset($more['cache']) && $more['cache'] == 'cache') unset($more['cache']);
+ if(!$more['w']) unset($more['w']);
+ if(!$more['h']) unset($more['h']);
+ if(isset($more['id']) && $direct) unset($more['id']);
+ $more = buildURLparams($more,$sep);
+ }else{
+ $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(preg_match('#^(https?|ftp)://#i',$id)){
+ $xlink .= 'lib/exe/fetch.php';
+ // add hash:
+ $xlink .= '?hash='.substr(md5(auth_cookiesalt().$id),0,6);
+ if($more){
+ $xlink .= $sep.$more;
+ $xlink .= $sep.'media='.rawurlencode($id);
+ }else{
+ $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;
+}
+
+
+
+/**
+ * Just builds a link to a script
+ *
+ * @todo maybe obsolete
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function script($script='doku.php'){
+ 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 $conf;
+ global $INFO;
+
+ if(!$conf['usewordblock']) return false;
+
+ if(!$text) $text = "$PRE $TEXT $SUF";
+
+ // we prepare the text a tiny bit to prevent spammers circumventing URL checks
+ $text = preg_replace('!(\b)(www\.[\w.:?\-;,]+?\.[\w.:?\-;,]+?[\w/\#~:.?+=&%@\!\-.:?\-;,]+?)([.:?\-;,]*[^\w/\#~:.?+=&%@\!\-.:?\-;,])!i','\1http://\2 \2\3',$text);
+
+ $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['matches'] = $matches;
+ $data['userinfo']['ip'] = $_SERVER['REMOTE_ADDR'];
+ if($_SERVER['REMOTE_USER']) {
+ $data['userinfo']['user'] = $_SERVER['REMOTE_USER'];
+ $data['userinfo']['name'] = $INFO['userinfo']['name'];
+ $data['userinfo']['mail'] = $INFO['userinfo']['mail'];
+ }
+ $callback = create_function('', 'return true;');
+ return trigger_event('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
+ *
+ * @param boolean $single If set only a single IP is returned
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function clientIP($single=false){
+ $ip = array();
+ $ip[] = $_SERVER['REMOTE_ADDR'];
+ if(!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
+ $ip = array_merge($ip,explode(',',str_replace(' ','',$_SERVER['HTTP_X_FORWARDED_FOR'])));
+ if(!empty($_SERVER['HTTP_X_REAL_IP']))
+ $ip = array_merge($ip,explode(',',str_replace(' ','',$_SERVER['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);
+
+ // decide which IP to use, trying to avoid local addresses
+ $ip = array_reverse($ip);
+ foreach($ip as $i){
+ if(preg_match('/^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)/',$i)){
+ continue;
+ }else{
+ return $i;
+ }
+ }
+ // still here? just use the first (last) address
+ return $ip[0];
+}
+
+/**
+ * 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
+ */
+function clientismobile(){
+
+ if(isset($_SERVER['HTTP_X_WAP_PROFILE'])) return true;
+
+ if(preg_match('/wap\.|\.wap/i',$_SERVER['HTTP_ACCEPT'])) return true;
+
+ if(!isset($_SERVER['HTTP_USER_AGENT'])) return false;
+
+ $uamatches = '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",$_SERVER['HTTP_USER_AGENT'])) return true;
+
+ return false;
+}
+
+
+/**
+ * Convert one or more comma separated IPs to hostnames
+ *
+ * @author Glen Harris <astfgl@iamnota.org>
+ * @returns a comma separated list of hostnames
+ */
+function gethostsbyaddrs($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>
+ */
+function checklock($id){
+ global $conf;
+ $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 == $_SERVER['REMOTE_USER'] || $ip == clientIP() || $session == session_id()){
+ return false;
+ }
+
+ return $ip;
+}
+
+/**
+ * Lock a page for editing
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function lock($id){
+ global $conf;
+
+ if($conf['locktime'] == 0){
+ return;
+ }
+
+ $lock = wikiLockFN($id);
+ if($_SERVER['REMOTE_USER']){
+ io_saveFile($lock,$_SERVER['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>
+ * @return bool true if a lock was removed
+ */
+function unlock($id){
+ $lock = wikiLockFN($id);
+ if(@file_exists($lock)){
+ list($ip,$session) = explode("\n",io_readFile($lock));
+ if($ip == $_SERVER['REMOTE_USER'] || $ip == clientIP() || $session == session_id()){
+ @unlink($lock);
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * convert line ending to unix format
+ *
+ * @see formText() for 2crlf conversion
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function cleanText($text){
+ $text = preg_replace("/(\015\012)|(\015)/","\012",$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>
+ */
+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>
+ */
+function rawLocale($id){
+ return io_readFile(localeFN($id));
+}
+
+/**
+ * Returns the raw WikiText
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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>
+ */
+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 Doku_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));
+ $tpl = '';
+ 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>
+ */
+function parsePageTemplate(&$data) {
+ extract($data);
+
+ global $USERINFO;
+ global $conf;
+
+ // replace placeholders
+ $file = noNS($id);
+ $page = strtr($file, $conf['sepchar'], ' ');
+
+ $tpl = str_replace(array(
+ '@ID@',
+ '@NS@',
+ '@FILE@',
+ '@!FILE@',
+ '@!FILE!@',
+ '@PAGE@',
+ '@!PAGE@',
+ '@!!PAGE@',
+ '@!PAGE!@',
+ '@USER@',
+ '@NAME@',
+ '@MAIL@',
+ '@DATE@',
+ ),
+ array(
+ $id,
+ getNS($id),
+ $file,
+ utf8_ucfirst($file),
+ utf8_strtoupper($file),
+ $page,
+ utf8_ucfirst($page),
+ utf8_ucwords($page),
+ utf8_strtoupper($page),
+ $_SERVER['REMOTE_USER'],
+ $USERINFO['name'],
+ $USERINFO['mail'],
+ $conf['dformat'],
+ ), $tpl);
+
+ // we need the callback to work around strftime's char limit
+ $tpl = preg_replace_callback('/%./',create_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>
+ */
+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[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>
+ */
+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;
+}
+
+/**
+ * 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>
+ */
+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;
+ // ignore if no changes were made
+ if($text == rawWiki($id,'')){
+ return;
+ }
+
+ $file = wikiFN($id);
+ $old = @filemtime($file); // from page
+ $wasRemoved = (trim($text) == ''); // check for empty or whitespace only
+ $wasCreated = !@file_exists($file);
+ $wasReverted = ($REV==true);
+ $newRev = false;
+ $oldRev = getRevisions($id, -1, 1, 1024); // from changelog
+ $oldRev = (int)(empty($oldRev)?0:$oldRev[0]);
+ if(!@file_exists(wikiFN($id, $old)) && @file_exists($file) && $old>=$oldRev) {
+ // add old revision to the attic if missing
+ saveOldRevision($id);
+ // add a changelog entry if this edit came from outside dokuwiki
+ if ($old>$oldRev) {
+ addLogEntry($old, $id, DOKU_CHANGE_TYPE_EDIT, $lang['external_edit'], '', array('ExternalEdit'=>true));
+ // remove soon to be stale instructions
+ $cache = new cache_instructions($id, $file);
+ $cache->removeCache();
+ }
+ }
+
+ if ($wasRemoved){
+ // Send "update" event with empty data, so plugins can react to page deletion
+ $data = array(array($file, '', false), getNS($id), noNS($id), false);
+ trigger_event('IO_WIKIPAGE_WRITE', $data);
+ // pre-save deleted revision
+ @touch($file);
+ clearstatcache();
+ $newRev = saveOldRevision($id);
+ // remove empty file
+ @unlink($file);
+ // 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);
+ $del = true;
+ // autoset summary on deletion
+ if(empty($summary)) $summary = $lang['deleted'];
+ // remove empty namespaces
+ io_sweepNS($id, 'datadir');
+ io_sweepNS($id, 'mediadir');
+ }else{
+ // save file (namespace dir is created in io_writeWikiPage)
+ io_writeWikiPage($file, $text, $id);
+ // pre-save the revision, to keep the attic in sync
+ $newRev = saveOldRevision($id);
+ $del = false;
+ }
+
+ // select changelog line type
+ $extra = '';
+ $type = DOKU_CHANGE_TYPE_EDIT;
+ if ($wasReverted) {
+ $type = DOKU_CHANGE_TYPE_REVERT;
+ $extra = $REV;
+ }
+ else if ($wasCreated) { $type = DOKU_CHANGE_TYPE_CREATE; }
+ else if ($wasRemoved) { $type = DOKU_CHANGE_TYPE_DELETE; }
+ else if ($minor && $conf['useacl'] && $_SERVER['REMOTE_USER']) { $type = DOKU_CHANGE_TYPE_MINOR_EDIT; } //minor edits only for logged in users
+
+ addLogEntry($newRev, $id, $type, $summary, $extra);
+ // send notify mails
+ notify($id,'admin',$old,$summary,$minor);
+ notify($id,'subscribers',$old,$summary,$minor);
+
+ // 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);
+ foreach ($pages as $page) {
+ $cache = new cache_renderer($page, wikiFN($page), 'xhtml');
+ $cache->removeCache();
+ }
+ }
+}
+
+/**
+ * moves the current version to the attic and returns its
+ * revision date
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function saveOldRevision($id){
+ global $conf;
+ $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 $rev Old page revision
+ * @param string $summary What changed
+ * @param boolean $minor Is this a minor edit?
+ * @param array $replace Additional string substitutions, @KEY@ to be replaced by value
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function notify($id,$who,$rev='',$summary='',$minor=false,$replace=array()){
+ global $lang;
+ global $conf;
+ global $INFO;
+
+ // decide if there is something to do
+ if($who == 'admin'){
+ if(empty($conf['notify'])) return; //notify enabled?
+ $text = rawLocale('mailtext');
+ $to = $conf['notify'];
+ $bcc = '';
+ }elseif($who == 'subscribers'){
+ if(!$conf['subscribers']) return; //subscribers enabled?
+ if($conf['useacl'] && $_SERVER['REMOTE_USER'] && $minor) return; //skip minors
+ $data = array('id' => $id, 'addresslist' => '', 'self' => false);
+ trigger_event('COMMON_NOTIFY_ADDRESSLIST', $data,
+ 'subscription_addresslist');
+ $bcc = $data['addresslist'];
+ if(empty($bcc)) return;
+ $to = '';
+ $text = rawLocale('subscr_single');
+ }elseif($who == 'register'){
+ if(empty($conf['registernotify'])) return;
+ $text = rawLocale('registermail');
+ $to = $conf['registernotify'];
+ $bcc = '';
+ }else{
+ return; //just to be safe
+ }
+
+ $ip = clientIP();
+ $text = str_replace('@DATE@',dformat(),$text);
+ $text = str_replace('@BROWSER@',$_SERVER['HTTP_USER_AGENT'],$text);
+ $text = str_replace('@IPADDRESS@',$ip,$text);
+ $text = str_replace('@HOSTNAME@',gethostsbyaddrs($ip),$text);
+ $text = str_replace('@NEWPAGE@',wl($id,'',true,'&'),$text);
+ $text = str_replace('@PAGE@',$id,$text);
+ $text = str_replace('@TITLE@',$conf['title'],$text);
+ $text = str_replace('@DOKUWIKIURL@',DOKU_URL,$text);
+ $text = str_replace('@SUMMARY@',$summary,$text);
+ $text = str_replace('@USER@',$_SERVER['REMOTE_USER'],$text);
+ $text = str_replace('@NAME@',$INFO['userinfo']['name'],$text);
+ $text = str_replace('@MAIL@',$INFO['userinfo']['mail'],$text);
+
+ foreach ($replace as $key => $substitution) {
+ $text = str_replace('@'.strtoupper($key).'@',$substitution, $text);
+ }
+
+ if($who == 'register'){
+ $subject = $lang['mail_new_user'].' '.$summary;
+ }elseif($rev){
+ $subject = $lang['mail_changed'].' '.$id;
+ $text = str_replace('@OLDPAGE@',wl($id,"rev=$rev",true,'&'),$text);
+ $df = new Diff(explode("\n",rawWiki($id,$rev)),
+ explode("\n",rawWiki($id)));
+ $dformat = new UnifiedDiffFormatter();
+ $diff = $dformat->format($df);
+ }else{
+ $subject=$lang['mail_newpage'].' '.$id;
+ $text = str_replace('@OLDPAGE@','none',$text);
+ $diff = rawWiki($id);
+ }
+ $text = str_replace('@DIFF@',$diff,$text);
+ if(empty($conf['mailprefix'])) {
+ if(utf8_strlen($conf['title']) < 20) {
+ $subject = '['.$conf['title'].'] '.$subject;
+ }else{
+ $subject = '['.utf8_substr($conf['title'], 0, 20).'...] '.$subject;
+ }
+ }else{
+ $subject = '['.$conf['mailprefix'].'] '.$subject;
+ }
+ mail_send($to,$subject,$text,$conf['mailfrom'],'',$bcc);
+}
+
+/**
+ * extracts the query from a search engine referrer
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Todd Augsburger <todd@rollerorgans.com>
+ */
+function getGoogleQuery(){
+ if (!isset($_SERVER['HTTP_REFERER'])) {
+ return '';
+ }
+ $url = parse_url($_SERVER['HTTP_REFERER']);
+
+ $query = array();
+
+ // temporary workaround against PHP bug #49733
+ // see http://bugs.php.net/bug.php?id=49733
+ if(UTF8_MBSTRING) $enc = mb_internal_encoding();
+ parse_str($url['query'],$query);
+ if(UTF8_MBSTRING) mb_internal_encoding($enc);
+
+ $q = '';
+ if(isset($query['q']))
+ $q = $query['q']; // google, live/msn, aol, ask, altavista, alltheweb, gigablast
+ elseif(isset($query['p']))
+ $q = $query['p']; // yahoo
+ elseif(isset($query['query']))
+ $q = $query['query']; // lycos, netscape, clusty, hotbot
+ elseif(preg_match("#a9\.com#i",$url['host'])) // a9
+ $q = urldecode(ltrim($url['path'],'/'));
+
+ if($q === '') return '';
+ $q = preg_split('/[\s\'"\\\\`()\]\[?:!\.{};,#+*<>\\/]+/',$q,-1,PREG_SPLIT_NO_EMPTY);
+ return $q;
+}
+
+/**
+ * Try to set correct locale
+ *
+ * @deprecated No longer used
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function setCorrectLocale(){
+ global $conf;
+ global $lang;
+
+ $enc = strtoupper($lang['encoding']);
+ foreach ($lang['locales'] as $loc){
+ //try locale
+ if(@setlocale(LC_ALL,$loc)) return;
+ //try loceale with encoding
+ if(@setlocale(LC_ALL,"$loc.$enc")) return;
+ }
+ //still here? try to set from environment
+ @setlocale(LC_ALL,"");
+}
+
+/**
+ * Return the human readable size of a file
+ *
+ * @param int $size A file size
+ * @param int $dec A number of decimal places
+ * @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) . ' ' . $sizes[$i];
+}
+
+/**
+ * Return the given timestamp as human readable, fuzzy age
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+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>
+ */
+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://www.php.net/manual/en/function.date.php#54072
+ */
+function date_iso8601($int_date) {
+ //$int_date: current date in UNIX timestamp
+ $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>
+ */
+function obfuscate($email) {
+ global $conf;
+
+ switch ($conf['mailguard']) {
+ case 'visible' :
+ $obfuscate = array('@' => ' [at] ', '.' => ' [dot] ', '-' => ' [dash] ');
+ return strtr($email, $obfuscate);
+
+ case 'hex' :
+ $encode = '';
+ $len = strlen($email);
+ for ($x=0; $x < $len; $x++){
+ $encode .= '&#x' . bin2hex($email{$x}).';';
+ }
+ return $encode;
+
+ case 'none' :
+ default :
+ return $email;
+ }
+}
+
+/**
+ * Removes quoting backslashes
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function unslash($string,$char="'"){
+ return str_replace('\\'.$char,$char,$string);
+}
+
+/**
+ * Convert php.ini shorthands to byte
+ *
+ * @author <gilthans dot NO dot SPAM at gmail dot com>
+ * @link http://de3.php.net/manual/en/ini.core.php#79564
+ */
+function php_to_byte($v){
+ $l = substr($v, -1);
+ $ret = substr($v, 0, -1);
+ switch(strtoupper($l)){
+ case 'P':
+ $ret *= 1024;
+ case 'T':
+ $ret *= 1024;
+ case 'G':
+ $ret *= 1024;
+ case 'M':
+ $ret *= 1024;
+ case 'K':
+ $ret *= 1024;
+ break;
+ default;
+ $ret *= 10;
+ break;
+ }
+ return $ret;
+}
+
+/**
+ * Wrapper around preg_quote adding the default delimiter
+ */
+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
+ */
+function shorten($keep,$short,$max,$min=9,$char='…'){
+ $max = $max - utf8_strlen($keep);
+ if($max < $min) return $keep;
+ $len = utf8_strlen($short);
+ if($len <= $max) return $keep.$short;
+ $half = floor($max/2);
+ return $keep.utf8_substr($short,0,$half-1).$char.utf8_substr($short,$len-$half);
+}
+
+/**
+ * Return the users realname or e-mail address for use
+ * in page footer and recent changes pages
+ *
+ * @author Andy Webber <dokuwiki AT andywebber DOT com>
+ */
+function editorinfo($username){
+ global $conf;
+ global $auth;
+
+ switch($conf['showuseras']){
+ case 'username':
+ case 'email':
+ case 'email_link':
+ if($auth) $info = $auth->getUserData($username);
+ break;
+ default:
+ return hsc($username);
+ }
+
+ if(isset($info) && $info) {
+ switch($conf['showuseras']){
+ case 'username':
+ return hsc($info['name']);
+ case 'email':
+ return obfuscate($info['mail']);
+ case 'email_link':
+ $mail=obfuscate($info['mail']);
+ return '<a href="mailto:'.$mail.'">'.$mail.'</a>';
+ default:
+ return hsc($username);
+ }
+ } else {
+ return hsc($username);
+ }
+}
+
+/**
+ * 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'
+ */
+function license_img($type){
+ global $license;
+ global $conf;
+ if(!$conf['license']) return '';
+ if(!is_array($license[$conf['license']])) return '';
+ $lic = $license[$conf['license']];
+ $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
+ *
+ * @param int $mem Size of memory you want to allocate in bytes
+ * @param int $used already allocated memory (see above)
+ * @author Filip Oscadal <webmaster@illusionsoftworks.cz>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function is_mem_available($mem,$bytes=1048576){
+ $limit = trim(ini_get('memory_limit'));
+ if(empty($limit)) return true; // no limit set!
+
+ // 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>
+ */
+function send_redirect($url){
+ //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();
+
+ // work around IE bug
+ // http://www.ianhoar.com/2008/11/16/internet-explorer-6-and-redirected-anchor-links/
+ list($url,$hash) = explode('#',$url);
+ if($hash){
+ if(strpos($url,'?')){
+ $url = $url.'&#'.$hash;
+ }else{
+ $url = $url.'?&#'.$hash;
+ }
+ }
+
+ // check if running on IIS < 6 with CGI-PHP
+ if( isset($_SERVER['SERVER_SOFTWARE']) && isset($_SERVER['GATEWAY_INTERFACE']) &&
+ (strpos($_SERVER['GATEWAY_INTERFACE'],'CGI') !== false) &&
+ (preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($_SERVER['SERVER_SOFTWARE']), $matches)) &&
+ $matches[1] < 6 ){
+ header('Refresh: 0;url='.$url);
+ }else{
+ header('Location: '.$url);
+ }
+ 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
+ *
+ * @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);
+ }
+}
+
+function get_doku_pref($pref, $default) {
+ if (strpos($_COOKIE['DOKU_PREFS'], $pref) !== false) {
+ $parts = explode('#', $_COOKIE['DOKU_PREFS']);
+ for ($i = 0; $i < count($parts); $i+=2){
+ if ($parts[$i] == $pref) {
+ return $parts[$i+1];
+ }
+ }
+ }
+ return $default;
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/config_cascade.php b/inc/config_cascade.php
new file mode 100644
index 000000000..443114f52
--- /dev/null
+++ b/inc/config_cascade.php
@@ -0,0 +1,78 @@
+<?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'),
+ ),
+ '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' => DOKU_CONF.'userstyle.css',
+ 'rtl' => DOKU_CONF.'userrtl.css',
+ 'print' => DOKU_CONF.'userprint.css',
+ 'feed' => DOKU_CONF.'userfeed.css',
+ 'all' => DOKU_CONF.'userall.css',
+ ),
+ 'userscript' => array(
+ 'default' => DOKU_CONF.'userscript.js'
+ ),
+ 'acl' => array(
+ 'default' => DOKU_CONF.'acl.auth.php',
+ ),
+ 'plainauth.users' => array(
+ 'default' => DOKU_CONF.'users.auth.php',
+ ),
+
+ 'plugins' => array(
+ 'local' => array(DOKU_CONF.'plugins.local.php'),
+ 'protected' => array(
+ DOKU_CONF.'plugins.required.php',
+ DOKU_CONF.'plugins.protected.php',
+ ),
+ ),
+ ),
+ $config_cascade
+);
+
diff --git a/inc/confutils.php b/inc/confutils.php
new file mode 100644
index 000000000..29ead1e9f
--- /dev/null
+++ b/inc/confutils.php
@@ -0,0 +1,334 @@
+<?php
+/**
+ * Utilities for collecting data from config files
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+
+
+/**
+ * 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>
+ */
+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');
+ }
+ return $mime;
+}
+
+/**
+ * returns a hash of acronyms
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+function getAcronyms() {
+ static $acronyms = null;
+ if ( !$acronyms ) {
+ $acronyms = retrieveConfig('acronyms','confToHash');
+ }
+ return $acronyms;
+}
+
+/**
+ * returns a hash of smileys
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+function getSmileys() {
+ static $smileys = null;
+ if ( !$smileys ) {
+ $smileys = retrieveConfig('smileys','confToHash');
+ }
+ return $smileys;
+}
+
+/**
+ * returns a hash of entities
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+function getEntities() {
+ static $entities = null;
+ if ( !$entities ) {
+ $entities = retrieveConfig('entities','confToHash');
+ }
+ 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));
+ }
+ //add sepecial case 'this'
+ $wikis['this'] = DOKU_URL.'{NAME}';
+ return $wikis;
+}
+
+/**
+ * returns array of wordblock patterns
+ *
+ */
+function getWordblocks() {
+ static $wordblocks = null;
+ if ( !$wordblocks ) {
+ $wordblocks = retrieveConfig('wordblock','file');
+ }
+ return $wordblocks;
+}
+
+
+function getSchemes() {
+ static $schemes = null;
+ if ( !$schemes ) {
+ $schemes = retrieveConfig('scheme','file');
+ }
+ $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>
+ */
+function linesToHash($lines, $lower=false) {
+ $conf = array();
+ foreach ( $lines as $line ) {
+ //ignore comments (except escaped ones)
+ $line = preg_replace('/(?<![&\\\\])#.*$/','',$line);
+ $line = str_replace('\\#','#',$line);
+ $line = trim($line);
+ if(empty($line)) continue;
+ $line = preg_split('/\s+/',$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>
+ */
+function confToHash($file,$lower=false) {
+ $conf = array();
+ $lines = @file( $file );
+ if ( !$lines ) return $conf;
+
+ return linesToHash($lines, $lower);
+}
+
+/**
+ * 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 $param optional additional params to pass to the callback
+ * @return array configuration values
+ */
+function retrieveConfig($type,$fn,$params=null) {
+ 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 = array_merge($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>
+ * @returns boolean true if enabled, false if disabled
+ */
+function actionOK($action){
+ static $disabled = null;
+ if(is_null($disabled)){
+ global $conf;
+ 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)) {
+ $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
+ * @returns boolean true if headings should be used for $linktype, false otherwise
+ */
+function useHeading($linktype) {
+ static $useHeading = null;
+
+ 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 encode (or unknown)
+ return $str;
+ }
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/events.php b/inc/events.php
new file mode 100644
index 000000000..621cb64c1
--- /dev/null
+++ b/inc/events.php
@@ -0,0 +1,197 @@
+<?php
+/**
+ * DokuWiki Events
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+class Doku_Event {
+
+ // public properties
+ var $name = ''; // READONLY event name, objects must register against this name to see the event
+ var $data = null; // READWRITE data relevant to the event, no standardised format (YET!)
+ var $result = 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
+ var $canPreventDefault = true; // READONLY if true, event handlers can prevent the events default action
+
+ // private properties, event handlers can effect these through the provided methods
+ var $_default = true; // whether or not to carry out the default action associated with the event
+ var $_continue = true; // whether or not to continue propagating the event to other handlers
+
+ /**
+ * event constructor
+ */
+ function Doku_Event($name, &$data) {
+
+ $this->name = $name;
+ $this->data =& $data;
+
+ }
+
+ /**
+ * advise functions
+ *
+ * advise all registered 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 Doku_Event(name, data);
+ * if ($evt->advise_before(canPreventDefault) {
+ * // default action code block
+ * }
+ * $evt->advise_after();
+ * unset($evt);
+ *
+ * @return results of processing the event, usually $this->_default
+ */
+ function advise_before($enablePreventDefault=true) {
+ global $EVENT_HANDLER;
+
+ $this->canPreventDefault = $enablePreventDefault;
+ $EVENT_HANDLER->process_event($this,'BEFORE');
+
+ return (!$enablePreventDefault || $this->_default);
+ }
+
+ function advise_after() {
+ global $EVENT_HANDLER;
+
+ $this->_continue = true;
+ $EVENT_HANDLER->process_event($this,'AFTER');
+ }
+
+ /**
+ * 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
+ *
+ * @return $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
+ */
+ function trigger($action=null, $enablePrevent=true) {
+
+ if (!is_callable($action)) $enablePrevent = false;
+
+ if ($this->advise_before($enablePrevent) && is_callable($action)) {
+ if (is_array($action)) {
+ list($obj,$method) = $action;
+ $this->result = $obj->$method($this->data);
+ } else {
+ $this->result = $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
+ */
+ function stopPropagation() { $this->_continue = false; }
+
+ /**
+ * preventDefault
+ *
+ * prevent the default action taking place
+ */
+ function preventDefault() { $this->_default = false; }
+}
+
+class Doku_Event_Handler {
+
+ // public properties: none
+
+ // private properties
+ var $_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
+ */
+ function Doku_Event_Handler() {
+
+ // load action plugins
+ $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 $event (string) name used by the event, (incl '_before' or '_after' for triggers)
+ * @param $obj (obj) object in whose scope method is to be executed,
+ * if NULL, method is assumed to be a globally available function
+ * @param $method (function) event handler function
+ * @param $param (mixed) data passed to the event handler
+ */
+ function register_hook($event, $advise, &$obj, $method, $param=null) {
+ $this->_hooks[$event.'_'.$advise][] = array(&$obj, $method, $param);
+ }
+
+ function process_event(&$event,$advise='') {
+
+ $evt_name = $event->name . ($advise ? '_'.$advise : '_BEFORE');
+
+ if (!empty($this->_hooks[$evt_name])) {
+ $hook = reset($this->_hooks[$evt_name]);
+ do {
+ // list($obj, $method, $param) = $hook;
+ $obj =& $hook[0];
+ $method = $hook[1];
+ $param = $hook[2];
+
+ if (is_null($obj)) {
+ $method($event, $param);
+ } else {
+ $obj->$method($event, $param);
+ }
+
+ } while ($event->_continue && $hook = next($this->_hooks[$evt_name]));
+ }
+ }
+}
+
+/**
+ * trigger_event
+ *
+ * function wrapper to process (create, trigger and destroy) an event
+ *
+ * @param $name (string) name for the event
+ * @param $data (mixed) event data
+ * @param $action (callback) (optional, default=NULL) default action, a php callback function
+ * @param $canPreventDefault (bool) (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
+ */
+function trigger_event($name, &$data, $action=null, $canPreventDefault=true) {
+
+ $evt = new Doku_Event($name, $data);
+ return $evt->trigger($action, $canPreventDefault);
+}
diff --git a/inc/feedcreator.class.php b/inc/feedcreator.class.php
new file mode 100644
index 000000000..435add6ac
--- /dev/null
+++ b/inc/feedcreator.class.php
@@ -0,0 +1,1580 @@
+<?php
+/***************************************************************************
+ * FeedCreator class v1.7.2-ppt
+ * 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
+ * v1.7.2-mod on-the-fly feed generation by Fabian Wolf (info@f2w.de)
+ * v1.7.2-ppt ATOM 1.0 support by Mohammad Hafiz bin Ismail (mypapit@gmail.com)
+ *
+ * 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
+ *
+ * @author www.bitfolge.de
+ *
+ * Changelog:
+ *
+ * this version contains some smaller modifications for DokuWiki as well
+ *
+ * v1.7.2-ppt 11-21-05
+ * added Atom 1.0 support
+ * added enclosure support for RSS 2.0/ATOM 1.0
+ * added docs for v1.7.2-ppt only!
+ *
+ * v1.7.2-mod 03-12-05
+ * added output function outputFeed for on-the-fly feed generation
+ *
+ * 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)
+ *
+ * See www.bitfolge.de for additional changelog info
+ */
+// your local timezone, set to "" to disable or for GMT
+define("TIME_ZONE",date("O", time()));
+
+
+
+
+/**
+ * Version string.
+ **/
+
+define("FEEDCREATOR_VERSION", "FeedCreator 1.7.2-ppt DokuWiki");
+
+
+
+/**
+ * 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.
+ */
+ var $title, $description, $link;
+
+ /**
+ * Optional attributes of an item.
+ */
+ var $author, $authorEmail, $image, $category, $comments, $guid, $source, $creator;
+
+ /**
+ * 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
+ */
+ var $date;
+
+ /**
+ * Add <enclosure> element tag RSS 2.0
+ * modified by : Mohammad Hafiz bin Ismail (mypapit@gmail.com)
+ *
+ *
+ * display :
+ * <enclosure length="17691" url="http://something.com/picture.jpg" type="image/jpeg" />
+ *
+ */
+ var $enclosure;
+
+ /**
+ * Any additional elements to include as an assiciated 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.
+ */
+ var $additionalElements = Array();
+
+ // on hold
+ // var $source;
+}
+
+class EnclosureItem extends HtmlDescribable {
+ /*
+ *
+ * core variables
+ *
+ **/
+ var $url,$length,$type;
+
+ /*
+ * For use with another extension like Yahoo mRSS
+ * Warning :
+ * These variables might not show up in
+ * later release / not finalize yet!
+ *
+ */
+ var $width, $height, $title, $description, $keywords, $thumburl;
+
+ var $additionalElements = Array();
+
+}
+
+
+/**
+ * An 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.
+ */
+ var $title, $url, $link;
+
+ /**
+ * Optional attributes of an image.
+ */
+ var $width, $height, $description;
+}
+
+
+
+/**
+ * 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.
+ */
+ var $descriptionHtmlSyndicated;
+
+ /**
+ * Indicates whether and to how many characters a description should be truncated.
+ */
+ var $descriptionTruncSize;
+
+ /**
+ * Returns a formatted description field, depending on descriptionHtmlSyndicated and
+ * $descriptionTruncSize properties
+ * @return string the formatted description
+ */
+ function getDescription() {
+ $descriptionField = new FeedHtmlField($this->description);
+ $descriptionField->syndicateHtml = $this->descriptionHtmlSyndicated;
+ $descriptionField->truncSize = $this->descriptionTruncSize;
+ return $descriptionField->output();
+ }
+
+}
+
+
+
+/**
+ * An 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.
+ */
+ var $rawFieldContent;
+
+ /**
+ * Optional attributes of a FeedHtmlField.
+ *
+ */
+ var $truncSize, $syndicateHtml;
+
+ /**
+ * Creates a new instance of FeedHtmlField.
+ * @param $string: if given, sets the rawFieldContent property
+ */
+ function FeedHtmlField($parFieldContent) {
+ if ($parFieldContent) {
+ $this->rawFieldContent = $parFieldContent;
+ }
+ }
+
+
+ /**
+ * Creates the right output, depending on $truncSize, $syndicateHtml properties.
+ * @return string the formatted field
+ */
+ 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;
+ }
+
+}
+
+
+
+/**
+ * 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 $_feed;
+
+ function _setFormat($format) {
+ switch (strtoupper($format)) {
+
+ case "2.0":
+ // fall through
+ case "RSS2.0":
+ $this->_feed = new RSSCreator20();
+ break;
+
+ 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 "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 "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};
+ }
+ }
+ }
+
+ function _sendMIME() {
+ header('Content-Type: '.$this->contentType.'; charset='.$this->encoding, true);
+ }
+
+ /**
+ * 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.
+ */
+ 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.
+ */
+ 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 filename string 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 timeout int optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
+ */
+ function useCached($format="RSS0.91", $filename="", $timeout=3600) {
+ $this->_setFormat($format);
+ $this->_feed->useCached($filename, $timeout);
+ }
+
+
+ /**
+ * Outputs feed to the browser - needed for on-the-fly feed generation (like it is done in WordPress, etc.)
+ *
+ * @param format string format the feed should comply to. Valid values are:
+ * "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3".
+ */
+ function outputFeed($format='RSS0.91') {
+ $this->_setFormat($format);
+ $this->_sendMIME();
+ $this->_feed->outputFeed();
+ }
+
+
+}
+
+
+/**
+ * FeedCreator is the abstract base implementation for concrete
+ * implementations that implement a specific format of syndication.
+ *
+ * @abstract
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ * @since 1.4
+ */
+class FeedCreator extends HtmlDescribable {
+
+ /**
+ * Mandatory attributes of a feed.
+ */
+ var $title, $description, $link;
+
+
+ /**
+ * Optional attributes of a feed.
+ */
+ var $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.
+ */
+ var $xslStyleSheet = "";
+
+
+ /**
+ * @access private
+ */
+ var $items = Array();
+
+
+ /**
+ * This feed's MIME content type.
+ * @since 1.4
+ * @access private
+ */
+ var $contentType = "application/xml";
+
+
+ /**
+ * This feed's character encoding.
+ * @since 1.6.1
+ **/
+ var $encoding = "utf-8";
+
+
+ /**
+ * Any additional elements to include as an assiciated 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.
+ */
+ var $additionalElements = Array();
+
+
+ /**
+ * Adds an FeedItem to the feed.
+ *
+ * @param object FeedItem $item The FeedItem to add to the feed.
+ * @access public
+ */
+ function addItem($item) {
+ $this->items[] = $item;
+ }
+
+
+ /**
+ * 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.
+ *
+ * @static
+ * @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
+ */
+ 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.
+ */
+ function _createGeneratorComment() {
+ return "<!-- generator=\"".FEEDCREATOR_VERSION."\" -->\n";
+ }
+
+
+ /**
+ * Creates a string containing all additional elements specified in
+ * $additionalElements.
+ * @param elements array an associative array containing key => value pairs
+ * @param indentString string a string that will be inserted before every generated line
+ * @return string the XML tags corresponding to $additionalElements
+ */
+ function _createAdditionalElements($elements, $indentString="") {
+ $ae = "";
+ if (is_array($elements)) {
+ foreach($elements AS $key => $value) {
+ $ae.= $indentString."<$key>$value</$key>\n";
+ }
+ }
+ return $ae;
+ }
+
+ function _createStylesheetReferences() {
+ $xml = "";
+ if ($this->cssStyleSheet) $xml .= "<?xml-stylesheet href=\"".$this->cssStyleSheet."\" type=\"text/css\"?>\n";
+ if ($this->xslStyleSheet) $xml .= "<?xml-stylesheet href=\"".$this->xslStyleSheet."\" type=\"text/xsl\"?>\n";
+ return $xml;
+ }
+
+
+ /**
+ * Builds the feed's text.
+ * @abstract
+ * @return string the feed's complete text
+ */
+ 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
+ */
+ function _generateFilename() {
+ $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+ return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".xml";
+ }
+
+
+ /**
+ * @since 1.4
+ * @access private
+ */
+ 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));
+ header("Content-Disposition: inline; filename=".basename($filename));
+ readfile($filename, "r");
+ die();
+ }
+
+ /**
+ * 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 filename string 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 timeout int optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
+ */
+ 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 filename string 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 redirect boolean optional send an HTTP redirect header or not. If true, the user will be automatically redirected to the created file.
+ */
+ 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 />";
+ }
+ }
+
+ /**
+ * Outputs this feed directly to the browser - for on-the-fly feed generation
+ * @since 1.7.2-mod
+ *
+ * still missing: proper header output - currently you have to add it manually
+ */
+ function outputFeed() {
+ echo $this->createFeed();
+ }
+
+
+}
+
+
+/**
+ * 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 {
+ var $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.
+ */
+ function FeedDate($dateString="") {
+ if ($dateString=="") $dateString = date("r");
+
+ if (is_numeric($dateString)) {
+ $this->unix = $dateString;
+ return;
+ }
+ 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 a date in RFC 822 format
+ */
+ function rfc822() {
+ //return gmdate("r",$this->unix);
+ $date = gmdate("D, d M Y H:i:s", $this->unix);
+ if (TIME_ZONE!="") $date .= " ".str_replace(":","",TIME_ZONE);
+ return $date;
+ }
+
+ /**
+ * Gets the date stored in this FeedDate as an ISO 8601 date.
+ *
+ * @return a date in ISO 8601 (RFC 3339) format
+ */
+ function iso8601() {
+ $date = gmdate("Y-m-d\TH:i:sO",$this->unix);
+ if (TIME_ZONE!="") $date = str_replace("+0000",TIME_ZONE,$date);
+ $date = substr($date,0,22) . ':' . substr($date,-2);
+ return $date;
+ }
+
+
+ /**
+ * Gets the date stored in this FeedDate as unix time stamp.
+ *
+ * @return a date as a unix time stamp
+ */
+ function unix() {
+ return $this->unix;
+ }
+}
+
+
+/**
+ * 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 {
+
+ /**
+ * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
+ * The feed will contain all items previously added in the same order.
+ * @return string the feed's complete text
+ */
+ function createFeed() {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed.= $this->_createGeneratorComment();
+ if ($this->cssStyleSheet=="") {
+ $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";
+ $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";
+ $icnt = count($this->items);
+ for ($i=0; $i<$icnt; $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>".htmlspecialchars($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, " ");
+
+ $icnt = count($this->items);
+ for ($i=0; $i<$icnt; $i++) {
+ $feed.= " <item rdf:about=\"".htmlspecialchars($this->items[$i]->link)."\">\n";
+ //$feed.= " <dc:type>Posting</dc:type>\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";
+ }
+ if ($this->items[$i]->author!="") {
+ $feed.= " <dc:creator>".htmlspecialchars($this->items[$i]->author)."</dc:creator>\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;
+ }
+}
+
+
+
+/**
+ * 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 {
+
+ /**
+ * Stores this RSS feed's version number.
+ * @access private
+ */
+ var $RSSVersion;
+
+ function RSSCreator091() {
+ $this->_setRSSVersion("0.91");
+ $this->contentType = "application/rss+xml";
+ }
+
+ /**
+ * Sets this RSS feed's version number.
+ * @access private
+ */
+ function _setRSSVersion($version) {
+ $this->RSSVersion = $version;
+ }
+
+ /**
+ * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
+ * The feed will contain all items previously added in the same order.
+ * @return string the feed's complete text
+ */
+ function createFeed() {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed.= $this->_createGeneratorComment();
+ $feed.= $this->_createStylesheetReferences();
+ $feed.= "<rss version=\"".$this->RSSVersion."\">\n";
+ $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($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>".$this->image->getDescription()."</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!="") {
+ // Changed for DokuWiki: multiple categories are possible
+ if(is_array($this->category)) foreach($this->category as $cat){
+ $feed.= " <category>".htmlspecialchars($cat)."</category>\n";
+ }else{
+ $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, " ");
+
+ $icnt = count($this->items);
+ for ($i=0; $i<$icnt; $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";
+
+ if ($this->items[$i]->author!="") {
+ $feed.= " <author>".htmlspecialchars($this->items[$i]->author)."</author>\n";
+ }
+ /*
+ // on hold
+ if ($this->items[$i]->source!="") {
+ $feed.= " <source>".htmlspecialchars($this->items[$i]->source)."</source>\n";
+ }
+ */
+ if ($this->items[$i]->category!="") {
+ // Changed for DokuWiki: multiple categories are possible
+ if(is_array($this->items[$i]->category)) foreach($this->items[$i]->category as $cat){
+ $feed.= " <category>".htmlspecialchars($cat)."</category>\n";
+ }else{
+ $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";
+ }
+ $feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
+
+ if ($this->RSSVersion == "2.0" && $this->items[$i]->enclosure != null) {
+ $feed.= " <enclosure url=\"";
+ $feed.= $this->items[$i]->enclosure->url;
+ $feed.= "\" length=\"";
+ $feed.= $this->items[$i]->enclosure->length;
+ $feed.= "\" type=\"";
+ $feed.= $this->items[$i]->enclosure->type;
+ $feed.= "\"/>\n";
+ }
+
+ $feed.= " </item>\n";
+ }
+
+ $feed.= " </channel>\n";
+ $feed.= "</rss>\n";
+ return $feed;
+ }
+}
+
+
+
+/**
+ * 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 {
+
+ function RSSCreator20() {
+ parent::_setRSSVersion("2.0");
+ }
+
+}
+
+
+/**
+ * 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 {
+
+ function PIECreator01() {
+ $this->encoding = "utf-8";
+ }
+
+ 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";
+ $icnt = count($this->items);
+ for ($i=0; $i<$icnt; $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;
+ }
+}
+
+/**
+ * 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 {
+
+ function AtomCreator10() {
+ $this->contentType = "application/atom+xml";
+ $this->encoding = "utf-8";
+ }
+
+ 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 ($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";
+ }
+ $feed.= " <generator>".FEEDCREATOR_VERSION."</generator>\n";
+ $feed.= "<link rel=\"self\" type=\"application/atom+xml\" href=\"". $this->syndicationURL . "\" />\n";
+ $feed.= $this->_createAdditionalElements($this->additionalElements, " ");
+ $icnt = count($this->items);
+ for ($i=0; $i<$icnt; $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";
+ $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 ($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 . "\" />\n";
+ }
+ $feed.= " </entry>\n";
+ }
+ $feed.= "</feed>\n";
+ return $feed;
+ }
+
+
+}
+
+
+/**
+ * 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 {
+
+ function AtomCreator03() {
+ $this->contentType = "application/atom+xml";
+ $this->encoding = "utf-8";
+ }
+
+ 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->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, " ");
+ $icnt = count($this->items);
+ for ($i=0; $i<$icnt; $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";
+ }
+ $feed.= " </entry>\n";
+ }
+ $feed.= "</feed>\n";
+ return $feed;
+ }
+}
+
+
+/**
+ * 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 {
+
+ function MBOXCreator() {
+ $this->contentType = "text/plain";
+ $this->encoding = "utf-8";
+ }
+
+ 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 = "";
+ while( list(, $line) = each($lines) ) {
+ //$line = rtrim($line); // remove trailing white space -> no =20\r\n necessary
+ $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.
+ * @return string the feed's complete text
+ */
+ function createFeed() {
+ $icnt = count($this->items);
+ for ($i=0; $i<$icnt; $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
+ */
+ function _generateFilename() {
+ $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+ return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".mbox";
+ }
+}
+
+
+/**
+ * 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 {
+
+ function OPMLCreator() {
+ $this->encoding = "utf-8";
+ }
+
+ 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";
+ $icnt = count($this->items);
+ for ($i=0;$i<$icnt; $i++) {
+ $feed.= " <outline type=\"rss\" ";
+ $title = htmlspecialchars(strip_tags(strtr($this->items[$i]->title,"\n\r"," ")));
+ $feed.= " title=\"".$title."\"";
+ $feed.= " text=\"".$title."\"";
+ //$feed.= " description=\"".htmlspecialchars($this->items[$i]->description)."\"";
+ $feed.= " url=\"".htmlspecialchars($this->items[$i]->link)."\"";
+ $feed.= "/>\n";
+ }
+ $feed.= " </body>\n";
+ $feed.= "</opml>\n";
+ return $feed;
+ }
+}
+
+
+
+/**
+ * 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 {
+
+ var $contentType = "text/html";
+
+ /**
+ * Contains HTML to be output at the start of the feed's html representation.
+ */
+ var $header;
+
+ /**
+ * Contains HTML to be output at the end of the feed's html representation.
+ */
+ var $footer ;
+
+ /**
+ * Contains HTML to be output between entries. A separator is only used in
+ * case of multiple entries.
+ */
+ var $separator;
+
+ /**
+ * Used to prefix the stylenames to make sure they are unique
+ * and do not clash with stylenames on the users' page.
+ */
+ var $stylePrefix;
+
+ /**
+ * Determines whether the links open in a new window or not.
+ */
+ var $openInNewWindow = true;
+
+ var $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().
+ */
+ var $stylelessOutput ="";
+
+ /**
+ * Writes the HTML.
+ * @return string the scripts's complete text
+ */
+ 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 = " target='_blank'";
+ }
+
+ // 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>";
+ }
+
+ $icnt = count($this->items);
+ for ($i=0; $i<$icnt; $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;
+ }
+
+ /**
+ * Overrrides parent to produce .html extensions
+ *
+ * @return string the feed cache filename
+ * @since 1.4
+ * @access private
+ */
+ function _generateFilename() {
+ $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+ return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".html";
+ }
+}
+
+
+/**
+ * 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 {
+ var $contentType = "text/javascript";
+
+ /**
+ * writes the javascript
+ * @return string the scripts's complete text
+ */
+ function createFeed() {
+ $feed = parent::createFeed();
+ $feedArray = explode("\n",$feed);
+
+ $jsFeed = "";
+ foreach ($feedArray as $value) {
+ $jsFeed .= "document.write('".trim(addslashes($value))."');\n";
+ }
+ return $jsFeed;
+ }
+
+ /**
+ * Overrrides parent to produce .js extensions
+ *
+ * @return string the feed cache filename
+ * @since 1.4
+ * @access private
+ */
+ function _generateFilename() {
+ $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+ return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".js";
+ }
+
+}
+
+/**
+ * This class allows to override the hardcoded charset
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class DokuWikiFeedCreator extends UniversalFeedCreator{
+ function createFeed($format = "RSS0.91",$encoding='iso-8859-15') {
+ $this->_setFormat($format);
+ $this->_feed->encoding = $encoding;
+ return $this->_feed->createFeed();
+ }
+}
+
+
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/form.php b/inc/form.php
new file mode 100644
index 000000000..e74c52c5d
--- /dev/null
+++ b/inc/form.php
@@ -0,0 +1,950 @@
+<?php
+/**
+ * DokuWiki XHTML Form
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * 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.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+class Doku_Form {
+
+ // Form id attribute
+ var $params = array();
+
+ // Draw a border around form fields.
+ // Adds <fieldset></fieldset> around the elements
+ var $_infieldset = false;
+
+ // Hidden form fields.
+ var $_hidden = array();
+
+ // Array of pseudo-tags
+ var $_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 string $action (optional, deprecated) submit URL, defaults to
+ * current page
+ * @param string $method (optional, deprecated) 'POST' or 'GET', default
+ * is POST
+ * @param string $enctype (optional, deprecated) Encoding type of the
+ * data
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ function Doku_Form($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>
+ */
+ 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>
+ */
+ 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>
+ */
+ 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 $elem Pseudo-tag or string to add to the form.
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ 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 $elem Pseudo-tag or string to add to the form.
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ 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 $elem Pseudo-tag or string to add to the form.
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ 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 array pseudo-element if found, false otherwise
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ 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 array pseudo-element if found, false otherwise
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ 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 array pseudo-element if found, false otherwise
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ 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 arrayreference pseudo-element
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ 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>
+ */
+ 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()
+ */
+ 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>
+ */
+
+ function addRadioSet($name, $entries) {
+ $value = (isset($_POST[$name]) && isset($entries[$_POST[$name]])) ?
+ $_POST[$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, 'class'=>'button');
+ 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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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) {
+ if (is_array($val))
+ @list($val,$text) = $val;
+ else
+ $text = null;
+ $options[] = array($val,$text,in_array($val,$selected));
+ }
+ }
+ $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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+function form_wikitext($attrs) {
+ // mandatory attributes
+ unset($attrs['name']);
+ unset($attrs['id']);
+ return '<textarea name="wikitext" id="wiki__text" '
+ .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>
+ */
+function form_button($attrs) {
+ $p = (!empty($attrs['_action'])) ? 'name="do['.$attrs['_action'].']" ' : '';
+ return '<input '.$p.buildAttributes($attrs,true).' />';
+}
+
+/**
+ * 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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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) = $opt;
+ $p = '';
+ if(is_null($text)) $text = $value;
+ $p .= ' value="'.formText($value).'"';
+ if (!empty($select)) $p .= ' selected="selected"';
+ $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/inc/fulltext.php b/inc/fulltext.php
new file mode 100644
index 000000000..620237296
--- /dev/null
+++ b/inc/fulltext.php
@@ -0,0 +1,753 @@
+<?php
+/**
+ * DokuWiki fulltextsearch functions using the index
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * 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()
+ *
+ */
+function ft_pageSearch($query,&$highlight){
+
+ $data['query'] = $query;
+ $data['highlight'] =& $highlight;
+
+ return trigger_event('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>
+ */
+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){
+ $text = utf8_strtolower(rawWiki($id));
+ if (strpos($text, $phrase) !== false) {
+ $pages_matched[$id] = 0; // phrase: always 0 hit
+ }
+ }
+ $stack[] = $pages_matched;
+ break;
+ case 'N+:':
+ case 'N-:': // namespace
+ $ns = 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]);
+ }
+ }
+
+ // sort docs by count
+ arsort($docs);
+
+ return $docs;
+}
+
+/**
+ * Returns the backlinks for a given page
+ *
+ * Uses the metadata index.
+ */
+function ft_backlinks($id){
+ $result = array();
+
+ $result = idx_get_indexer()->lookupKey('relation_references', $id);
+
+ if(!count($result)) return $result;
+
+ // check ACL permissions
+ foreach(array_keys($result) as $idx){
+ if(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
+ *
+ * Does a quick lookup with the fulltext index, then
+ * evaluates the instructions of the found pages
+ *
+ * Aborts after $max found results
+ */
+function ft_mediause($id,$max){
+ if(!$max) $max = 1; // need to find at least one
+
+ $result = array();
+
+ // quick lookup of the mediafile
+ // FIXME use metadata key lookup
+ $media = noNS($id);
+ $matches = idx_lookup(idx_tokenizer($media));
+ $docs = array_keys(ft_resultCombine(array_values($matches)));
+ if(!count($docs)) return $result;
+
+ // go through all found pages
+ $found = 0;
+ $pcre = preg_quote($media,'/');
+ foreach($docs as $doc){
+ $ns = getNS($doc);
+ preg_match_all('/\{\{([^|}]*'.$pcre.'[^|}]*)(|[^}]+)?\}\}/i',rawWiki($doc),$matches);
+ foreach($matches[1] as $img){
+ $img = trim($img);
+ if(preg_match('/^https?:\/\//i',$img)) continue; // skip external images
+ list($img) = explode('?',$img); // remove any parameters
+ resolve_mediaid($ns,$img,$exists); // resolve the possibly relative img
+
+ if($img == $id){ // we have a match
+ $result[] = $doc;
+ $found++;
+ break;
+ }
+ }
+ if($found >= $max) break;
+ }
+
+ 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>
+ */
+function ft_pageLookup($id, $in_ns=false, $in_title=false){
+ $data = compact('id', 'in_ns', 'in_title');
+ $data['has_titles'] = true; // for plugin backward compatibility check
+ return trigger_event('SEARCH_QUERY_PAGELOOKUP', $data, '_ft_pageLookup');
+}
+
+function _ft_pageLookup(&$data){
+ // split out original parameters
+ $id = $data['id'];
+ if (preg_match('/(?:^| )@(\w+)/', $id, $matches)) {
+ $ns = cleanID($matches[1]) . ':';
+ $id = str_replace($matches[0], '', $id);
+ }
+
+ $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]);
+ }
+ }
+
+ uksort($pages,'ft_pagesorter');
+ return $pages;
+}
+
+/**
+ * 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.
+ */
+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.
+ */
+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);
+}
+
+/**
+ * Creates a snippet extract
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @triggers FULLTEXT_SNIPPET_CREATE
+ */
+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 Doku_Event('FULLTEXT_SNIPPET_CREATE',$evdata);
+ if ($evt->advise_before()) {
+ $match = array();
+ $snippets = array();
+ $utf8_offset = $offset = $end = 0;
+ $len = utf8_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 = utf8_strlen(substr($text,0,$idx));
+ $utf8_len = utf8_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 {
+ // 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] .= utf8_substr($text,$append,$end-$append);
+ } else {
+ $snippets[] = utf8_substr($text,$start,$end-$start);
+ }
+
+ // set $offset for next match attempt
+ // substract strlen to avoid splitting a potential search success,
+ // this is an approximation as the search pattern may match strings
+ // of varying length and it will fail if the context snippet
+ // boundary breaks a matching string longer than the current match
+ $utf8_offset = $utf8_idx + $post;
+ $offset = $idx + strlen(utf8_substr($text,$utf8_idx,$post));
+ $offset = utf8_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.
+ */
+function ft_snippet_re_preprocess($term) {
+ // do not process asian terms where word boundaries are not explicit
+ if(preg_match('/'.IDX_ASIAN.'/u',$term)){
+ return $term;
+ }
+
+ if(substr($term,0,2) == '\\*'){
+ $term = substr($term,2);
+ }else{
+ $term = '\b'.$term;
+ }
+
+ if(substr($term,-2,2) == '\\*'){
+ $term = substr($term,0,-2);
+ }else{
+ $term = $term.'\b';
+ }
+ 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
+ */
+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
+ * @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
+ * @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>
+ */
+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', utf8_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 ($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>
+ */
+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 = preg_split('/('.IDX_ASIAN.'+)/u', $term, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+ foreach ($words as $word) {
+ $phrase_mode = $phrase_mode ? true : preg_match('/'.IDX_ASIAN.'/u', $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;
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/geshi.php b/inc/geshi.php
new file mode 100644
index 000000000..31d2da49f
--- /dev/null
+++ b/inc/geshi.php
@@ -0,0 +1,4656 @@
+<?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 - 2008 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.8.8');
+
+// 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);
+
+/** Used to work around missing PHP features **/
+define('GESHI_PHP_PRE_433', !(version_compare(PHP_VERSION, '4.3.3') === 1));
+
+/** make sure we can call stripos **/
+if (!function_exists('stripos')) {
+ // the offset param of preg_match is not supported below PHP 4.3.3
+ if (GESHI_PHP_PRE_433) {
+ /**
+ * @ignore
+ */
+ function stripos($haystack, $needle, $offset = null) {
+ if (!is_null($offset)) {
+ $haystack = substr($haystack, $offset);
+ }
+ if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE)) {
+ return $match[0][1];
+ }
+ return false;
+ }
+ }
+ else {
+ /**
+ * @ignore
+ */
+ function stripos($haystack, $needle, $offset = null) {
+ if (preg_match('/'. preg_quote($needle, '/') . '/', $haystack, $match, PREG_OFFSET_CAPTURE, $offset)) {
+ return $match[0][1];
+ }
+ return false;
+ }
+ }
+}
+
+/** 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 suffix of o */
+define('GESHI_NUMBER_OCT_SUFFIX', 1024); //[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 suffix of h */
+define('GESHI_NUMBER_HEX_SUFFIX', 8192); //[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>, Benny Baumann <BenBE@omorphia.de>
+ * @copyright (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2008 Benny Baumann
+ */
+class GeSHi {
+ /**#@+
+ * @access private
+ */
+ /**
+ * The source code to highlight
+ * @var string
+ */
+ var $source = '';
+
+ /**
+ * The language to use when highlighting
+ * @var string
+ */
+ var $language = '';
+
+ /**
+ * The data for the language used
+ * @var array
+ */
+ var $language_data = array();
+
+ /**
+ * The path to the language files
+ * @var string
+ */
+ var $language_path = GESHI_LANG_ROOT;
+
+ /**
+ * The error message associated with an error
+ * @var string
+ * @todo check err reporting works
+ */
+ var $error = false;
+
+ /**
+ * Possible error messages
+ * @var array
+ */
+ var $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
+ */
+ var $strict_mode = false;
+
+ /**
+ * Whether to use CSS classes in output
+ * @var boolean
+ */
+ var $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
+ */
+ var $header_type = GESHI_HEADER_PRE;
+
+ /**
+ * Array of permissions for which lexics should be highlighted
+ * @var array
+ */
+ var $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
+ */
+ var $time = 0;
+
+ /**
+ * The content of the header block
+ * @var string
+ */
+ var $header_content = '';
+
+ /**
+ * The content of the footer block
+ * @var string
+ */
+ var $footer_content = '';
+
+ /**
+ * The style of the header block
+ * @var string
+ */
+ var $header_content_style = '';
+
+ /**
+ * The style of the footer block
+ * @var string
+ */
+ var $footer_content_style = '';
+
+ /**
+ * Tells if a block around the highlighted source should be forced
+ * if not using line numbering
+ * @var boolean
+ */
+ var $force_code_block = false;
+
+ /**
+ * The styles for hyperlinks in the code
+ * @var array
+ */
+ var $link_styles = array();
+
+ /**
+ * Whether important blocks should be recognised or not
+ * @var boolean
+ * @deprecated
+ * @todo REMOVE THIS FUNCTIONALITY!
+ */
+ var $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
+ */
+ var $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
+ */
+ var $add_ids = false;
+
+ /**
+ * Lines that should be highlighted extra
+ * @var array
+ */
+ var $highlight_extra_lines = array();
+
+ /**
+ * Styles of lines that should be highlighted extra
+ * @var array
+ */
+ var $highlight_extra_lines_styles = array();
+
+ /**
+ * Styles of extra-highlighted lines
+ * @var string
+ */
+ var $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
+ */
+ var $line_ending = null;
+
+ /**
+ * Number at which line numbers should start at
+ * @var int
+ */
+ var $line_numbers_start = 1;
+
+ /**
+ * The overall style for this code block
+ * @var string
+ */
+ var $overall_style = 'font-family:monospace;';
+
+ /**
+ * The style for the actual code
+ * @var string
+ */
+ var $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
+ */
+ var $overall_class = '';
+
+ /**
+ * The overall ID for this code block
+ * @var string
+ */
+ var $overall_id = '';
+
+ /**
+ * Line number styles
+ * @var string
+ */
+ var $line_style1 = 'font-weight: normal; vertical-align:top;';
+
+ /**
+ * Line number styles for fancy lines
+ * @var string
+ */
+ var $line_style2 = 'font-weight: bold; vertical-align:top;';
+
+ /**
+ * Style for line numbers when GESHI_HEADER_PRE_TABLE is chosen
+ * @var string
+ */
+ var $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
+ */
+ var $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
+ */
+ var $allow_multiline_span = true;
+
+ /**
+ * The "nth" value for fancy line highlighting
+ * @var int
+ */
+ var $line_nth_row = 0;
+
+ /**
+ * The size of tab stops
+ * @var int
+ */
+ var $tab_width = 8;
+
+ /**
+ * Should we use language-defined tab stop widths?
+ * @var int
+ */
+ var $use_language_tab_width = false;
+
+ /**
+ * Default target for keyword links
+ * @var string
+ */
+ var $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
+ */
+ var $encoding = 'utf-8';
+
+ /**
+ * Should keywords be linked?
+ * @var boolean
+ */
+ var $keyword_links = true;
+
+ /**
+ * Currently loaded language file
+ * @var string
+ * @since 1.0.7.22
+ */
+ var $loaded_language = '';
+
+ /**
+ * Wether the caches needed for parsing are built or not
+ *
+ * @var bool
+ * @since 1.0.8
+ */
+ var $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
+ */
+ var $_kw_replace_group = 0;
+ var $_rx_key = 0;
+
+ /**
+ * some "callback parameters" for handle_multiline_regexps
+ *
+ * @since 1.0.8
+ * @access private
+ * @var string
+ */
+ var $_hmr_before = '';
+ var $_hmr_replace = '';
+ var $_hmr_after = '';
+ var $_hmr_key = 0;
+
+ /**#@-*/
+
+ /**
+ * Creates a new GeSHi object, with source and language
+ *
+ * @param string The source code to highlight
+ * @param string The language to highlight the source with
+ * @param string 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
+ */
+ function GeSHi($source = '', $language = '', $path = '') {
+ if (!empty($source)) {
+ $this->set_source($source);
+ }
+ if (!empty($language)) {
+ $this->set_language($language);
+ }
+ $this->set_language_path($path);
+ }
+
+ /**
+ * Returns an error message associated with the last GeSHi operation,
+ * or false if no error has occured
+ *
+ * @return string|false An error message if there has been an error, else false
+ * @since 1.0.0
+ */
+ 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
+ */
+ 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 The source code to highlight
+ * @since 1.0.0
+ */
+ function set_source($source) {
+ $this->source = $source;
+ $this->highlight_extra_lines = array();
+ }
+
+ /**
+ * 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 The name of the language to use
+ * @since 1.0.0
+ */
+ function set_language($language, $force_reset = false) {
+ if ($force_reset) {
+ $this->loaded_language = false;
+ }
+
+ //Clean up the language name to prevent malicious code injection
+ $language = preg_replace('#[^a-zA-Z0-9\-_]#', '', $language);
+
+ $language = strtolower($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;
+
+ $this->error = false;
+ $this->strict_mode = GESHI_NEVER;
+
+ //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 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.
+ */
+ 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
+ }
+ }
+
+ /**
+ * 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 The type of header to be used
+ * @since 1.0.0
+ */
+ 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 The overall style for the outputted code block
+ * @param boolean Whether to merge the styles with the current styles or not
+ * @since 1.0.0
+ */
+ 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 The class name to use for this block of code
+ * @since 1.0.0
+ */
+ 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 The ID to use for this block of code
+ * @since 1.0.0
+ */
+ 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 Whether to turn classes on or not
+ * @since 1.0.0
+ */
+ 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 The style to use for actual code
+ * @param boolean Whether to merge the current styles with the new styles
+ * @since 1.0.2
+ */
+ 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 The style for the line numbers that are "normal"
+ * @param string|boolean 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 If set, is the flag for whether to merge the "fancy"
+ * styles with the current styles or not
+ * @since 1.0.2
+ */
+ 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 How line numbers should be displayed
+ * @param int Defines which lines are fancy
+ * @since 1.0.0
+ */
+ 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 Wether multiline spans are allowed or not
+ * @since 1.0.7.22
+ */
+ 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
+ */
+ 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 The key of the keyword group to change the styles of
+ * @param string The style to make the keywords
+ * @param boolean Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ */
+ function set_keyword_group_style($key, $style, $preserve_defaults = false) {
+ //Set the style for this keyword group
+ 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 The key of the keyword group to turn on or off
+ * @param boolean Whether to turn highlighting for that group on or off
+ * @since 1.0.0
+ */
+ 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 The key of the comment group to change the styles of
+ * @param string The style to make the comments
+ * @param boolean Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ */
+ function set_comments_style($key, $style, $preserve_defaults = false) {
+ 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 The key of the comment group to turn on or off
+ * @param boolean Whether to turn highlighting for that group on or off
+ * @since 1.0.0
+ */
+ 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 The style to make the escape characters
+ * @param boolean Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ */
+ 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 Whether to turn highlighting for escape characters on or off
+ * @since 1.0.0
+ */
+ 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 The style to make the brackets
+ * @param boolean 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
+ */
+ 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 Whether to turn highlighting for brackets on or off
+ * @since 1.0.0
+ * @deprecated In favour of set_symbols_highlighting
+ */
+ 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 The style to make the symbols
+ * @param boolean Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param int Tells the group of symbols for which style should be set.
+ * @since 1.0.1
+ */
+ 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 Whether to turn highlighting for symbols on or off
+ * @since 1.0.0
+ */
+ 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 The style to make the escape characters
+ * @param boolean Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param int Tells the group of strings for which style should be set.
+ * @since 1.0.0
+ */
+ 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 Whether to turn highlighting for strings on or off
+ * @since 1.0.0
+ */
+ 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 The style to make the script blocks
+ * @param boolean Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param int Tells the group of script blocks for which style should be set.
+ * @since 1.0.8.4
+ */
+ 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 The style to make the numbers
+ * @param boolean Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param int Tells the group of numbers for which style should be set.
+ * @since 1.0.0
+ */
+ 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 Whether to turn highlighting for numbers on or off
+ * @since 1.0.0
+ */
+ 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 The key of the object splitter to change the styles of
+ * @param string The style to make the methods
+ * @param boolean Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ */
+ 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 Whether to turn highlighting for methods on or off
+ * @since 1.0.0
+ */
+ 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 The style to make the regular expression matches
+ * @param boolean Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ */
+ 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 The key of the regular expression group to turn on or off
+ * @param boolean Whether to turn highlighting for the regular expression group on or off
+ * @since 1.0.0
+ */
+ 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 The key of the keyword group to change the case sensitivity of
+ * @param boolean Whether to check in a case sensitive manner or not
+ * @since 1.0.0
+ */
+ 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 A constant specifying what to do with matched keywords
+ * @since 1.0.1
+ */
+ 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 The tab width
+ * @since 1.0.0
+ */
+ 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 Whether to use language-specific tab-stop widths
+ * @since 1.0.7.20
+ */
+ 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
+ */
+ 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 Whether to enable strict mode or not
+ * @since 1.0.0
+ */
+ 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
+ */
+ 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 A flag specifying whether to enable or disable all highlighting
+ * @todo Rewrite with array traversal
+ */
+ 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 The extension to get a language name for
+ * @param array 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?)
+ * @todo static?
+ */
+ function get_language_name_from_extension( $extension, $lookup = array() ) {
+ if ( !is_array($lookup) || empty($lookup)) {
+ $lookup = array(
+ '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'),
+ 'html4strict' => array('html', 'htm'),
+ 'ini' => array('ini', 'desktop'),
+ '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'),
+ 'vb' => array('bas'),
+ 'vbnet' => array(),
+ 'visualfoxpro' => array(),
+ 'whitespace' => array('ws'),
+ 'xml' => array('xml', 'svg', 'xrc'),
+ 'z80' => array('z80', 'asm', 'inc')
+ );
+ }
+
+ foreach ($lookup as $lang => $extensions) {
+ if (in_array($extension, $extensions)) {
+ return $lang;
+ }
+ }
+ return '';
+ }
+
+ /**
+ * 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 The filename to load the source from
+ * @param array A lookup array to use instead of the default one
+ * @todo Complete rethink of this and above method
+ * @since 1.0.5
+ */
+ function load_from_file($file_name, $lookup = array()) {
+ if (is_readable($file_name)) {
+ $this->set_source(file_get_contents($file_name));
+ $this->set_language($this->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 The key of the keyword group to add the keyword to
+ * @param string The word to add to the keyword group
+ * @since 1.0.0
+ */
+ function add_keyword($key, $word) {
+ 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 The key of the keyword group to remove the keyword from
+ * @param string The word to remove from the keyword group
+ * @param bool 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
+ */
+ 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 The key of the keyword group to create
+ * @param string The styles for the keyword group
+ * @param boolean Whether the keyword group is case sensitive ornot
+ * @param array The words to use for the keyword group
+ * @since 1.0.0
+ */
+ 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);
+ }
+ }
+
+ /**
+ * Removes a keyword group
+ *
+ * @param int The key of the keyword group to remove
+ * @since 1.0.0
+ */
+ 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 The key of the keyword group to compile & optimize
+ * @since 1.0.8
+ */
+ 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 The content of the header block
+ * @since 1.0.2
+ */
+ function set_header_content($content) {
+ $this->header_content = $content;
+ }
+
+ /**
+ * Sets the content of the footer block
+ *
+ * @param string The content of the footer block
+ * @since 1.0.2
+ */
+ function set_footer_content($content) {
+ $this->footer_content = $content;
+ }
+
+ /**
+ * Sets the style for the header content
+ *
+ * @param string The style for the header content
+ * @since 1.0.2
+ */
+ function set_header_content_style($style) {
+ $this->header_content_style = $style;
+ }
+
+ /**
+ * Sets the style for the footer content
+ *
+ * @param string The style for the footer content
+ * @since 1.0.2
+ */
+ 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 Tells whether to enable or disable this feature
+ * @since 1.0.7.20
+ */
+ function enable_inner_code_block($flag) {
+ $this->force_code_block = (bool)$flag;
+ }
+
+ /**
+ * Sets the base URL to be used for keywords
+ *
+ * @param int The key of the keyword group to set the URL for
+ * @param string 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
+ */
+ function set_url_for_keyword_group($group, $url) {
+ $this->language_data['URLS'][$group] = $url;
+ }
+
+ /**
+ * Sets styles for links in code
+ *
+ * @param int A constant that specifies what state the style is being
+ * set for - e.g. :hover or :visited
+ * @param string The styles to use for that state
+ * @since 1.0.2
+ */
+ function set_link_styles($type, $styles) {
+ $this->link_styles[$type] = $styles;
+ }
+
+ /**
+ * Sets the target for links in code
+ *
+ * @param string The target for links in the code, e.g. _blank
+ * @since 1.0.3
+ */
+ 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 The styles to use on important parts of the code
+ * @since 1.0.2
+ */
+ function set_important_styles($styles) {
+ $this->important_styles = $styles;
+ }
+
+ /**
+ * Sets whether context-important blocks are highlighted
+ *
+ * @param boolean Tells whether to enable or disable highlighting of important blocks
+ * @todo REMOVE THIS SHIZ FROM GESHI!
+ * @deprecated
+ * @since 1.0.2
+ */
+ function enable_important_blocks($flag) {
+ $this->enable_important_blocks = ( $flag ) ? true : false;
+ }
+
+ /**
+ * Whether CSS IDs should be added to each line
+ *
+ * @param boolean If true, IDs will be added to each line.
+ * @since 1.0.2
+ */
+ 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 An array of line numbers to highlight, or just a line
+ * number on its own.
+ * @param string 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
+ */
+ 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]);
+ } else if ($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 The style for extra-highlighted lines
+ * @since 1.0.2
+ */
+ function set_highlight_lines_extra_style($styles) {
+ $this->highlight_extra_lines_style = $styles;
+ }
+
+ /**
+ * Sets the line-ending
+ *
+ * @param string The new line-ending
+ * @since 1.0.2
+ */
+ 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 The number to start line numbers at
+ * @since 1.0.2
+ */
+ 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 The encoding to use for the source
+ * @since 1.0.3
+ */
+ function set_encoding($encoding) {
+ if ($encoding) {
+ $this->encoding = strtolower($encoding);
+ }
+ }
+
+ /**
+ * Turns linking of keywords on or off.
+ *
+ * @param boolean If true, links will be added to keywords
+ * @since 1.0.2
+ */
+ 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
+ * @access private
+ */
+ 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
+ * @access private
+ */
+ function build_parse_cache() {
+ // 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, '/');
+ } else if ($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_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_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"; //
+ }
+ }
+
+ $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
+ */
+ 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);
+
+ // 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(!GESHI_PHP_PRE_433 && //Needs proper rewrite to work with PHP >=4.3.0; 4.3.3 is guaranteed to work.
+ 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;
+ } else if (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'];
+ } else if (
+ //This is to allow use of the offset parameter in preg_match and stay as compatible with older PHP versions as possible
+ (GESHI_PHP_PRE_433 && preg_match($regexp, substr($part, $i), $match, PREG_OFFSET_CAPTURE)) ||
+ (!GESHI_PHP_PRE_433 && preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, $i))
+ ) {
+ $match_i = $match[0][1];
+ if (GESHI_PHP_PRE_433) {
+ $match_i += $i;
+ }
+
+ $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'];
+ } else if (
+ //This is to allow use of the offset parameter in preg_match and stay as compatible with older PHP versions as possible
+ (GESHI_PHP_PRE_433 && preg_match($regexp, substr($part, $start), $match, PREG_OFFSET_CAPTURE)) ||
+ (!GESHI_PHP_PRE_433 && preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, $start))
+ ) {
+ $match_i = $match[0][1];
+ if (GESHI_PHP_PRE_433) {
+ $match_i += $start;
+ }
+
+ $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;
+ } else if (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>';
+ } else if (!GESHI_PHP_PRE_433 && '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;
+ }
+ } else if ($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;
+ } else if ($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];
+ } else if (($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];
+ } else if (
+ // 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 The source to indent (reference!)
+ * @since 1.0.0
+ * @access private
+ */
+ 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;
+ } else if ('<' == $char) {
+ $IN_TAG = true;
+ $lines[$key] .= '<';
+ } else if ('&' == $char) {
+ $substr = substr($line, $i + 3, 5);
+ $posi = strpos($substr, ';');
+ if (false === $posi) {
+ ++$pos;
+ } else {
+ $pos -= $posi+2;
+ }
+ $lines[$key] .= $char;
+ } else if ("\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;
+ }
+ } else if (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 The keyword to change the case of
+ * @return string The keyword with its case changed
+ * @since 1.0.0
+ * @access private
+ */
+ 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 The keyword to add the Markup to
+ * @return The HTML for the match found
+ * @since 1.0.8
+ * @access private
+ *
+ * @todo Get rid of ender in keyword links
+ */
+ function handle_keyword_replace($match) {
+ $k = $this->_kw_replace_group;
+ $keyword = $match[0];
+
+ $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) == 0) {
+ break;
+ }
+ }
+ } else {
+ $word = $keyword;
+ }
+
+ $before = '<|UR1|"' .
+ str_replace(
+ array(
+ '{FNAME}',
+ '{FNAMEL}',
+ '{FNAMEU}',
+ '.'),
+ array(
+ str_replace('+', '%20', urlencode($this->hsc($word))),
+ str_replace('+', '%20', urlencode($this->hsc(strtolower($word)))),
+ str_replace('+', '%20', urlencode($this->hsc(strtoupper($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 the matches array
+ * @return The highlighted string
+ * @since 1.0.8
+ * @access private
+ */
+ 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 the matches array
+ * @return string
+ * @since 1.0.8
+ * @access private
+ */
+ 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 The string to parse for keyword, numbers etc.
+ * @since 1.0.0
+ * @access private
+ * @todo BUGGY! Why? Why not build string and return?
+ */
+ 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))$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('#\d#', $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_end = $symbol_length + $symbol_offset;
+ $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 microtime The time when parsing started
+ * @param microtime The time when parsing ended
+ * @since 1.0.2
+ * @access private
+ */
+ 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
+ */
+ function get_time() {
+ return $this->time;
+ }
+
+ /**
+ * Merges arrays recursively, overwriting values of the first array with values of later arrays
+ *
+ * @since 1.0.8
+ * @access private
+ */
+ 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 The filename of the language file you want to load
+ * @since 1.0.0
+ * @access private
+ * @todo Needs to load keys for lexic permissions for keywords, regexps etc
+ */
+ 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 The code already parsed (reference!)
+ * @since 1.0.0
+ * @access private
+ */
+ 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" : '';
+
+ // Set vars to defaults for following loop
+ $i = 0;
+
+ // 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);
+ } else if ($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;
+ }
+ elseif ($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
+ * @access private
+ */
+ 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>";
+ } else if ($this->header_type == GESHI_HEADER_DIV ||
+ $this->header_type == GESHI_HEADER_PRE_VALID) {
+ return "<div$attributes>$header<ol$ol_attributes>";
+ } else if ($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
+ * @access private
+ */
+ 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 The header or footer content to do replacement on
+ * @return string The header or footer with replaced keywords
+ * @since 1.0.2
+ * @access private
+ */
+ 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}
+ *
+ * @access private
+ * @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
+ */
+ 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);
+ }
+
+ 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 Whether to use economy mode or not
+ * @return string A stylesheet built on the data for the current language
+ * @since 1.0.0
+ */
+ 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 - 2008 Benny Baumann\n" .
+ " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
+ " * --------------------------------------\n".
+ " */\n";
+ } else {
+ $stylesheet = "/**\n".
+ " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 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 The line number information is requested for
+ * @access private
+ * @since 1.0.7.21
+ */
+ function get_line_style($line) {
+ //$style = null;
+ $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 $list array of (unquoted) strings
+ * @param $regexp_delimiter your regular expression delimiter, @see preg_quote()
+ * @return string for regular expression
+ * @author Milian Wolff <mail@milianw.de>
+ * @since 1.0.8
+ * @access private
+ */
+ 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 &$tokens array of tokens
+ * @param $recursed bool to know wether we recursed or not
+ * @return string
+ * @author Milian Wolff <mail@milianw.de>
+ * @since 1.0.8
+ * @access private
+ */
+ 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 = create_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 The code to highlight
+ * @param string The language to highlight the code in
+ * @param string 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 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;
+ }
+}
+
+?> \ No newline at end of file
diff --git a/inc/geshi/4cs.php b/inc/geshi/4cs.php
new file mode 100644
index 000000000..48b671f4a
--- /dev/null
+++ b/inc/geshi/4cs.php
@@ -0,0 +1,139 @@
+<?php
+/*************************************************************************************
+ * 4cs.php
+ * ------
+ * Author: Jason Curl (jason.curl@continental-corporation.com)
+ * Copyright: (c) 2009 Jason Curl
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/abap.php b/inc/geshi/abap.php
new file mode 100644
index 000000000..942d2397e
--- /dev/null
+++ b/inc/geshi/abap.php
@@ -0,0 +1,1409 @@
+<?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.8.8
+ * 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; text-transform: uppercase; font-weight: bold; zzz:control;', //control statements
+ 2 => 'color: #cc4050; text-transform: uppercase; font-weight: bold; zzz:data;', //data statements
+ 3 => 'color: #005066; text-transform: uppercase; font-weight: bold; zzz:statement;', //first token of other statements
+ 4 => 'color: #500066; text-transform: uppercase; font-weight: bold; zzz:keyword;', // next tokens of other statements ("keywords")
+ 5 => 'color: #005066; text-transform: uppercase; font-weight: bold; zzz:statement;',
+ 6 => 'color: #000066; text-transform: uppercase; font-weight: bold; zzz:control;',
+ 7 => 'color: #000066; text-transform: uppercase; font-weight: bold; zzz:control;',
+ 8 => 'color: #005066; text-transform: uppercase; font-weight: bold; zzz:statement;',
+ 9 => 'color: #500066; text-transform: uppercase; 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/en/ABAP{FNAMEU}.htm',
+ 2 => 'http://help.sap.com/abapdocu/en/ABAP{FNAMEU}.htm',
+ 3 => 'http://help.sap.com/abapdocu/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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/actionscript-french.php b/inc/geshi/actionscript-french.php
new file mode 100644
index 000000000..e81605098
--- /dev/null
+++ b/inc/geshi/actionscript-french.php
@@ -0,0 +1,957 @@
+<?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.7.9
+ * CVS Revision Version: $Revision: 1.9 $
+ * Date Started: 2004/06/20
+ * Last Modified: $Date: 2006/04/23 01:14:41 $
+ *
+ * Actionscript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/25 (1.0.2)
+ * Author [ NikO ] - http://niko.informatif.org
+ * - add full link for myInstance.methods to http://wiki.media-box.net/documentation/flash
+ * 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',
+ 'if',
+ 'elseif',
+ 'else',
+ 'while',
+ 'do',
+ 'dowhile',
+ 'endwhile',
+ 'endif',
+ 'switch',
+ 'case',
+ 'endswitch',
+ 'break',
+ 'continue',
+ 'in',
+ 'null',
+ 'false',
+ 'true',
+ 'var',
+ 'default',
+ 'new',
+ '_global',
+ 'undefined',
+ 'super'
+ ),
+ 2 => array(
+ 'static',
+ 'private',
+ 'public',
+ 'class',
+ 'extends',
+ 'implements',
+ 'import',
+ 'return',
+ 'trace',
+ '_quality',
+ '_root',
+ 'set',
+ 'setInterval',
+ 'setProperty',
+ 'stopAllSounds',
+ 'targetPath',
+ 'this',
+ 'typeof',
+ 'unescape',
+ 'updateAfterEvent'
+ ),
+ 3 => array (
+ 'Accessibility',
+ 'Array',
+ 'Boolean',
+ 'Button',
+ 'Camera',
+ 'Color',
+ 'ContextMenuItem',
+ 'ContextMenu',
+ 'Cookie',
+ 'Date',
+ 'Error',
+ 'function',
+ 'FWEndCommand',
+ 'FWJavascript',
+ 'Key',
+ 'LoadMovieNum',
+ 'LoadMovie',
+ 'LoadVariablesNum',
+ 'LoadVariables',
+ 'LoadVars',
+ 'LocalConnection',
+ 'Math',
+ 'Microphone',
+ 'MMExecute',
+ 'MMEndCommand',
+ 'MMSave',
+ 'Mouse',
+ 'MovieClipLoader',
+ 'MovieClip',
+ 'NetConnexion',
+ 'NetStream',
+ 'Number',
+ 'Object',
+ 'printAsBitmapNum',
+ 'printNum',
+ 'printAsBitmap',
+ 'printJob',
+ 'print',
+ 'Selection',
+ 'SharedObject',
+ 'Sound',
+ 'Stage',
+ 'String',
+ 'System',
+ 'TextField',
+ 'TextFormat',
+ 'Tween',
+ 'Video',
+ 'XMLUI',
+ 'XMLNode',
+ 'XMLSocket',
+ 'XML'
+ ),
+ 4 => array (
+ 'isactive',
+ 'updateProperties'
+ ),
+ 5 => array (
+ 'callee',
+ 'caller',
+ ),
+ 6 => array (
+ 'concat',
+ 'join',
+ 'pop',
+ 'push',
+ 'reverse',
+ 'shift',
+ 'slice',
+ 'sort',
+ 'sortOn',
+ 'splice',
+ 'toString',
+ 'unshift'
+ ),
+ 7 => array (
+ 'valueOf'
+ ),
+ 8 => array (
+ 'onDragOut',
+ 'onDragOver',
+ 'onKeyUp',
+ 'onKillFocus',
+ 'onPress',
+ 'onRelease',
+ 'onReleaseOutside',
+ 'onRollOut',
+ 'onRollOver',
+ 'onSetFocus'
+ ),
+ 9 => array (
+ 'setMode',
+ 'setMotionLevel',
+ 'setQuality',
+ 'activityLevel',
+ 'bandwidth',
+ 'currentFps',
+ 'fps',
+ 'index',
+ 'motionLevel',
+ 'motionTimeOut',
+ 'muted',
+ 'names',
+ 'quality',
+ 'onActivity',
+ 'onStatus'
+ ),
+ 10 => array (
+ 'getRGB',
+ 'setRGB',
+ 'getTransform',
+ 'setTransform'
+ ),
+ 11 => array (
+ 'caption',
+ 'enabled',
+ 'separatorBefore',
+ 'visible',
+ 'onSelect'
+ ),
+ 12 => array (
+ 'setCookie',
+ 'getcookie'
+ ),
+ 13 => array (
+ 'hideBuiltInItems',
+ 'builtInItems',
+ 'customItems',
+ 'onSelect'
+ ),
+ 14 => array (
+ 'CustomActions.get',
+ 'CustomActions.install',
+ 'CustomActions.list',
+ 'CustomActions.uninstall',
+ ),
+ 15 => array (
+ 'getDate',
+ 'getDay',
+ 'getFullYear',
+ 'getHours',
+ 'getMilliseconds',
+ 'getMinutes',
+ 'getMonth',
+ 'getSeconds',
+ 'getTime',
+ 'getTimezoneOffset',
+ 'getUTCDate',
+ 'getUTCDay',
+ 'getUTCFullYear',
+ 'getUTCHours',
+ 'getUTCMinutes',
+ 'getUTCMilliseconds',
+ 'getUTCMonth',
+ 'getUTCSeconds',
+ 'getYear',
+ 'setDate',
+ 'setFullYear',
+ 'setHours',
+ 'setMilliseconds',
+ 'setMinutes',
+ 'setMonth',
+ 'setSeconds',
+ 'setTime',
+ 'setUTCDate',
+ 'setUTCDay',
+ 'setUTCFullYear',
+ 'setUTCHours',
+ 'setUTCMinutes',
+ 'setUTCMilliseconds',
+ 'setUTCMonth',
+ 'setUTCSeconds',
+ 'setYear',
+ 'UTC'
+ ),
+ 16 => array (
+ 'message',
+ 'name',
+ 'throw',
+ 'try',
+ 'catch',
+ 'finally'
+ ),
+ 17 => array (
+ 'apply',
+ 'call'
+ ),
+ 18 => array (
+ 'BACKSPACE',
+ 'CAPSLOCK',
+ 'CONTROL',
+ 'DELETEKEY',
+ 'DOWN',
+ 'END',
+ 'ENTER',
+ 'ESCAPE',
+ 'getAscii',
+ 'getCode',
+ 'HOME',
+ 'INSERT',
+ 'isDown',
+ 'isToggled',
+ 'LEFT',
+ 'onKeyDown',
+ 'onKeyUp',
+ 'PGDN',
+ 'PGUP',
+ 'RIGHT',
+ 'SPACE',
+ 'TAB',
+ 'UP'
+ ),
+ 19 => array (
+ 'addRequestHeader',
+ 'contentType',
+ 'decode'
+ ),
+ 20 => array (
+ 'allowDomain',
+ 'allowInsecureDomain',
+ 'close',
+ 'domain'
+ ),
+ 21 => array (
+ 'abs',
+ 'acos',
+ 'asin',
+ 'atan',
+ 'atan2',
+ 'ceil',
+ 'cos',
+ 'exp',
+ 'floor',
+ 'log',
+ 'LN2',
+ 'LN10',
+ 'LOG2E',
+ 'LOG10E',
+ 'max',
+ 'min',
+ 'PI',
+ 'pow',
+ 'random',
+ 'sin',
+ 'SQRT1_2',
+ 'sqrt',
+ 'tan',
+ 'round',
+ 'SQRT2'
+ ),
+ 22 => array (
+ 'activityLevel',
+ 'muted',
+ 'names',
+ 'onActivity',
+ 'onStatus',
+ 'setRate',
+ 'setGain',
+ 'gain',
+ 'rate',
+ 'setSilenceLevel',
+ 'setUseEchoSuppression',
+ 'silenceLevel',
+ 'silenceTimeOut',
+ 'useEchoSuppression'
+ ),
+ 23 => array (
+ 'hide',
+ 'onMouseDown',
+ 'onMouseMove',
+ 'onMouseUp',
+ 'onMouseWeel',
+ 'show'
+ ),
+ 24 => array (
+ '_alpha',
+ 'attachAudio',
+ 'attachMovie',
+ 'beginFill',
+ 'beginGradientFill',
+ 'clear',
+ 'createEmptyMovieClip',
+ 'createTextField',
+ '_current',
+ 'curveTo',
+ '_dropTarget',
+ 'duplicateMovieClip',
+ 'endFill',
+ 'focusEnabled',
+ 'enabled',
+ '_focusrec',
+ '_framesLoaded',
+ 'getBounds',
+ 'getBytesLoaded',
+ 'getBytesTotal',
+ 'getDepth',
+ 'getInstanceAtDepth',
+ 'getNextHighestDepth',
+ 'getSWFVersion',
+ 'getTextSnapshot',
+ 'getURL',
+ 'globalToLocal',
+ 'gotoAndPlay',
+ 'gotoAndStop',
+ '_height',
+ 'hitArea',
+ 'hitTest',
+ 'lineStyle',
+ 'lineTo',
+ 'localToGlobal',
+ '_lockroot',
+ 'menu',
+ 'onUnload',
+ '_parent',
+ 'play',
+ 'prevFrame',
+ '_quality',
+ 'removeMovieClip',
+ '_rotation',
+ 'setMask',
+ '_soundbuftime',
+ 'startDrag',
+ 'stopDrag',
+ 'stop',
+ 'swapDepths',
+ 'tabChildren',
+ '_target',
+ '_totalFrames',
+ 'trackAsMenu',
+ 'unloadMovie',
+ 'useHandCursor',
+ '_visible',
+ '_width',
+ '_xmouse',
+ '_xscale',
+ '_x',
+ '_ymouse',
+ '_yscale',
+ '_y'
+ ),
+ 25 => array (
+ 'getProgress',
+ 'loadClip',
+ 'onLoadComplete',
+ 'onLoadError',
+ 'onLoadInit',
+ 'onLoadProgress',
+ 'onLoadStart'
+ ),
+ 26 => array (
+ 'bufferLength',
+ 'currentFps',
+ 'seek',
+ 'setBufferTime',
+ 'bufferTime',
+ 'time',
+ 'pause'
+ ),
+ 27 => array (
+ 'MAX_VALUE',
+ 'MIN_VALUE',
+ 'NEGATIVE_INFINITY',
+ 'POSITIVE_INFINITY'
+ ),
+ 28 => array (
+ 'addProperty',
+ 'constructor',
+ '__proto__',
+ 'registerClass',
+ '__resolve',
+ 'unwatch',
+ 'watch',
+ 'onUpDate'
+ ),
+ 29 => array (
+ 'addPage'
+ ),
+ 30 => array (
+ 'getBeginIndex',
+ 'getCaretIndex',
+ 'getEndIndex',
+ 'setSelection'
+ ),
+ 31 => array (
+ 'flush',
+ 'getLocal',
+ 'getSize'
+ ),
+ 32 => array (
+ 'attachSound',
+ 'duration',
+ 'getPan',
+ 'getVolume',
+ 'onID3',
+ 'loadSound',
+ 'id3',
+ 'onSoundComplete',
+ 'position',
+ 'setPan',
+ 'setVolume'
+ ),
+ 33 => array (
+ 'getBeginIndex',
+ 'getCaretIndex',
+ 'getEndIndex',
+ 'setSelection'
+ ),
+ 34 => array (
+ 'getEndIndex',
+ ),
+ 35 => array (
+ 'align',
+ 'height',
+ 'width',
+ 'onResize',
+ 'scaleMode',
+ 'showMenu'
+ ),
+ 36 => array (
+ 'charAt',
+ 'charCodeAt',
+ 'concat',
+ 'fromCharCode',
+ 'indexOf',
+ 'lastIndexOf',
+ 'substr',
+ 'substring',
+ 'toLowerCase',
+ 'toUpperCase'
+ ),
+ 37 => array (
+ 'avHardwareDisable',
+ 'hasAccessibility',
+ 'hasAudioEncoder',
+ 'hasAudio',
+ 'hasEmbeddedVideo',
+ 'hasMP3',
+ 'hasPrinting',
+ 'hasScreenBroadcast',
+ 'hasScreenPlayback',
+ 'hasStreamingAudio',
+ 'hasStreamingVideo',
+ 'hasVideoEncoder',
+ 'isDebugger',
+ 'language',
+ 'localFileReadDisable',
+ 'manufacturer',
+ 'os',
+ 'pixelAspectRatio',
+ 'playerType',
+ 'screenColor',
+ 'screenDPI',
+ 'screenResolutionX',
+ 'screenResolutionY',
+ 'serverString',
+ 'version'
+ ),
+ 38 => array (
+ 'allowDomain',
+ 'allowInsecureDomain',
+ 'loadPolicyFile'
+ ),
+ 39 => array (
+ 'exactSettings',
+ 'setClipboard',
+ 'showSettings',
+ 'useCodepage'
+ ),
+ 40 => array (
+ 'getStyle',
+ 'getStyleNames',
+ 'parseCSS',
+ 'setStyle',
+ 'transform'
+ ),
+ 41 => array (
+ 'autoSize',
+ 'background',
+ 'backgroundColor',
+ 'border',
+ 'borderColor',
+ 'bottomScroll',
+ 'condenseWhite',
+ 'embedFonts',
+ 'getFontList',
+ 'getNewTextFormat',
+ 'getTextFormat',
+ 'hscroll',
+ 'htmlText',
+ 'html',
+ 'maxChars',
+ 'maxhscroll',
+ 'maxscroll',
+ 'mouseWheelEnabled',
+ 'multiline',
+ 'onScroller',
+ 'password',
+ 'removeTextField',
+ 'replaceSel',
+ 'replaceText',
+ 'restrict',
+ 'scroll',
+ 'selectable',
+ 'setNewTextFormat',
+ 'setTextFormat',
+ 'styleSheet',
+ 'tabEnabled',
+ 'tabIndex',
+ 'textColor',
+ 'textHeight',
+ 'textWidth',
+ 'text',
+ 'type',
+ '_url',
+ 'variable',
+ 'wordWrap'
+ ),
+ 42 => array (
+ 'blockIndent',
+ 'bold',
+ 'bullet',
+ 'font',
+ 'getTextExtent',
+ 'indent',
+ 'italic',
+ 'leading',
+ 'leftMargin',
+ 'rightMargin',
+ 'size',
+ 'tabStops',
+ 'underline'
+ ),
+ 43 => array (
+ 'findText',
+ 'getCount',
+ 'getSelected',
+ 'getSelectedText',
+ 'getText',
+ 'hitTestTextNearPos',
+ 'setSelectColor',
+ 'setSelected'
+ ),
+ 44 => array (
+ 'begin',
+ 'change',
+ 'continueTo',
+ 'fforward',
+ 'finish',
+ 'func',
+ 'FPS',
+ 'getPosition',
+ 'isPlaying',
+ 'looping',
+ 'obj',
+ 'onMotionChanged',
+ 'onMotionFinished',
+ 'onMotionLooped',
+ 'onMotionStarted',
+ 'onMotionResumed',
+ 'onMotionStopped',
+ 'prop',
+ 'rewind',
+ 'resume',
+ 'setPosition',
+ 'time',
+ 'userSeconds',
+ 'yoyo'
+ ),
+ 45 => array (
+ 'attachVideo',
+ 'deblocking',
+ 'smoothing'
+ ),
+ 46 => array (
+ 'addRequestHeader',
+ 'appendChild',
+ 'attributes',
+ 'childNodes',
+ 'cloneNode',
+ 'contentType',
+ 'createElement',
+ 'createTextNode',
+ 'docTypeDecl',
+ 'firstChild',
+ 'hasChildNodes',
+ 'ignoreWhite',
+ 'insertBefore',
+ 'lastChild',
+ 'nextSibling',
+ 'nodeName',
+ 'nodeType',
+ 'nodeValue',
+ 'parentNode',
+ 'parseXML',
+ 'previousSibling',
+ 'removeNode',
+ 'xmlDecl'
+ ),
+ 47 => array (
+ 'onClose',
+ 'onXML'
+ ),
+ 48 => array (
+ 'add',
+ 'and',
+ '_highquality',
+ 'chr',
+ 'eq',
+ 'ge',
+ 'ifFrameLoaded',
+ 'int',
+ 'le',
+ 'it',
+ 'mbchr',
+ 'mblength',
+ 'mbord',
+ 'ne',
+ 'not',
+ 'or',
+ 'ord',
+ 'tellTarget',
+ 'toggleHighQuality'
+ ),
+ 49 => array (
+ 'ASSetPropFlags',
+ 'ASnative',
+ 'ASconstructor',
+ 'AsSetupError',
+ 'FWEndCommand',
+ 'FWJavascript',
+ 'MMEndCommand',
+ 'MMSave',
+ 'XMLUI'
+ ),
+ 50 => array (
+ 'System.capabilities'
+ ),
+ 51 => array (
+ 'System.security'
+ ),
+ 52 => array (
+ 'TextField.StyleSheet'
+ )
+ ),
+ '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,
+ 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
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #006600;',
+ 3 => 'color: #000080;',
+ 4 => 'color: #006600;',
+ 5 => 'color: #006600;',
+ 6 => 'color: #006600;',
+ 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;',
+ 17 => 'color: #006600;',
+ 18 => 'color: #006600;',
+ 19 => 'color: #006600;',
+ 20 => 'color: #006600;',
+ 21 => 'color: #006600;',
+ 22 => 'color: #006600;',
+ 23 => 'color: #006600;',
+ 24 => 'color: #006600;',
+ 25 => 'color: #006600;',
+ 26 => 'color: #006600;',
+ 27 => 'color: #006600;',
+ 28 => 'color: #006600;',
+ 29 => 'color: #006600;',
+ 30 => 'color: #006600;',
+ 31 => 'color: #006600;',
+ 32 => 'color: #006600;',
+ 33 => 'color: #006600;',
+ 34 => 'color: #006600;',
+ 35 => 'color: #006600;',
+ 36 => 'color: #006600;',
+ 37 => 'color: #006600;',
+ 38 => 'color: #006600;',
+ 39 => 'color: #006600;',
+ 40 => 'color: #006600;',
+ 41 => 'color: #006600;',
+ 42 => 'color: #006600;',
+ 43 => 'color: #006600;',
+ 44 => 'color: #006600;',
+ 45 => 'color: #006600;',
+ 46 => 'color: #006600;',
+ 47 => 'color: #006600;',
+ 48 => 'color: #CC0000;',
+ 49 => 'color: #5700d1;',
+ 50 => 'color: #006600;',
+ 51 => 'color: #006600;',
+ 52 => 'color: #CC0000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #ff8000; font-style: italic;',
+ 2 => 'color: #ff8000; font-style: italic;',
+ 'MULTI' => 'color: #ff8000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #333333;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #333333; background-color: #eeeeee;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #c50000;'
+ ),
+
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://wiki.media-box.net/documentation/flash/{FNAME}',
+ 2 => 'http://wiki.media-box.net/documentation/flash/{FNAME}',
+ 3 => 'http://wiki.media-box.net/documentation/flash/{FNAME}',
+ 4 => 'http://wiki.media-box.net/documentation/flash/accessibility/{FNAME}',
+ 5 => 'http://wiki.media-box.net/documentation/flash/arguments/{FNAME}',
+ 6 => 'http://wiki.media-box.net/documentation/flash/array/{FNAME}',
+ 7 => 'http://wiki.media-box.net/documentation/flash/boolean/{FNAME}',
+ 8 => 'http://wiki.media-box.net/documentation/flash/button/{FNAME}',
+ 9 => 'http://wiki.media-box.net/documentation/flash/camera/{FNAME}',
+ 10 => 'http://wiki.media-box.net/documentation/flash/color/{FNAME}',
+ 11 => 'http://wiki.media-box.net/documentation/flash/contextmenuitem/{FNAME}',
+ 12 => 'http://wiki.media-box.net/documentation/flash/contextmenu/{FNAME}',
+ 13 => 'http://wiki.media-box.net/documentation/flash/cookie/{FNAME}',
+ 14 => 'http://wiki.media-box.net/documentation/flash/customactions/{FNAME}',
+ 15 => 'http://wiki.media-box.net/documentation/flash/date/{FNAME}',
+ 16 => 'http://wiki.media-box.net/documentation/flash/error/{FNAME}',
+ 17 => 'http://wiki.media-box.net/documentation/flash/function/{FNAME}',
+ 18 => 'http://wiki.media-box.net/documentation/flash/key/{FNAME}',
+ 19 => 'http://wiki.media-box.net/documentation/flash/loadvars/{FNAME}',
+ 20 => 'http://wiki.media-box.net/documentation/flash/localconnection/{FNAME}',
+ 21 => 'http://wiki.media-box.net/documentation/flash/math/{FNAME}',
+ 22 => 'http://wiki.media-box.net/documentation/flash/microphone/{FNAME}',
+ 23 => 'http://wiki.media-box.net/documentation/flash/mouse/{FNAME}',
+ 24 => 'http://wiki.media-box.net/documentation/flash/movieclip/{FNAME}',
+ 25 => 'http://wiki.media-box.net/documentation/flash/moviecliploader/{FNAME}',
+ 26 => 'http://wiki.media-box.net/documentation/flash/netstream/{FNAME}',
+ 27 => 'http://wiki.media-box.net/documentation/flash/number/{FNAME}',
+ 28 => 'http://wiki.media-box.net/documentation/flash/object/{FNAME}',
+ 29 => 'http://wiki.media-box.net/documentation/flash/printJob/{FNAME}',
+ 30 => 'http://wiki.media-box.net/documentation/flash/selection/{FNAME}',
+ 31 => 'http://wiki.media-box.net/documentation/flash/sharedobject/{FNAME}',
+ 32 => 'http://wiki.media-box.net/documentation/flash/sound/{FNAME}',
+ 33 => 'http://wiki.media-box.net/documentation/flash/selection/{FNAME}',
+ 34 => 'http://wiki.media-box.net/documentation/flash/sharedobject/{FNAME}',
+ 35 => 'http://wiki.media-box.net/documentation/flash/stage/{FNAME}',
+ 36 => 'http://wiki.media-box.net/documentation/flash/string/{FNAME}',
+ 37 => 'http://wiki.media-box.net/documentation/flash/system/capabilities/{FNAME}',
+ 38 => 'http://wiki.media-box.net/documentation/flash/system/security/{FNAME}',
+ 39 => 'http://wiki.media-box.net/documentation/flash/system/{FNAME}',
+ 40 => 'http://wiki.media-box.net/documentation/flash/textfield/stylesheet/{FNAME}',
+ 41 => 'http://wiki.media-box.net/documentation/flash/textfield/{FNAME}',
+ 42 => 'http://wiki.media-box.net/documentation/flash/textformat/{FNAME}',
+ 43 => 'http://wiki.media-box.net/documentation/flash/textsnapshot/{FNAME}',
+ 44 => 'http://wiki.media-box.net/documentation/flash/tween/{FNAME}',
+ 45 => 'http://wiki.media-box.net/documentation/flash/video/{FNAME}',
+ 46 => 'http://wiki.media-box.net/documentation/flash/xml/{FNAME}',
+ 47 => 'http://wiki.media-box.net/documentation/flash/xmlsocket/{FNAME}',
+ 48 => 'http://wiki.media-box.net/documentation/flash/{FNAME}',
+ 49 => 'http://wiki.media-box.net/documentation/flash/{FNAME}',
+ 50 => 'http://wiki.media-box.net/documentation/flash/system/capabilities',
+ 51 => 'http://wiki.media-box.net/documentation/flash/system/security',
+ 52 => 'http://wiki.media-box.net/documentation/flash/textfield/stylesheet'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
+
+?>
diff --git a/inc/geshi/actionscript.php b/inc/geshi/actionscript.php
new file mode 100644
index 000000000..41d66edd2
--- /dev/null
+++ b/inc/geshi/actionscript.php
@@ -0,0 +1,197 @@
+<?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.8.8
+ * 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()
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/actionscript3.php b/inc/geshi/actionscript3.php
new file mode 100644
index 000000000..4aab929dc
--- /dev/null
+++ b/inc/geshi/actionscript3.php
@@ -0,0 +1,473 @@
+<?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.8.8
+ * 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)\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\/\\\\])*\\/[msixpogcde]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])(m|q[qrwx]?)?\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[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'
+ ),
+ 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()
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/ada.php b/inc/geshi/ada.php
new file mode 100644
index 000000000..c6b0597bb
--- /dev/null
+++ b/inc/geshi/ada.php
@@ -0,0 +1,135 @@
+<?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.8.8
+ * 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;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ '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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/apache.php b/inc/geshi/apache.php
new file mode 100644
index 000000000..34704eb22
--- /dev/null
+++ b/inc/geshi/apache.php
@@ -0,0 +1,480 @@
+<?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.8.8
+ * 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_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;)',
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/applescript.php b/inc/geshi/applescript.php
new file mode 100644
index 000000000..9e214f2e1
--- /dev/null
+++ b/inc/geshi/applescript.php
@@ -0,0 +1,157 @@
+<?php
+/*************************************************************************************
+ * applescript.php
+ * --------
+ * Author: Stephan Klimek (http://www.initware.org)
+ * Copyright: Stephan Klimek (http://www.initware.org)
+ * Release Version: 1.0.8.8
+ * 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
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/apt_sources.php b/inc/geshi/apt_sources.php
new file mode 100644
index 000000000..f4cf9ae3f
--- /dev/null
+++ b/inc/geshi/apt_sources.php
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * apt_sources.php
+ * ----------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff (http://milianw.de)
+ * Release Version: 1.0.8.8
+ * 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', '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'
+ ),
+ 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/inc/geshi/asm.php b/inc/geshi/asm.php
new file mode 100644
index 000000000..d54e24023
--- /dev/null
+++ b/inc/geshi/asm.php
@@ -0,0 +1,225 @@
+<?php
+/*************************************************************************************
+ * asm.php
+ * -------
+ * Author: Tux (tux@inmail.cz)
+ * Copyright: (c) 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * Date Started: 2004/07/27
+ *
+ * x86 Assembler language file for GeSHi.
+ * Words are from SciTe configuration file (based on NASM syntax)
+ *
+ * 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
+ * - 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(
+ /*CPU*/
+ 1 => array(
+ 'aaa','aad','aam','aas','adc','add','and','call','cbw','clc','cld','cli','cmc','cmp',
+ 'cmps','cmpsb','cmpsw','cwd','daa','das','dec','div','esc','hlt','idiv','imul','in','inc',
+ 'int','into','iret','ja','jae','jb','jbe','jc','jcxz','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','lahf','lds','lea','les','lods','lodsb','lodsw','loop',
+ 'loope','loopew','loopne','loopnew','loopnz','loopnzw','loopw','loopz','loopzw','mov',
+ 'movs','movsb','movsw','mul','neg','nop','not','or','out','pop','popf','push','pushf',
+ 'rcl','rcr','ret','retf','retn','rol','ror','sahf','sal','sar','sbb','scas','scasb','scasw',
+ 'shl','shr','stc','std','sti','stos','stosb','stosw','sub','test','wait','xchg','xlat',
+ 'xlatb','xor','bound','enter','ins','insb','insw','leave','outs','outsb','outsw','popa','pusha','pushw',
+ 'arpl','lar','lsl','sgdt','sidt','sldt','smsw','str','verr','verw','clts','lgdt','lidt','lldt','lmsw','ltr',
+ 'bsf','bsr','bt','btc','btr','bts','cdq','cmpsd','cwde','insd','iretd','iretdf','iretf',
+ 'jecxz','lfs','lgs','lodsd','loopd','looped','loopned','loopnzd','loopzd','lss','movsd',
+ 'movsx','movzx','outsd','popad','popfd','pushad','pushd','pushfd','scasd','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','shld','shrd','stosd','bswap','cmpxchg','invd','invlpg','wbinvd','xadd','lock',
+ 'rep','repe','repne','repnz','repz'
+ ),
+ /*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'
+ ),
+ /*registers*/
+ 3 => array(
+ 'ah','al','ax','bh','bl','bp','bx','ch','cl','cr0','cr2','cr3','cs','cx','dh','di','dl',
+ 'dr0','dr1','dr2','dr3','dr6','dr7','ds','dx','eax','ebp','ebx','ecx','edi','edx',
+ 'es','esi','esp','fs','gs','si','sp','ss','st','tr3','tr4','tr5','tr6','tr7'
+ ),
+ /*Directive*/
+ 4 => array(
+ '186','286','286c','286p','287','386','386c','386p','387','486','486p',
+ '8086','8087','alpha','break','code','const','continue','cref','data','data?',
+ 'dosseg','else','elseif','endif','endw','err','err1','err2','errb',
+ 'errdef','errdif','errdifi','erre','erridn','erridni','errnb','errndef',
+ 'errnz','exit','fardata','fardata?','if','lall','lfcond','list','listall',
+ 'listif','listmacro','listmacroall',' model','no87','nocref','nolist',
+ 'nolistif','nolistmacro','radix','repeat','sall','seq','sfcond','stack',
+ 'startup','tfcond','type','until','untilcxz','while','xall','xcref',
+ 'xlist','alias','align','assume','catstr','comm','comment','db','dd','df','dq',
+ 'dt','dup','dw','echo','elseif1','elseif2','elseifb','elseifdef','elseifdif',
+ 'elseifdifi','elseife','elseifidn','elseifidni','elseifnb','elseifndef','end',
+ 'endm','endp','ends','eq',' equ','even','exitm','extern','externdef','extrn','for',
+ 'forc','ge','goto','group','high','highword','if1','if2','ifb','ifdef','ifdif',
+ 'ifdifi','ife',' ifidn','ifidni','ifnb','ifndef','include','includelib','instr','invoke',
+ 'irp','irpc','label','le','length','lengthof','local','low','lowword','lroffset',
+ 'macro','mask','mod','msfloat','name','ne','offset','opattr','option','org','%out',
+ 'page','popcontext','private','proc','proto','ptr','public','purge','pushcontext','record',
+ 'rept','seg','segment','short','size','sizeof','sizestr','struc','struct',
+ 'substr','subtitle','subttl','textequ','this','title','typedef','union','width',
+ '.model', '.stack', '.code', '.data'
+ ),
+ /*Operands*/
+ 5 => array(
+ '@b','@f','addr','basic','byte','c','carry?','dword',
+ 'far','far16','fortran','fword','near','near16','overflow?','parity?','pascal','qword',
+ 'real4',' real8','real10','sbyte','sdword','sign?','stdcall','sword','syscall','tbyte',
+ 'vararg','word','zero?','flat','near32','far32',
+ 'abs','all','assumes','at','casemap','common','compact',
+ 'cpu','dotname','emulator','epilogue','error','export','expr16','expr32','farstack',
+ 'forceframe','huge','language','large','listing','ljmp','loadds','m510','medium','memory',
+ 'nearstack','nodotname','noemulator','nokeyword','noljmp','nom510','none','nonunique',
+ 'nooldmacros','nooldstructs','noreadonly','noscoped','nosignextend','nothing',
+ 'notpublic','oldmacros','oldstructs','os_dos','para','prologue',
+ 'readonly','req','scoped','setif2','smallstack','tiny','use16','use32','uses'
+ )
+ ),
+ '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; 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: #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;'
+ ),
+ '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/inc/geshi/asp.php b/inc/geshi/asp.php
new file mode 100644
index 000000000..4a9d6c8e2
--- /dev/null
+++ b/inc/geshi/asp.php
@@ -0,0 +1,164 @@
+<?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.8.8
+ * 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
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/autoconf.php b/inc/geshi/autoconf.php
new file mode 100644
index 000000000..0883f9f54
--- /dev/null
+++ b/inc/geshi/autoconf.php
@@ -0,0 +1,512 @@
+<?php
+/*************************************************************************************
+ * autoconf.php
+ * -----
+ * Author: Mihai Vasilian (grayasm@gmail.com)
+ * Copyright: (c) 2010 Mihai Vasilian
+ * Release Version: 1.0.8.8
+ * 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_%\\/])"
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/autohotkey.php b/inc/geshi/autohotkey.php
new file mode 100644
index 000000000..6a3528334
--- /dev/null
+++ b/inc/geshi/autohotkey.php
@@ -0,0 +1,373 @@
+<?php
+/*************************************************************************************
+ * autohotkey.php
+ * --------
+ * Author: Naveen Garg (naveen.garg@gmail.com)
+ * Copyright: (c) 2009 Naveen Garg and GeSHi
+ * Release Version: 1.0.8.8
+ * 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)\#'
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/autoit.php b/inc/geshi/autoit.php
new file mode 100644
index 000000000..c8ef4404b
--- /dev/null
+++ b/inc/geshi/autoit.php
@@ -0,0 +1,1175 @@
+<?php
+/*************************************************************************************
+ * autoit.php
+ * --------
+ * Author: big_daddy (robert.i.anthony@gmail.com)
+ * Copyright: (c) 2006 and to GESHi ;)
+ * Release Version: 1.0.8.8
+ * Date Started: 2006/01/26
+ *
+ * AutoIT language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * Release 1.0.8.1 (2008/09/15)
+ * - Updated on 22.03.2008 By Tlem (tlem@tuxolem.fr)
+ * - The link on functions will now correctly re-direct to
+ * - http://www.autoitscript.com/autoit3/docs/functions/{FNAME}.htm
+ * - Updated whith au3.api (09.02.2008).
+ * - Updated - 16 Mai 2008 - v3.2.12.0
+ * - Updated - 12 June 2008 - v3.2.12.1
+ * Release 1.0.7.20 (2006/01/26)
+ * - First Release
+ *
+ * Current bugs & todo:
+ * ----------
+ * - not sure how to get sendkeys to work " {!}, {SPACE} etc... "
+ * - just copyied the regexp for variable from php so this HAVE to be checked and fixed to a better one ;)
+ *
+ * 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(';'),
+ 'COMMENT_MULTI' => array(
+ '#comments-start' => '#comments-end',
+ '#cs' => '#ce'),
+ 'COMMENT_REGEXP' => array(
+ 0 => '/(?<!#)#(\s.*)?$/m',
+ 1 => '/(?<=include)\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','Or','ReDim','Return',
+ 'Select','Step','Switch','Then','To','True','Until','WEnd','While',
+ 'With'
+ ),
+ 2 => array(
+ '@AppDataCommonDir','@AppDataDir','@AutoItExe','@AutoItPID',
+ '@AutoItUnicode','@AutoItVersion','@AutoItX64','@COM_EventObj',
+ '@CommonFilesDir','@Compiled','@ComputerName','@ComSpec','@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','@InetGetActive','@InetGetBytesRead',
+ '@IPAddress1','@IPAddress2','@IPAddress3','@IPAddress4','@KBLayout',
+ '@LF','@LogonDNSDomain','@LogonDomain','@LogonServer','@MDAY',
+ '@MIN','@MON','@MyDocumentsDir','@NumParams','@OSBuild','@OSLang',
+ '@OSServicePack','@OSTYPE','@OSVersion','@ProcessorArch',
+ '@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','AdlibDisable','AdlibEnable','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','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','FileGetAttrib','FileGetLongName',
+ 'FileGetShortcut','FileGetShortName','FileGetSize','FileGetTime',
+ 'FileGetVersion','FileInstall','FileMove','FileOpen',
+ 'FileOpenDialog','FileRead','FileReadLine','FileRecycle',
+ 'FileRecycleEmpty','FileSaveDialog','FileSelectFolder',
+ 'FileSetAttrib','FileSetTime','FileWrite','FileWriteLine','Floor',
+ 'FtpSetProxy','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','GUICtrlSetFont','GUICtrlSetDefColor',
+ 'GUICtrlSetDefBkColor','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','HWnd','InetGet','InetGetSize','IniDelete','IniRead',
+ 'IniReadSection','IniReadSectionNames','IniRenameSection',
+ 'IniWrite','IniWriteSection','InputBox','Int','IsAdmin','IsArray',
+ 'IsBinary','IsBool','IsDeclared','IsDllStruct','IsFloat','IsHWnd',
+ 'IsInt','IsKeyword','IsNumber','IsObj','IsPtr','IsString','Log',
+ 'MemGetStats','Mod','MouseClick','MouseClickDrag','MouseDown',
+ 'MouseGetCursor','MouseGetPos','MouseMove','MouseUp','MouseWheel',
+ 'MsgBox','Number','ObjCreate','ObjEvent','ObjGet','ObjName','Opt',
+ 'Ping','PixelChecksum','PixelGetColor','PixelSearch','PluginClose',
+ 'PluginOpen','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','StringInStr',
+ 'StringIsAlNum','StringIsAlpha','StringIsASCII','StringIsDigit',
+ 'StringIsFloat','StringIsInt','StringIsLower','StringIsSpace',
+ 'StringIsUpper','StringIsXDigit','StringLeft','StringLen',
+ 'StringLower','StringMid','StringRegExp','StringRegExpReplace',
+ 'StringReplace','StringRight','StringSplit','StringStripCR',
+ 'StringStripWS','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(
+ 'ArrayAdd','ArrayBinarySearch','ArrayConcatenate','ArrayDelete',
+ 'ArrayDisplay','ArrayFindAll','ArrayInsert','ArrayMax',
+ 'ArrayMaxIndex','ArrayMin','ArrayMinIndex','ArrayPop','ArrayPush',
+ 'ArrayReverse','ArraySearch','ArraySort','ArraySwap','ArrayToClip',
+ 'ArrayToString','ArrayTrim','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',
+ 'ColorGetGreen','ColorGetRed','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','DateAdd',
+ 'DateDayOfWeek','DateDaysInMonth','DateDiff','DateIsLeapYear',
+ 'DateIsValid','DateTimeFormat','DateTimeSplit','DateToDayOfWeek',
+ 'DateToDayOfWeekISO','DateToDayValue','DateToMonth',
+ 'DayValueToDate','DebugBugReportEnv','DebugOut','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','FileCountLines','FileCreate','FileListToArray',
+ 'FilePrint','FileReadToArray','FileWriteFromArray',
+ 'FileWriteLog','FileWriteToLine','GDIPlus_ArrowCapCreate',
+ 'GDIPlus_ArrowCapDispose','GDIPlus_ArrowCapGetFillState',
+ 'GDIPlus_ArrowCapGetHeight','GDIPlus_ArrowCapGetMiddleInset',
+ 'GDIPlus_ArrowCapGetWidth','GDIPlus_ArrowCapSetFillState',
+ 'GDIPlus_ArrowCapSetHeight','GDIPlus_ArrowCapSetMiddleInset',
+ 'GDIPlus_ArrowCapSetWidth','GDIPlus_BitmapCloneArea',
+ 'GDIPlus_BitmapCreateFromFile','GDIPlus_BitmapCreateFromGraphics',
+ 'GDIPlus_BitmapCreateFromHBITMAP',
+ 'GDIPlus_BitmapCreateHBITMAPFromBitmap','GDIPlus_BitmapDispose',
+ 'GDIPlus_BitmapLockBits','GDIPlus_BitmapUnlockBits',
+ 'GDIPlus_BrushClone','GDIPlus_BrushCreateSolid',
+ 'GDIPlus_BrushDispose','GDIPlus_BrushGetType',
+ 'GDIPlus_CustomLineCapDispose','GDIPlus_Decoders',
+ 'GDIPlus_DecodersGetCount','GDIPlus_DecodersGetSize',
+ 'GDIPlus_Encoders','GDIPlus_EncodersGetCLSID',
+ 'GDIPlus_EncodersGetCount','GDIPlus_EncodersGetParamList',
+ 'GDIPlus_EncodersGetParamListSize','GDIPlus_EncodersGetSize',
+ 'GDIPlus_FontCreate','GDIPlus_FontDispose',
+ 'GDIPlus_FontFamilyCreate','GDIPlus_FontFamilyDispose',
+ 'GDIPlus_GraphicsClear','GDIPlus_GraphicsCreateFromHDC',
+ 'GDIPlus_GraphicsCreateFromHWND','GDIPlus_GraphicsDispose',
+ 'GDIPlus_GraphicsDrawArc','GDIPlus_GraphicsDrawBezier',
+ 'GDIPlus_GraphicsDrawClosedCurve','GDIPlus_GraphicsDrawCurve',
+ 'GDIPlus_GraphicsDrawEllipse','GDIPlus_GraphicsDrawImage',
+ 'GDIPlus_GraphicsDrawImageRect','GDIPlus_GraphicsDrawImageRectRect',
+ 'GDIPlus_GraphicsDrawLine','GDIPlus_GraphicsDrawPie',
+ 'GDIPlus_GraphicsDrawPolygon','GDIPlus_GraphicsDrawRect',
+ 'GDIPlus_GraphicsDrawString','GDIPlus_GraphicsDrawStringEx',
+ 'GDIPlus_GraphicsFillClosedCurve','GDIPlus_GraphicsFillEllipse',
+ 'GDIPlus_GraphicsFillPie','GDIPlus_GraphicsFillRect',
+ 'GDIPlus_GraphicsGetDC','GDIPlus_GraphicsGetSmoothingMode',
+ 'GDIPlus_GraphicsMeasureString','GDIPlus_GraphicsReleaseDC',
+ 'GDIPlus_GraphicsSetSmoothingMode','GDIPlus_GraphicsSetTransform',
+ 'GDIPlus_ImageDispose','GDIPlus_ImageGetGraphicsContext',
+ 'GDIPlus_ImageGetHeight','GDIPlus_ImageGetWidth',
+ 'GDIPlus_ImageLoadFromFile','GDIPlus_ImageSaveToFile',
+ 'GDIPlus_ImageSaveToFileEx','GDIPlus_MatrixCreate',
+ 'GDIPlus_MatrixDispose','GDIPlus_MatrixRotate','GDIPlus_ParamAdd',
+ 'GDIPlus_ParamInit','GDIPlus_PenCreate','GDIPlus_PenDispose',
+ 'GDIPlus_PenGetAlignment','GDIPlus_PenGetColor',
+ 'GDIPlus_PenGetCustomEndCap','GDIPlus_PenGetDashCap',
+ 'GDIPlus_PenGetDashStyle','GDIPlus_PenGetEndCap',
+ 'GDIPlus_PenGetWidth','GDIPlus_PenSetAlignment',
+ 'GDIPlus_PenSetColor','GDIPlus_PenSetCustomEndCap',
+ 'GDIPlus_PenSetDashCap','GDIPlus_PenSetDashStyle',
+ 'GDIPlus_PenSetEndCap','GDIPlus_PenSetWidth','GDIPlus_RectFCreate',
+ 'GDIPlus_Shutdown','GDIPlus_Startup','GDIPlus_StringFormatCreate',
+ 'GDIPlus_StringFormatDispose','GetIP','GUICtrlAVI_Close',
+ 'GUICtrlAVI_Create','GUICtrlAVI_Destroy','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_GetState','GUICtrlButton_GetText',
+ 'GUICtrlButton_GetTextMargin','GUICtrlButton_SetCheck',
+ 'GUICtrlButton_SetFocus','GUICtrlButton_SetImage',
+ 'GUICtrlButton_SetImageList','GUICtrlButton_SetSize',
+ 'GUICtrlButton_SetState','GUICtrlButton_SetStyle',
+ 'GUICtrlButton_SetText','GUICtrlButton_SetTextMargin',
+ 'GUICtrlButton_Show','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_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_SetCurSel',
+ 'GUICtrlComboBox_SetDroppedWidth','GUICtrlComboBox_SetEditSel',
+ 'GUICtrlComboBox_SetEditText','GUICtrlComboBox_SetExtendedUI',
+ 'GUICtrlComboBox_SetHorizontalExtent',
+ 'GUICtrlComboBox_SetItemHeight','GUICtrlComboBox_SetMinVisible',
+ 'GUICtrlComboBox_SetTopIndex','GUICtrlComboBox_ShowDropDown',
+ '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_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_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_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_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_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_GetGroupInfo',
+ '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_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_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_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_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_SetBKColor',
+ 'GUICtrlRebar_SetColorScheme','GUICtrlRebar_SetTextColor',
+ 'GUICtrlRebar_SetToolTips','GUICtrlRebar_SetUnicodeFormat',
+ 'GUICtrlRebar_ShowBand','GUICtrlSlider_ClearSel',
+ 'GUICtrlSlider_ClearTics','GUICtrlSlider_Create',
+ 'GUICtrlSlider_Destroy','GUICtrlSlider_GetBuddy',
+ 'GUICtrlSlider_GetChannelRect','GUICtrlSlider_GetLineSize',
+ 'GUICtrlSlider_GetNumTics','GUICtrlSlider_GetPageSize',
+ 'GUICtrlSlider_GetPos','GUICtrlSlider_GetPTics',
+ '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_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_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_TTFToBits','GUIToolTip_Update',
+ 'GUIToolTip_UpdateTipText','HexToString','IE_Example',
+ 'IE_Introduction','IE_VersionInfo','IEAction','IEAttach',
+ 'IEBodyReadHTML','IEBodyReadText','IEBodyWriteHTML','IECreate',
+ 'IECreateEmbedded','IEDocGetObj','IEDocInsertHTML',
+ 'IEDocInsertText','IEDocReadHTML','IEDocWriteHTML',
+ 'IEErrorHandlerDeRegister','IEErrorHandlerRegister','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','Iif',
+ 'INetExplorerCapable','INetGetSource','INetMail','INetSmtpMail',
+ 'IsPressed','MathCheckDiv','Max','MemGlobalAlloc','MemGlobalFree',
+ 'MemGlobalLock','MemGlobalSize','MemGlobalUnlock','MemMoveMemory',
+ 'MemMsgBox','MemShowError','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','PathMake','PathSplit',
+ 'ProcessGetName','ProcessGetPriority','Radian',
+ 'ReplaceStringInFile','RunDOS','ScreenCapture_Capture',
+ 'ScreenCapture_CaptureWnd','ScreenCapture_SaveImage',
+ 'ScreenCapture_SetBMPFormat','ScreenCapture_SetJPGQuality',
+ 'ScreenCapture_SetTIFColorDepth','ScreenCapture_SetTIFCompression',
+ 'Security__AdjustTokenPrivileges','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__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_FetchData','SQLite_FetchNames',
+ 'SQLite_GetTable','SQLite_GetTable2d','SQLite_LastInsertRowID',
+ 'SQLite_LibVersion','SQLite_Open','SQLite_Query',
+ 'SQLite_QueryFinalize','SQLite_QueryReset','SQLite_QuerySingleRow',
+ 'SQLite_SaveMode','SQLite_SetTimeout','SQLite_Shutdown',
+ 'SQLite_SQLiteExe','SQLite_Startup','SQLite_TotalChanges',
+ 'StringAddComma','StringBetween','StringEncrypt','StringInsert',
+ 'StringProper','StringRepeat','StringReverse','StringSplit',
+ 'StringToHex','TCPIpToName','TempFile','TicksToTime','Timer_Diff',
+ 'Timer_GetTimerID','Timer_Init','Timer_KillAllTimers',
+ 'Timer_KillTimer','Timer_SetTimer','TimeToTicks','VersionCompare',
+ 'viClose','viExecCommand','viFindGpib','viGpibBusReset','viGTL',
+ 'viOpen','viSetAttribute','viSetTimeout','WeekNumberISO',
+ 'WinAPI_AttachConsole','WinAPI_AttachThreadInput','WinAPI_Beep',
+ 'WinAPI_BitBlt','WinAPI_CallNextHookEx','WinAPI_Check',
+ 'WinAPI_ClientToScreen','WinAPI_CloseHandle',
+ 'WinAPI_CommDlgExtendedError','WinAPI_CopyIcon',
+ 'WinAPI_CreateBitmap','WinAPI_CreateCompatibleBitmap',
+ 'WinAPI_CreateCompatibleDC','WinAPI_CreateEvent',
+ 'WinAPI_CreateFile','WinAPI_CreateFont','WinAPI_CreateFontIndirect',
+ 'WinAPI_CreateProcess','WinAPI_CreateSolidBitmap',
+ 'WinAPI_CreateSolidBrush','WinAPI_CreateWindowEx',
+ 'WinAPI_DefWindowProc','WinAPI_DeleteDC','WinAPI_DeleteObject',
+ 'WinAPI_DestroyIcon','WinAPI_DestroyWindow','WinAPI_DrawEdge',
+ 'WinAPI_DrawFrameControl','WinAPI_DrawIcon','WinAPI_DrawIconEx',
+ 'WinAPI_DrawText','WinAPI_EnableWindow','WinAPI_EnumDisplayDevices',
+ 'WinAPI_EnumWindows','WinAPI_EnumWindowsPopup',
+ 'WinAPI_EnumWindowsTop','WinAPI_ExpandEnvironmentStrings',
+ 'WinAPI_ExtractIconEx','WinAPI_FatalAppExit','WinAPI_FillRect',
+ 'WinAPI_FindExecutable','WinAPI_FindWindow','WinAPI_FlashWindow',
+ 'WinAPI_FlashWindowEx','WinAPI_FloatToInt',
+ 'WinAPI_FlushFileBuffers','WinAPI_FormatMessage','WinAPI_FrameRect',
+ 'WinAPI_FreeLibrary','WinAPI_GetAncestor','WinAPI_GetAsyncKeyState',
+ 'WinAPI_GetClassName','WinAPI_GetClientHeight',
+ 'WinAPI_GetClientRect','WinAPI_GetClientWidth',
+ 'WinAPI_GetCurrentProcess','WinAPI_GetCurrentProcessID',
+ 'WinAPI_GetCurrentThread','WinAPI_GetCurrentThreadId',
+ 'WinAPI_GetCursorInfo','WinAPI_GetDC','WinAPI_GetDesktopWindow',
+ 'WinAPI_GetDeviceCaps','WinAPI_GetDIBits','WinAPI_GetDlgCtrlID',
+ 'WinAPI_GetDlgItem','WinAPI_GetFileSizeEx','WinAPI_GetFocus',
+ 'WinAPI_GetForegroundWindow','WinAPI_GetIconInfo',
+ 'WinAPI_GetLastError','WinAPI_GetLastErrorMessage',
+ 'WinAPI_GetModuleHandle','WinAPI_GetMousePos','WinAPI_GetMousePosX',
+ 'WinAPI_GetMousePosY','WinAPI_GetObject','WinAPI_GetOpenFileName',
+ 'WinAPI_GetOverlappedResult','WinAPI_GetParent',
+ 'WinAPI_GetProcessAffinityMask','WinAPI_GetSaveFileName',
+ 'WinAPI_GetStdHandle','WinAPI_GetStockObject','WinAPI_GetSysColor',
+ 'WinAPI_GetSysColorBrush','WinAPI_GetSystemMetrics',
+ 'WinAPI_GetTextExtentPoint32','WinAPI_GetWindow',
+ 'WinAPI_GetWindowDC','WinAPI_GetWindowHeight',
+ 'WinAPI_GetWindowLong','WinAPI_GetWindowRect',
+ 'WinAPI_GetWindowText','WinAPI_GetWindowThreadProcessId',
+ 'WinAPI_GetWindowWidth','WinAPI_GetXYFromPoint',
+ 'WinAPI_GlobalMemStatus','WinAPI_GUIDFromString',
+ 'WinAPI_GUIDFromStringEx','WinAPI_HiWord','WinAPI_InProcess',
+ 'WinAPI_IntToFloat','WinAPI_InvalidateRect','WinAPI_IsClassName',
+ 'WinAPI_IsWindow','WinAPI_IsWindowVisible','WinAPI_LoadBitmap',
+ 'WinAPI_LoadImage','WinAPI_LoadLibrary','WinAPI_LoadLibraryEx',
+ 'WinAPI_LoadShell32Icon','WinAPI_LoadString','WinAPI_LocalFree',
+ 'WinAPI_LoWord','WinAPI_MakeDWord','WinAPI_MAKELANGID',
+ 'WinAPI_MAKELCID','WinAPI_MakeLong','WinAPI_MessageBeep',
+ 'WinAPI_Mouse_Event','WinAPI_MoveWindow','WinAPI_MsgBox',
+ 'WinAPI_MulDiv','WinAPI_MultiByteToWideChar',
+ 'WinAPI_MultiByteToWideCharEx','WinAPI_OpenProcess',
+ 'WinAPI_PointFromRect','WinAPI_PostMessage','WinAPI_PrimaryLangId',
+ 'WinAPI_PtInRect','WinAPI_ReadFile','WinAPI_ReadProcessMemory',
+ 'WinAPI_RectIsEmpty','WinAPI_RedrawWindow',
+ 'WinAPI_RegisterWindowMessage','WinAPI_ReleaseCapture',
+ 'WinAPI_ReleaseDC','WinAPI_ScreenToClient','WinAPI_SelectObject',
+ 'WinAPI_SetBkColor','WinAPI_SetCapture','WinAPI_SetCursor',
+ 'WinAPI_SetDefaultPrinter','WinAPI_SetDIBits','WinAPI_SetEvent',
+ 'WinAPI_SetFocus','WinAPI_SetFont','WinAPI_SetHandleInformation',
+ 'WinAPI_SetLastError','WinAPI_SetParent',
+ 'WinAPI_SetProcessAffinityMask','WinAPI_SetSysColors',
+ 'WinAPI_SetTextColor','WinAPI_SetWindowLong','WinAPI_SetWindowPos',
+ 'WinAPI_SetWindowsHookEx','WinAPI_SetWindowText',
+ 'WinAPI_ShowCursor','WinAPI_ShowError','WinAPI_ShowMsg',
+ 'WinAPI_ShowWindow','WinAPI_StringFromGUID','WinAPI_SubLangId',
+ 'WinAPI_SystemParametersInfo','WinAPI_TwipsPerPixelX',
+ 'WinAPI_TwipsPerPixelY','WinAPI_UnhookWindowsHookEx',
+ 'WinAPI_UpdateLayeredWindow','WinAPI_UpdateWindow',
+ 'WinAPI_ValidateClassName','WinAPI_WaitForInputIdle',
+ 'WinAPI_WaitForMultipleObjects','WinAPI_WaitForSingleObject',
+ 'WinAPI_WideCharToMultiByte','WinAPI_WindowFromPoint',
+ 'WinAPI_WriteConsole','WinAPI_WriteFile',
+ 'WinAPI_WriteProcessMemory','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_VersionInfo','WordAttach','WordCreate',
+ 'WordDocAdd','WordDocAddLink','WordDocAddPicture','WordDocClose',
+ 'WordDocFindReplace','WordDocGetCollection',
+ 'WordDocLinkGetCollection','WordDocOpen','WordDocPrint',
+ 'WordDocPropertyGet','WordDocPropertySet','WordDocSave',
+ 'WordDocSaveAs','WordErrorHandlerDeRegister',
+ 'WordErrorHandlerRegister','WordErrorNotify','WordMacroRun',
+ 'WordPropertyGet','WordPropertySet','WordQuit'
+ ),
+ 5 => array(
+ 'ce','comments-end','comments-start','cs','include','include-once',
+ 'NoTrayIcon','RequireAdmin'
+ ),
+ 6 => array(
+ 'AutoIt3Wrapper_Au3Check_Parameters',
+ 'AutoIt3Wrapper_Au3Check_Stop_OnWarning',
+ 'AutoIt3Wrapper_Change2CUI','AutoIt3Wrapper_Compression',
+ 'AutoIt3Wrapper_cvsWrapper_Parameters','AutoIt3Wrapper_Icon',
+ 'AutoIt3Wrapper_Outfile','AutoIt3Wrapper_Outfile_Type',
+ 'AutoIt3Wrapper_Plugin_Funcs','AutoIt3Wrapper_Res_Comment',
+ '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_requestedExecutionLevel',
+ 'AutoIt3Wrapper_Res_SaveSource','AutoIt3Wrapper_Run_After',
+ 'AutoIt3Wrapper_Run_Au3check','AutoIt3Wrapper_Run_Before',
+ 'AutoIt3Wrapper_Run_cvsWrapper','AutoIt3Wrapper_Run_Debug_Mode',
+ 'AutoIt3Wrapper_Run_Obfuscator','AutoIt3Wrapper_Run_Tidy',
+ 'AutoIt3Wrapper_Tidy_Stop_OnError','AutoIt3Wrapper_UseAnsi',
+ 'AutoIt3Wrapper_UseUpx','AutoIt3Wrapper_UseX64',
+ 'AutoIt3Wrapper_Version','EndRegion','forceref',
+ 'Obfuscator_Ignore_Funcs','Obfuscator_Ignore_Variables',
+ 'Obfuscator_Parameters','Region','Tidy_Parameters'
+ )
+ ),
+ '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: #0000FF; font-weight: bold;',
+ 2 => 'color: #800000; font-weight: bold;',
+ 3 => 'color: #000080; font-style: italic; font-weight: bold;',
+ 4 => 'color: #0080FF; font-style: italic; font-weight: bold;',
+ 5 => 'color: #F000FF; font-style: italic;',
+ 6 => 'color: #A00FF0; font-style: italic;'
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'font-style: italic; color: #669900;',
+ 0 => 'font-style: italic; color: #009933;',
+ 1 => 'font-style: italic; color: #9977BB;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #FF0000; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'font-weight: bold; color: #9977BB;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #AC00A9; font-style: italic; font-weight: bold;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000FF; font-style: italic; font-weight: bold;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #FF0000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'font-weight: bold; color: #AA0000;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.autoitscript.com/autoit3/docs/keywords.htm',
+ 2 => 'http://www.autoitscript.com/autoit3/docs/macros.htm',
+ 3 => 'http://www.autoitscript.com/autoit3/docs/functions/{FNAME}.htm',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => '[\\$%@]+[a-zA-Z_][a-zA-Z0-9_]*'
+ ),
+ '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)\#'
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/avisynth.php b/inc/geshi/avisynth.php
new file mode 100644
index 000000000..f74f50c3a
--- /dev/null
+++ b/inc/geshi/avisynth.php
@@ -0,0 +1,194 @@
+<?php
+/*************************************************************************************
+ * avisynth.php
+ * --------
+ * Author: Ryan Jones (sciguyryan@gmail.com)
+ * Copyright: (c) 2008 Ryan Jones
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/awk.php b/inc/geshi/awk.php
new file mode 100644
index 000000000..5d540315c
--- /dev/null
+++ b/inc/geshi/awk.php
@@ -0,0 +1,158 @@
+<?php
+/************************************************
+ * awk.php
+ * -------
+ * Author: George Pollard (porges@porg.es)
+ * Copyright: (c) 2009 George Pollard
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/bash.php b/inc/geshi/bash.php
new file mode 100644
index 000000000..dad391c8a
--- /dev/null
+++ b/inc/geshi/bash.php
@@ -0,0 +1,327 @@
+<?php
+/*************************************************************************************
+ * bash.php
+ * --------
+ * Author: Andreas Gohr (andi@splitbrain.org)
+ * Copyright: (c) 2004 Andreas Gohr, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * 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"
+ ),
+ '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(
+ 1 => array(
+ 'case', 'do', 'done', 'elif', 'else', 'esac', 'fi', 'for', 'function',
+ 'if', 'in', 'select', 'set', 'then', 'until', 'while', 'time'
+ ),
+ 2 => array(
+ 'aclocal', 'aconnect', 'aplay', 'apm', 'apmsleep', 'apropos',
+ 'apt-cache', 'apt-file', 'apt-get', 'apt-key', 'apt-src', 'aptitude',
+ 'ar', 'arch', 'arecord', 'as', 'as86', 'ash', 'autoconf',
+ 'autoheader', 'automake', 'awk',
+
+ 'basename', 'bash', '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',
+
+ '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', 'ffmpeg', 'fgconsole','fgrep', 'file', 'find',
+ 'flex', 'flex++', 'fmt', 'free', 'ftp', 'funzip', 'fuser',
+
+ 'g++', 'gawk', 'gc','gcc', 'gdb', 'getent', 'getkeycodes',
+ 'getopt', 'gettext', 'gettextize', 'gimp', 'gimp-remote',
+ 'gimptool', 'gmake', 'gocr', 'grep', 'groups', 'gs', 'gunzip',
+ 'gzexe', 'gzip',
+
+ 'git', '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',
+
+ 'id', 'ifconfig', 'ifdown', 'ifup', 'igawk', 'install',
+
+ 'join',
+
+ 'kbd_mode','kbdrate', 'kdialog', 'kfile', 'kill', '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', 'pcregrep', 'pcretest', 'perl', 'perror',
+ 'pgawk', 'pidof', 'ping', 'pr', 'procmail', 'prune', 'ps', 'pstree',
+ 'ps2ascii', 'ps2epsi', 'ps2frag', 'ps2pdf', 'ps2ps', 'psbook',
+ 'psmerge', 'psnup', 'psresize', 'psselect', 'pstops',
+
+ 'rbash', 'rcs', 'rcs2log', 'read', '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', 'stat', 'strace',
+ 'strings', 'strip', 'stty', 'su', 'sudo', 'suidperl', 'sum', 'svn',
+ 'svnadmin', 'svndumpfilter', 'svnlook', 'svnmerge', 'svnmucc',
+ 'svnserve', 'svnshell', 'svnsync', 'svnversion', 'svnwrap', 'sync',
+
+ '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',
+
+ 'zcat', 'zcmp', 'zdiff', 'zdump', 'zegrep', 'zfgrep', 'zforce',
+ 'zgrep', 'zip', 'zipgrep', 'zipinfo', 'zless', 'zmore', 'znew',
+ 'zsh', 'zsoelim'
+ ),
+ 3 => array(
+ 'alias', 'bg', 'bind', 'break', 'builtin', 'cd', 'command',
+ 'compgen', 'complete', 'continue', 'declare', 'dirs', 'disown',
+ 'echo', 'enable', 'eval', 'exec', 'exit', 'export', 'fc',
+ 'fg', 'getopts', 'hash', 'help', 'history', 'jobs', 'let',
+ 'local', 'logout', 'popd', 'printf', 'pushd', 'pwd', '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;'
+ ),
+ '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_%=\\/])"
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/basic4gl.php b/inc/geshi/basic4gl.php
new file mode 100644
index 000000000..7ac869304
--- /dev/null
+++ b/inc/geshi/basic4gl.php
@@ -0,0 +1,341 @@
+<?php
+/*************************************************************************************
+ * basic4gl.php
+ * ---------------------------------
+ * Author: Matthew Webb (bmatthew1@blueyonder.co.uk)
+ * Copyright: (c) 2004 Matthew Webb (http://matthew-4gl.wikispaces.com)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/bf.php b/inc/geshi/bf.php
new file mode 100644
index 000000000..ba44e6caf
--- /dev/null
+++ b/inc/geshi/bf.php
@@ -0,0 +1,114 @@
+<?php
+/*************************************************************************************
+ * bf.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #006600;',
+ 1 => 'color: #660000;',
+ 2 => 'color: #000066;',
+ 3 => 'color: #660066;',
+ 4 => 'color: #666600;'
+ ),
+ '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
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOW_BEFORE' => '',
+ 'DISALLOW_AFTER' => ''
+ )
+ )
+);
+
+?>
diff --git a/inc/geshi/bibtex.php b/inc/geshi/bibtex.php
new file mode 100644
index 000000000..e47e0665c
--- /dev/null
+++ b/inc/geshi/bibtex.php
@@ -0,0 +1,183 @@
+<?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.8.8
+ * 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*=)'
+ ),
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/blitzbasic.php b/inc/geshi/blitzbasic.php
new file mode 100644
index 000000000..e43ec4635
--- /dev/null
+++ b/inc/geshi/blitzbasic.php
@@ -0,0 +1,185 @@
+<?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.8.8
+ * 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 If','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/inc/geshi/bnf.php b/inc/geshi/bnf.php
new file mode 100644
index 000000000..f52df9cb8
--- /dev/null
+++ b/inc/geshi/bnf.php
@@ -0,0 +1,119 @@
+<?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.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/boo.php b/inc/geshi/boo.php
new file mode 100644
index 000000000..09d4ee40e
--- /dev/null
+++ b/inc/geshi/boo.php
@@ -0,0 +1,217 @@
+<?php
+/*************************************************************************************
+ * boo.php
+ * --------
+ * Author: Marcus Griep (neoeinstein+GeSHi@gmail.com)
+ * Copyright: (c) 2007 Marcus Griep (http://www.xpdm.us)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/c.php b/inc/geshi/c.php
new file mode 100644
index 000000000..b0e2987d7
--- /dev/null
+++ b/inc/geshi/c.php
@@ -0,0 +1,202 @@
+<?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.8.8
+ * 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(
+ 'printf', 'cout'
+ ),
+ 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'
+ ),
+ ),
+ '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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/c_mac.php b/inc/geshi/c_mac.php
new file mode 100644
index 000000000..1a034ae08
--- /dev/null
+++ b/inc/geshi/c_mac.php
@@ -0,0 +1,227 @@
+<?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.8.8
+ * 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/caddcl.php b/inc/geshi/caddcl.php
new file mode 100644
index 000000000..74310d6d9
--- /dev/null
+++ b/inc/geshi/caddcl.php
@@ -0,0 +1,126 @@
+<?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.8.8
+ * 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/inc/geshi/cadlisp.php b/inc/geshi/cadlisp.php
new file mode 100644
index 000000000..9277e5192
--- /dev/null
+++ b/inc/geshi/cadlisp.php
@@ -0,0 +1,186 @@
+<?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.8.8
+ * 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/inc/geshi/cfdg.php b/inc/geshi/cfdg.php
new file mode 100644
index 000000000..ee17fdf53
--- /dev/null
+++ b/inc/geshi/cfdg.php
@@ -0,0 +1,124 @@
+<?php
+/*************************************************************************************
+ * cfdg.php
+ * --------
+ * Author: John Horigan <john@glyphic.com>
+ * Copyright: (c) 2006 John Horigan http://www.ozonehouse.com/john/
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/cfm.php b/inc/geshi/cfm.php
new file mode 100644
index 000000000..dd508eec7
--- /dev/null
+++ b/inc/geshi/cfm.php
@@ -0,0 +1,299 @@
+<?php
+/*************************************************************************************
+ * cfm.php
+ * -------
+ * Author: Diego
+ * Copyright: (c) 2006 Diego
+ * Release Version: 1.0.8.8
+ * 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
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/chaiscript.php b/inc/geshi/chaiscript.php
new file mode 100644
index 000000000..e1baad4db
--- /dev/null
+++ b/inc/geshi/chaiscript.php
@@ -0,0 +1,140 @@
+<?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.8.8
+ * 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', 'else if', '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
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/cil.php b/inc/geshi/cil.php
new file mode 100644
index 000000000..142c7743a
--- /dev/null
+++ b/inc/geshi/cil.php
@@ -0,0 +1,196 @@
+<?php
+/*************************************************************************************
+ * cil.php
+ * --------
+ * Author: Marcus Griep (neoeinstein+GeSHi@gmail.com)
+ * Copyright: (c) 2007 Marcus Griep (http://www.xpdm.us)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/clojure.php b/inc/geshi/clojure.php
new file mode 100644
index 000000000..4bcb9a3ae
--- /dev/null
+++ b/inc/geshi/clojure.php
@@ -0,0 +1,134 @@
+<?php
+/*************************************************************************************
+ * clojure.php
+ * --------
+ * Author: Jess Johnson (jess@grok-code.com)
+ * Copyright: (c) 2009 Jess Johnson (http://grok-code.com)
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/cmake.php b/inc/geshi/cmake.php
new file mode 100644
index 000000000..ccd855b0b
--- /dev/null
+++ b/inc/geshi/cmake.php
@@ -0,0 +1,181 @@
+<?php
+/*************************************************************************************
+ * cmake.php
+ * -------
+ * Author: Daniel Nelson (danieln@eng.utah.edu)
+ * Copyright: (c) 2009 Daniel Nelson
+ * Release Version: 1.0.8.8
+ * 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
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/cobol.php b/inc/geshi/cobol.php
new file mode 100644
index 000000000..c1220a06f
--- /dev/null
+++ b/inc/geshi/cobol.php
@@ -0,0 +1,244 @@
+<?php
+/*************************************************************************************
+ * cobol.php
+ * ----------
+ * Author: BenBE (BenBE@omorphia.org)
+ * Copyright: (c) 2007-2008 BenBE (http://www.omorphia.de/)
+ * Release Version: 1.0.8.8
+ * Date Started: 2007/07/02
+ *
+ * COBOL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ * TODO (updated 2007/07/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' => 'COBOL',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(1 => '/^\*.*?$/m'),
+ '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(
+ 1 => array( //Compiler Directives
+ 'ANSI', 'BLANK', 'NOBLANK', 'CALL-SHARED', 'CANCEL', 'NOCANCEL',
+ 'CHECK', 'CODE', 'NOCODE', 'COLUMNS', 'COMPACT', 'NOCOMPACT',
+ 'COMPILE', 'CONSULT', 'NOCONSULT', 'CROSSREF', 'NOCROSSREF',
+ 'DIAGNOSE-74', 'NODIAGNOSE-74', 'DIAGNOSE-85', 'NODIAGNOSE-85',
+ 'DIAGNOSEALL', 'NODIAGNOSEALL', 'ENDIF', 'ENDUNIT', 'ENV',
+ 'ERRORFILE', 'ERRORS', 'FIPS', 'NOFIPS', 'FMAP', 'HEADING', 'HEAP',
+ 'HIGHPIN', 'HIGHREQUESTERS', 'ICODE', 'NOICODE', 'IF', 'IFNOT',
+ 'INNERLIST', 'NOINNERLIST', 'INSPECT', 'NOINSPECT', 'LARGEDATA',
+ 'LD', 'LESS-CODE', 'LIBRARY', 'LINES', 'LIST', 'NOLIST', 'LMAP',
+ 'NOLMAP', 'MAIN', 'MAP', 'NOMAP', 'NLD', 'NONSTOP', 'NON-SHARED',
+ 'OPTIMIZE', 'PERFORM-TRACE', 'PORT', 'NOPORT', 'RESETTOG',
+ 'RUNNABLE', 'RUNNAMED', 'SAVE', 'SAVEABEND', 'NOSAVEABEND',
+ 'SEARCH', 'NOSEARCH', 'SECTION', 'SETTOG', 'SHARED', 'SHOWCOPY',
+ 'NOSHOWCOPY', 'SHOWFILE', 'NOSHOWFILE', 'SOURCE', 'SQL', 'NOSQL',
+ 'SQLMEM', 'SUBSET', 'SUBTYPE', 'SUPPRESS', 'NOSUPPRESS', 'SYMBOLS',
+ 'NOSYMBOLS', 'SYNTAX', 'TANDEM', 'TRAP2', 'NOTRAP2', 'TRAP2-74',
+ 'NOTRAP2-74', 'UL', 'WARN', 'NOWARN'
+ ),
+ 2 => array( //Statement Keywords
+ 'ACCEPT', 'ADD', 'TO', 'GIVING', 'CORRESPONDING', 'ALTER', 'CALL',
+ 'CHECKPOINT', 'CLOSE', 'COMPUTE', 'CONTINUE', 'COPY',
+ 'DELETE', 'DISPLAY', 'DIVIDE', 'INTO', 'REMAINDER', 'ENTER',
+ 'COBOL', 'EVALUATE', 'EXIT', 'GO', 'INITIALIZE',
+ 'TALLYING', 'REPLACING', 'CONVERTING', 'LOCKFILE', 'MERGE', 'MOVE',
+ 'MULTIPLY', 'OPEN', 'PERFORM', 'TIMES',
+ 'UNTIL', 'VARYING', 'RETURN',
+ ),
+ 3 => array( //Reserved in some contexts
+ 'ACCESS', 'ADDRESS', 'ADVANCING', 'AFTER', 'ALL',
+ 'ALPHABET', 'ALPHABETIC', 'ALPHABETIC-LOWER', 'ALPHABETIC-UPPER',
+ 'ALPHANUMERIC', 'ALPHANUMERIC-EDITED', 'ALSO', 'ALTERNATE',
+ 'AND', 'ANY', 'APPROXIMATE', 'AREA', 'AREAS', 'ASCENDING', 'ASSIGN',
+ 'AT', 'AUTHOR', 'BEFORE', 'BINARY', 'BLOCK', 'BOTTOM', 'BY',
+ 'CD', 'CF', 'CH', 'CHARACTER', 'CHARACTERS',
+ 'CHARACTER-SET', 'CLASS', 'CLOCK-UNITS',
+ 'CODE-SET', 'COLLATING', 'COLUMN', 'COMMA',
+ 'COMMON', 'COMMUNICATION', 'COMP', 'COMP-3', 'COMP-5',
+ 'COMPUTATIONAL', 'COMPUTATIONAL-3', 'COMPUTATIONAL-5',
+ 'CONFIGURATION', 'CONTAINS', 'CONTENT', 'CONTROL',
+ 'CONTROLS', 'CORR', 'COUNT',
+ 'CURRENCY', 'DATA', 'DATE', 'DATE-COMPILED', 'DATE-WRITTEN', 'DAY',
+ 'DAY-OF-WEEK', 'DE', 'DEBUG-CONTENTS', 'DEBUG-ITEM', 'DEBUG-LINE',
+ 'DEBUG-SUB-2', 'DEBUG-SUB-3', 'DEBUGGING', 'DECIMAL-POINT',
+ 'DECLARATIVES', 'DEBUG-NAME', 'DEBUG-SUB-1', 'DELIMITED',
+ 'DELIMITER', 'DEPENDING', 'DESCENDING', 'DESTINATION', 'DETAIL',
+ 'DISABLE', 'DIVISION', 'DOWN', 'DUPLICATES',
+ 'DYNAMIC', 'EGI', 'ELSE', 'EMI', 'ENABLE', 'END', 'END-ADD',
+ 'END-COMPUTE', 'END-DELETE', 'END-DIVIDE', 'END-EVALUATE', 'END-IF',
+ 'END-MULTIPLY', 'END-OF-PAGE', 'END-PERFORM', 'END-READ',
+ 'END-RECEIVE', 'END-RETURN', 'END-REWRITE', 'END-SEARCH',
+ 'END-START', 'END-STRING', 'END-SUBTRACT', 'END-UNSTRING',
+ 'END-WRITE', 'EOP', 'EQUAL', 'ERROR', 'ESI',
+ 'EVERY', 'EXCEPTION', 'EXCLUSIVE', 'EXTEND',
+ 'EXTENDED-STORAGE', 'EXTERNAL', 'FALSE', 'FD', 'FILE',
+ 'FILE-CONTROL', 'FILLER', 'FINAL', 'FIRST', 'FOOTING', 'FOR',
+ 'FROM', 'FUNCTION', 'GENERATE', 'GENERIC', 'GLOBAL',
+ 'GREATER', 'GROUP', 'GUARDIAN-ERR', 'HIGH-VALUE',
+ 'HIGH-VALUES', 'I-O', 'I-O-CONTROL', 'IDENTIFICATION', 'IN',
+ 'INDEX', 'INDEXED', 'INDICATE', 'INITIAL', 'INITIATE',
+ 'INPUT', 'INPUT-OUTPUT', 'INSTALLATION',
+ 'INVALID', 'IS', 'JUST', 'JUSTIFIED', 'KEY', 'LABEL', 'LAST',
+ 'LEADING', 'LEFT', 'LESS', 'LIMIT', 'LIMITS', 'LINAGE',
+ 'LINAGE-COUNTER', 'LINE', 'LINE-COUNTER', 'LINKAGE', 'LOCK',
+ 'LOW-VALUE', 'LOW-VALUES', 'MEMORY', 'MESSAGE',
+ 'MODE', 'MODULES', 'MULTIPLE', 'NATIVE',
+ 'NEGATIVE', 'NEXT', 'NO', 'NOT', 'NULL', 'NULLS', 'NUMBER',
+ 'NUMERIC', 'NUMERIC-EDITED', 'OBJECT-COMPUTER', 'OCCURS', 'OF',
+ 'OFF', 'OMITTED', 'ON', 'OPTIONAL', 'OR', 'ORDER',
+ 'ORGANIZATION', 'OTHER', 'OUTPUT', 'OVERFLOW', 'PACKED-DECIMAL',
+ 'PADDING', 'PAGE', 'PAGE-COUNTER', 'PF', 'PH', 'PIC',
+ 'PICTURE', 'PLUS', 'POINTER', 'POSITION', 'POSITIVE', 'PRINTING',
+ 'PROCEDURE', 'PROCEDURES', 'PROCEED', 'PROGRAM', 'PROGRAM-ID',
+ 'PROGRAM-STATUS', 'PROGRAM-STATUS-1', 'PROGRAM-STATUS-2', 'PROMPT',
+ 'PROTECTED', 'PURGE', 'QUEUE', 'QUOTE', 'QUOTES', 'RD',
+ 'RECEIVE', 'RECEIVE-CONTROL', 'RECORD', 'RECORDS',
+ 'REDEFINES', 'REEL', 'REFERENCE', 'REFERENCES', 'RELATIVE',
+ 'REMOVAL', 'RENAMES', 'REPLACE',
+ 'REPLY', 'REPORT', 'REPORTING', 'REPORTS', 'RERUN',
+ 'RESERVE', 'RESET', 'REVERSED', 'REWIND', 'REWRITE', 'RF',
+ 'RH', 'RIGHT', 'ROUNDED', 'RUN', 'SAME', 'SD',
+ 'SECURITY', 'SEGMENT', 'SEGMENT-LIMIT', 'SELECT', 'SEND',
+ 'SENTENCE', 'SEPARATE', 'SEQUENCE', 'SEQUENTIAL', 'SET',
+ 'SIGN', 'SIZE', 'SORT', 'SORT-MERGE', 'SOURCE-COMPUTER',
+ 'SPACE', 'SPACES', 'SPECIAL-NAMES', 'STANDARD', 'STANDARD-1',
+ 'STANDARD-2', 'START', 'STARTBACKUP', 'STATUS', 'STOP', 'STRING',
+ 'SUB-QUEUE-1', 'SUB-QUEUE-2', 'SUB-QUEUE-3', 'SUBTRACT',
+ 'SYMBOLIC', 'SYNC', 'SYNCDEPTH', 'SYNCHRONIZED',
+ 'TABLE', 'TAL', 'TAPE', 'TERMINAL', 'TERMINATE', 'TEST',
+ 'TEXT', 'THAN', 'THEN', 'THROUGH', 'THRU', 'TIME',
+ 'TOP', 'TRAILING', 'TRUE', 'TYPE', 'UNIT', 'UNLOCK', 'UNLOCKFILE',
+ 'UNLOCKRECORD', 'UNSTRING', 'UP', 'UPON', 'USAGE', 'USE',
+ 'USING', 'VALUE', 'VALUES', 'WHEN', 'WITH', 'WORDS',
+ 'WORKING-STORAGE', 'WRITE', 'ZERO', 'ZEROES'
+ ),
+ 4 => array( //Standard functions
+ 'ACOS', 'ANNUITY', 'ASIN', 'ATAN', 'CHAR', 'COS', 'CURRENT-DATE',
+ 'DATE-OF-INTEGER', 'DAY-OF-INTEGER', 'FACTORIAL', 'INTEGER',
+ 'INTEGER-OF-DATE', 'INTEGER-OF-DAY', 'INTEGER-PART', 'LENGTH',
+ 'LOG', 'LOG10', 'LOWER-CASE', 'MAX', 'MEAN', 'MEDIAN', 'MIDRANGE',
+ 'MIN', 'MOD', 'NUMVAL', 'NUMVAL-C', 'ORD', 'ORD-MAX', 'ORD-MIN',
+ 'PRESENT-VALUE', 'RANDOM', 'RANGE', 'REM', 'REVERSE', 'SIN', 'SQRT',
+ 'STANDARD-DEVIATION', 'SUM', 'TAN', 'UPPER-CASE', 'VARIANCE',
+ 'WHEN-COMPILED'
+ ),
+ 5 => array( //Privileged Built-in Functions
+ '#IN', '#OUT', '#TERM', '#TEMP', '#DYNAMIC', 'COBOL85^ARMTRAP',
+ 'COBOL85^COMPLETION', 'COBOL_COMPLETION_', 'COBOL_CONTROL_',
+ 'COBOL_GETENV_', 'COBOL_PUTENV_', 'COBOL85^RETURN^SORT^ERRORS',
+ 'COBOL_RETURN_SORT_ERRORS_', 'COBOL85^REWIND^SEQUENTIAL',
+ 'COBOL_REWIND_SEQUENTIAL_', 'COBOL85^SET^SORT^PARAM^TEXT',
+ 'COBOL_SET_SORT_PARAM_TEXT_', 'COBOL85^SET^SORT^PARAM^VALUE',
+ 'COBOL_SET_SORT_PARAM_VALUE_', 'COBOL_SET_MAX_RECORD_',
+ 'COBOL_SETMODE_', 'COBOL85^SPECIAL^OPEN', 'COBOL_SPECIAL_OPEN_',
+ 'COBOLASSIGN', 'COBOL_ASSIGN_', 'COBOLFILEINFO', 'COBOL_FILE_INFO_',
+ 'COBOLSPOOLOPEN', 'CREATEPROCESS', 'ALTERPARAMTEXT',
+ 'CHECKLOGICALNAME', 'CHECKMESSAGE', 'DELETEASSIGN', 'DELETEPARAM',
+ 'DELETESTARTUP', 'GETASSIGNTEXT', 'GETASSIGNVALUE', 'GETBACKUPCPU',
+ 'GETPARAMTEXT', 'GETSTARTUPTEXT', 'PUTASSIGNTEXT', 'PUTASSIGNVALUE',
+ 'PUTPARAMTEXT', 'PUTSTARTUPTEXT'
+ )
+ ),
+ 'SYMBOLS' => array(
+ //Avoid having - in identifiers marked as symbols
+ ' + ', ' - ', ' * ', ' / ', ' ** ',
+ '.', ',',
+ '=',
+ '(', ')', '[', ']'
+ ),
+ '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: #000000; font-weight: bold;',
+ 3 => 'color: #008000; font-weight: bold;',
+ 4 => 'color: #000080;',
+ 5 => 'color: #008000;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #a0a0a0; font-style: italic;',
+ 'MULTI' => 'color: #a0a0a0; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #993399;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;'
+ ),
+ '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(
+ ),
+ 'TAB_WIDTH' => 4
+ );
+
+?>
diff --git a/inc/geshi/cpp-qt.php b/inc/geshi/cpp-qt.php
new file mode 100644
index 000000000..8523d16b7
--- /dev/null
+++ b/inc/geshi/cpp-qt.php
@@ -0,0 +1,564 @@
+<?php
+/*************************************************************************************
+ * cpp.php
+ * -------
+ * Author: Iulian M
+ * Copyright: (c) 2006 Iulian M
+ * Release Version: 1.0.8.8
+ * 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'
+ ),
+ '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'
+ ),
+ 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_UINT16", "Q_UINT32", "Q_UINT64", "Q_UINT8", "Q_ULLONG",
+ "Q_ULONG", "Q3Accel", "Q3Action", "Q3ActionGroup", "Q3AsciiBucket",
+ "Q3AsciiCache", "Q3AsciiCacheIterator", "Q3AsciiDict",
+ "Q3AsciiDictIterator", "Q3BaseBucket", "Q3BoxLayout", "Q3Button",
+ "Q3ButtonGroup", "Q3Cache", "Q3CacheIterator", "Q3Canvas",
+ "Q3CanvasEllipse", "Q3CanvasItem", "Q3CanvasItemList",
+ "Q3CanvasLine", "Q3CanvasPixmap", "Q3CanvasPixmapArray",
+ "Q3CanvasPolygon", "Q3CanvasPolygonalItem", "Q3CanvasRectangle",
+ "Q3CanvasSpline", "Q3CanvasSprite", "Q3CanvasText", "Q3CanvasView",
+ "Q3CheckListItem", "Q3CheckTableItem", "Q3CleanupHandler",
+ "Q3ColorDrag", "Q3ComboBox", "Q3ComboTableItem", "Q3CString",
+ "Q3DataBrowser", "Q3DataTable", "Q3DataView", "Q3DateEdit",
+ "Q3DateTimeEdit", "Q3DateTimeEditBase", "Q3DeepCopy", "Q3Dict",
+ "Q3DictIterator", "Q3Dns", "Q3DnsSocket", "Q3DockArea",
+ "Q3DockAreaLayout", "Q3DockWindow", "Q3DragObject", "Q3DropSite",
+ "Q3EditorFactory", "Q3FileDialog", "Q3FileIconProvider",
+ "Q3FilePreview", "Q3Frame", "Q3Ftp", "Q3GArray", "Q3GCache",
+ "Q3GCacheIterator", "Q3GDict", "Q3GDictIterator", "Q3GList",
+ "Q3GListIterator", "Q3GListStdIterator", "Q3Grid", "Q3GridLayout",
+ "Q3GridView", "Q3GroupBox", "Q3GVector", "Q3HBox", "Q3HBoxLayout",
+ "Q3HButtonGroup", "Q3Header", "Q3HGroupBox", "Q3Http",
+ "Q3HttpHeader", "Q3HttpRequestHeader", "Q3HttpResponseHeader",
+ "Q3IconDrag", "Q3IconDragItem", "Q3IconView", "Q3IconViewItem",
+ "Q3ImageDrag", "Q3IntBucket", "Q3IntCache", "Q3IntCacheIterator",
+ "Q3IntDict", "Q3IntDictIterator", "Q3ListBox", "Q3ListBoxItem",
+ "Q3ListBoxPixmap", "Q3ListBoxText", "Q3ListView", "Q3ListViewItem",
+ "Q3ListViewItemIterator", "Q3LNode", "Q3LocalFs", "Q3MainWindow",
+ "Q3MemArray", "Q3MimeSourceFactory", "Q3MultiLineEdit",
+ "Q3NetworkOperation", "Q3NetworkProtocol", "Q3NetworkProtocolDict",
+ "Q3NetworkProtocolFactory", "Q3NetworkProtocolFactoryBase",
+ "Q3ObjectDictionary", "Q3PaintDeviceMetrics", "Q3Painter",
+ "Q3Picture", "Q3PointArray", "Q3PolygonScanner", "Q3PopupMenu",
+ "Q3Process", "Q3ProgressBar", "Q3ProgressDialog", "Q3PtrBucket",
+ "Q3PtrCollection", "Q3PtrDict", "Q3PtrDictIterator", "Q3PtrList",
+ "Q3PtrListIterator", "Q3PtrListStdIterator", "Q3PtrQueue",
+ "Q3PtrStack", "Q3PtrVector", "Q3RangeControl", "Q3ScrollView",
+ "Q3Semaphore", "Q3ServerSocket", "Q3Shared", "Q3Signal",
+ "Q3SimpleRichText", "Q3SingleCleanupHandler", "Q3Socket",
+ "Q3SocketDevice", "Q3SortedList", "Q3SpinWidget", "Q3SqlCursor",
+ "Q3SqlEditorFactory", "Q3SqlFieldInfo", "Q3SqlFieldInfoList",
+ "Q3SqlForm", "Q3SqlPropertyMap", "Q3SqlRecordInfo",
+ "Q3SqlSelectCursor", "Q3StoredDrag", "Q3StrIList", "Q3StringBucket",
+ "Q3StrIVec", "Q3StrList", "Q3StrListIterator", "Q3StrVec",
+ "Q3StyleSheet", "Q3StyleSheetItem", "Q3SyntaxHighlighter",
+ "Q3TabDialog", "Q3Table", "Q3TableItem", "Q3TableSelection",
+ "Q3TextBrowser", "Q3TextDrag", "Q3TextEdit",
+ "Q3TextEditOptimPrivate", "Q3TextStream", "Q3TextView",
+ "Q3TimeEdit", "Q3ToolBar", "Q3TSFUNC", "Q3UriDrag", "Q3Url",
+ "Q3UrlOperator", "Q3ValueList", "Q3ValueListConstIterator",
+ "Q3ValueListIterator", "Q3ValueStack", "Q3ValueVector", "Q3VBox",
+ "Q3VBoxLayout", "Q3VButtonGroup", "Q3VGroupBox", "Q3WhatsThis",
+ "Q3WidgetStack", "Q3Wizard", "QAbstractButton",
+ "QAbstractEventDispatcher", "QAbstractExtensionFactory",
+ "QAbstractExtensionManager", "QAbstractFileEngine",
+ "QAbstractFileEngineHandler", "QAbstractFileEngineIterator",
+ "QAbstractFormBuilder", "QAbstractGraphicsShapeItem",
+ "QAbstractItemDelegate", "QAbstractItemModel", "QAbstractItemView",
+ "QAbstractListModel", "QAbstractMessageHandler",
+ "QAbstractNetworkCache", "QAbstractPageSetupDialog",
+ "QAbstractPrintDialog", "QAbstractProxyModel",
+ "QAbstractScrollArea", "QAbstractSlider", "QAbstractSocket",
+ "QAbstractSpinBox", "QAbstractTableModel",
+ "QAbstractTextDocumentLayout", "QAbstractUndoItem",
+ "QAbstractUriResolver", "QAbstractXmlNodeModel",
+ "QAbstractXmlReceiver", "QAccessible", "QAccessible2Interface",
+ "QAccessibleApplication", "QAccessibleBridge",
+ "QAccessibleBridgeFactoryInterface", "QAccessibleBridgePlugin",
+ "QAccessibleEditableTextInterface", "QAccessibleEvent",
+ "QAccessibleFactoryInterface", "QAccessibleInterface",
+ "QAccessibleInterfaceEx", "QAccessibleObject",
+ "QAccessibleObjectEx", "QAccessiblePlugin",
+ "QAccessibleSimpleEditableTextInterface",
+ "QAccessibleTableInterface", "QAccessibleTextInterface",
+ "QAccessibleValueInterface", "QAccessibleWidget",
+ "QAccessibleWidgetEx", "QAction", "QActionEvent", "QActionGroup",
+ "QApplication", "QArgument", "QAssistantClient", "QAtomicInt",
+ "QAtomicPointer", "QAuthenticator", "QBasicAtomicInt",
+ "QBasicAtomicPointer", "QBasicTimer", "QBitArray", "QBitmap",
+ "QBitRef", "QBool", "QBoxLayout", "QBrush", "QBrushData", "QBuffer",
+ "QButtonGroup", "QByteArray", "QByteArrayMatcher", "QByteRef",
+ "QCache", "QCalendarWidget", "QCDEStyle", "QChar", "QCharRef",
+ "QCheckBox", "QChildEvent", "QCleanlooksStyle", "QClipboard",
+ "QClipboardEvent", "QCloseEvent", "QColor", "QColorDialog",
+ "QColorGroup", "QColormap", "QColumnView", "QComboBox",
+ "QCommandLinkButton", "QCommonStyle", "QCompleter",
+ "QConicalGradient", "QConstString", "QContextMenuEvent", "QCOORD",
+ "QCoreApplication", "QCryptographicHash", "QCursor", "QCursorShape",
+ "QCustomEvent", "QDataStream", "QDataWidgetMapper", "QDate",
+ "QDateEdit", "QDateTime", "QDateTimeEdit", "QDB2Driver",
+ "QDB2Result", "QDBusAbstractAdaptor", "QDBusAbstractInterface",
+ "QDBusArgument", "QDBusConnection", "QDBusConnectionInterface",
+ "QDBusContext", "QDBusError", "QDBusInterface", "QDBusMessage",
+ "QDBusMetaType", "QDBusObjectPath", "QDBusPendingCall",
+ "QDBusPendingCallWatcher", "QDBusPendingReply",
+ "QDBusPendingReplyData", "QDBusReply", "QDBusServer",
+ "QDBusSignature", "QDBusVariant", "QDebug",
+ "QDesignerActionEditorInterface", "QDesignerBrushManagerInterface",
+ "QDesignerComponents", "QDesignerContainerExtension",
+ "QDesignerCustomWidgetCollectionInterface",
+ "QDesignerCustomWidgetInterface", "QDesignerDnDItemInterface",
+ "QDesignerDynamicPropertySheetExtension", "QDesignerExportWidget",
+ "QDesignerExtraInfoExtension", "QDesignerFormEditorInterface",
+ "QDesignerFormEditorPluginInterface", "QDesignerFormWindowCursorInterface",
+ "QDesignerFormWindowInterface", "QDesignerFormWindowManagerInterface",
+ "QDesignerFormWindowToolInterface",
+ "QDesignerIconCacheInterface", "QDesignerIntegrationInterface",
+ "QDesignerLanguageExtension", "QDesignerLayoutDecorationExtension",
+ "QDesignerMemberSheetExtension", "QDesignerMetaDataBaseInterface",
+ "QDesignerMetaDataBaseItemInterface",
+ "QDesignerObjectInspectorInterface", "QDesignerPromotionInterface",
+ "QDesignerPropertyEditorInterface",
+ "QDesignerPropertySheetExtension", "QDesignerResourceBrowserInterface",
+ "QDesignerTaskMenuExtension", "QDesignerWidgetBoxInterface",
+ "QDesignerWidgetDataBaseInterface", "QDesignerWidgetDataBaseItemInterface",
+ "QDesignerWidgetFactoryInterface", "QDesktopServices",
+ "QDesktopWidget", "QDial", "QDialog", "QDialogButtonBox", "QDir",
+ "QDirIterator", "QDirModel", "QDockWidget", "QDomAttr",
+ "QDomCDATASection", "QDomCharacterData", "QDomComment",
+ "QDomDocument", "QDomDocumentFragment", "QDomDocumentType",
+ "QDomElement", "QDomEntity", "QDomEntityReference",
+ "QDomImplementation", "QDomNamedNodeMap", "QDomNode",
+ "QDomNodeList", "QDomNotation", "QDomProcessingInstruction",
+ "QDomText", "QDoubleSpinBox", "QDoubleValidator", "QDrag",
+ "QDragEnterEvent", "QDragLeaveEvent", "QDragMoveEvent",
+ "QDragResponseEvent", "QDropEvent", "QDynamicPropertyChangeEvent",
+ "QErrorMessage", "QEvent", "QEventLoop", "QEventSizeOfChecker",
+ "QExplicitlySharedDataPointer", "QExtensionFactory",
+ "QExtensionManager", "QFactoryInterface", "QFile", "QFileDialog",
+ "QFileIconProvider", "QFileInfo", "QFileInfoList",
+ "QFileInfoListIterator", "QFileOpenEvent", "QFileSystemModel",
+ "QFileSystemWatcher", "QFlag", "QFlags", "QFocusEvent",
+ "QFocusFrame", "QFont", "QFontComboBox", "QFontDatabase",
+ "QFontDialog", "QFontInfo", "QFontMetrics", "QFontMetricsF",
+ "QForeachContainer", "QForeachContainerBase", "QFormBuilder",
+ "QFormLayout", "QFrame", "QFSFileEngine", "QFtp", "QFuture",
+ "QFutureInterface", "QFutureInterfaceBase", "QFutureIterator",
+ "QFutureSynchronizer", "QFutureWatcher", "QFutureWatcherBase",
+ "QGenericArgument", "QGenericReturnArgument", "QGLColormap",
+ "QGLContext", "QGLFormat", "QGLFramebufferObject", "QGlobalStatic",
+ "QGlobalStaticDeleter", "QGLPixelBuffer", "QGLWidget", "QGradient",
+ "QGradientStop", "QGradientStops", "QGraphicsEllipseItem",
+ "QGraphicsGridLayout", "QGraphicsItem", "QGraphicsItemAnimation",
+ "QGraphicsItemGroup", "QGraphicsLayout", "QGraphicsLayoutItem",
+ "QGraphicsLinearLayout", "QGraphicsLineItem", "QGraphicsPathItem",
+ "QGraphicsPixmapItem", "QGraphicsPolygonItem",
+ "QGraphicsProxyWidget", "QGraphicsRectItem", "QGraphicsScene",
+ "QGraphicsSceneContextMenuEvent", "QGraphicsSceneDragDropEvent",
+ "QGraphicsSceneEvent", "QGraphicsSceneHelpEvent",
+ "QGraphicsSceneHoverEvent", "QGraphicsSceneMouseEvent",
+ "QGraphicsSceneMoveEvent", "QGraphicsSceneResizeEvent",
+ "QGraphicsSceneWheelEvent", "QGraphicsSimpleTextItem",
+ "QGraphicsSvgItem", "QGraphicsTextItem", "QGraphicsView",
+ "QGraphicsWidget", "QGridLayout", "QGroupBox", "QGtkStyle", "QHash",
+ "QHashData", "QHashDummyNode", "QHashDummyValue", "QHashIterator",
+ "QHashNode", "QHBoxLayout", "QHeaderView", "QHelpContentItem",
+ "QHelpContentModel", "QHelpContentWidget", "QHelpEngine",
+ "QHelpEngineCore", "QHelpEvent", "QHelpGlobal", "QHelpIndexModel",
+ "QHelpIndexWidget", "QHelpSearchEngine", "QHelpSearchQuery",
+ "QHelpSearchQueryWidget", "QHelpSearchResultWidget", "QHideEvent",
+ "QHostAddress", "QHostInfo", "QHoverEvent", "QHttp", "QHttpHeader",
+ "QHttpRequestHeader", "QHttpResponseHeader", "QIBaseDriver",
+ "QIBaseResult", "QIcon", "QIconDragEvent", "QIconEngine",
+ "QIconEngineFactoryInterface", "QIconEngineFactoryInterfaceV2",
+ "QIconEnginePlugin", "QIconEnginePluginV2", "QIconEngineV2",
+ "QIconSet", "QImage", "QImageIOHandler",
+ "QImageIOHandlerFactoryInterface", "QImageIOPlugin", "QImageReader",
+ "QImageTextKeyLang", "QImageWriter", "QIncompatibleFlag",
+ "QInputContext", "QInputContextFactory",
+ "QInputContextFactoryInterface", "QInputContextPlugin",
+ "QInputDialog", "QInputEvent", "QInputMethodEvent", "Q_INT16",
+ "Q_INT32", "Q_INT64", "Q_INT8", "QInternal", "QIntForSize",
+ "QIntForType", "QIntValidator", "QIODevice", "Q_IPV6ADDR",
+ "QIPv6Address", "QItemDelegate", "QItemEditorCreator",
+ "QItemEditorCreatorBase", "QItemEditorFactory", "QItemSelection",
+ "QItemSelectionModel", "QItemSelectionRange", "QKeyEvent",
+ "QKeySequence", "QLabel", "QLatin1Char", "QLatin1String", "QLayout",
+ "QLayoutItem", "QLayoutIterator", "QLCDNumber", "QLibrary",
+ "QLibraryInfo", "QLine", "QLinearGradient", "QLineEdit", "QLineF",
+ "QLinkedList", "QLinkedListData", "QLinkedListIterator",
+ "QLinkedListNode", "QList", "QListData", "QListIterator",
+ "QListView", "QListWidget", "QListWidgetItem", "Q_LLONG", "QLocale",
+ "QLocalServer", "QLocalSocket", "Q_LONG", "QMacCompatGLenum",
+ "QMacCompatGLint", "QMacCompatGLuint", "QMacGLCompatTypes",
+ "QMacMime", "QMacPasteboardMime", "QMainWindow", "QMap", "QMapData",
+ "QMapIterator", "QMapNode", "QMapPayloadNode", "QMatrix",
+ "QMdiArea", "QMdiSubWindow", "QMenu", "QMenuBar",
+ "QMenubarUpdatedEvent", "QMenuItem", "QMessageBox",
+ "QMetaClassInfo", "QMetaEnum", "QMetaMethod", "QMetaObject",
+ "QMetaObjectExtraData", "QMetaProperty", "QMetaType", "QMetaTypeId",
+ "QMetaTypeId2", "QMimeData", "QMimeSource", "QModelIndex",
+ "QModelIndexList", "QMotifStyle", "QMouseEvent", "QMoveEvent",
+ "QMovie", "QMultiHash", "QMultiMap", "QMutableFutureIterator",
+ "QMutableHashIterator", "QMutableLinkedListIterator",
+ "QMutableListIterator", "QMutableMapIterator",
+ "QMutableSetIterator", "QMutableStringListIterator",
+ "QMutableVectorIterator", "QMutex", "QMutexLocker", "QMYSQLDriver",
+ "QMYSQLResult", "QNetworkAccessManager", "QNetworkAddressEntry",
+ "QNetworkCacheMetaData", "QNetworkCookie", "QNetworkCookieJar",
+ "QNetworkDiskCache", "QNetworkInterface", "QNetworkProxy",
+ "QNetworkProxyFactory", "QNetworkProxyQuery", "QNetworkReply",
+ "QNetworkRequest", "QNoDebug", "QNoImplicitBoolCast", "QObject",
+ "QObjectCleanupHandler", "QObjectData", "QObjectList",
+ "QObjectUserData", "QOCIDriver", "QOCIResult", "QODBCDriver",
+ "QODBCResult", "QPageSetupDialog", "QPaintDevice", "QPaintEngine",
+ "QPaintEngineState", "QPainter", "QPainterPath",
+ "QPainterPathPrivate", "QPainterPathStroker", "QPaintEvent",
+ "QPair", "QPalette", "QPen", "QPersistentModelIndex", "QPicture",
+ "QPictureFormatInterface", "QPictureFormatPlugin", "QPictureIO",
+ "Q_PID", "QPixmap", "QPixmapCache", "QPlainTextDocumentLayout",
+ "QPlainTextEdit", "QPlastiqueStyle", "QPluginLoader", "QPoint",
+ "QPointer", "QPointF", "QPolygon", "QPolygonF", "QPrintDialog",
+ "QPrintEngine", "QPrinter", "QPrinterInfo", "QPrintPreviewDialog",
+ "QPrintPreviewWidget", "QProcess", "QProgressBar",
+ "QProgressDialog", "QProxyModel", "QPSQLDriver", "QPSQLResult",
+ "QPushButton", "QQueue", "QRadialGradient", "QRadioButton",
+ "QReadLocker", "QReadWriteLock", "QRect", "QRectF", "QRegExp",
+ "QRegExpValidator", "QRegion", "QResizeEvent", "QResource",
+ "QReturnArgument", "QRgb", "QRubberBand", "QRunnable",
+ "QScriptable", "QScriptClass", "QScriptClassPropertyIterator",
+ "QScriptContext", "QScriptContextInfo", "QScriptContextInfoList",
+ "QScriptEngine", "QScriptEngineAgent", "QScriptEngineDebugger",
+ "QScriptExtensionInterface", "QScriptExtensionPlugin",
+ "QScriptString", "QScriptSyntaxCheckResult", "QScriptValue",
+ "QScriptValueIterator", "QScriptValueList", "QScrollArea",
+ "QScrollBar", "QSemaphore", "QSessionManager", "QSet",
+ "QSetIterator", "QSettings", "QSharedData", "QSharedDataPointer",
+ "QSharedMemory", "QSharedPointer", "QShortcut", "QShortcutEvent",
+ "QShowEvent", "QSignalMapper", "QSignalSpy", "QSimpleXmlNodeModel",
+ "QSize", "QSizeF", "QSizeGrip", "QSizePolicy", "QSlider",
+ "QSocketNotifier", "QSortFilterProxyModel", "QSound",
+ "QSourceLocation", "QSpacerItem", "QSpinBox", "QSplashScreen",
+ "QSplitter", "QSplitterHandle", "QSpontaneKeyEvent", "QSqlDatabase",
+ "QSqlDriver", "QSqlDriverCreator", "QSqlDriverCreatorBase",
+ "QSqlDriverFactoryInterface", "QSqlDriverPlugin", "QSqlError",
+ "QSqlField", "QSqlIndex", "QSQLite2Driver", "QSQLite2Result",
+ "QSQLiteDriver", "QSQLiteResult", "QSqlQuery", "QSqlQueryModel",
+ "QSqlRecord", "QSqlRelation", "QSqlRelationalDelegate",
+ "QSqlRelationalTableModel", "QSqlResult", "QSqlTableModel", "QSsl",
+ "QSslCertificate", "QSslCipher", "QSslConfiguration", "QSslError",
+ "QSslKey", "QSslSocket", "QStack", "QStackedLayout",
+ "QStackedWidget", "QStandardItem", "QStandardItemEditorCreator",
+ "QStandardItemModel", "QStatusBar", "QStatusTipEvent",
+ "QStdWString", "QString", "QStringList", "QStringListIterator",
+ "QStringListModel", "QStringMatcher", "QStringRef", "QStyle",
+ "QStyledItemDelegate", "QStyleFactory", "QStyleFactoryInterface",
+ "QStyleHintReturn", "QStyleHintReturnMask",
+ "QStyleHintReturnVariant", "QStyleOption", "QStyleOptionButton",
+ "QStyleOptionComboBox", "QStyleOptionComplex",
+ "QStyleOptionDockWidget", "QStyleOptionDockWidgetV2",
+ "QStyleOptionFocusRect", "QStyleOptionFrame", "QStyleOptionFrameV2",
+ "QStyleOptionFrameV3", "QStyleOptionGraphicsItem",
+ "QStyleOptionGroupBox", "QStyleOptionHeader",
+ "QStyleOptionMenuItem", "QStyleOptionProgressBar",
+ "QStyleOptionProgressBarV2", "QStyleOptionQ3DockWindow",
+ "QStyleOptionQ3ListView", "QStyleOptionQ3ListViewItem",
+ "QStyleOptionRubberBand", "QStyleOptionSizeGrip",
+ "QStyleOptionSlider", "QStyleOptionSpinBox", "QStyleOptionTab",
+ "QStyleOptionTabBarBase", "QStyleOptionTabBarBaseV2",
+ "QStyleOptionTabV2", "QStyleOptionTabV3",
+ "QStyleOptionTabWidgetFrame", "QStyleOptionTitleBar",
+ "QStyleOptionToolBar", "QStyleOptionToolBox",
+ "QStyleOptionToolBoxV2", "QStyleOptionToolButton",
+ "QStyleOptionViewItem", "QStyleOptionViewItemV2",
+ "QStyleOptionViewItemV3", "QStyleOptionViewItemV4", "QStylePainter",
+ "QStylePlugin", "QSvgGenerator", "QSvgRenderer", "QSvgWidget",
+ "QSyntaxHighlighter", "QSysInfo", "QSystemLocale",
+ "QSystemSemaphore", "QSystemTrayIcon", "Qt", "Qt3Support",
+ "QTabBar", "QTabletEvent", "QTableView", "QTableWidget",
+ "QTableWidgetItem", "QTableWidgetSelectionRange", "QTabWidget",
+ "QtAlgorithms", "QtAssistant", "QtCleanUpFunction",
+ "QtConcurrentFilter", "QtConcurrentMap", "QtConcurrentRun",
+ "QtContainerFwd", "QtCore", "QTcpServer", "QTcpSocket", "QtDBus",
+ "QtDebug", "QtDesigner", "QTDSDriver", "QTDSResult",
+ "QTemporaryFile", "QtEndian", "QTest", "QTestAccessibility",
+ "QTestAccessibilityEvent", "QTestData", "QTestDelayEvent",
+ "QTestEvent", "QTestEventList", "QTestEventLoop",
+ "QTestKeyClicksEvent", "QTestKeyEvent", "QTestMouseEvent",
+ "QtEvents", "QTextBlock", "QTextBlockFormat", "QTextBlockGroup",
+ "QTextBlockUserData", "QTextBoundaryFinder", "QTextBrowser",
+ "QTextCharFormat", "QTextCodec", "QTextCodecFactoryInterface",
+ "QTextCodecPlugin", "QTextCursor", "QTextDecoder", "QTextDocument",
+ "QTextDocumentFragment", "QTextDocumentWriter", "QTextEdit",
+ "QTextEncoder", "QTextFormat", "QTextFragment", "QTextFrame",
+ "QTextFrameFormat", "QTextFrameLayoutData", "QTextImageFormat",
+ "QTextInlineObject", "QTextIStream", "QTextItem", "QTextLayout",
+ "QTextLength", "QTextLine", "QTextList", "QTextListFormat",
+ "QTextObject", "QTextObjectInterface", "QTextOption",
+ "QTextOStream", "QTextStream", "QTextStreamFunction",
+ "QTextStreamManipulator", "QTextTable", "QTextTableCell",
+ "QTextTableCellFormat", "QTextTableFormat", "QtGlobal", "QtGui",
+ "QtHelp", "QThread", "QThreadPool", "QThreadStorage",
+ "QThreadStorageData", "QTime", "QTimeEdit", "QTimeLine", "QTimer",
+ "QTimerEvent", "QtMsgHandler", "QtNetwork", "QToolBar",
+ "QToolBarChangeEvent", "QToolBox", "QToolButton", "QToolTip",
+ "QtOpenGL", "QtPlugin", "QtPluginInstanceFunction", "QTransform",
+ "QTranslator", "QTreeView", "QTreeWidget", "QTreeWidgetItem",
+ "QTreeWidgetItemIterator", "QTS", "QtScript", "QtScriptTools",
+ "QtSql", "QtSvg", "QtTest", "QtUiTools", "QtWebKit", "QtXml",
+ "QtXmlPatterns", "QTypeInfo", "QUdpSocket", "QUiLoader",
+ "QUintForSize", "QUintForType", "QUndoCommand", "QUndoGroup",
+ "QUndoStack", "QUndoView", "QUnixPrintWidget", "QUpdateLaterEvent",
+ "QUrl", "QUrlInfo", "QUuid", "QValidator", "QVariant",
+ "QVariantComparisonHelper", "QVariantHash", "QVariantList",
+ "QVariantMap", "QVarLengthArray", "QVBoxLayout", "QVector",
+ "QVectorData", "QVectorIterator", "QVectorTypedData",
+ "QWaitCondition", "QWeakPointer", "QWebDatabase", "QWebFrame",
+ "QWebHistory", "QWebHistoryInterface", "QWebHistoryItem",
+ "QWebHitTestResult", "QWebPage", "QWebPluginFactory",
+ "QWebSecurityOrigin", "QWebSettings", "QWebView", "QWhatsThis",
+ "QWhatsThisClickedEvent", "QWheelEvent", "QWidget", "QWidgetAction",
+ "QWidgetData", "QWidgetItem", "QWidgetItemV2", "QWidgetList",
+ "QWidgetMapper", "QWidgetSet", "QWindowsCEStyle", "QWindowsMime",
+ "QWindowsMobileStyle", "QWindowsStyle", "QWindowStateChangeEvent",
+ "QWindowsVistaStyle", "QWindowsXPStyle", "QWizard", "QWizardPage",
+ "QWMatrix", "QWorkspace", "QWriteLocker", "QX11EmbedContainer",
+ "QX11EmbedWidget", "QX11Info", "QXmlAttributes",
+ "QXmlContentHandler", "QXmlDeclHandler", "QXmlDefaultHandler",
+ "QXmlDTDHandler", "QXmlEntityResolver", "QXmlErrorHandler",
+ "QXmlFormatter", "QXmlInputSource", "QXmlItem",
+ "QXmlLexicalHandler", "QXmlLocator", "QXmlName", "QXmlNamePool",
+ "QXmlNamespaceSupport", "QXmlNodeModelIndex", "QXmlParseException",
+ "QXmlQuery", "QXmlReader", "QXmlResultItems", "QXmlSerializer",
+ "QXmlSimpleReader", "QXmlStreamAttribute", "QXmlStreamAttributes",
+ "QXmlStreamEntityDeclaration", "QXmlStreamEntityDeclarations",
+ "QXmlStreamEntityResolver", "QXmlStreamNamespaceDeclaration",
+ "QXmlStreamNamespaceDeclarations", "QXmlStreamNotationDeclaration",
+ "QXmlStreamNotationDeclarations", "QXmlStreamReader",
+ "QXmlStreamStringRef", "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;',
+ '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://doc.trolltech.com/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_]*',
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/cpp.php b/inc/geshi/cpp.php
new file mode 100644
index 000000000..30f5a93f2
--- /dev/null
+++ b/inc/geshi/cpp.php
@@ -0,0 +1,240 @@
+<?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.8.8
+ * 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++',
+ '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(
+ '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'
+ ),
+ ),
+ '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;',
+ '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_\|%\\-])"
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/csharp.php b/inc/geshi/csharp.php
new file mode 100644
index 000000000..6a9c3c2bd
--- /dev/null
+++ b/inc/geshi/csharp.php
@@ -0,0 +1,253 @@
+<?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.8.8
+ * Date Started: 2004/06/04
+ *
+ * C# language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 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(
+ 'as', 'auto', 'base', 'break', 'case', 'catch', 'const', 'continue',
+ 'default', 'do', 'else', 'event', 'explicit', 'extern', 'false',
+ 'finally', 'fixed', 'for', 'foreach', 'from', 'goto', 'if',
+ 'implicit', 'in', 'internal', 'lock', 'namespace', 'null',
+ 'operator', 'out', 'override', 'params', 'partial', 'private',
+ 'protected', 'public', 'readonly', 'ref', 'return', 'sealed',
+ 'select', 'stackalloc', 'static', 'switch', 'this', 'throw', 'true',
+ 'try', 'unsafe', 'using', 'virtual', 'where', 'while', 'yield'
+ ),
+ 2 => array(
+ '#elif', '#endif', '#endregion', '#else', '#error', '#define', '#if',
+ '#line', '#region', '#undef', '#warning'
+ ),
+ 3 => array(
+ 'checked', 'is', 'new', 'sizeof', 'typeof', 'unchecked'
+ ),
+ 4 => array(
+ 'bool', 'byte', 'char', 'class', 'decimal', 'delegate', 'double',
+ '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_%\\-])"
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/css.php b/inc/geshi/css.php
new file mode 100644
index 000000000..51f261486
--- /dev/null
+++ b/inc/geshi/css.php
@@ -0,0 +1,212 @@
+<?php
+/*************************************************************************************
+ * css.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * Date Started: 2004/06/18
+ *
+ * CSS 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)
+ * - 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/psuedoclass 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(1 => '@'),
+ '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' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'aqua', 'azimuth', 'background-attachment', 'background-color',
+ 'background-image', 'background-position', 'background-repeat',
+ 'background', 'black', 'blue', 'border-bottom-color',
+ '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', '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'
+ ),
+ 2 => array(
+ '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', 'fuchsia', 'georgian', 'gray', 'green', 'groove',
+ 'hebrew', 'help', 'hidden', 'hide', 'higher', 'high',
+ 'hiragana-iroha', 'hiragana', 'icon', 'inherit', 'inline-table',
+ 'inline', 'inset', 'inside', 'invert', 'italic', 'justify',
+ 'katakana-iroha', 'katakana', 'landscape', 'larger', 'large',
+ 'left-side', 'leftwards', 'level', 'lighter', 'lime',
+ 'line-through', 'list-item', 'loud', 'lower-alpha', 'lower-greek',
+ 'lower-roman', 'lowercase', 'ltr', 'lower', 'low', 'maroon',
+ 'medium', 'message-box', 'middle', 'mix', 'monospace', 'n-resize',
+ 'narrower', 'navy', 'ne-resize', 'no-close-quote',
+ 'no-open-quote', 'no-repeat', 'none', 'normal', 'nowrap',
+ 'nw-resize', 'oblique', 'olive', 'once', 'open-quote', 'outset',
+ 'outside', 'overline', 'pointer', 'portrait', 'purple', 'px',
+ 'red', 'relative', 'repeat-x', 'repeat-y', 'repeat', 'rgb',
+ 'ridge', 'right-side', 'rightwards', 's-resize', 'sans-serif',
+ 'scroll', 'se-resize', 'semi-condensed', 'semi-expanded',
+ 'separate', 'serif', 'show', 'silent', 'silver', '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', 'teal', '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',
+ 'white', 'wider', 'x-fast', 'x-high', 'x-large', 'x-loud',
+ 'x-low', 'x-small', 'x-soft', 'xx-large', 'xx-small', 'yellow',
+ 'yes'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', ':', ';',
+ '>', '+', '*', ',', '^', '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #993333;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #a1a100;',
+ 2 => 'color: #ff0000; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => '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: #3333ff;',
+ 3 => 'color: #933;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ '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 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|%)',
+ ),
+ '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_\|%\\-&\.])'
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/cuesheet.php b/inc/geshi/cuesheet.php
new file mode 100644
index 000000000..81c607c10
--- /dev/null
+++ b/inc/geshi/cuesheet.php
@@ -0,0 +1,138 @@
+<?php
+/*************************************************************************************
+ * cuesheet.php
+ * ----------
+ * Author: Benny Baumann (benbe@geshi.org)
+ * Copyright: (c) 2009 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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\.])',
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/d.php b/inc/geshi/d.php
new file mode 100644
index 000000000..5ef349d52
--- /dev/null
+++ b/inc/geshi/d.php
@@ -0,0 +1,272 @@
+<?php
+/*************************************************************************************
+ * d.php
+ * -----
+ * Author: Thomas Kuehne (thomas@kuehne.cn)
+ * Copyright: (c) 2005 Thomas Kuehne (http://thomas.kuehne.cn/)
+ * Release Version: 1.0.8.8
+ * Date Started: 2005/04/22
+ *
+ * D language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 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'
+ ),
+ 2 => array(
+ 'alias', 'asm', 'assert', 'body', 'cast',
+ 'catch', 'default', 'delegate', 'delete',
+ 'extern', 'false', 'finally', 'function',
+ 'import', 'in', 'inout', 'interface',
+ 'invariant', 'is', 'mixin', 'module', 'new',
+ 'null', 'out', 'pragma', 'ref', 'super', 'this',
+ 'throw', 'true', 'try', 'typedef', 'typeid',
+ 'typeof', 'union', 'with'
+ ),
+ 3 => array(
+ 'ArrayBoundsError', 'AssertError',
+ 'ClassInfo', 'Error', 'Exception',
+ 'Interface', 'ModuleInfo', 'Object',
+ 'OutOfMemoryException', 'SwitchError',
+ 'TypeInfo', '_d_arrayappend',
+ '_d_arrayappendb', '_d_arrayappendc',
+ '_d_arrayappendcb', '_d_arraycast',
+ '_d_arraycast_frombit', '_d_arraycat',
+ '_d_arraycatb', '_d_arraycatn',
+ '_d_arraycopy', '_d_arraycopybit',
+ '_d_arraysetbit', '_d_arraysetbit2',
+ '_d_arraysetlength', '_d_arraysetlengthb',
+ '_d_callfinalizer',
+ '_d_create_exception_object',
+ '_d_criticalenter', '_d_criticalexit',
+ '_d_delarray', '_d_delclass',
+ '_d_delinterface', '_d_delmemory',
+ '_d_dynamic_cast', '_d_exception',
+ '_d_exception_filter', '_d_framehandler',
+ '_d_interface_cast', '_d_interface_vtbl',
+ '_d_invariant', '_d_isbaseof',
+ '_d_isbaseof2', '_d_local_unwind',
+ '_d_monitorenter', '_d_monitorexit',
+ '_d_monitorrelease', '_d_monitor_epilog',
+ '_d_monitor_handler', '_d_monitor_prolog',
+ '_d_new', '_d_newarrayi', '_d_newbitarray',
+ '_d_newclass', '_d_obj_cmp', '_d_obj_eq',
+ '_d_OutOfMemory', '_d_switch_dstring',
+ '_d_switch_string', '_d_switch_ustring',
+ '_d_throw',
+ ),
+ 4 => array(
+ 'abstract', 'align', 'auto', 'bit', 'bool',
+ 'byte', 'cdouble', 'cent', 'cfloat', 'char',
+ 'class', 'const', 'creal', 'dchar', 'debug',
+ 'deprecated', 'double', 'enum', 'export',
+ 'final', 'float', 'idouble', 'ifloat', 'int',
+ 'ireal', 'long', 'override', 'package',
+ 'private', 'protected', 'ptrdiff_t',
+ 'public', 'real', 'short', 'size_t',
+ 'static', 'struct', 'synchronized',
+ 'template', 'ubyte', 'ucent', 'uint',
+ 'ulong', 'unittest', 'ushort', 'version',
+ 'void', 'volatile', 'wchar'
+ )
+ ),
+ '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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/dcs.php b/inc/geshi/dcs.php
new file mode 100644
index 000000000..4762ed906
--- /dev/null
+++ b/inc/geshi/dcs.php
@@ -0,0 +1,182 @@
+<?php
+/*************************************************************************************
+ * dcs.php
+ * ---------------------------------
+ * Author: Stelio Passaris (GeSHi@stelio.net)
+ * Copyright: (c) 2009 Stelio Passaris (http://stelio.net/stiki/GeSHi)
+ * Release Version: 1.0.8.8
+ * 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/delphi.php b/inc/geshi/delphi.php
new file mode 100644
index 000000000..ff54af8f9
--- /dev/null
+++ b/inc/geshi/delphi.php
@@ -0,0 +1,289 @@
+<?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.8.8
+ * Date Started: 2004/07/26
+ *
+ * Delphi (Object Pascal) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 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' => 0,
+ 'QUOTEMARKS' => array("'"),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'Abstract', 'And', 'Array', 'As', 'Asm', 'At', 'Begin', 'Case',
+ 'Class', 'Const', 'Constructor', 'Contains', 'Destructor',
+ 'DispInterface', 'Div', 'Do', 'DownTo', 'Else', 'End', 'Except',
+ 'Export', 'Exports', 'External', 'File', 'Finalization', 'Finally',
+ 'For', 'Function', 'Goto', 'If', 'Implementation', 'In', 'Inherited',
+ 'Initialization', 'Inline', 'Interface', 'Is', 'Label', 'Library',
+ 'Mod', 'Not', 'Object', 'Of', 'On', 'Or', 'Overload', 'Override',
+ 'Package', 'Packed', 'Private', 'Procedure', 'Program', 'Property',
+ 'Protected', 'Public', 'Published', 'Raise', 'Record', 'Register',
+ 'Repeat', 'Requires', 'Resourcestring', 'Set', 'Shl', 'Shr', 'Then',
+ 'ThreadVar', 'To', 'Try', 'Type', 'Unit', 'Until', 'Uses', 'Var',
+ 'Virtual', 'While', 'With', 'Xor', 'assembler', 'far',
+ 'near', 'pascal', 'cdecl', 'safecall', 'stdcall', 'varargs'
+ ),
+ 2 => array(
+ 'nil', 'false', 'self', 'true', 'var', 'type', 'const'
+ ),
+ 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: #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-9a-fA-F]{1,2}|\d{1,3})'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 2
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/diff.php b/inc/geshi/diff.php
new file mode 100644
index 000000000..5570406da
--- /dev/null
+++ b/inc/geshi/diff.php
@@ -0,0 +1,196 @@
+<?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.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/div.php b/inc/geshi/div.php
new file mode 100644
index 000000000..276e9e882
--- /dev/null
+++ b/inc/geshi/div.php
@@ -0,0 +1,126 @@
+<?php
+/*************************************************************************************
+ * div.php
+ * ---------------------------------
+ * Author: Gabriel Lorenzo (ermakina@gmail.com)
+ * Copyright: (c) 2005 Gabriel Lorenzo (http://ermakina.gazpachito.net)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/dos.php b/inc/geshi/dos.php
new file mode 100644
index 000000000..9484d3766
--- /dev/null
+++ b/inc/geshi/dos.php
@@ -0,0 +1,202 @@
+<?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.8.8
+ * 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"
+ ),
+ '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;',
+ ),
+ '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;'
+ )
+ ),
+ '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)[^\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'
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 4 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)'
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/dot.php b/inc/geshi/dot.php
new file mode 100644
index 000000000..04b6792d7
--- /dev/null
+++ b/inc/geshi/dot.php
@@ -0,0 +1,164 @@
+<?php
+/*************************************************************************************
+ * dot.php
+ * ---------------------------------
+ * Author: Adrien Friggeri (adrien@friggeri.net)
+ * Copyright: (c) 2007 Adrien Friggeri (http://www.friggeri.net)
+ * Release Version: 1.0.8.8
+ * 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
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/ecmascript.php b/inc/geshi/ecmascript.php
new file mode 100644
index 000000000..3e61b57cb
--- /dev/null
+++ b/inc/geshi/ecmascript.php
@@ -0,0 +1,210 @@
+<?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.8.8
+ * 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/eiffel.php b/inc/geshi/eiffel.php
new file mode 100644
index 000000000..89cef7965
--- /dev/null
+++ b/inc/geshi/eiffel.php
@@ -0,0 +1,395 @@
+<?php
+/*************************************************************************************
+ * eiffel.php
+ * ----------
+ * Author: Zoran Simic (zsimic@axarosenberg.com)
+ * Copyright: (c) 2005 Zoran Simic
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/email.php b/inc/geshi/email.php
new file mode 100644
index 000000000..91a104840
--- /dev/null
+++ b/inc/geshi/email.php
@@ -0,0 +1,210 @@
+<?php
+/*************************************************************************************
+ * email.php
+ * ---------------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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(
+ 'Authentication-Results','Content-Description','Content-Type',
+ 'Content-Disposition','Content-Transfer-Encoding','Delivered-To',
+ 'Dkim-Signature','Domainkey-Signature','In-Reply-To','Message-Id',
+ 'MIME-Version','OpenPGP','Received','Received-SPF','References',
+ 'Resend-From','Resend-To','Return-Path','User-Agent'
+ ),
+ 3 => array(
+ 'Date','From','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;',
+ ),
+ '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[\w\.\-]+@\w+(?:(?:\.\w+)*\.\w{2,4})?",
+ 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}(?=<)",
+ 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-Z][a-zA-Z0-9\-]*\s*:\s*(?:.|(?=\n\s)\n)*(?P<end>$)/m"
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ ),
+ '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
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/erlang.php b/inc/geshi/erlang.php
new file mode 100644
index 000000000..d98de2f37
--- /dev/null
+++ b/inc/geshi/erlang.php
@@ -0,0 +1,441 @@
+<?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.8.8
+ * 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 => ''
+ ),
+ // ASCIIcodes
+ 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' => '',
+ 'DISALLOWED_AFTER' => '(?=\s*\()'
+ ),
+ 5 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\'|)',
+ 'DISALLOWED_AFTER' => '(?=(\'|):)'
+ ),
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\/|-)',
+ 'DISALLOWED_AFTER' => ''
+ )
+ )
+ ),
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/fo.php b/inc/geshi/fo.php
new file mode 100644
index 000000000..3a1d24021
--- /dev/null
+++ b/inc/geshi/fo.php
@@ -0,0 +1,327 @@
+<?php
+/*************************************************************************************
+ * fo.php
+ * --------
+ * Author: Tan-Vinh Nguyen (tvnguyen@web.de)
+ * Copyright: (c) 2009 Tan-Vinh Nguyen
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+?> \ No newline at end of file
diff --git a/inc/geshi/fortran.php b/inc/geshi/fortran.php
new file mode 100644
index 000000000..6eac52ae0
--- /dev/null
+++ b/inc/geshi/fortran.php
@@ -0,0 +1,160 @@
+<?php
+/*************************************************************************************
+ * fortran.php
+ * -----------
+ * Author: Cedric Arrabie (cedric.arrabie@univ-pau.fr)
+ * Copyright: (C) 2006 Cetric Arrabie
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/freebasic.php b/inc/geshi/freebasic.php
new file mode 100644
index 000000000..35fc8ca6f
--- /dev/null
+++ b/inc/geshi/freebasic.php
@@ -0,0 +1,141 @@
+<?php
+/*************************************************************************************
+ * freebasic.php
+ * -------------
+ * Author: Roberto Rossi
+ * Copyright: (c) 2005 Roberto Rossi (http://rsoftware.altervista.org)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/fsharp.php b/inc/geshi/fsharp.php
new file mode 100644
index 000000000..56146958c
--- /dev/null
+++ b/inc/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.8.8
+ * 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('(*' => '*)', '/*' => '*/'),
+ '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 */
+ ),
+ '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_<\|%\\-])"
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/gambas.php b/inc/geshi/gambas.php
new file mode 100644
index 000000000..0fc89bb59
--- /dev/null
+++ b/inc/geshi/gambas.php
@@ -0,0 +1,214 @@
+<?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.8.8
+ * 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_\|%\\-&;\$])"
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/gdb.php b/inc/geshi/gdb.php
new file mode 100644
index 000000000..ed7ee2ffa
--- /dev/null
+++ b/inc/geshi/gdb.php
@@ -0,0 +1,175 @@
+<?php
+/*************************************************************************************
+ * gdb.php
+ * --------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2009 Milian Wolff
+ * Release Version: 1.0.8.8
+ * 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' =>
+ GESHI_NUMBER_INT_BASIC,
+ '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(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000066; font-weight:bold;',
+ 1 => 'color: #006600;',
+ 2 => 'color: #000066;',
+ 3 => 'color: #0066FF; text-style:italic;',
+ 4 => 'color: #80B5FF; text-style:italic;',
+ 5 => 'color: #A3007D;',
+ 6 => 'color: #FF00BF;',
+ 7 => 'font-weight: bold;'
+ ),
+ '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 )(.+)(:\d+\s*)$',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ //Libs without linenumbers
+ 4 => array(
+ GESHI_SEARCH => '(from )(.+)(\s*)$',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ //Hex mem address
+ 5 => '0x[a-f0-9]+',
+ //Line numbers
+ 6 => array(
+ GESHI_SEARCH => '(:)(\d+)(\s*)$',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ //Location
+ 7 => array(
+ GESHI_SEARCH => '( in )([^ \(\)]+)( \()',
+ 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/inc/geshi/genero.php b/inc/geshi/genero.php
new file mode 100644
index 000000000..a7ccf5fee
--- /dev/null
+++ b/inc/geshi/genero.php
@@ -0,0 +1,463 @@
+<?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.8.8
+ * 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/inc/geshi/genie.php b/inc/geshi/genie.php
new file mode 100644
index 000000000..66bea6dc7
--- /dev/null
+++ b/inc/geshi/genie.php
@@ -0,0 +1,157 @@
+<?php
+/*************************************************************************************
+ * genie.php
+ * ----------
+ * Author: Nicolas Joseph (nicolas.joseph@valaide.org)
+ * Copyright: (c) 2009 Nicolas Joseph
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/gettext.php b/inc/geshi/gettext.php
new file mode 100644
index 000000000..e1c88e185
--- /dev/null
+++ b/inc/geshi/gettext.php
@@ -0,0 +1,97 @@
+<?php
+/*************************************************************************************
+ * gettext.php
+ * --------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/glsl.php b/inc/geshi/glsl.php
new file mode 100644
index 000000000..f9a37ed07
--- /dev/null
+++ b/inc/geshi/glsl.php
@@ -0,0 +1,205 @@
+<?php
+/*************************************************************************************
+ * glsl.php
+ * -----
+ * Author: Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2008 Benny Baumann (BenBE@omorphia.de)
+ * Release Version: 1.0.8.8
+ * 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]*'
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/gml.php b/inc/geshi/gml.php
new file mode 100644
index 000000000..3f8a06c4f
--- /dev/null
+++ b/inc/geshi/gml.php
@@ -0,0 +1,506 @@
+<?php
+/*************************************************************************************
+ * gml.php
+ * --------
+ * Author: Jos� Jorge Enr�quez (jenriquez@users.sourceforge.net)
+ * Copyright: (c) 2005 Jos� Jorge Enr�quez Rodr�guez (http://www.zonamakers.com)
+ * Release Version: 1.0.8.8
+ * 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(
+ // language keywords
+ 1 => array(
+ 'break', 'continue', 'do', 'until', 'if', 'else',
+ 'exit', 'for', 'repeat', 'return', 'switch',
+ 'case', 'default', 'var', 'while', 'with', 'div', 'mod',
+ // GML Language overview
+ 'self', 'other', 'all', 'noone', 'global',
+ ),
+ // modifiers and built-in variables
+ 2 => array(
+ // Game play
+ 'x','y','xprevious','yprevious','xstart','ystart','hspeed','vspeed','direction','speed',
+ 'friction','gravity','gravity_direction',
+ 'path_index','path_position','path_positionprevious','path_speed','path_orientation',
+ 'path_endaction',
+ 'object_index','id','mask_index','solid','persistent','instance_count','instance_id',
+ 'room_speed','fps','current_time','current_year','current_month','current_day','current_weekday',
+ 'current_hour','current_minute','current_second','alarm','timeline_index','timeline_position',
+ 'timeline_speed',
+ 'room','room_first','room_last','room_width','room_height','room_caption','room_persistent',
+ 'score','lives','health','show_score','show_lives','show_health','caption_score','caption_lives',
+ 'caption_health',
+ 'event_type','event_number','event_object','event_action',
+ 'error_occurred','error_last',
+ // User interaction
+ 'keyboard_lastkey','keyboard_key','keyboard_lastchar','keyboard_string',
+ 'mouse_x','mouse_y','mouse_button','mouse_lastbutton',
+ // Game Graphics
+ 'sprite_index','sprite_width','sprite_height','sprite_xoffset','sprite_yoffset',
+ 'image_number','image_index','image_speed','image_xscale','image_yscale','image_angle',
+ 'image_alpha','image_blend','bbox_left','bbox_right','bbox_top','bbox_bottom',
+ 'background_color','background_showcolor','background_visible','background_foreground',
+ 'background_index','background_x','background_y','background_width','background_height',
+ 'background_htiled','background_vtiled','background_xscale','background_yscale',
+ 'background_hspeed','background_vspeed','background_blend','background_alpha',
+ 'background','left, top, width, height','depth','visible','xscale','yscale','blend','alpha',
+ 'view_enabled','view_current','view_visible','view_yview','view_wview','view_hview','view_xport',
+ 'view_yport','view_wport','view_hport','view_angle','view_hborder','view_vborder','view_hspeed',
+ 'view_vspeed','view_object',
+ 'transition_kind',
+ // Files, registry and executing programs
+ 'game_id','working_directory','temp_directory',
+ 'secure_mode',
+ // Creating particles
+ 'xmin', 'xmax', 'ymin', 'ymax','shape','distribution','particle type','number',
+ 'force','dist','kind','additive', 'parttype1', 'parttype2'
+ ),
+ // functions
+ 3 => array(
+ // Computing things
+ 'random','choose','abs','sign','round','floor','ceil','frac','sqrt','sqr','power','exp','ln',
+ 'log2','log10','logn','sin','cos','tan','arcsin','arccos','arctan','arctan2','degtorad',
+ 'radtodeg','min','max','mean','median','point_distance','point_direction','lengthdir_x',
+ 'lengthdir_y','is_real','is_string',
+ 'chr','ord','real','string','string_format','string_length','string_pos','string_copy',
+ 'string_char_at','string_delete','string_insert','string_replace','string_replace_all',
+ 'string_count','string_lower','string_upper','string_repeat','string_letters','string_digits',
+ 'string_lettersdigits','clipboard_has_text','clipboard_get_text','clipboard_set_text',
+ 'date_current_datetime','date_current_date','date_current_time','date_create_datetime',
+ 'date_create_date','date_create_time','date_valid_datetime','date_valid_date','date_valid_time',
+ 'date_inc_year','date_inc_month','date_inc_week','date_inc_day','date_inc_hour',
+ 'date_inc_minute','date_inc_second','date_get_year','date_get_month','date_get_week',
+ 'date_get_day','date_get_hour', 'date_get_minute','date_get_second','date_get_weekday',
+ 'date_get_day_of_year','date_get_hour_of_year','date_get_minute_of_year',
+ 'date_get_second_of_year','date_year_span','date_month_span','date_week_span','date_day_span',
+ 'date_hour_span','date_minute_span','date_second_span','date_compare_datetime',
+ 'date_compare_date','date_compare_time','date_date_of','date_time_of','date_datetime_string',
+ 'date_date_string','date_time_string','date_days_in_month','date_days_in_year','date_leap_year',
+ 'date_is_today',
+ // Game play
+ 'motion_set','motion_add','place_free','place_empty','place_meeting','place_snapped',
+ 'move_random','move_snap','move_wrap','move_towards_point','move_bounce_solid','move_bounce_all',
+ 'move_contact_solid','move_contact_all','move_outside_solid','move_outside_all',
+ 'distance_to_point','distance_to_object','position_empty','position_meeting',
+ 'path_start','path_end',
+ 'mp_linear_step','mp_linear_step_object','mp_potential_step','mp_potential_step_object',
+ 'mp_potential_settings','mp_linear_path','mp_linear_path_object', 'mp_potential_path',
+ 'mp_potential_path_object','mp_grid_create','mp_grid_destroy','mp_grid_clear_all',
+ 'mp_grid_clear_cell','mp_grid_clear_rectangle','mp_grid_add_cell','mp_grid_add_rectangle',
+ 'mp_grid_add_instances','mp_grid_path','mp_grid_draw',
+ 'collision_point','collision_rectangle','collision_circle','collision_ellipse','collision_line',
+ 'instance_find','instance_exists','instance_number','instance_position','instance_nearest',
+ 'instance_furthest','instance_place','instance_create','instance_copy','instance_destroy',
+ 'instance_change','position_destroy','position_change',
+ 'instance_deactivate_all','instance_deactivate_object','instance_deactivate_region',
+ 'instance_activate_all','instance_activate_object','instance_activate_region',
+ 'sleep',
+ 'room_goto','room_goto_previous','room_goto_next','room_restart','room_previous','room_next',
+ 'game_end','game_restart','game_save','game_load',
+ 'event_perform', 'event_perform_object','event_user','event_inherited',
+ 'show_debug_message','variable_global_exists','variable_local_exists','variable_global_get',
+ 'variable_global_array_get','variable_global_array2_get','variable_local_get',
+ 'variable_local_array_get','variable_local_array2_get','variable_global_set',
+ 'variable_global_array_set','variable_global_array2_set','variable_local_set',
+ 'variable_local_array_set','variable_local_array2_set','set_program_priority',
+ // User interaction
+ 'keyboard_set_map','keyboard_get_map','keyboard_unset_map','keyboard_check',
+ 'keyboard_check_pressed','keyboard_check_released','keyboard_check_direct',
+ 'keyboard_get_numlock','keyboard_set_numlock','keyboard_key_press','keyboard_key_release',
+ 'keyboard_clear','io_clear','io_handle','keyboard_wait',
+ 'mouse_check_button','mouse_check_button_pressed','mouse_check_button_released','mouse_clear',
+ 'mouse_wait',
+ 'joystick_exists','joystick_name','joystick_axes','joystick_buttons','joystick_has_pov',
+ 'joystick_direction','joystick_check_button','joystick_xpos','joystick_ypos','joystick_zpos',
+ 'joystick_rpos','joystick_upos','joystick_vpos','joystick_pov',
+ // Game Graphics
+ 'draw_sprite','draw_sprite_stretched','draw_sprite_tiled','draw_sprite_part','draw_background',
+ 'draw_background_stretched','draw_background_tiled','draw_background_part','draw_sprite_ext',
+ 'draw_sprite_stretched_ext','draw_sprite_tiled_ext','draw_sprite_part_ext','draw_sprite_general',
+ 'draw_background_ext','draw_background_stretched_ext','draw_background_tiled_ext',
+ 'draw_background_part_ext','draw_background_general',
+ 'draw_clear','draw_clear_alpha','draw_point','draw_line','draw_rectangle','draw_roundrect',
+ 'draw_triangle','draw_circle','draw_ellipse','draw_arrow','draw_button','draw_path',
+ 'draw_healthbar','draw_set_color','draw_set_alpha','draw_get_color','draw_get_alpha',
+ 'make_color_rgb','make_color_hsv','color_get_red','color_get_green','color_get_blue',
+ 'color_get_hue','color_get_saturation','color_get_value','merge_color','draw_getpixel',
+ 'screen_save','screen_save_part',
+ 'draw_set_font','draw_set_halign','draw_set_valign','draw_text','draw_text_ext','string_width',
+ 'string_height','string_width_ext','string_height_ext','draw_text_transformed',
+ 'draw_text_ext_transformed','draw_text_color','draw_text_ext_color',
+ 'draw_text_transformed_color','draw_text_ext_transformed_color',
+ 'draw_point_color','draw_line_color','draw_rectangle_color','draw_roundrect_color',
+ 'draw_triangle_color','draw_circle_color','draw_ellipse_color','draw_primitive_begin',
+ 'draw_vertex','draw_vertex_color','draw_primitive_end','sprite_get_texture',
+ 'background_get_texture','texture_preload','texture_set_priority',
+ 'texture_get_width','texture_get_height','draw_primitive_begin_texture','draw_vertex_texture',
+ 'draw_vertex_texture_color','texture_set_interpolation',
+ 'texture_set_blending','texture_set_repeat','draw_set_blend_mode','draw_set_blend_mode_ext',
+ 'surface_create','surface_free','surface_exists','surface_get_width','surface_get_height',
+ 'surface_get_texture','surface_set_target','surface_reset_target','surface_getpixel',
+ 'surface_save','surface_save_part','draw_surface','draw_surface_stretched','draw_surface_tiled',
+ 'draw_surface_part','draw_surface_ext','draw_surface_stretched_ext','draw_surface_tiled_ext',
+ 'draw_surface_part_ext','draw_surface_general','surface_copy','surface_copy_part',
+ 'tile_add','tile_delete','tile_exists','tile_get_x','tile_get_y','tile_get_left','tile_get_top',
+ 'tile_get_width','tile_get_height','tile_get_depth','tile_get_visible','tile_get_xscale',
+ 'tile_get_yscale','tile_get_background','tile_get_blend','tile_get_alpha','tile_set_position',
+ 'tile_set_region','tile_set_background','tile_set_visible','tile_set_depth','tile_set_scale',
+ 'tile_set_blend','tile_set_alpha','tile_layer_hide','tile_layer_show','tile_layer_delete',
+ 'tile_layer_shift','tile_layer_find','tile_layer_delete_at','tile_layer_depth',
+ 'display_get_width','display_get_height','display_get_colordepth','display_get_frequency',
+ 'display_set_size','display_set_colordepth','display_set_frequency','display_set_all',
+ 'display_test_all','display_reset','display_mouse_get_x','display_mouse_get_y','display_mouse_set',
+ 'window_set_visible','window_get_visible','window_set_fullscreen','window_get_fullscreen',
+ 'window_set_showborder','window_get_showborder','window_set_showicons','window_get_showicons',
+ 'window_set_stayontop','window_get_stayontop','window_set_sizeable','window_get_sizeable',
+ 'window_set_caption','window_get_caption','window_set_cursor', 'window_get_cursor',
+ 'window_set_color','window_get_color','window_set_region_scale','window_get_region_scale',
+ 'window_set_position','window_set_size','window_set_rectangle','window_center','window_default',
+ 'window_get_x','window_get_y','window_get_width','window_get_height','window_mouse_get_x',
+ 'window_mouse_get_y','window_mouse_set',
+ 'window_set_region_size','window_get_region_width','window_get_region_height',
+ 'window_view_mouse_get_x','window_view_mouse_get_y','window_view_mouse_set',
+ 'window_views_mouse_get_x','window_views_mouse_get_y','window_views_mouse_set',
+ 'screen_redraw','screen_refresh','set_automatic_draw','set_synchronization','screen_wait_vsync',
+ // Sound and music)
+ 'sound_play','sound_loop','sound_stop','sound_stop_all','sound_isplaying','sound_volume',
+ 'sound_global_volume','sound_fade','sound_pan','sound_background_tempo','sound_set_search_directory',
+ 'sound_effect_set','sound_effect_chorus','sound_effect_echo', 'sound_effect_flanger',
+ 'sound_effect_gargle','sound_effect_reverb','sound_effect_compressor','sound_effect_equalizer',
+ 'sound_3d_set_sound_position','sound_3d_set_sound_velocity','sound_3d_set_sound_distance',
+ 'sound_3d_set_sound_cone',
+ 'cd_init','cd_present','cd_number','cd_playing','cd_paused','cd_track','cd_length',
+ 'cd_track_length','cd_position','cd_track_position','cd_play','cd_stop','cd_pause','cd_resume',
+ 'cd_set_position','cd_set_track_position','cd_open_door','cd_close_door','MCI_command',
+ // Splash screens, highscores, and other pop-ups
+ 'show_text','show_image','show_video','show_info','load_info',
+ 'show_message','show_message_ext','show_question','get_integer','get_string',
+ 'message_background','message_alpha','message_button','message_text_font','message_button_font',
+ 'message_input_font','message_mouse_color','message_input_color','message_caption',
+ 'message_position','message_size','show_menu','show_menu_pos','get_color','get_open_filename',
+ 'get_save_filename','get_directory','get_directory_alt','show_error',
+ 'highscore_show','highscore_set_background','highscore_set_border','highscore_set_font',
+ 'highscore_set_colors','highscore_set_strings','highscore_show_ext','highscore_clear',
+ 'highscore_add','highscore_add_current','highscore_value','highscore_name','draw_highscore',
+ // Resources
+ 'sprite_exists','sprite_get_name','sprite_get_number','sprite_get_width','sprite_get_height',
+ 'sprite_get_transparent','sprite_get_smooth','sprite_get_preload','sprite_get_xoffset',
+ 'sprite_get_yoffset','sprite_get_bbox_left','sprite_get_bbox_right','sprite_get_bbox_top',
+ 'sprite_get_bbox_bottom','sprite_get_bbox_mode','sprite_get_precise',
+ 'sound_exists','sound_get_name','sound_get_kind','sound_get_preload','sound_discard',
+ 'sound_restore',
+ 'background_exists','background_get_name','background_get_width','background_get_height',
+ 'background_get_transparent','background_get_smooth','background_get_preload',
+ 'font_exists','font_get_name','font_get_fontname','font_get_bold','font_get_italic',
+ 'font_get_first','font_get_last',
+ 'path_exists','path_get_name','path_get_length','path_get_kind','path_get_closed',
+ 'path_get_precision','path_get_number','path_get_point_x','path_get_point_y',
+ 'path_get_point_speed','path_get_x','path_get_y','path_get_speed',
+ 'script_exists','script_get_name','script_get_text',
+ 'timeline_exists','timeline_get_name',
+ 'object_exists','object_get_name','object_get_sprite','object_get_solid','object_get_visible',
+ 'object_get_depth','object_get_persistent','object_get_mask','object_get_parent',
+ 'object_is_ancestor',
+ 'room_exists','room_get_name',
+ // Changing resources
+ 'sprite_set_offset','sprite_set_bbox_mode','sprite_set_bbox','sprite_set_precise',
+ 'sprite_duplicate','sprite_assign','sprite_merge','sprite_add','sprite_replace',
+ 'sprite_create_from_screen','sprite_add_from_screen','sprite_create_from_surface',
+ 'sprite_add_from_surface','sprite_delete','sprite_set_alpha_from_sprite',
+ 'sound_add','sound_replace','sound_delete',
+ 'background_duplicate','background_assign','background_add','background_replace',
+ 'background_create_color','background_create_gradient','background_create_from_screen',
+ 'background_create_from_surface','background_delete','background_set_alpha_from_background',
+ 'font_add','font_add_sprite','font_replace_sprite','font_delete',
+ 'path_set_kind','path_set_closed','path_set_precision','path_add','path_delete','path_duplicate',
+ 'path_assign','path_append','path_add_point','path_insert_point','path_change_point',
+ 'path_delete_point','path_clear_points','path_reverse','path_mirror','path_flip','path_rotate',
+ 'path_scale','path_shift',
+ 'execute_string','execute_file','script_execute',
+ 'timeline_add','timeline_delete','timeline_moment_add','timeline_moment_clear',
+ 'object_set_sprite','object_set_solid','object_set_visible','object_set_depth',
+ 'object_set_persistent','object_set_mask','object_set_parent','object_add','object_delete',
+ 'object_event_add','object_event_clear',
+ 'room_set_width','room_set_height','room_set_caption','room_set_persistent','room_set_code',
+ 'room_set_background_color','room_set_background','room_set_view','room_set_view_enabled',
+ 'room_add','room_duplicate','room_assign','room_instance_add','room_instance_clear',
+ 'room_tile_add','room_tile_add_ext','room_tile_clear',
+ // Files, registry and executing programs
+ 'file_text_open_read','file_text_open_write','file_text_open_append','file_text_close',
+ 'file_text_write_string','file_text_write_real','file_text_writeln','file_text_read_string',
+ 'file_text_read_real','file_text_readln','file_text_eof','file_exists','file_delete',
+ 'file_rename','file_copy','directory_exists','directory_create','file_find_first',
+ 'file_find_next','file_find_close','file_attributes', 'filename_name','filename_path',
+ 'filename_dir','filename_drive','filename_ext','filename_change_ext','file_bin_open',
+ 'file_bin_rewrite','file_bin_close','file_bin_size','file_bin_position','file_bin_seek',
+ 'file_bin_write_byte','file_bin_read_byte','parameter_count','parameter_string',
+ 'environment_get_variable',
+ 'registry_write_string','registry_write_real','registry_read_string','registry_read_real',
+ 'registry_exists','registry_write_string_ext','registry_write_real_ext',
+ 'registry_read_string_ext','registry_read_real_ext','registry_exists_ext','registry_set_root',
+ 'ini_open','ini_close','ini_read_string','ini_read_real','ini_write_string','ini_write_real',
+ 'ini_key_exists','ini_section_exists','ini_key_delete','ini_section_delete',
+ 'execute_program','execute_shell',
+ // Data structures
+ 'ds_stack_create','ds_stack_destroy','ds_stack_clear','ds_stack_size','ds_stack_empty',
+ 'ds_stack_push','ds_stack_pop','ds_stack_top',
+ 'ds_queue_create','ds_queue_destroy','ds_queue_clear','ds_queue_size','ds_queue_empty',
+ 'ds_queue_enqueue','ds_queue_dequeue','ds_queue_head','ds_queue_tail',
+ 'ds_list_create','ds_list_destroy','ds_list_clear','ds_list_size','ds_list_empty','ds_list_add',
+ 'ds_list_insert','ds_list_replace','ds_list_delete','ds_list_find_index','ds_list_find_value',
+ 'ds_list_sort',
+ 'ds_map_create','ds_map_destroy','ds_map_clear','ds_map_size','ds_map_empty','ds_map_add',
+ 'ds_map_replace','ds_map_delete','ds_map_exists','ds_map_find_value','ds_map_find_previous',
+ 'ds_map_find_next','ds_map_find_first','ds_map_find_last',
+ 'ds_priority_create','ds_priority_destroy','ds_priority_clear','ds_priority_size',
+ 'ds_priority_empty','ds_priority_add','ds_priority_change_priority','ds_priority_find_priority',
+ 'ds_priority_delete_value','ds_priority_delete_min','ds_priority_find_min',
+ 'ds_priority_delete_max','ds_priority_find_max',
+ 'ds_grid_create','ds_grid_destroy','ds_grid_resize','ds_grid_width','ds_grid_height',
+ 'ds_grid_clear','ds_grid_set','ds_grid_add','ds_grid_multiply','ds_grid_set_region',
+ 'ds_grid_add_region','ds_grid_multiply_region','ds_grid_set_disk','ds_grid_add_disk',
+ 'ds_grid_multiply_disk','ds_grid_get','ds_grid_get_sum','ds_grid_get_max','ds_grid_get_min',
+ 'ds_grid_get_mean','ds_grid_get_disk_sum','ds_grid_get_disk_min','ds_grid_get_disk_max',
+ 'ds_grid_get_disk_mean','ds_grid_value_exists','ds_grid_value_x','ds_grid_value_y',
+ 'ds_grid_value_disk_exists','ds_grid_value_disk_x','ds_grid_value_disk_y',
+ // Creating particles
+ 'effect_create_below','effect_create_above','effect_clear',
+ 'part_type_create','part_type_destroy','part_type_exists','part_type_clear','part_type_shape',
+ 'part_type_sprite','part_type_size','part_type_scale',
+ 'part_type_orientation','part_type_color1','part_type_color2','part_type_color3',
+ 'part_type_color_mix','part_type_color_rgb','part_type_color_hsv',
+ 'part_type_alpha1','part_type_alpha2','part_type_alpha3','part_type_blend','part_type_life',
+ 'part_type_step','part_type_death','part_type_speed','part_type_direction','part_type_gravity',
+ 'part_system_create','part_system_destroy','part_system_exists','part_system_clear',
+ 'part_system_draw_order','part_system_depth','part_system_position',
+ 'part_system_automatic_update','part_system_automatic_draw','part_system_update',
+ 'part_system_drawit','part_particles_create','part_particles_create_color',
+ 'part_particles_clear','part_particles_count',
+ 'part_emitter_create','part_emitter_destroy','part_emitter_destroy_all','part_emitter_exists',
+ 'part_emitter_clear','part_emitter_region','part_emitter_burst','part_emitter_stream',
+ 'part_attractor_create','part_attractor_destroy','part_attractor_destroy_all',
+ 'part_attractor_exists','part_attractor_clear','part_attractor_position','part_attractor_force',
+ 'part_destroyer_create','part_destroyer_destroy','part_destroyer_destroy_all',
+ 'part_destroyer_exists','part_destroyer_clear','part_destroyer_region',
+ 'part_deflector_create','part_deflector_destroy','part_deflector_destroy_all',
+ 'part_deflector_exists','part_deflector_clear','part_deflector_region','part_deflector_kind',
+ 'part_deflector_friction',
+ 'part_changer_create','part_changer_destroy','part_changer_destroy_all','part_changer_exists',
+ 'part_changer_clear','part_changer_region','part_changer_types','part_changer_kind',
+ // Multiplayer games
+ 'mplay_init_ipx','mplay_init_tcpip','mplay_init_modem','mplay_init_serial',
+ 'mplay_connect_status','mplay_end','mplay_ipaddress',
+ 'mplay_session_create','mplay_session_find','mplay_session_name','mplay_session_join',
+ 'mplay_session_mode','mplay_session_status','mplay_session_end',
+ 'mplay_player_find','mplay_player_name','mplay_player_id',
+ 'mplay_data_write','mplay_data_read','mplay_data_mode',
+ 'mplay_message_send','mplay_message_send_guaranteed','mplay_message_receive','mplay_message_id',
+ 'mplay_message_value','mplay_message_player','mplay_message_name','mplay_message_count',
+ 'mplay_message_clear',
+ // Using DLL's
+ 'external_define','external_call','external_free','window_handle',
+ // 3D Graphics
+ 'd3d_start','d3d_end','d3d_set_hidden','d3d_set_perspective',
+ 'd3d_set_depth',
+ 'd3d_primitive_begin','d3d_vertex','d3d_vertex_color','d3d_primitive_end',
+ 'd3d_primitive_begin_texture','d3d_vertex_texture','d3d_vertex_texture_color','d3d_set_culling',
+ 'd3d_draw_block','d3d_draw_cylinder','d3d_draw_cone','d3d_draw_ellipsoid','d3d_draw_wall',
+ 'd3d_draw_floor',
+ 'd3d_set_projection','d3d_set_projection_ext','d3d_set_projection_ortho',
+ 'd3d_set_projection_perspective',
+ 'd3d_transform_set_identity','d3d_transform_set_translation','d3d_transform_set_scaling',
+ 'd3d_transform_set_rotation_x','d3d_transform_set_rotation_y','d3d_transform_set_rotation_z',
+ 'd3d_transform_set_rotation_axis','d3d_transform_add_translation','d3d_transform_add_scaling',
+ 'd3d_transform_add_rotation_x','d3d_transform_add_rotation_y','d3d_transform_add_rotation_z',
+ 'd3d_transform_add_rotation_axis','d3d_transform_stack_clear','d3d_transform_stack_empty',
+ 'd3d_transform_stack_push','d3d_transform_stack_pop','d3d_transform_stack_top',
+ 'd3d_transform_stack_discard',
+ 'd3d_set_fog',
+ 'd3d_set_lighting','d3d_set_shading','d3d_light_define_direction','d3d_light_define_point',
+ 'd3d_light_enable','d3d_vertex_normal','d3d_vertex_normal_color','d3d_vertex_normal_texture',
+ 'd3d_vertex_normal_texture_color',
+ 'd3d_model_create','d3d_model_destroy','d3d_model_clear','d3d_model_save','d3d_model_load',
+ 'd3d_model_draw','d3d_model_primitive_begin','d3d_model_vertex','d3d_model_vertex_color',
+ 'd3d_model_vertex_texture','d3d_model_vertex_texture_color','d3d_model_vertex_normal',
+ 'd3d_model_vertex_normal_color','d3d_model_vertex_normal_texture',
+ 'd3d_model_vertex_normal_texture_color','d3d_model_primitive_end','d3d_model_block',
+ 'd3d_model_cylinder','d3d_model_cone','d3d_model_ellipsoid','d3d_model_wall','d3d_model_floor'
+ ),
+ // constants
+ 4 => array(
+ 'true', 'false', 'pi',
+ 'ev_destroy','ev_step','ev_alarm','ev_keyboard','ev_mouse','ev_collision','ev_other','ev_draw',
+ 'ev_keypress','ev_keyrelease','ev_left_button','ev_right_button','ev_middle_button',
+ 'ev_no_button','ev_left_press','ev_right_press','ev_middle_press','ev_left_release',
+ 'ev_right_release','ev_middle_release','ev_mouse_enter','ev_mouse_leave','ev_mouse_wheel_up',
+ 'ev_mouse_wheel_down','ev_global_left_button','ev_global_right_button','ev_global_middle_button',
+ 'ev_global_left_press','ev_global_right_press','ev_global_middle_press','ev_global_left_release',
+ 'ev_global_right_release','ev_global_middle_release','ev_joystick1_left','ev_joystick1_right',
+ 'ev_joystick1_up','ev_joystick1_down','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_joystick2_left','ev_joystick2_right',
+ 'ev_joystick2_up','ev_joystick2_down','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_outside','ev_boundary','ev_game_start','ev_game_end','ev_room_start','ev_room_end',
+ 'ev_no_more_lives','ev_no_more_health','ev_animation_end','ev_end_of_path','ev_user0','ev_user1',
+ 'ev_user2','ev_user3','ev_user4','ev_user5','ev_user6','ev_user7','ev_user8','ev_user9',
+ 'ev_user10','ev_user11','ev_user12','ev_user13','ev_user14','ev_user15','ev_step_normal',
+ 'ev_step_begin','ev_step_end',
+ 'vk_nokey','vk_anykey','vk_left','vk_right','vk_up','vk_down','vk_enter','vk_escape','vk_space',
+ 'vk_shift','vk_control','vk_alt','vk_backspace','vk_tab','vk_home','vk_end','vk_delete',
+ 'vk_insert','vk_pageup','vk_pagedown','vk_pause','vk_printscreen',
+ 'vk_f1','vk_f2','vk_f3','vk_f4','vk_f5','vk_f6','vk_f7','vk_f8','vk_f9','vk_f10','vk_f11','vk_f12',
+ 'vk_numpad0','vk_numpad1','vk_numpad2','vk_numpad3','vk_numpad4','vk_numpad5','vk_numpad6',
+ 'vk_numpad7','vk_numpad8','vk_numpad9', 'vk_multiply','vk_divide','vk_add','vk_subtract',
+ 'vk_decimal','vk_lshift','vk_lcontrol','vk_lalt','vk_rshift','vk_rcontrol','vk_ralt',
+ '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_purple','c_red','c_silver','c_teal','c_white','c_yellow',
+ 'fa_left', 'fa_center','fa_right','fa_top','fa_middle','fa_bottom',
+ 'pr_pointlist','pr_linelist','pr_linestrip','pr_trianglelist','pr_trianglestrip',
+ 'pr_trianglefan',
+ 'cr_none','cr_arrow','cr_cross','cr_beam','cr_size_nesw','cr_size_ns','cr_size_nwse',
+ 'cr_size_we','cr_uparrow','cr_hourglass','cr_drag','cr_nodrop','cr_hsplit','cr_vsplit',
+ 'cr_multidrag','cr_sqlwait','cr_no','cr_appstart','cr_help','cr_handpoint','cr_size_all',
+ 'se_chorus','se_echo','se_flanger','se_gargle','se_reverb','se_compressor','se_equalizer',
+ 'fa_readonly','fa_hidden','fa_sysfile','fa_volumeid','fa_directory','fa_archive',
+ 'pt_shape_pixel','pt_shape_disk','pt_shape_square','pt_shape_line','pt_shape_star',
+ 'pt_shape_circle','pt_shape_ring','pt_shape_sphere','pt_shape_flare','pt_shape_spark',
+ 'pt_shape_explosion','pt_shape_cloud','pt_shape_smoke','pt_shape_snow',
+ 'ps_shape_rectangle','ps_shape_ellipse ','ps_shape_diamond','ps_shape_line',
+ 'ps_distr_linear','ps_distr_gaussian','ps_force_constant','ps_force_linear','ps_force_quadratic',
+ 'ps_deflect_horizontal', 'ps_deflect_vertical',
+ 'ps_change_motion','ps_change_shape','ps_change_all'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']',
+ '&&', '||', '^^', '&', '|', '^',
+ '<', '<=', '==', '!=', '>', '>=', '=',
+ '<<', '>>',
+ '+=', '-=', '*=', '/=',
+ '+', '-', '*', '/',
+ '!', '~', ',', ';'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'font-weight: bold; color: #000000;',
+ 2 => 'font-weight: bold; color: #000000;',
+ 3 => 'color: navy;',
+ 4 => 'color: #663300;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'font-style: italic; color: green;',
+ 'MULTI' => 'font-style: italic; color: green;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;' //'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66; font-weight: bold;'
+ ),
+ '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/inc/geshi/gnuplot.php b/inc/geshi/gnuplot.php
new file mode 100644
index 000000000..980561d35
--- /dev/null
+++ b/inc/geshi/gnuplot.php
@@ -0,0 +1,296 @@
+<?php
+/*************************************************************************************
+ * gnuplot.php
+ * ----------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff (http://milianw.de)
+ * Release Version: 1.0.8.8
+ * 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/groovy.php b/inc/geshi/groovy.php
new file mode 100644
index 000000000..f2a2e9ab5
--- /dev/null
+++ b/inc/geshi/groovy.php
@@ -0,0 +1,1011 @@
+<?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.8.8
+ * 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%3Adocs.codehaus.org/%20{FNAMEL}',
+ 2 => 'http://www.google.de/search?q=site%3Adocs.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%3Adocs.codehaus.org/%20{FNAME}',
+ 5 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}',
+ 6 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}',
+ 7 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}',
+ 8 => 'http://www.google.de/search?q=site%3Adocs.codehaus.org/%20{FNAME}',
+ 9 => 'http://www.google.de/search?q=site%3Adocs.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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/gwbasic.php b/inc/geshi/gwbasic.php
new file mode 100644
index 000000000..7b2385de7
--- /dev/null
+++ b/inc/geshi/gwbasic.php
@@ -0,0 +1,153 @@
+<?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.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/haskell.php b/inc/geshi/haskell.php
new file mode 100644
index 000000000..4997a26c3
--- /dev/null
+++ b/inc/geshi/haskell.php
@@ -0,0 +1,202 @@
+<?php
+/*************************************************************************************
+ * haskell.php
+ * ----------
+ * Author: Jason Dagit (dagit@codersbase.com) based on ocaml.php by Flaie (fireflaie@gmail.com)
+ * Copyright: (c) 2005 Flaie, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * Date Started: 2005/08/27
+ *
+ * Haskell 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' => '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 librarys, 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', 'teakWhile', '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'
+ ),
+ /* here Prelude Types */
+ 4 => array (
+ 'Bool', 'Maybe', 'Either', 'Ord', 'Ordering',
+ 'Char', 'String', 'Eq', 'Enum', 'Bounded',
+ 'Int', 'Integer', 'Float', 'Double', 'Rational',
+ 'Num', 'Real', 'Integral', 'Fractional',
+ 'Floating', 'RealFrac', 'RealFloat', 'Monad',
+ 'Functor', 'Show', 'ShowS', 'Read', 'ReadS',
+ 'IO'
+ ),
+ /* finally Prelude Exceptions */
+ 5 => array (
+ 'IOError', 'IOException'
+ )
+ ),
+ /* highlighting symbols is really important in Haskell */
+ 'SYMBOLS' => array(
+ '|', '->', '<-', '@', '!', '::', '_', '~', '=', '?',
+ '&&', '||', '==', '/=', '<', '<=', '>',
+ '>=','+', '-', '*','/', '%', '**', '^', '^^',
+ '>>=', '>>', '=<<', '$', '.', ',', '$!',
+ '++', '!!'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true, /* functions name are case seinsitive */
+ 3 => true, /* types name too */
+ 4 => true, /* finally exceptions too */
+ 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;'
+ ),
+ '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 => 'background-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://haskell.org/ghc/docs/latest/html/libraries/base/{FNAME}.html',
+ /* link to Prelude functions */
+ 3 => 'http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:{FNAME}',
+ /* link to Prelude types */
+ 4 => 'http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:{FNAME}',
+ /* link to Prelude exceptions */
+ 5 => 'http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:{FNAME}',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/hicest.php b/inc/geshi/hicest.php
new file mode 100644
index 000000000..6cb61f87c
--- /dev/null
+++ b/inc/geshi/hicest.php
@@ -0,0 +1,108 @@
+<?php
+/*************************************************************************************
+ * hicest.php
+ * --------
+ * Author: Georg Petrich (spt@hicest.com)
+ * Copyright: (c) 2010 Georg Petrich (http://www.HicEst.com)
+ * Release Version: 1.0.8.8
+ * 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()
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/hq9plus.php b/inc/geshi/hq9plus.php
new file mode 100644
index 000000000..50a0f80c6
--- /dev/null
+++ b/inc/geshi/hq9plus.php
@@ -0,0 +1,104 @@
+<?php
+/*************************************************************************************
+ * hq9plus.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/html4strict.php b/inc/geshi/html4strict.php
new file mode 100644
index 000000000..301513e4e
--- /dev/null
+++ b/inc/geshi/html4strict.php
@@ -0,0 +1,203 @@
+<?php
+/*************************************************************************************
+ * html4strict.php
+ * ---------------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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',
+
+ '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(
+ -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(
+ -1 => array(
+ '<!--' => '-->'
+ ),
+ 0 => array(
+ '<!DOCTYPE' => '>'
+ ),
+ 1 => array(
+ '&' => ';'
+ ),
+ 2 => array(
+ '<' => '>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ -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/inc/geshi/icon.php b/inc/geshi/icon.php
new file mode 100644
index 000000000..0712c21c3
--- /dev/null
+++ b/inc/geshi/icon.php
@@ -0,0 +1,212 @@
+<?php
+/*************************************************************************************
+ * icon.php
+ * --------
+ * Author: Matt Oates (mattoates@gmail.com)
+ * Copyright: (c) 2010 Matt Oates (http://mattoates.co.uk)
+ * Release Version: 1.0.8.8
+ * 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' => '(?<=#)'
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/idl.php b/inc/geshi/idl.php
new file mode 100644
index 000000000..d2d9a92fa
--- /dev/null
+++ b/inc/geshi/idl.php
@@ -0,0 +1,123 @@
+<?php
+/*************************************************************************************
+ * idl.php
+ * -------
+ * Author: Cedric Bosdonnat (cedricbosdo@openoffice.org)
+ * Copyright: (c) 2006 Cedric Bosdonnat
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/ini.php b/inc/geshi/ini.php
new file mode 100644
index 000000000..e48cc045c
--- /dev/null
+++ b/inc/geshi/ini.php
@@ -0,0 +1,128 @@
+<?php
+/*************************************************************************************
+ * ini.php
+ * --------
+ * Author: deguix (cevo_deguix@yahoo.com.br)
+ * Copyright: (c) 2005 deguix
+ * Release Version: 1.0.8.8
+ * 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(0 => ';'),
+ '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(
+ 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/inc/geshi/inno.php b/inc/geshi/inno.php
new file mode 100644
index 000000000..9ec8cdfd9
--- /dev/null
+++ b/inc/geshi/inno.php
@@ -0,0 +1,212 @@
+<?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.8.8
+ * 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/inc/geshi/intercal.php b/inc/geshi/intercal.php
new file mode 100644
index 000000000..cd800a8eb
--- /dev/null
+++ b/inc/geshi/intercal.php
@@ -0,0 +1,122 @@
+<?php
+/*************************************************************************************
+ * intercal.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/io.php b/inc/geshi/io.php
new file mode 100644
index 000000000..94c278f03
--- /dev/null
+++ b/inc/geshi/io.php
@@ -0,0 +1,138 @@
+<?php
+/*************************************************************************************
+ * io.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2006 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/j.php b/inc/geshi/j.php
new file mode 100644
index 000000000..61154c7ef
--- /dev/null
+++ b/inc/geshi/j.php
@@ -0,0 +1,227 @@
+<?php
+/*************************************************************************************
+ * j.php
+ * --------
+ * Author: Ric Sherlock (tikkanz@gmail.com)
+ * Copyright: (c) 2009 Ric Sherlock
+ * Release Version: 1.0.8.8
+ * Date Started: 2009/11/10
+ *
+ * J language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 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(
+ //Some instances of infinity are not correctly handled by GeSHi NUMBERS currently
+ //There are two solutions labelled "infinity Method A" and "infinity Method B"
+ //infinity Method B - requires following adjustment to line 3349 of geshi.php
+ // preg_match('#\d#' becomes preg_match('#[\d_]#'
+ 0 => '\b(?:_?\d+(?:\.\d+)?(?:x|[bejprx]_?[\da-z]+(?:\.[\da-z]+)?)?)(?![\w\.\:])', //infinity Method A
+ //0 => '\b(?:_?\d+(?:\.\d+)?(?:x|[bejprx]_?[\da-z]+(?:\.[\da-z]+)?)?|__?)(?![\w\.\:])', //infinity Method B
+ ),
+ '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'
+ ),
+/*
+Commented out for now due to conflicts with Lang Check
+ //Primitives beginning with a symbol (except . or :)
+ 6 => array(
+ '=', '&lt;', '&lt;.', '&lt;:', //verbs
+ '_:','&gt;', '&gt;.', '&gt;:',
+ '+', '+.', '+:', '*', '*.', '*:', '-', '-.', '-:', '%', '%.', '%:',
+ '^', '^.', '$', '$.', '$:', '~.', '~:', '\|', '|.', '|:',
+ ',', ',.', ',:', ';', ';:', '#', '#.', '#:', '!', '/:', '\:',
+ '[', '[:', ']', '{', '{.', '{:', '{::', '}.', '}:',
+ '&quot;.', '&quot;:', '?', '?.',
+ '~', '\/;', '\\', '/.', '\\.', '}', //adverbs
+ '^:', ';.', '!.', '!:', //conj
+ '&quot;', '`', '`:', '@', '@.', '@:',
+ '&amp;', '&amp;.', '&amp;:', '&amp;.:',
+ '_.', //nouns
+ '=.', '=:', //other
+ ),
+ //Primitives beginning with a letter or number
+ 7 => array(
+ 'A.', 'c.', 'C.', 'e.', 'E.', //verbs
+ 'i.', 'i:', 'I.', 'j.', 'L.', 'o.',
+ 'p.', 'p..', 'p:', 'q:', 'r.', 's:', 'u:', 'x:',
+ '_9:', '_8:', '_7:', '_6:', '_5:', '_4:', '_3:', '_2:', '_1:',
+ '0:', '1:', '2:', '3:', '4:', '5:', '6:', '7:', '8:', '9:',
+ 'b.', 'f.', 'M.', 't.', 't:', //adverbs
+ 'd.', 'D.', 'D:', 'H.', 'L:', 'S:', 'T.', //conj
+ 'a.', 'a:', //nouns
+ ),
+ //Primitives beginning with symbol . or :
+ 8 => array(
+ '..', '.:', '.', ':.', '::', ':', //conj
+ ),
+*/
+ ),
+ '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
+ 1 => 'color: #009999; font-weight: bold;' //infinity - same as nu0
+ ),
+ '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
+ 1 => '\b__?(?![\w\.\:])' //infinity - should be nu0
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ ),
+ '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' => '(?=.*)',
+ ),
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/java.php b/inc/geshi/java.php
new file mode 100644
index 000000000..3269dffe2
--- /dev/null
+++ b/inc/geshi/java.php
@@ -0,0 +1,983 @@
+<?php
+/*************************************************************************************
+ * java.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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;',
+ 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%3A{FNAMEL}+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
+
+?>
diff --git a/inc/geshi/java5.php b/inc/geshi/java5.php
new file mode 100644
index 000000000..bc9af739a
--- /dev/null
+++ b/inc/geshi/java5.php
@@ -0,0 +1,1037 @@
+<?php
+/*************************************************************************************
+ * java.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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://java.sun.com/j2se/1%2E5%2E0/docs/api/java/applet/{FNAME}.html',
+ 6 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/{FNAME}.html',
+ 7 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/color/{FNAME}.html',
+ 8 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/datatransfer/{FNAME}.html',
+ 9 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/dnd/{FNAME}.html',
+ 10 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/event/{FNAME}.html',
+ 11 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/font/{FNAME}.html',
+ 12 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/geom/{FNAME}.html',
+ 13 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/im/{FNAME}.html',
+ 14 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/im/spi/{FNAME}.html',
+ 15 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/image/{FNAME}.html',
+ 16 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/image/renderable/{FNAME}.html',
+ 17 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/awt/print/{FNAME}.html',
+ 18 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/beans/{FNAME}.html',
+ 19 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/beans/beancontext/{FNAME}.html',
+ 20 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/io/{FNAME}.html',
+ 21 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/lang/{FNAME}.html',
+ 22 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/lang/annotation/{FNAME}.html',
+ 23 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/lang/instrument/{FNAME}.html',
+ 24 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/lang/management/{FNAME}.html',
+ 25 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/lang/ref/{FNAME}.html',
+ 26 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/lang/reflect/{FNAME}.html',
+ 27 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/math/{FNAME}.html',
+ 28 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/net/{FNAME}.html',
+ 29 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/nio/{FNAME}.html',
+ 30 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/nio/channels/{FNAME}.html',
+ 31 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/nio/channels/spi/{FNAME}.html',
+ 32 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/nio/charset/{FNAME}.html',
+ 33 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/nio/charset/spi/{FNAME}.html',
+ 34 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/rmi/{FNAME}.html',
+ 35 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/rmi/activation/{FNAME}.html',
+ 36 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/rmi/dgc/{FNAME}.html',
+ 37 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/rmi/registry/{FNAME}.html',
+ 38 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/rmi/server/{FNAME}.html',
+ 39 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/security/{FNAME}.html',
+ 40 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/security/acl/{FNAME}.html',
+ 41 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/security/cert/{FNAME}.html',
+ 42 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/security/interfaces/{FNAME}.html',
+ 43 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/security/spec/{FNAME}.html',
+ 44 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/sql/{FNAME}.html',
+ 45 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/text/{FNAME}.html',
+ 46 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/util/{FNAME}.html',
+ 47 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/util/concurrent/{FNAME}.html',
+ 48 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/util/concurrent/atomic/{FNAME}.html',
+ 49 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/util/concurrent/locks/{FNAME}.html',
+ 50 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/util/jar/{FNAME}.html',
+ 51 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/util/logging/{FNAME}.html',
+ 52 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/util/prefs/{FNAME}.html',
+ 53 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/util/regex/{FNAME}.html',
+ 54 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/java/util/zip/{FNAME}.html',
+ 55 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/accessibility/{FNAME}.html',
+ 56 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/activity/{FNAME}.html',
+ 57 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/crypto/{FNAME}.html',
+ 58 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/crypto/interfaces/{FNAME}.html',
+ 59 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/crypto/spec/{FNAME}.html',
+ 60 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/imageio/{FNAME}.html',
+ 61 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/imageio/event/{FNAME}.html',
+ 62 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/imageio/metadata/{FNAME}.html',
+ 63 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/imageio/plugins/bmp/{FNAME}.html',
+ 64 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/imageio/plugins/jpeg/{FNAME}.html',
+ 65 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/imageio/spi/{FNAME}.html',
+ 66 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/imageio/stream/{FNAME}.html',
+ 67 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/management/{FNAME}.html',
+ 68 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/management/loading/{FNAME}.html',
+ 69 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/management/modelmbean/{FNAME}.html',
+ 70 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/management/monitor/{FNAME}.html',
+ 71 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/management/openmbean/{FNAME}.html',
+ 72 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/management/relation/{FNAME}.html',
+ 73 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/management/remote/{FNAME}.html',
+ 74 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/management/remote/rmi/{FNAME}.html',
+ 75 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/management/timer/{FNAME}.html',
+ 76 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/naming/{FNAME}.html',
+ 77 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/naming/directory/{FNAME}.html',
+ 78 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/naming/event/{FNAME}.html',
+ 79 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/naming/ldap/{FNAME}.html',
+ 80 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/naming/spi/{FNAME}.html',
+ 81 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/net/{FNAME}.html',
+ 82 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/net/ssl/{FNAME}.html',
+ 83 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/print/{FNAME}.html',
+ 84 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/print/attribute/{FNAME}.html',
+ 85 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/print/attribute/standard/{FNAME}.html',
+ 86 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/print/event/{FNAME}.html',
+ 87 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/rmi/{FNAME}.html',
+ 88 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/rmi/CORBA/{FNAME}.html',
+ 89 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/rmi/ssl/{FNAME}.html',
+ 90 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/security/auth/{FNAME}.html',
+ 91 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/security/auth/callback/{FNAME}.html',
+ 92 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/security/auth/kerberos/{FNAME}.html',
+ 93 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/security/auth/login/{FNAME}.html',
+ 94 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/security/auth/spi/{FNAME}.html',
+ 95 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/security/auth/x500/{FNAME}.html',
+ 96 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/security/sasl/{FNAME}.html',
+ 97 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/sound/midi/{FNAME}.html',
+ 98 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/sound/midi/spi/{FNAME}.html',
+ 99 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/sound/sampled/{FNAME}.html',
+ 100 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/sound/sampled/spi/{FNAME}.html',
+ 101 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/sql/{FNAME}.html',
+ 102 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/sql/rowset/{FNAME}.html',
+ 103 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/sql/rowset/serial/{FNAME}.html',
+ 104 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/sql/rowset/spi/{FNAME}.html',
+ 105 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/{FNAME}.html',
+ 106 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/border/{FNAME}.html',
+ 107 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/colorchooser/{FNAME}.html',
+ 108 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/event/{FNAME}.html',
+ 109 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/filechooser/{FNAME}.html',
+ 110 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/plaf/{FNAME}.html',
+ 111 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/plaf/basic/{FNAME}.html',
+ 112 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/plaf/metal/{FNAME}.html',
+ 113 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/plaf/multi/{FNAME}.html',
+ 114 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/plaf/synth/{FNAME}.html',
+ 115 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/table/{FNAME}.html',
+ 116 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/text/{FNAME}.html',
+ 117 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/text/html/{FNAME}.html',
+ 118 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/text/html/parser/{FNAME}.html',
+ 119 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/text/rtf/{FNAME}.html',
+ 120 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/tree/{FNAME}.html',
+ 121 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/swing/undo/{FNAME}.html',
+ 122 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/transaction/{FNAME}.html',
+ 123 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/transaction/xa/{FNAME}.html',
+ 124 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/{FNAME}.html',
+ 125 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/datatype/{FNAME}.html',
+ 126 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/namespace/{FNAME}.html',
+ 127 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/parsers/{FNAME}.html',
+ 128 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/transform/{FNAME}.html',
+ 129 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/transform/dom/{FNAME}.html',
+ 130 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/transform/sax/{FNAME}.html',
+ 131 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/transform/stream/{FNAME}.html',
+ 132 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/validation/{FNAME}.html',
+ 133 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/javax/xml/xpath/{FNAME}.html',
+ 134 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/ietf/jgss/{FNAME}.html',
+ 135 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/CORBA/{FNAME}.html',
+ 136 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/CORBA/DynAnyPackage/{FNAME}.html',
+ 137 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/CORBA/TypeCodePackage/{FNAME}.html',
+ 138 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/CORBA/portable/{FNAME}.html',
+ 139 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/CosNaming/{FNAME}.html',
+ 140 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/CosNaming/NamingContextExtPackage/{FNAME}.html',
+ 141 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/CosNaming/NamingContextPackage/{FNAME}.html',
+ 142 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/Dynamic/{FNAME}.html',
+ 143 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/DynamicAny/{FNAME}.html',
+ 144 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/DynamicAny/DynAnyFactoryPackage/{FNAME}.html',
+ 145 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/DynamicAny/DynAnyPackage/{FNAME}.html',
+ 146 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/IOP/{FNAME}.html',
+ 147 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/IOP/CodecFactoryPackage/{FNAME}.html',
+ 148 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/IOP/CodecPackage/{FNAME}.html',
+ 149 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/Messaging/{FNAME}.html',
+ 150 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/PortableInterceptor/{FNAME}.html',
+ 151 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/PortableInterceptor/ORBInitInfoPackage/{FNAME}.html',
+ 152 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/PortableServer/{FNAME}.html',
+ 153 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/PortableServer/CurrentPackage/{FNAME}.html',
+ 154 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/PortableServer/POAManagerPackage/{FNAME}.html',
+ 155 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/PortableServer/POAPackage/{FNAME}.html',
+ 156 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/PortableServer/ServantLocatorPackage/{FNAME}.html',
+ 157 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/SendingContext/{FNAME}.html',
+ 158 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/omg/stub/java/rmi/{FNAME}.html',
+ 159 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/w3c/dom/{FNAME}.html',
+ 160 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/w3c/dom/bootstrap/{FNAME}.html',
+ 161 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/w3c/dom/events/{FNAME}.html',
+ 162 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/w3c/dom/ls/{FNAME}.html',
+ 163 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/xml/sax/{FNAME}.html',
+ 164 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/xml/sax/ext/{FNAME}.html',
+ 165 => 'http://java.sun.com/j2se/1%2E5%2E0/docs/api/org/xml/sax/helpers/{FNAME}.html',
+ /* ambiguous class names (appear in more than one package) */
+ 166 => 'http://www.google.com/search?sitesearch=java.sun.com&amp;q=allinurl%3Aj2se%2F1+5+0%2Fdocs%2Fapi+{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_\|%\\-;"\'])'
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/javascript.php b/inc/geshi/javascript.php
new file mode 100644
index 000000000..429cdd653
--- /dev/null
+++ b/inc/geshi/javascript.php
@@ -0,0 +1,150 @@
+<?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.8.8
+ * Date Started: 2004/06/20
+ *
+ * JavaScript 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' => 'Javascript',
+ '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', 'blur', 'close', 'confirm', 'focus', 'forward', 'home',
+ 'name', 'navigate', 'onblur', 'onerror', 'onfocus', 'onload', 'onmove',
+ 'onresize', 'onunload', 'open', 'print', 'prompt', 'scroll', 'status',
+ 'stop',
+ )
+ ),
+ '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(
+ '<script type="text/javascript">' => '</script>'
+ ),
+ 1 => array(
+ '<script language="javascript">' => '</script>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true
+ )
+);
+
+?>
diff --git a/inc/geshi/jquery.php b/inc/geshi/jquery.php
new file mode 100644
index 000000000..54e653ed1
--- /dev/null
+++ b/inc/geshi/jquery.php
@@ -0,0 +1,238 @@
+<?php
+/*************************************************************************************
+ * jquery.php
+ * --------------
+ * Author: Rob Loach (http://www.robloach.net)
+ * Copyright: (c) 2009 Rob Loach (http://www.robloach.net)
+ * Release Version: 1.0.8.8
+ * 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
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/kixtart.php b/inc/geshi/kixtart.php
new file mode 100644
index 000000000..62cb54652
--- /dev/null
+++ b/inc/geshi/kixtart.php
@@ -0,0 +1,329 @@
+<?php
+/*************************************************************************************
+ * kixtart.php
+ * --------
+ * Author: Riley McArdle (riley@glyff.net)
+ * Copyright: (c) 2007 Riley McArdle (http://www.glyff.net/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/klonec.php b/inc/geshi/klonec.php
new file mode 100644
index 000000000..e47e597ef
--- /dev/null
+++ b/inc/geshi/klonec.php
@@ -0,0 +1,282 @@
+<?php
+/*************************************************************************************
+ * klonec.php
+ * --------
+ * Author: AUGER Mickael
+ * Copyright: Synchronic
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/klonecpp.php b/inc/geshi/klonecpp.php
new file mode 100644
index 000000000..1a2d2082b
--- /dev/null
+++ b/inc/geshi/klonecpp.php
@@ -0,0 +1,310 @@
+<?php
+/*************************************************************************************
+ * klonecpp.php
+ * --------
+ * Author: AUGER Mickael
+ * Copyright: Synchronic
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/latex.php b/inc/geshi/latex.php
new file mode 100644
index 000000000..1ba3d409e
--- /dev/null
+++ b/inc/geshi/latex.php
@@ -0,0 +1,223 @@
+<?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.8.8
+ * 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','hfill','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','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/index.php?title=%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
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/lisp.php b/inc/geshi/lisp.php
new file mode 100644
index 000000000..a8f50691e
--- /dev/null
+++ b/inc/geshi/lisp.php
@@ -0,0 +1,144 @@
+<?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.8.8
+ * Date Started: 2004/08/30
+ *
+ * Generic Lisp language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 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(
+ 'OOLANG' => array(
+ 'MATCH_AFTER' => '[a-zA-Z][a-zA-Z0-9_\-]*'
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/locobasic.php b/inc/geshi/locobasic.php
new file mode 100644
index 000000000..a3e22a7be
--- /dev/null
+++ b/inc/geshi/locobasic.php
@@ -0,0 +1,130 @@
+<?php
+/*************************************************************************************
+ * locobasic.php
+ * -------------
+ * Author: Nacho Cabanes
+ * Copyright: (c) 2009 Nacho Cabanes (http://www.nachocabanes.com)
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/logtalk.php b/inc/geshi/logtalk.php
new file mode 100644
index 000000000..fb77bd6d3
--- /dev/null
+++ b/inc/geshi/logtalk.php
@@ -0,0 +1,330 @@
+<?php
+/*************************************************************************************
+ * logtalk.php
+ * -----------
+ *
+ * Author: Paulo Moura (pmoura@logtalk.org)
+ * Copyright: (c) 2009 Paulo Moura (http://logtalk.org/)
+ * Release Version: 1.0.8.8
+ * Date Started: 2009/10/24
+ *
+ * Logtalk language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 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', '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',
+ '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', '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',
+ // term testing
+ 'atom', 'atomic', 'compound', 'float', 'integer', 'nonvar', 'number', 'sub_atom', 'var',
+ // 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',
+ //
+ 'halt'
+ ),
+ // 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(
+ '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_\|%\\-&\'"])'
+ )
+ )
+ ),
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/lolcode.php b/inc/geshi/lolcode.php
new file mode 100644
index 000000000..a804913cc
--- /dev/null
+++ b/inc/geshi/lolcode.php
@@ -0,0 +1,152 @@
+<?php
+/*************************************************************************************
+ * lolcode.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * Date Started: 2009/10/31
+ *
+ * LOLcode 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' => 'LOLcode',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ '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(
+ 1 => 'color: #666666; style: italic;',
+ 2 => 'color: #666666; style: italic;'
+ ),
+ '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(
+ )
+ ),
+ '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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/lotusformulas.php b/inc/geshi/lotusformulas.php
new file mode 100644
index 000000000..862adbc82
--- /dev/null
+++ b/inc/geshi/lotusformulas.php
@@ -0,0 +1,318 @@
+<?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.8.8
+ * 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/inc/geshi/lotusscript.php b/inc/geshi/lotusscript.php
new file mode 100644
index 000000000..1ef2f3eee
--- /dev/null
+++ b/inc/geshi/lotusscript.php
@@ -0,0 +1,191 @@
+<?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.8.8
+ * 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/inc/geshi/lscript.php b/inc/geshi/lscript.php
new file mode 100644
index 000000000..b7e313212
--- /dev/null
+++ b/inc/geshi/lscript.php
@@ -0,0 +1,387 @@
+<?php
+/*************************************************************************************
+ * lscript.php
+ * ---------
+ * Author: Arendedwinter (admin@arendedwinter.com)
+ * Copyright: (c) 2008 Beau McGuigan (http://www.arendedwinter.com)
+ * Release Version: 1.0.8.8
+ * 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' => '(?<=\.)'
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/lsl2.php b/inc/geshi/lsl2.php
new file mode 100644
index 000000000..e5f40969b
--- /dev/null
+++ b/inc/geshi/lsl2.php
@@ -0,0 +1,898 @@
+<?php
+/*************************************************************************************
+ * lsl2.php
+ * --------
+ * Author: William Fry (william.fry@nyu.edu)
+ * Copyright: (c) 2009 William Fry
+ * Release Version: 1.0.8.8
+ * Date Started: 2009/02/04
+ *
+ * Linden Scripting Language (LSL2) language file for GeSHi.
+ *
+ * Data derived and validated against the following:
+ * http://wiki.secondlife.com/wiki/LSL_Portal
+ * http://www.lslwiki.net/lslwiki/wakka.php?wakka=HomePage
+ * http://rpgstats.com/wiki/index.php?title=Main_Page
+ *
+ * CHANGES
+ * -------
+ * 2009/02/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2009/02/05)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GeSHi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General 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' => '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_AWAY',
+ 'AGENT_BUSY',
+ 'AGENT_CROUCHING',
+ 'AGENT_FLYING',
+ 'AGENT_IN_AIR',
+ 'AGENT_MOUSELOOK',
+ 'AGENT_ON_OBJECT',
+ 'AGENT_SCRIPTED',
+ 'AGENT_SITTING',
+ 'AGENT_TYPING',
+ 'AGENT_WALKING',
+ 'ALL_SIDES',
+ 'ANIM_ON',
+ '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_LEYE',
+ 'ATTACH_LFOOT',
+ 'ATTACH_LHAND',
+ 'ATTACH_LHIP',
+ 'ATTACH_LLARM',
+ 'ATTACH_LLLEG',
+ 'ATTACH_LPEC',
+ 'ATTACH_LSHOULDER',
+ 'ATTACH_LUARM',
+ 'ATTACH_LULEG',
+ 'ATTACH_MOUTH',
+ 'ATTACH_NOSE',
+ 'ATTACH_PELVIS',
+ 'ATTACH_REAR',
+ 'ATTACH_REYE',
+ 'ATTACH_RFOOT',
+ 'ATTACH_RHAND',
+ 'ATTACH_RHIP',
+ 'ATTACH_RLARM',
+ 'ATTACH_RLLEG',
+ 'ATTACH_RPEC',
+ 'ATTACH_RSHOULDER',
+ 'ATTACH_RUARM',
+ 'ATTACH_RULEG',
+ '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_OWNER',
+ 'CHANGED_REGION',
+ 'CHANGED_SCALE',
+ 'CHANGED_SHAPE',
+ 'CHANGED_TELEPORT',
+ 'CHANGED_TEXTURE',
+ 'CLICK_ACTION_NONE',
+ 'CLICK_ACTION_OPEN',
+ 'CLICK_ACTION_OPEN_MEDIA',
+ 'CLICK_ACTION_PAY',
+ 'CLICK_ACTION_SIT',
+ 'CLICK_ACTION_TOUCH',
+ '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_RATING',
+ 'DATA_SIM_POS',
+ 'DATA_SIM_RATING',
+ 'DATA_SIM_STATUS',
+ 'DEBUG_CHANNEL',
+ 'DEG_TO_RAD',
+ 'EOF',
+ 'FALSE',
+ 'HTTP_BODY_MAXLENGTH',
+ 'HTTP_BODY_TRUNCATED',
+ 'HTTP_METHOD',
+ 'HTTP_MIMETYPE',
+ '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',
+ 'LAND_LEVEL',
+ 'LAND_LOWER',
+ 'LAND_NOISE',
+ 'LAND_RAISE',
+ 'LAND_REVERT',
+ '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_CREATOR',
+ 'OBJECT_DESC',
+ 'OBJECT_GROUP',
+ 'OBJECT_NAME',
+ 'OBJECT_OWNER',
+ 'OBJECT_POS',
+ 'OBJECT_ROT',
+ 'OBJECT_UNKNOWN_DETAIL',
+ 'OBJECT_VELOCITY',
+ 'PARCEL_DETAILS_AREA',
+ 'PARCEL_DETAILS_DESC',
+ 'PARCEL_DETAILS_GROUP',
+ 'PARCEL_DETAILS_NAME',
+ 'PARCEL_DETAILS_OWNER',
+ '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_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_URL',
+ 'PASSIVE',
+ 'PAYMENT_INFO_ON_FILE',
+ 'PAYMENT_INFO_USED',
+ 'PAY_DEFAULT',
+ 'PAY_HIDE',
+ 'PERMISSION_ATTACH',
+ 'PERMISSION_CHANGE_LINKS',
+ 'PERMISSION_CONTROL_CAMERA',
+ 'PERMISSION_DEBIT',
+ 'PERMISSION_TAKE_CONTROLS',
+ 'PERMISSION_TRACK_CAMERA',
+ 'PERMISSION_TRIGGER_ANIMATION',
+ 'PERM_ALL',
+ 'PERM_COPY',
+ 'PERM_MODIFY',
+ 'PERM_MOVE',
+ 'PERM_TRANSFER',
+ 'PI',
+ '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_FULLBRIGHT',
+ 'PRIM_HOLE_CIRCLE',
+ 'PRIM_HOLE_DEFAULT',
+ 'PRIM_HOLE_SQUARE',
+ 'PRIM_HOLE_TRIANGLE',
+ 'PRIM_MATERIAL',
+ 'PRIM_MATERIAL_FLESH',
+ 'PRIM_MATERIAL_GLASS',
+ 'PRIM_MATERIAL_LIGHT',
+ 'PRIM_MATERIAL_METAL',
+ 'PRIM_MATERIAL_PLASTIC',
+ 'PRIM_MATERIAL_RUBBER',
+ 'PRIM_MATERIAL_STONE',
+ 'PRIM_MATERIAL_WOOD',
+ 'PRIM_PHANTOM',
+ 'PRIM_PHYSICS',
+ 'PRIM_POSITION',
+ 'PRIM_ROTATION',
+ 'PRIM_SHINY_HIGH',
+ 'PRIM_SHINY_LOW',
+ 'PRIM_SHINY_MEDIUM',
+ 'PRIM_SHINY_NONE',
+ 'PRIM_SIZE',
+ 'PRIM_TEMP_ON_REZ',
+ 'PRIM_TEXTURE',
+ 'PRIM_TYPE',
+ 'PRIM_TYPE_BOX',
+ 'PRIM_TYPE_CYLINDER',
+ 'PRIM_TYPE_PRISM',
+ 'PRIM_TYPE_RING',
+ 'PRIM_TYPE_SPHERE',
+ 'PRIM_TYPE_TORUS',
+ 'PRIM_TYPE_TUBE',
+ 'PSYS_PART_BOUNCE_MASK',
+ 'PSYS_PART_EMISSIVE_MASK',
+ 'PSYS_PART_END_ALPHA',
+ 'PSYS_PART_END_COLOR',
+ '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_START_ALPHA',
+ 'PSYS_PART_START_COLOR',
+ '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_INNERANGLE',
+ 'PSYS_SRC_MAX_AGE',
+ 'PSYS_SRC_OMEGA',
+ 'PSYS_SRC_OUTERANGLE',
+ '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',
+ 'RAD_TO_DEG',
+ 'REMOTE_DATA_CHANNEL',
+ 'REMOTE_DATA_REQUEST',
+ 'SCRIPTED',
+ 'SQRT2',
+ 'STATUS_BLOCK_GRAB',
+ 'STATUS_DIE_AT_EDGE',
+ 'STATUS_PHANTOM',
+ 'STATUS_PHYSICS',
+ 'STATUS_RETURN_AT_EDGE',
+ 'STATUS_ROTATE_X',
+ 'STATUS_ROTATE_Y',
+ 'STATUS_ROTATE_Z',
+ 'STATUS_SANDBOX',
+ 'TRUE',
+ 'TWO_PI',
+ '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',
+ 'ZERO_ROTATION',
+ 'ZERO_VECTOR',
+ ),
+ 3 => array( // handlers
+ 'at_rot_target',
+ 'at_target',
+ 'attached',
+ 'changed',
+ 'collision',
+ 'collision_end',
+ 'collision_start',
+ 'control',
+ 'dataserver',
+ 'email',
+ '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',
+ 'remote_data',
+ 'run_time_permissions',
+ 'sensor',
+ 'state_entry',
+ 'state_exit',
+ 'timer',
+ 'touch',
+ 'touch_end',
+ 'touch_start',
+ ),
+ 4 => array( // data types
+ 'float',
+ 'integer',
+ 'key',
+ 'list',
+ 'rotation',
+ 'string',
+ 'vector',
+ ),
+ 5 => array( // library
+ 'default',
+ 'llAbs',
+ 'llAcos',
+ 'llAddToLandBanList',
+ 'llAddToLandPassList',
+ 'llAdjustSoundVolume',
+ 'llAllowInventoryDrop',
+ 'llAngleBetween',
+ 'llApplyImpulse',
+ 'llApplyRotationalImpulse',
+ 'llAsin',
+ 'llAtan2',
+ 'llAttachToAvatar',
+ 'llAvatarOnSitTarget',
+ 'llAxes2Rot',
+ 'llAxisAngle2Rot',
+ 'llBase64ToInteger',
+ 'llBase64ToString',
+ 'llBreakAllLinks',
+ 'llBreakLink',
+ 'llCeil',
+ 'llClearCameraParams',
+ 'llCloseRemoteDataChannel',
+ 'llCloud',
+ 'llCollisionFilter',
+ 'llCollisionSound',
+ 'llCollisionSprite',
+ 'llCos',
+ 'llCreateLink',
+ 'llCSV2List',
+ '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',
+ 'llFabs',
+ 'llFloor',
+ 'llForceMouselook',
+ 'llFrand',
+ 'llGetAccel',
+ 'llGetAgentInfo',
+ 'llGetAgentLanguage',
+ 'llGetAgentSize',
+ 'llGetAlpha',
+ 'llGetAndResetTime',
+ 'llGetAnimation',
+ 'llGetAnimationList',
+ 'llGetAttached',
+ 'llGetBoundingBox',
+ 'llGetCameraPos',
+ 'llGetCameraRot',
+ 'llGetCenterOfMass',
+ 'llGetColor',
+ 'llGetCreator',
+ 'llGetDate',
+ 'llGetEnergy',
+ 'llGetForce',
+ 'llGetFreeMemory',
+ 'llGetGeometricCenter',
+ 'llGetGMTclock',
+ 'llGetInventoryCreator',
+ 'llGetInventoryKey',
+ 'llGetInventoryName',
+ 'llGetInventoryNumber',
+ 'llGetInventoryPermMask',
+ 'llGetInventoryType',
+ 'llGetKey',
+ 'llGetLandOwnerAt',
+ 'llGetLinkKey',
+ 'llGetLinkName',
+ 'llGetLinkNumber',
+ 'llGetListEntryType',
+ 'llGetListLength',
+ 'llGetLocalPos',
+ 'llGetLocalRot',
+ 'llGetMass',
+ 'llGetNextEmail',
+ 'llGetNotecardLine',
+ 'llGetNumberOfNotecardLines',
+ 'llGetNumberOfPrims',
+ 'llGetNumberOfSides',
+ 'llGetObjectDesc',
+ 'llGetObjectDetails',
+ 'llGetObjectMass',
+ 'llGetObjectName',
+ 'llGetObjectPermMask',
+ 'llGetObjectPrimCount',
+ 'llGetOmega',
+ 'llGetOwner',
+ 'llGetOwnerKey',
+ 'llGetParcelDetails',
+ 'llGetParcelFlags',
+ 'llGetParcelMaxPrims',
+ 'llGetParcelPrimCount',
+ 'llGetParcelPrimOwners',
+ 'llGetPermissions',
+ 'llGetPermissionsKey',
+ 'llGetPos',
+ 'llGetPrimitiveParams',
+ 'llGetRegionAgentCount',
+ 'llGetRegionCorner',
+ 'llGetRegionFlags',
+ 'llGetRegionFPS',
+ 'llGetRegionName',
+ 'llGetRegionTimeDilation',
+ 'llGetRootPosition',
+ 'llGetRootRotation',
+ 'llGetRot',
+ 'llGetScale',
+ 'llGetScriptName',
+ 'llGetScriptState',
+ 'llGetSimulatorHostname',
+ 'llGetStartParameter',
+ 'llGetStatus',
+ 'llGetSubString',
+ 'llGetSunDirection',
+ 'llGetTexture',
+ 'llGetTextureOffset',
+ 'llGetTextureRot',
+ 'llGetTextureScale',
+ 'llGetTime',
+ 'llGetTimeOfDay',
+ 'llGetTimestamp',
+ 'llGetTorque',
+ 'llGetUnixTime',
+ 'llGetVel',
+ 'llGetWallclock',
+ 'llGiveInventory',
+ 'llGiveInventoryList',
+ 'llGiveMoney',
+ 'llGround',
+ 'llGroundContour',
+ 'llGroundNormal',
+ 'llGroundRepel',
+ 'llGroundSlope',
+ 'llHTTPRequest',
+ 'llInsertString',
+ 'llInstantMessage',
+ 'llIntegerToBase64',
+ 'llKey2Name',
+ 'llList2CSV',
+ 'llList2Float',
+ 'llList2Integer',
+ 'llList2Key',
+ 'llList2List',
+ 'llList2ListStrided',
+ 'llList2Rot',
+ 'llList2String',
+ 'llList2Vector',
+ 'llListen',
+ 'llListenControl',
+ 'llListenRemove',
+ 'llListFindList',
+ 'llListInsertList',
+ 'llListRandomize',
+ 'llListReplaceList',
+ 'llListSort',
+ 'llListStatistics',
+ 'llLoadURL',
+ 'llLog',
+ 'llLog10',
+ 'llLookAt',
+ 'llLoopSound',
+ 'llLoopSoundMaster',
+ 'llLoopSoundSlave',
+ 'llMapDestination',
+ 'llMD5String',
+ 'llMessageLinked',
+ 'llMinEventDelay',
+ 'llModifyLand',
+ 'llModPow',
+ 'llMoveToTarget',
+ 'llOffsetTexture',
+ 'llOpenRemoteDataChannel',
+ 'llOverMyLand',
+ 'llOwnerSay',
+ 'llParcelMediaCommandList',
+ 'llParcelMediaQuery',
+ 'llParseString2List',
+ 'llParseStringKeepNulls',
+ 'llParticleSystem',
+ 'llPassCollisions',
+ 'llPassTouches',
+ 'llPlaySound',
+ 'llPlaySoundSlave',
+ 'llPow',
+ 'llPreloadSound',
+ 'llPushObject',
+ 'llRegionSay',
+ 'llReleaseControls',
+ 'llRemoteDataReply',
+ 'llRemoteDataSetRegion',
+ 'llRemoteLoadScriptPin',
+ 'llRemoveFromLandBanList',
+ 'llRemoveFromLandPassList',
+ 'llRemoveInventory',
+ 'llRemoveVehicleFlags',
+ 'llRequestAgentData',
+ 'llRequestInventoryData',
+ 'llRequestPermissions',
+ 'llRequestSimulatorData',
+ 'llResetLandBanList',
+ 'llResetLandPassList',
+ 'llResetOtherScript',
+ 'llResetScript',
+ 'llResetTime',
+ 'llRezAtRoot',
+ 'llRezObject',
+ 'llRot2Angle',
+ 'llRot2Axis',
+ 'llRot2Euler',
+ 'llRot2Fwd',
+ 'llRot2Left',
+ 'llRot2Up',
+ 'llRotateTexture',
+ 'llRotBetween',
+ 'llRotLookAt',
+ 'llRotTarget',
+ 'llRotTargetRemove',
+ 'llRound',
+ 'llSameGroup',
+ 'llSay',
+ 'llScaleTexture',
+ 'llScriptDanger',
+ 'llSendRemoteData',
+ 'llSensor',
+ 'llSensorRemove',
+ 'llSensorRepeat',
+ 'llSetAlpha',
+ 'llSetBuoyancy',
+ 'llSetCameraAtOffset',
+ 'llSetCameraEyeOffset',
+ 'llSetCameraParams',
+ 'llSetClickAction',
+ 'llSetColor',
+ 'llSetDamage',
+ 'llSetForce',
+ 'llSetForceAndTorque',
+ 'llSetHoverHeight',
+ 'llSetLinkAlpha',
+ 'llSetLinkColor',
+ 'llSetLinkPrimitiveParams',
+ 'llSetLinkTexture',
+ 'llSetLocalRot',
+ 'llSetObjectDesc',
+ 'llSetObjectName',
+ 'llSetParcelMusicURL',
+ 'llSetPayPrice',
+ 'llSetPos',
+ 'llSetPrimitiveParams',
+ 'llSetRemoteScriptAccessPin',
+ 'llSetRot',
+ 'llSetScale',
+ 'llSetScriptState',
+ 'llSetSitText',
+ 'llSetSoundQueueing',
+ 'llSetSoundRadius',
+ 'llSetStatus',
+ 'llSetText',
+ 'llSetTexture',
+ 'llSetTextureAnim',
+ 'llSetTimerEvent',
+ 'llSetTorque',
+ 'llSetTouchText',
+ 'llSetVehicleFlags',
+ 'llSetVehicleFloatParam',
+ 'llSetVehicleRotationParam',
+ 'llSetVehicleType',
+ 'llSetVehicleVectorParam',
+ 'llSHA1String',
+ 'llShout',
+ 'llSin',
+ 'llSitTarget',
+ 'llSleep',
+ 'llSqrt',
+ 'llStartAnimation',
+ 'llStopAnimation',
+ 'llStopHover',
+ 'llStopLookAt',
+ 'llStopMoveToTarget',
+ 'llStopSound',
+ 'llStringLength',
+ 'llStringToBase64',
+ 'llStringTrim',
+ 'llSubStringIndex',
+ 'llTakeControls',
+ 'llTan',
+ 'llTarget',
+ 'llTargetOmega',
+ 'llTargetRemove',
+ 'llTeleportAgentHome',
+ 'llToLower',
+ 'llToUpper',
+ 'llTriggerSound',
+ 'llTriggerSoundLimited',
+ 'llUnescapeURL',
+ 'llUnSit',
+ 'llVecDist',
+ 'llVecMag',
+ 'llVecNorm',
+ 'llVolumeDetect',
+ 'llWater',
+ 'llWhisper',
+ 'llWind',
+ 'llXorBase64StringsCorrect',
+ ),
+ 6 => array( // deprecated
+ 'llMakeExplosion',
+ 'llMakeFire',
+ 'llMakeFountain',
+ 'llMakeSmoke',
+ 'llSound',
+ 'llSoundPreload',
+ 'llXorBase64Strings',
+ ),
+ 7 => array( // unimplemented
+ 'llPointAt',
+ 'llRefreshPrimURL',
+ 'llReleaseCamera',
+ 'llRemoteLoadScript',
+ 'llSetPrimURL',
+ 'llStopPointAt',
+ 'llTakeCamera',
+ 'llTextBox',
+ ),
+ 8 => array( // God mode
+ 'llGodLikeRezObject',
+ 'llSetInventoryPermMask',
+ 'llSetObjectPermMask',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '{', '}', '(', ')', '[', ']',
+ '=', '+', '-', '*', '/',
+ '+=', '-=', '*=', '/=', '++', '--',
+ '!', '%', '&amp;', '|', '&amp;&amp;', '||',
+ '==', '!=', '&lt;', '&gt;', '&lt;=', '&gt;=',
+ '~', '&lt;&lt;', '&gt;&gt;', '^', ':',
+ ),
+ '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;',
+ ),
+ '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://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+ 4 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+ 5 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+ 6 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+ 7 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // http://wiki.secondlife.com/wiki/{FNAME}
+ 8 => 'http://www.lslwiki.net/lslwiki/wakka.php?wakka={FNAME}', // 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(
+ )
+);
+?> \ No newline at end of file
diff --git a/inc/geshi/lua.php b/inc/geshi/lua.php
new file mode 100644
index 000000000..abeaa54ea
--- /dev/null
+++ b/inc/geshi/lua.php
@@ -0,0 +1,137 @@
+<?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.8.8
+ * 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('--[[' => ']]'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'and','break','do','else','elseif','end','false','for','function','if',
+ 'in','local','nil','not','or','repeat','return','then','true','until','while',
+ '_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'
+ )
+ ),
+ '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;',
+ '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: #b1b100;'
+ ),
+ '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/inc/geshi/m68k.php b/inc/geshi/m68k.php
new file mode 100644
index 000000000..543b73c8b
--- /dev/null
+++ b/inc/geshi/m68k.php
@@ -0,0 +1,143 @@
+<?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.8.8
+ * 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/inc/geshi/magiksf.php b/inc/geshi/magiksf.php
new file mode 100644
index 000000000..f3da7fcf2
--- /dev/null
+++ b/inc/geshi/magiksf.php
@@ -0,0 +1,193 @@
+<?php
+/*************************************************************************************
+ * magiksf.php
+ * --------
+ * Author: Sjoerd van Leent (svanleent@gmail.com)
+ * Copyright: (c) 2010 Sjoerd van Leent
+ * Release Version: 1.0.8.8
+ * 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' => '',
+ '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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/make.php b/inc/geshi/make.php
new file mode 100644
index 000000000..689552312
--- /dev/null
+++ b/inc/geshi/make.php
@@ -0,0 +1,151 @@
+<?php
+/*************************************************************************************
+ * make.php
+ * --------
+ * Author: Neil Bird <phoenix@fnxweb.com>
+ * Copyright: (c) 2008 Neil Bird
+ * Release Version: 1.0.8.8
+ * 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
+// vim: set sw=4 sts=4 :
+);
+?>
diff --git a/inc/geshi/mapbasic.php b/inc/geshi/mapbasic.php
new file mode 100644
index 000000000..0025d4e22
--- /dev/null
+++ b/inc/geshi/mapbasic.php
@@ -0,0 +1,908 @@
+<?php
+/*************************************************************************************
+ * mapbasic.php
+ * ------
+ * Author: Tomasz Berus (t.berus@gisodkuchni.pl)
+ * Copyright: (c) 2009 Tomasz Berus (http://sourceforge.net/projects/mbsyntax/)
+ * Release Version: 1.0.8.8
+ * 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(
+ ),
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/matlab.php b/inc/geshi/matlab.php
new file mode 100644
index 000000000..1f9c12b78
--- /dev/null
+++ b/inc/geshi/matlab.php
@@ -0,0 +1,227 @@
+<?php
+/*************************************************************************************
+ * matlab.php
+ * -----------
+ * Author: Florian Knorn (floz@gmx.de)
+ * Copyright: (c) 2004 Florian Knorn (http://www.florian-knorn.com)
+ * Release Version: 1.0.8.8
+ * 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', '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','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','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','date','datenum',
+ 'datestr','datetick','datevec','dbclear','dbcont','dbdown',
+ 'dblquad','dbmex','dbquit','dbstack','dbstatus','dbstep','dbstop',
+ 'dbtype','dbup','deblank','dec2bin','dec2hex','deconv','del2',
+ 'delaunay','det','diag','dialog','diff','diffuse','dlmread',
+ 'dlmwrite','dmperm','double','dragrect','drawnow','dsearch','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','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','interp1','interp2','interp3','interpft',
+ 'interpn','intersect','inv','invhilb','ipermute','isa','ishandle',
+ 'ismember','isocaps','isonormals','isosurface','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','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','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','strings','strjust','strmatch',
+ 'strncmp','strrep','strtok','struct','struct2cell','strvcat',
+ 'sub2ind','subplot','subspace','subvolume','sum','summer',
+ 'superiorto','surf','surf2patch','surface','surfc','surfl',
+ 'surfnorm','svd','svds','symmmd','symrcm','symvar','tan','tanh',
+ 'texlabel','text Create','textread','textwrap','tic','title','toc',
+ 'toeplitz','trace','trapz','tril','trimesh','trisurf','triu',
+ 'tsearch','uicontext Create','uicontextmenu','uicontrol',
+ 'uigetfile','uimenu','uint32','uint8','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','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','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 => 'http://www.mathworks.com/access/helpdesk/help/techdoc/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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/mirc.php b/inc/geshi/mirc.php
new file mode 100644
index 000000000..1b7df83aa
--- /dev/null
+++ b/inc/geshi/mirc.php
@@ -0,0 +1,171 @@
+<?php
+/*************************************************************************************
+ * mirc.php
+ * -----
+ * Author: Alberto 'Birckin' de Areba (Birckin@hotmail.com)
+ * Copyright: (c) 2006 Alberto de Areba
+ * Release Version: 1.0.8.8
+ * 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://www.mirc.com/{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\$\|\#;<^&])'
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/mmix.php b/inc/geshi/mmix.php
new file mode 100644
index 000000000..3e90dce29
--- /dev/null
+++ b/inc/geshi/mmix.php
@@ -0,0 +1,173 @@
+<?php
+/*************************************************************************************
+ * mmix.php
+ * -------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2009 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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 => ';'),
+ 'COMMENT_MULTI' => array(),
+ //Line address prefix suppression
+ 'COMMENT_REGEXP' => array(2 => "/^\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' => '',
+ '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','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'
+ ),
+ /*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: #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;'
+ ),
+ '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_<\|%])"
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/modula2.php b/inc/geshi/modula2.php
new file mode 100644
index 000000000..042e7404a
--- /dev/null
+++ b/inc/geshi/modula2.php
@@ -0,0 +1,136 @@
+<?php
+/****************************************************************************
+ * modula2.php
+ * -----------
+ * Author: Benjamin Kowarsch (benjamin@modula2.net)
+ * Copyright: (c) 2009 Benjamin Kowarsch (benjamin@modula2.net)
+ * Release Version: 1.0.8.8
+ * 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/modula3.php b/inc/geshi/modula3.php
new file mode 100644
index 000000000..ad827a3e6
--- /dev/null
+++ b/inc/geshi/modula3.php
@@ -0,0 +1,135 @@
+<?php
+/*************************************************************************************
+ * modula3.php
+ * ----------
+ * Author: mbishop (mbishop@esoteriq.org)
+ * Copyright: (c) 2009 mbishop (mbishop@esoteriq.org)
+ * Release Version: 1.0.8.8
+ * 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', 'OVERRIDE', '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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/mpasm.php b/inc/geshi/mpasm.php
new file mode 100644
index 000000000..59247ff69
--- /dev/null
+++ b/inc/geshi/mpasm.php
@@ -0,0 +1,164 @@
+<?php
+/*************************************************************************************
+ * mpasm.php
+ * ---------
+ * Author: Bakalex (bakalex@gmail.com)
+ * Copyright: (c) 2004 Bakalex, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/mxml.php b/inc/geshi/mxml.php
new file mode 100644
index 000000000..df4c9d50e
--- /dev/null
+++ b/inc/geshi/mxml.php
@@ -0,0 +1,145 @@
+<?php
+/*************************************************************************************
+ * mxml.php
+ * -------
+ * Author: David Spurr
+ * Copyright: (c) 2007 David Spurr (http://www.defusion.org.uk/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/mysql.php b/inc/geshi/mysql.php
new file mode 100644
index 000000000..ca171733f
--- /dev/null
+++ b/inc/geshi/mysql.php
@@ -0,0 +1,475 @@
+<?php
+/*************************************************************************************
+ * mysql.php
+ * ---------
+ * Author: Marjolein Katsma (marjolein.is.back@gmail.com)
+ * Copyright: (c) 2008 Marjolein Katsma (http://blog.marjoleinkatsma.com/)
+ * Release Version: 1.0.8.8
+ * 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','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','PREV','PRIMARY KEY','PRIVILEGES','PROCEDURE','PURGE',
+ 'QUICK','READS SQL DATA','READ','REFERENCES','RELEASE','RENAME',
+ '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,
+ 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 => 'http://search.mysql.com/search?site=refman-%35%31&amp;q={FNAME}',
+ 2 => 'http://search.mysql.com/search?site=refman-%35%31&amp;q={FNAME}',
+ 3 => 'http://search.mysql.com/search?site=refman-%35%31&amp;q={FNAME}',
+ 4 => 'http://search.mysql.com/search?site=refman-%35%31&amp;q={FNAME}',
+ 5 => 'http://search.mysql.com/search?site=refman-%35%31&amp;q={FNAME}',
+ 6 => 'http://search.mysql.com/search?site=refman-%35%31&amp;q={FNAME}',
+ 7 => 'http://search.mysql.com/search?site=refman-%35%31&amp;q={FNAME}',
+ 8 => 'http://search.mysql.com/search?site=refman-%35%31&amp;q={FNAME}',
+ 9 => 'http://search.mysql.com/search?site=refman-%35%31&amp;q={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' => '(?=\()'
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/newlisp.php b/inc/geshi/newlisp.php
new file mode 100644
index 000000000..027e86588
--- /dev/null
+++ b/inc/geshi/newlisp.php
@@ -0,0 +1,191 @@
+<?php
+/*************************************************************************************
+ * newlisp.php
+ * ----------
+ * Author: cormullion (cormullion@mac.com) Sept 2009
+ * Copyright: (c) 2009 Cormullion (http://unbalanced-parentheses.nfshost.com/)
+ * Release Version: 1.0.8.8
+ * 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\-])',
+ )
+ ),
+
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/nsis.php b/inc/geshi/nsis.php
new file mode 100644
index 000000000..5631a8389
--- /dev/null
+++ b/inc/geshi/nsis.php
@@ -0,0 +1,351 @@
+<?php
+/*************************************************************************************
+ * nsis.php
+ * --------
+ * Author: deguix (cevo_deguix@yahoo.com.br), Tux (http://tux.a4.cz/)
+ * Copyright: (c) 2005 deguix, 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * Date Started: 2005/12/03
+ *
+ * Nullsoft Scriptable Install System language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 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(
+ '!appendfile', '!addIncludeDir', '!addplugindir', '!cd', '!define', '!delfile', '!echo', '!else',
+ '!endif', '!error', '!execute', '!ifdef', '!ifmacrodef', '!ifmacrondef', '!ifndef', '!include',
+ '!insertmacro', '!macro', '!macroend', '!packhdr', '!tempfile', '!system', '!undef', '!verbose',
+ '!warning'
+ ),
+ 2 => array(
+ 'AddBrandingImage', 'AllowRootDirInstall', 'AutoCloseWindow', 'BGFont',
+ 'BGGradient', 'BrandingText', 'Caption', 'ChangeUI', 'CheckBitmap', 'CompletedText', 'ComponentText',
+ 'CRCCheck', 'DetailsButtonText', 'DirShow', 'DirText', 'DirVar', 'DirVerify', 'FileErrorText',
+ 'Function', 'FunctionEnd', 'Icon', 'InstallButtonText', 'InstallColors', 'InstallDir',
+ 'InstallDirRegKey', 'InstProgressFlags', 'InstType', 'LangString', 'LangStringUP', 'LicenseBkColor',
+ 'LicenseData', 'LicenseForceSelection', 'LicenseLangString', 'LicenseText', 'LoadLanguageFile',
+ 'MiscButtonText', 'Name', 'OutFile', 'Page', 'PageEx', 'PageExEnd', 'Section',
+ 'SectionEnd', 'SectionGroup', 'SectionGroupEnd', 'SetCompressor', 'SetFont', 'ShowInstDetails',
+ 'ShowUninstDetails', 'SilentInstall', 'SilentUnInstall', 'SpaceTexts', 'SubCaption', 'SubSection',
+ 'SubSectionEnd', 'UninstallButtonText', 'UninstallCaption', 'UninstallIcon', 'UninstallSubCaption',
+ 'UninstallText', 'UninstPage', 'Var', 'VIAddVersionKey', 'VIProductVersion', 'WindowIcon', 'XPStyle'
+ ),
+ 3 => array(
+ 'AddSize', 'AllowSkipFiles', 'FileBufSize', 'GetInstDirError', 'PageCallbacks',
+ 'SectionIn', 'SetCompress', 'SetCompressionLevel', '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', 'FileSeek', 'FileWrite', 'FileWriteByte', 'FindClose', 'FindFirst', 'FindNext',
+ 'FindWindow', 'FlushINI', 'GetCurInstType', 'GetCurrentAddress', 'GetDlgItem', 'GetDLLVersion',
+ 'GetDLLVersionLocal', 'GetErrorLevel', 'GetFileTime', 'GetFileTimeLocal', 'GetFullPathName',
+ 'GetFunctionAddress', 'GetLabelAddress', 'GetTempFileName', 'GetWindowText', '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', 'SetShellVarContext', 'SetSilent', 'ShowWindow', 'Sleep', 'StrCmp',
+ '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/inc/geshi/oberon2.php b/inc/geshi/oberon2.php
new file mode 100644
index 000000000..8339f3fb8
--- /dev/null
+++ b/inc/geshi/oberon2.php
@@ -0,0 +1,135 @@
+<?php
+/*************************************************************************************
+ * oberon2.php
+ * ----------
+ * Author: mbishop (mbishop@esoteriq.org)
+ * Copyright: (c) 2009 mbishop (mbishop@esoteriq.org)
+ * Release Version: 1.0.8.8
+ * 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/objc.php b/inc/geshi/objc.php
new file mode 100644
index 000000000..5a5c5940f
--- /dev/null
+++ b/inc/geshi/objc.php
@@ -0,0 +1,358 @@
+<?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.8.8
+ * 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/inc/geshi/ocaml-brief.php b/inc/geshi/ocaml-brief.php
new file mode 100644
index 000000000..2e2a82fb2
--- /dev/null
+++ b/inc/geshi/ocaml-brief.php
@@ -0,0 +1,112 @@
+<?php
+/*************************************************************************************
+ * ocaml.php
+ * ----------
+ * Author: Flaie (fireflaie@gmail.com)
+ * Copyright: (c) 2005 Flaie, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/ocaml.php b/inc/geshi/ocaml.php
new file mode 100644
index 000000000..46e6a22aa
--- /dev/null
+++ b/inc/geshi/ocaml.php
@@ -0,0 +1,187 @@
+<?php
+/*************************************************************************************
+ * ocaml.php
+ * ----------
+ * Author: Flaie (fireflaie@gmail.com)
+ * Copyright: (c) 2005 Flaie, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/oobas.php b/inc/geshi/oobas.php
new file mode 100644
index 000000000..6f6e13fc2
--- /dev/null
+++ b/inc/geshi/oobas.php
@@ -0,0 +1,135 @@
+<?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.8.8
+ * 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/inc/geshi/oracle11.php b/inc/geshi/oracle11.php
new file mode 100644
index 000000000..f57c3f044
--- /dev/null
+++ b/inc/geshi/oracle11.php
@@ -0,0 +1,614 @@
+<?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.8.8
+ * 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/inc/geshi/oracle8.php b/inc/geshi/oracle8.php
new file mode 100644
index 000000000..e470e0dd4
--- /dev/null
+++ b/inc/geshi/oracle8.php
@@ -0,0 +1,496 @@
+<?php
+/*************************************************************************************
+ * oracle8.php
+ * -----------
+ * Author: Guy Wicks (Guy.Wicks@rbs.co.uk)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/oxygene.php b/inc/geshi/oxygene.php
new file mode 100644
index 000000000..3af03bfc2
--- /dev/null
+++ b/inc/geshi/oxygene.php
@@ -0,0 +1,152 @@
+<?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.8.8
+ * Date Started: 2010/01/11
+ *
+ * Delphi Prism (Oxygene) language file for GeSHi.
+ * Based on the original Delphi language file.
+ *
+ * CHANGES
+ * -------
+ * 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 (Delphi Prism)',
+ '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'
+ ),
+ 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'
+ ),
+ 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/oz.php b/inc/geshi/oz.php
new file mode 100644
index 000000000..cd594d4ca
--- /dev/null
+++ b/inc/geshi/oz.php
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * oz.php
+ * --------
+ * Author: Wolfgang Meyer (Wolfgang.Meyer@gmx.net)
+ * Copyright: (c) 2010 Wolfgang Meyer
+ * Release Version: 1.0.8.8
+ * 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 => ''
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/pascal.php b/inc/geshi/pascal.php
new file mode 100644
index 000000000..7ee5729a6
--- /dev/null
+++ b/inc/geshi/pascal.php
@@ -0,0 +1,152 @@
+<?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.8.8
+ * 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('{' => '}','(*' => '*)'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => 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','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'
+ ),
+ ),
+ '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: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #000066; 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;',
+ '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/inc/geshi/pcre.php b/inc/geshi/pcre.php
new file mode 100644
index 000000000..a67cf2858
--- /dev/null
+++ b/inc/geshi/pcre.php
@@ -0,0 +1,188 @@
+<?php
+/*************************************************************************************
+ * pcre.php
+ * --------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2010 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/per.php b/inc/geshi/per.php
new file mode 100644
index 000000000..b656c105e
--- /dev/null
+++ b/inc/geshi/per.php
@@ -0,0 +1,302 @@
+<?php
+/*************************************************************************************
+ * per.php
+ * --------
+ * Author: Lars Gersmann (lars.gersmann@gmail.com)
+ * Copyright: (c) 2007 Lars Gersmann
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/perl.php b/inc/geshi/perl.php
new file mode 100644
index 000000000..5d1c4320b
--- /dev/null
+++ b/inc/geshi/perl.php
@@ -0,0 +1,213 @@
+<?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.8.8
+ * 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' => '$'
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/perl6.php b/inc/geshi/perl6.php
new file mode 100644
index 000000000..9ea20fc78
--- /dev/null
+++ b/inc/geshi/perl6.php
@@ -0,0 +1,197 @@
+<?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.8.8
+ * 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' => '$'
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/pf.php b/inc/geshi/pf.php
new file mode 100644
index 000000000..d59a609d5
--- /dev/null
+++ b/inc/geshi/pf.php
@@ -0,0 +1,178 @@
+<?php
+/*************************************************************************************
+ * pf.php
+ * --------
+ * Author: David Berard (david@nfrance.com)
+ * Copyright: (c) 2010 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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_%\\/])"
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/php-brief.php b/inc/geshi/php-brief.php
new file mode 100644
index 000000000..c28d985f4
--- /dev/null
+++ b/inc/geshi/php-brief.php
@@ -0,0 +1,222 @@
+<?php
+/*************************************************************************************
+ * php-brief.php
+ * -------------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
+ ),
+ '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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/php.php b/inc/geshi/php.php
new file mode 100644
index 000000000..ec6981134
--- /dev/null
+++ b/inc/geshi/php.php
@@ -0,0 +1,1114 @@
+<?php
+/*************************************************************************************
+ * php.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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',
+
+ 'echo','print'
+ ),
+ 2 => array(
+ '&amp;new','&lt;/script&gt;','&lt;?php','&lt;script language',
+ 'class','const','declare','extends','function','global','interface',
+ 'namespace','new','private','protected','public','self','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 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
+ ),
+ '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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/pic16.php b/inc/geshi/pic16.php
new file mode 100644
index 000000000..626a768b0
--- /dev/null
+++ b/inc/geshi/pic16.php
@@ -0,0 +1,141 @@
+<?php
+/*************************************************************************************
+ * pic16.php
+ * -------
+ * Author: Phil Mattison (mattison@ohmikron.com)
+ * Copyright: (c) 2008 Ohmikron Corp. (http://www.ohmikron.com/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/pike.php b/inc/geshi/pike.php
new file mode 100644
index 000000000..2b860ccd6
--- /dev/null
+++ b/inc/geshi/pike.php
@@ -0,0 +1,103 @@
+<?php
+/*************************************************************************************
+ * pike.php
+ * --------
+ * Author: Rick E. (codeblock@eighthbit.net)
+ * Copyright: (c) 2009 Rick E.
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/pixelbender.php b/inc/geshi/pixelbender.php
new file mode 100644
index 000000000..82c64ae52
--- /dev/null
+++ b/inc/geshi/pixelbender.php
@@ -0,0 +1,176 @@
+<?php
+/*************************************************************************************
+ * pixelbender.php
+ * ----------------
+ * Author: Richard Olsson (r@richardolsson.se)
+ * Copyright: (c) 2008 Richard Olsson (richardolsson.se)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/plsql.php b/inc/geshi/plsql.php
new file mode 100644
index 000000000..e0145362c
--- /dev/null
+++ b/inc/geshi/plsql.php
@@ -0,0 +1,256 @@
+<?php
+/*************************************************************************************
+ * plsql.php
+ * -------
+ * Author: Victor Engmark <victor.engmark@gmail.com>
+ * Copyright: (c) 2006 Victor Engmark (http://l0b0.net/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/postgresql.php b/inc/geshi/postgresql.php
new file mode 100644
index 000000000..7f89fe2a4
--- /dev/null
+++ b/inc/geshi/postgresql.php
@@ -0,0 +1,288 @@
+<?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.8.8
+ * 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])'
+ ),
+ )
+ )
+
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/povray.php b/inc/geshi/povray.php
new file mode 100644
index 000000000..c987a013e
--- /dev/null
+++ b/inc/geshi/povray.php
@@ -0,0 +1,199 @@
+<?php
+/*************************************************************************************
+ * povray.php
+ * --------
+ * Author: Carl Fürstenberg (azatoth@gmail.com)
+ * Copyright: © 2007 Carl Fürstenberg
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/powerbuilder.php b/inc/geshi/powerbuilder.php
new file mode 100644
index 000000000..ef86c242c
--- /dev/null
+++ b/inc/geshi/powerbuilder.php
@@ -0,0 +1,418 @@
+<?php
+/*************************************************************************************
+ * powerbuilder.php
+ * ------
+ * Author: Doug Porter (powerbuilder.geshi@gmail.com)
+ * Copyright: (c) 2009 Doug Porter
+ * Release Version: 1.0.8.8
+ * 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!', '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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/powershell.php b/inc/geshi/powershell.php
new file mode 100644
index 000000000..c90538809
--- /dev/null
+++ b/inc/geshi/powershell.php
@@ -0,0 +1,277 @@
+<?php
+/*************************************************************************************
+ * powershell.php
+ * ---------------------------------
+ * Author: Frode Aarebrot (frode@aarebrot.net)
+ * Copyright: (c) 2008 Frode Aarebrot (http://www.aarebrot.net)
+ * Release Version: 1.0.8.8
+ * 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' => '(?<!\$>)\$'
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/progress.php b/inc/geshi/progress.php
new file mode 100644
index 000000000..90c3bf0fa
--- /dev/null
+++ b/inc/geshi/progress.php
@@ -0,0 +1,485 @@
+<?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.8.8
+ * 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
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/prolog.php b/inc/geshi/prolog.php
new file mode 100644
index 000000000..4dd01ff7e
--- /dev/null
+++ b/inc/geshi/prolog.php
@@ -0,0 +1,143 @@
+<?php
+/*************************************************************************************
+ * prolog.php
+ * --------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/properties.php b/inc/geshi/properties.php
new file mode 100644
index 000000000..9fc8b8da4
--- /dev/null
+++ b/inc/geshi/properties.php
@@ -0,0 +1,127 @@
+<?php
+/*************************************************************************************
+ * properties.php
+ * --------
+ * Author: Edy Hinzen
+ * Copyright: (c) 2009 Edy Hinzen
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/providex.php b/inc/geshi/providex.php
new file mode 100644
index 000000000..0352ac2a1
--- /dev/null
+++ b/inc/geshi/providex.php
@@ -0,0 +1,299 @@
+<?php
+/******************************************************************************
+ * providex.php
+ * ----------
+ * Author: Jeff Wilder (jeff@coastallogix.com)
+ * Copyright: (c) 2008 Coastal Logix (http://www.coastallogix.com)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/purebasic.php b/inc/geshi/purebasic.php
new file mode 100644
index 000000000..b24986f57
--- /dev/null
+++ b/inc/geshi/purebasic.php
@@ -0,0 +1,303 @@
+<?php
+/*************************************************************************************
+ * purebasic.php
+ * -------
+ * Author: GuShH
+ * Copyright: (c) 2009 Gustavo Julio Fiorenza
+ * Release Version: 1.0.8.8
+ * 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
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/python.php b/inc/geshi/python.php
new file mode 100644
index 000000000..1be7e2953
--- /dev/null
+++ b/inc/geshi/python.php
@@ -0,0 +1,237 @@
+<?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.8.8
+ * 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' => '\\',
+ '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'
+ ),
+
+ /*
+ ** 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(
+ '(', ')', '[', ']', '{', '}', '*', '&', '%', '!', ';', '<', '>', '?', '`'
+ ),
+ '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/inc/geshi/q.php b/inc/geshi/q.php
new file mode 100644
index 000000000..9629ded4a
--- /dev/null
+++ b/inc/geshi/q.php
@@ -0,0 +1,149 @@
+<?php
+/*************************************************************************************
+ * q.php
+ * -----
+ * Author: Ian Roddis (ian.roddis@proteanmind.net)
+ * Copyright: (c) 2008 Ian Roddis (http://proteanmind.net)
+ * Release Version: 1.0.8.8
+ * 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 => '',
+ ),
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/qbasic.php b/inc/geshi/qbasic.php
new file mode 100644
index 000000000..da4372258
--- /dev/null
+++ b/inc/geshi/qbasic.php
@@ -0,0 +1,158 @@
+<?php
+/*************************************************************************************
+ * qbasic.php
+ * ----------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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' => '',
+ '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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/rails.php b/inc/geshi/rails.php
new file mode 100644
index 000000000..64d83ea16
--- /dev/null
+++ b/inc/geshi/rails.php
@@ -0,0 +1,406 @@
+<?php
+/*************************************************************************************
+ * rails.php
+ * ---------
+ * Author: Moises Deniz
+ * Copyright: (c) 2005 Moises Deniz
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/rebol.php b/inc/geshi/rebol.php
new file mode 100644
index 000000000..a3889eec9
--- /dev/null
+++ b/inc/geshi/rebol.php
@@ -0,0 +1,196 @@
+<?php
+/*************************************************************************************
+ * rebol.php
+ * --------
+ * Author: Lecanu Guillaume (Guillaume@LyA.fr)
+ * Copyright: (c) 2004-2005 Lecanu Guillaume (Guillaume@LyA.fr)
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/reg.php b/inc/geshi/reg.php
new file mode 100644
index 000000000..bb2e845f3
--- /dev/null
+++ b/inc/geshi/reg.php
@@ -0,0 +1,233 @@
+<?php
+/*************************************************************************************
+ * reg.php
+ * -------
+ * Author: Sean Hanna (smokingrope@gmail.com)
+ * Copyright: (c) 2006 Sean Hanna
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/robots.php b/inc/geshi/robots.php
new file mode 100644
index 000000000..baf286b7f
--- /dev/null
+++ b/inc/geshi/robots.php
@@ -0,0 +1,100 @@
+<?php
+/*************************************************************************************
+ * robots.php
+ * --------
+ * Author: Christian Lescuyer (cl@goelette.net)
+ * Copyright: (c) 2006 Christian Lescuyer http://xtian.goelette.info
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/rpmspec.php b/inc/geshi/rpmspec.php
new file mode 100644
index 000000000..96dc9556f
--- /dev/null
+++ b/inc/geshi/rpmspec.php
@@ -0,0 +1,133 @@
+<?php
+/*************************************************************************************
+ * rpmspec.php
+ * ---------------------------------
+ * Author: Paul Grinberg (gri6507 TA unity-linux TOD org)
+ * Copyright: (c) 2010 Paul Grinberg
+ * Release Version: 1.0.8.8
+ * 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(),
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/rsplus.php b/inc/geshi/rsplus.php
new file mode 100644
index 000000000..b73f5ea77
--- /dev/null
+++ b/inc/geshi/rsplus.php
@@ -0,0 +1,483 @@
+<?php
+/*************************************************************************************
+ * rsplus.php
+ * ———–
+ * Author: Ron Fredericks (ronf@LectureMaker.com)
+ * Contributors:
+ * - Benilton Carvalho (beniltoncarvalho@gmail.com)
+ * Copyright: (c) 2009 Ron Fredericks (http://www.LectureMaker.com)
+ * Release Version: 1.0.8.8
+ * 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', 'methods', '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://astrostatistics.psu.edu/su07/R/html/graphics/html/{FNAME}.html', // http://sekhon.berkeley.edu/library/graphics/html/{FNAME}.html
+ 3 => 'http://astrostatistics.psu.edu/su07/R/html/stats/html/Normal.html', // http://sekhon.berkeley.edu/library/stats/html/Normal.html
+ 4 => 'http://astrostatistics.psu.edu/su07/R/html/stats/html/{FNAME}.html', // http://sekhon.berkeley.edu/library/stats/html/{FNAME}.html
+ 5 => 'http://astrostatistics.psu.edu/su07/R/html/stats/html/summary.lm.html', // http://sekhon.berkeley.edu/library/stats/html/summary.lm.html
+ 6 => 'http://astrostatistics.psu.edu/su07/R/html/base/html/Log.html', // http://sekhon.berkeley.edu/library/base/html/Log.html
+ 7 => '',
+ 8 => ''
+ ),
+ '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_\|%\\-&;\\.])"
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/ruby.php b/inc/geshi/ruby.php
new file mode 100644
index 000000000..47ecbb2e2
--- /dev/null
+++ b/inc/geshi/ruby.php
@@ -0,0 +1,231 @@
+<?php
+/*************************************************************************************
+ * ruby.php
+ * --------
+ * Author: Moises Deniz
+ * Copyright: (c) 2007 Moises Deniz
+ * Release Version: 1.0.8.8
+ * 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/sas.php b/inc/geshi/sas.php
new file mode 100644
index 000000000..c4d426fa0
--- /dev/null
+++ b/inc/geshi/sas.php
@@ -0,0 +1,290 @@
+<?php
+/*************************************************************************************
+ * sas.php
+ * -------
+ * Author: Galen Johnson (solitaryr@gmail.com)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/scala.php b/inc/geshi/scala.php
new file mode 100644
index 000000000..202c06c83
--- /dev/null
+++ b/inc/geshi/scala.php
@@ -0,0 +1,122 @@
+<?php
+/*************************************************************************************
+ * scala.php
+ * ----------
+ * Author: Franco Lombardo (franco@francolombardo.net)
+ * Copyright: (c) 2008 Franco Lombardo, Benny Baumann
+ * Release Version: 1.0.8.8
+ * 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('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ '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;',
+ 'MULTI' => 'color: #00ff00; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #0000ff; 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/inc/geshi/scheme.php b/inc/geshi/scheme.php
new file mode 100644
index 000000000..2e2430bff
--- /dev/null
+++ b/inc/geshi/scheme.php
@@ -0,0 +1,170 @@
+<?php
+/*************************************************************************************
+ * scheme.php
+ * ----------
+ * Author: Jon Raphaelson (jonraphaelson@gmail.com)
+ * Copyright: (c) 2005 Jon Raphaelson, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/scilab.php b/inc/geshi/scilab.php
new file mode 100644
index 000000000..d1ff6fc16
--- /dev/null
+++ b/inc/geshi/scilab.php
@@ -0,0 +1,295 @@
+<?php
+/*************************************************************************************
+ * scilab.php
+ * --------
+ * Author: Christophe David (geshi@christophedavid.org)
+ * Copyright: (c) 2008 Christophe David (geshi@christophedavid.org)
+ * Release Version: 1.0.8.8
+ * 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',
+ 'scilab', 'Scilab', '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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/sdlbasic.php b/inc/geshi/sdlbasic.php
new file mode 100644
index 000000000..876dc09a6
--- /dev/null
+++ b/inc/geshi/sdlbasic.php
@@ -0,0 +1,165 @@
+<?php
+/*************************************************************************************
+ * sdlbasic.php
+ * ------------
+ * Author: Roberto Rossi
+ * Copyright: (c) 2005 Roberto Rossi (http://rsoftware.altervista.org)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/smalltalk.php b/inc/geshi/smalltalk.php
new file mode 100644
index 000000000..b475ad711
--- /dev/null
+++ b/inc/geshi/smalltalk.php
@@ -0,0 +1,154 @@
+<?php
+/*************************************************************************************
+ * smalltalk.php
+ * --------
+ * Author: Bananeweizen (Bananeweizen@gmx.de)
+ * Copyright: (c) 2005 Bananeweizen (www.bananeweizen.de)
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/smarty.php b/inc/geshi/smarty.php
new file mode 100644
index 000000000..7f4489289
--- /dev/null
+++ b/inc/geshi/smarty.php
@@ -0,0 +1,192 @@
+<?php
+/*************************************************************************************
+ * smarty.php
+ * ----------
+ * Author: Alan Juden (alan@judenware.org)
+ * Copyright: (c) 2004 Alan Juden, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/sql.php b/inc/geshi/sql.php
new file mode 100644
index 000000000..9e45e850d
--- /dev/null
+++ b/inc/geshi/sql.php
@@ -0,0 +1,140 @@
+<?php
+/*************************************************************************************
+ * sql.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * Date Started: 2004/06/04
+ *
+ * SQL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 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', 'BETWEEN', 'BINARY', 'BOOLEAN',
+ 'BOTH', 'BY', 'CHANGE', 'CHECK', 'COLUMN', 'COLUMNS',
+ 'CREATE', 'CROSS', 'DATA', 'DATABASE', 'DATABASES',
+ 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE',
+ 'DISTINCT', 'DROP', 'ENCLOSED', 'ESCAPED', 'EXISTS',
+ 'EXPLAIN', 'FIELD', 'FIELDS', 'FLUSH', 'FOR',
+ 'FOREIGN', 'FROM', 'FULL', 'FUNCTION', 'GRANT',
+ 'GROUP', 'HAVING', 'IDENTIFIED', 'IF', 'IGNORE',
+ 'IN', 'INDEX', 'INFILE', 'INNER', 'INSERT', 'INTO',
+ 'IS', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LANGUAGE',
+ 'LEADING', 'LEFT', 'LIKE', 'LIMIT', 'LINES', 'LOAD',
+ 'LOCAL', 'LOCK', 'LOW_PRIORITY', 'MODIFY', 'NATURAL',
+ 'NEXTVAL', 'NOT', 'NULL', 'ON', 'OPTIMIZE', 'OPTION',
+ 'OPTIONALLY', 'OR', 'ORDER', 'OUTER', 'OUTFILE',
+ 'PRIMARY', 'PROCEDURAL', 'PROCEEDURE', 'READ',
+ 'REFERENCES', 'REGEXP', 'RENAME', 'REPLACE',
+ 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SELECT',
+ 'SET', 'SETVAL', 'SHOW', 'SONAME', 'STATUS',
+ 'STRAIGHT_JOIN', 'TABLE', 'TABLES', 'TEMINATED',
+ 'TEMPORARY', 'TO', 'TRAILING', 'TRIGGER', 'TRUNCATE',
+ 'TRUSTED', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED',
+ 'UPDATE', 'USE', 'USING', 'VALUES', 'VARIABLES',
+ 'VIEW', 'WHERE', 'WITH', 'WRITE', 'XOR', '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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/systemverilog.php b/inc/geshi/systemverilog.php
new file mode 100644
index 000000000..19405c097
--- /dev/null
+++ b/inc/geshi/systemverilog.php
@@ -0,0 +1,317 @@
+<?php
+/************************************************************************************
+ * systemverilog.php
+ * -------
+ * Author: Sean O'Boyle
+ * Copyright: (C) 2008 IntelligentDV
+ * Release Version: 1.0.8.8
+ * 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: seanoboyle $
+ * $LastChangedDate: 2009-07-22 22:20:25 -0700 (Wed, 22 Jul 2009) $
+ * $LastChangedRevision: 17 $
+ *
+ ************************************************************************/
+
+$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' => '(?<=$)'
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/tcl.php b/inc/geshi/tcl.php
new file mode 100644
index 000000000..2a07ccd46
--- /dev/null
+++ b/inc/geshi/tcl.php
@@ -0,0 +1,194 @@
+<?php
+/*************************************************************************************
+ * tcl.php
+ * ---------------------------------
+ * Author: Reid van Melle (rvanmelle@gmail.com)
+ * Copyright: (c) 2004 Reid van Melle (sorry@nowhere)
+ * Release Version: 1.0.8.8
+ * 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(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(
+ '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' => '\\'
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/teraterm.php b/inc/geshi/teraterm.php
new file mode 100644
index 000000000..443bf7b4c
--- /dev/null
+++ b/inc/geshi/teraterm.php
@@ -0,0 +1,317 @@
+<?php
+/*************************************************************************************
+ * teraterm.php
+ * --------
+ * Author: Boris Maisuradze (boris at logmett.com)
+ * Copyright: (c) 2008 Boris Maisuradze (http://logmett.com)
+ * Release Version: 1.0.8.8
+ * Date Started: 2008/09/26
+ *
+ * Tera Term Macro language file for GeSHi.
+ *
+ *
+ * This version of ttl.php was created for Tera Term 4.60 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 ttl.php
+ * can be downloaded from Download section of LogMeTT.com
+ *
+ * CHANGES
+ * -------
+ * 2008/09/26 (1.0.8)
+ * - First Release for Tera Term 4.60 and below.
+ *
+ * TODO (updated 2008/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' => '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', // (version 4.53 or later)
+ 'Call',
+ 'CallMenu', // (version 4.56 or later)
+ 'ChangeDir',
+ 'ClearScreen',
+ 'Clipb2Var', //(version 4.46 or later)
+ 'ClosesBox',
+ 'CloseTT',
+ 'Code2Str',
+ 'Connect',
+ 'CRC32', // (version 4.60 or later)
+ 'CRC32File', // (version 4.60 or later)
+ 'CygConnect', // (version 4.57 or later)
+ 'DelPassword',
+ 'Disconnect',
+ 'Do', // (version 4.56 or later)
+ 'Else',
+ 'EnableKeyb',
+ 'End',
+ 'EndIf',
+ 'EndUntil', // (version 4.56 or later)
+ 'EndWhile',
+ 'Exec',
+ 'ExecCmnd',
+ 'Exit',
+ 'FileClose',
+ 'FileConcat',
+ 'FileCopy',
+ 'FileCreate',
+ 'FileDelete',
+ 'FileMarkPtr',
+ 'FilenameBox', //(version 4.54 or later)
+ 'FileOpen',
+ 'FileRead',
+ 'FileReadln', // (version 4.48 or later)
+ 'FileRename',
+ 'FileSearch',
+ 'FileSeek',
+ 'FileSeekBack',
+ 'FileStrSeek',
+ 'FileStrSeek2',
+ 'FileWrite',
+ 'FileWriteln',
+ 'FindOperations',
+ 'FlushRecv',
+ 'ForNext',
+ 'GetDate',
+ 'GetDir', //(version 4.46 or later)
+ 'GetEnv',
+ 'GetPassword',
+ 'GetTime',
+ 'GetTitle',
+ 'GetVer', //(version 4.58 or later)
+ 'GoTo',
+ 'If',
+ 'IfDefined', // (version 4.46 or later)
+ 'IfThenElseIf',
+ 'Include',
+ 'InputBox',
+ 'Int2Str',
+ 'KmtFinish',
+ 'KmtGet',
+ 'KmtRecv',
+ 'KmtSend',
+ 'LoadKeyMap',
+ 'LogClose',
+ 'LogOpen',
+ 'LogPause',
+ 'LogStart',
+ 'LogWrite',
+ 'Loop', // (version 4.56 or later)
+ 'MakePath',
+ 'MessageBox',
+ 'MPause', // (version 4.27 or later)
+ 'PasswordBox',
+ 'Pause',
+ 'QuickvanRecv',
+ 'QuickvanSend',
+ 'Random', //(version 4.27 or later)
+ 'Recvln',
+ 'RestoreSetup',
+ 'Return',
+ 'RotateLeft', //(version 4.54 or later)
+ 'RotateRight', //(version 4.54 or later)
+ 'ScpRecv', // (version 4.57 or later)
+ 'ScpSend', // (version 4.57 or later)
+ 'Send',
+ 'SendBreak',
+ 'SendFile',
+ 'SendKcode',
+ 'Sendln',
+ 'SetBaud', // (version 4.58 or later)
+ 'SetDate',
+ 'SetDir',
+ 'SetDlgPos',
+ 'SetDTR', // (version 4.59 or later)
+ 'SetRTS', // (version 4.59 or later)
+ 'SetEnv', // (version 4.54 or later)
+ 'SetEcho',
+ 'SetExitCode',
+ 'SetSync',
+ 'SetTime',
+ 'SetTitle',
+ 'Show',
+ 'ShowTT',
+ 'Sprintf', // (version 4.52 or later)
+ 'StatusBox',
+ 'Str2Code',
+ 'Str2Int',
+ 'StrCompare',
+ 'StrConcat',
+ 'StrCopy',
+ 'StrLen',
+ 'StrMatch', // (version 4.59 or later)
+ 'StrScan',
+ 'Testlink',
+ 'Then',
+ 'ToLower', //(version 4.53 or later)
+ 'ToUpper', //(version 4.53 or later)
+ 'Unlink',
+ 'Until', // (version 4.56 or later)
+ 'Var2Clipb', //(version 4.46 or later)
+ 'Wait',
+ 'WaitEvent',
+ 'Waitln',
+ 'WaitRecv',
+ 'WaitRegex', // (version 4.21 or later)
+ 'While',
+ 'XmodemRecv',
+ 'XmodemSend',
+ 'YesNoBox',
+ 'ZmodemRecv',
+ 'ZmodemSend'
+ ),
+ /* System Variables */
+ 2 => array(
+ 'groupmatchstr1',
+ 'groupmatchstr2',
+ 'groupmatchstr3',
+ 'groupmatchstr4',
+ 'groupmatchstr5',
+ 'groupmatchstr6',
+ 'groupmatchstr7',
+ 'groupmatchstr8',
+ 'groupmatchstr9',
+ 'inputstr',
+ 'matchstr',
+ 'param2',
+ 'param3',
+ 'param4',
+ 'param5',
+ 'param6',
+ 'param7',
+ 'param8',
+ 'param9',
+ 'result',
+ 'timeout'
+ ),
+ /* LogMeTT Key Words */
+ 3 => array(
+ '$[1]',
+ '$[2]',
+ '$[3]',
+ '$[4]',
+ '$[5]',
+ '$[6]',
+ '$[7]',
+ '$[8]',
+ '$connection$',
+ '$email$',
+ '$logdir$',
+ '$logfilename$',
+ '$logit$',
+ '$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/inc/geshi/text.php b/inc/geshi/text.php
new file mode 100644
index 000000000..66f459293
--- /dev/null
+++ b/inc/geshi/text.php
@@ -0,0 +1,84 @@
+<?php
+/*************************************************************************************
+ * text.php
+ * --------
+ * Author: Sean Hanna (smokingrope@gmail.com)
+ * Copyright: (c) 2006 Sean Hanna
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/thinbasic.php b/inc/geshi/thinbasic.php
new file mode 100644
index 000000000..693c698d6
--- /dev/null
+++ b/inc/geshi/thinbasic.php
@@ -0,0 +1,868 @@
+<?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.8.8
+ * 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/inc/geshi/tsql.php b/inc/geshi/tsql.php
new file mode 100644
index 000000000..b915b087d
--- /dev/null
+++ b/inc/geshi/tsql.php
@@ -0,0 +1,375 @@
+<?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.8.8
+ * 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("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ // Datatypes
+ 'bigint', 'tinyint', 'money',
+ 'smallmoney', 'datetime', 'smalldatetime',
+ 'text', 'nvarchar', 'ntext', 'varbinary', 'image',
+ 'sql_variant', 'uniqueidentifier',
+
+ // Keywords
+ 'ABSOLUTE', 'ACTION', 'ADD', 'ADMIN', 'AFTER', 'AGGREGATE', 'ALIAS', 'ALLOCATE', 'ALTER', 'ARE', 'ARRAY', 'AS',
+ 'ASC', 'ASSERTION', 'AT', 'AUTHORIZATION', 'BACKUP', 'BEFORE', 'BEGIN', 'BINARY', 'BIT', 'BLOB', 'BOOLEAN', 'BOTH', 'BREADTH',
+ 'BREAK', 'BROWSE', 'BULK', 'BY', 'CALL', 'CASCADE', 'CASCADED', 'CASE', 'CAST', 'CATALOG', 'CHAR', 'CHARACTER', 'CHECK', 'CHECKPOINT',
+ 'CLASS', 'CLOB', 'CLOSE', 'CLUSTERED', 'COALESCE', 'COLLATE', 'COLLATION', 'COLUMN', 'COMMIT', 'COMPLETION', 'COMPUTE', 'CONNECT',
+ 'CONNECTION', 'CONSTRAINT', 'CONSTRAINTS', 'CONSTRUCTOR', 'CONTAINS', 'CONTAINSTABLE', 'CONTINUE', 'CONVERT', 'CORRESPONDING', 'CREATE',
+ 'CUBE', 'CURRENT', 'CURRENT_DATE', 'CURRENT_PATH', 'CURRENT_ROLE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER',
+ 'CURSOR', 'CYCLE', 'DATA', 'DATABASE', 'DATE', 'DAY', 'DBCC', 'DEALLOCATE', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DEFERRABLE',
+ 'DEFERRED', 'DELETE', 'DENY', 'DEPTH', 'DEREF', 'DESC', 'DESCRIBE', 'DESCRIPTOR', 'DESTROY', 'DESTRUCTOR', 'DETERMINISTIC',
+ 'DIAGNOSTICS', 'DICTIONARY', 'DISCONNECT', 'DISK', 'DISTINCT', 'DISTRIBUTED', 'DOMAIN', 'DOUBLE', 'DROP', 'DUMMY', 'DUMP', 'DYNAMIC',
+ 'EACH', 'ELSE', 'END', 'END-EXEC', 'EQUALS', 'ERRLVL', 'ESCAPE', 'EVERY', 'EXCEPT', 'EXCEPTION', 'EXEC', 'EXECUTE', 'EXIT',
+ 'EXTERNAL', 'FALSE', 'FETCH', 'FILE', 'FILLFACTOR', 'FIRST', 'FLOAT', 'FOR', 'FOREIGN', 'FOUND', 'FREE', 'FREETEXT', 'FREETEXTTABLE',
+ 'FROM', 'FULL', 'FUNCTION', 'GENERAL', 'GET', 'GLOBAL', 'GOTO', 'GRANT', 'GROUP', 'GROUPING', 'HAVING', 'HOLDLOCK', 'HOST', 'HOUR',
+ 'IDENTITY', 'IDENTITY_INSERT', 'IDENTITYCOL', 'IF', 'IGNORE', 'IMMEDIATE', 'INDEX', 'INDICATOR', 'INITIALIZE', 'INITIALLY',
+ 'INNER', 'INOUT', 'INPUT', 'INSERT', 'INT', 'INTEGER', 'INTERSECT', 'INTERVAL', 'INTO', 'IS', 'ISOLATION', 'ITERATE', 'KEY',
+ 'KILL', 'LANGUAGE', 'LARGE', 'LAST', 'LATERAL', 'LEADING', 'LEFT', 'LESS', 'LEVEL', 'LIMIT', 'LINENO', 'LOAD', 'LOCAL',
+ 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCATOR', 'MAP', 'MATCH', 'MINUTE', 'MODIFIES', 'MODIFY', 'MODULE', 'MONTH', 'NAMES', 'NATIONAL',
+ 'NATURAL', 'NCHAR', 'NCLOB', 'NEW', 'NEXT', 'NO', 'NOCHECK', 'NONCLUSTERED', 'NONE', 'NULLIF', 'NUMERIC', 'OBJECT', 'OF',
+ 'OFF', 'OFFSETS', 'OLD', 'ON', 'ONLY', 'OPEN', 'OPENDATASOURCE', 'OPENQUERY', 'OPENROWSET', 'OPENXML', 'OPERATION', 'OPTION',
+ 'ORDER', 'ORDINALITY', 'OUT', 'OUTPUT', 'OVER', 'PAD', 'PARAMETER', 'PARAMETERS', 'PARTIAL', 'PATH', 'PERCENT', 'PLAN',
+ 'POSTFIX', 'PRECISION', 'PREFIX', 'PREORDER', 'PREPARE', 'PRESERVE', 'PRIMARY', 'PRINT', 'PRIOR', 'PRIVILEGES', 'PROC', 'PROCEDURE',
+ 'PUBLIC', 'RAISERROR', 'READ', 'READS', 'READTEXT', 'REAL', 'RECONFIGURE', 'RECURSIVE', 'REF', 'REFERENCES', 'REFERENCING', 'RELATIVE',
+ 'REPLICATION', 'RESTORE', 'RESTRICT', 'RESULT', 'RETURN', 'RETURNS', 'REVOKE', 'RIGHT', 'ROLE', 'ROLLBACK', 'ROLLUP', 'ROUTINE', 'ROW',
+ 'ROWGUIDCOL', 'ROWS', 'RULE', 'SAVE', 'SAVEPOINT', 'SCHEMA', 'SCOPE', 'SCROLL', 'SEARCH', 'SECOND', 'SECTION', 'SELECT',
+ 'SEQUENCE', 'SESSION', 'SESSION_USER', 'SET', 'SETS', 'SETUSER', 'SHUTDOWN', 'SIZE', 'SMALLINT', 'SPACE', 'SPECIFIC',
+ 'SPECIFICTYPE', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'START', 'STATE', 'STATEMENT', 'STATIC', 'STATISTICS', 'STRUCTURE',
+ 'SYSTEM_USER', 'TABLE', 'TEMPORARY', 'TERMINATE', 'TEXTSIZE', 'THAN', 'THEN', 'TIME', 'TIMESTAMP', 'TIMEZONE_HOUR', 'TIMEZONE_MINUTE',
+ 'TO', 'TOP', 'TRAILING', 'TRAN', 'TRANSACTION', 'TRANSLATION', 'TREAT', 'TRIGGER', 'TRUE', 'TRUNCATE', 'TSEQUAL', 'UNDER', 'UNION',
+ 'UNIQUE', 'UNKNOWN', 'UNNEST', 'UPDATE', 'UPDATETEXT', 'USAGE', 'USE', 'USER', 'USING', 'VALUE', 'VALUES', 'VARCHAR', 'VARIABLE',
+ 'VARYING', 'VIEW', 'WAITFOR', 'WHEN', 'WHENEVER', 'WHERE', 'WHILE', 'WITH', 'WITHOUT', 'WORK', 'WRITE', 'WRITETEXT', 'YEAR', 'ZONE',
+ 'UNCOMMITTED', 'NOCOUNT',
+ ),
+ 2 => array(
+ /*
+ Built-in functions
+ Highlighted in pink.
+ */
+
+ //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',
+
+ //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',
+
+ //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',
+
+ //Security Functions
+ 'IS_SRVROLEMEMBER','SUSER_SID','SUSER_SNAME','USER_ID',
+ 'HAS_DBACCESS','IS_MEMBER',
+
+ //String Functions
+ 'ASCII','SOUNDEX','PATINDEX','CHARINDEX','REPLACE','STR',
+ 'DIFFERENCE','QUOTENAME','STUFF','REPLICATE','SUBSTRING','LEN',
+ 'REVERSE','UNICODE','LOWER','UPPER','LTRIM','RTRIM',
+
+ //System Functions
+ 'APP_NAME','COLLATIONPROPERTY','@@ERROR','FORMATMESSAGE',
+ 'GETANSINULL','HOST_ID','HOST_NAME','IDENT_CURRENT','IDENT_INCR',
+ 'IDENT_SEED','@@IDENTITY','ISDATE','ISNUMERIC','PARSENAME','PERMISSIONS',
+ '@@ROWCOUNT','ROWCOUNT_BIG','SCOPE_IDENTITY','SERVERPROPERTY','SESSIONPROPERTY',
+ 'STATS_DATE','@@TRANCOUNT','USER_NAME',
+
+ //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'
+ ),
+ 3 => array(
+ /*
+ System stored procedures
+ Higlighted dark brown
+ */
+
+ //Active Directory Procedures
+ 'sp_ActiveDirectory_Obj', 'sp_ActiveDirectory_SCP',
+
+ //Catalog Procedures
+ 'sp_column_privileges', 'sp_special_columns', 'sp_columns', 'sp_sproc_columns',
+ 'sp_databases', 'sp_statistics', 'sp_fkeys', 'sp_stored_procedures', 'sp_pkeys',
+ 'sp_table_privileges', 'sp_server_info', 'sp_tables',
+
+ //Cursor Procedures
+ 'sp_cursor_list', 'sp_describe_cursor_columns', 'sp_describe_cursor', 'sp_describe_cursor_tables',
+
+ //Database Maintenance Plan Procedures
+ 'sp_add_maintenance_plan', 'sp_delete_maintenance_plan_db', 'sp_add_maintenance_plan_db',
+ 'sp_delete_maintenance_plan_job', 'sp_add_maintenance_plan_job', 'sp_help_maintenance_plan',
+ 'sp_delete_maintenance_plan',
+
+ //Distributed Queries Procedures
+ 'sp_addlinkedserver', 'sp_indexes', 'sp_addlinkedsrvlogin', 'sp_linkedservers', 'sp_catalogs',
+ 'sp_primarykeys', 'sp_column_privileges_ex', 'sp_columns_ex',
+ 'sp_table_privileges_ex', 'sp_tables_ex', 'sp_foreignkeys',
+
+ //Full-Text Search Procedures
+ 'sp_fulltext_catalog', 'sp_help_fulltext_catalogs_cursor', 'sp_fulltext_column',
+ 'sp_help_fulltext_columns', 'sp_fulltext_database', 'sp_help_fulltext_columns_cursor',
+ 'sp_fulltext_service', 'sp_help_fulltext_tables', 'sp_fulltext_table',
+ 'sp_help_fulltext_tables_cursor', 'sp_help_fulltext_catalogs',
+
+ //Log Shipping Procedures
+ 'sp_add_log_shipping_database', 'sp_delete_log_shipping_database', 'sp_add_log_shipping_plan',
+ 'sp_delete_log_shipping_plan', 'sp_add_log_shipping_plan_database',
+ 'sp_delete_log_shipping_plan_database', 'sp_add_log_shipping_primary',
+ 'sp_delete_log_shipping_primary', 'sp_add_log_shipping_secondary',
+ 'sp_delete_log_shipping_secondary', 'sp_can_tlog_be_applied', 'sp_get_log_shipping_monitor_info',
+ 'sp_change_monitor_role', 'sp_remove_log_shipping_monitor', 'sp_change_primary_role',
+ 'sp_resolve_logins', 'sp_change_secondary_role', 'sp_update_log_shipping_monitor_info',
+ 'sp_create_log_shipping_monitor_account', 'sp_update_log_shipping_plan',
+ 'sp_define_log_shipping_monitor', 'sp_update_log_shipping_plan_database',
+
+ //OLE Automation Extended Stored Procedures
+ 'sp_OACreate', 'sp_OAMethod', 'sp_OADestroy', 'sp_OASetProperty', 'sp_OAGetErrorInfo',
+ 'sp_OAStop', 'sp_OAGetProperty',
+
+ //Replication Procedures
+ 'sp_add_agent_parameter', 'sp_enableagentoffload', 'sp_add_agent_profile',
+ 'sp_enumcustomresolvers', 'sp_addarticle', 'sp_enumdsn', 'sp_adddistpublisher',
+ 'sp_enumfullsubscribers', 'sp_adddistributiondb', 'sp_expired_subscription_cleanup',
+ 'sp_adddistributor', 'sp_generatefilters', 'sp_addmergealternatepublisher',
+ 'sp_getagentoffloadinfo', 'sp_addmergearticle', 'sp_getmergedeletetype', 'sp_addmergefilter',
+ 'sp_get_distributor', 'sp_addmergepublication', 'sp_getqueuedrows', 'sp_addmergepullsubscription',
+ 'sp_getsubscriptiondtspackagename', 'sp_addmergepullsubscription_agent', 'sp_grant_publication_access',
+ 'sp_addmergesubscription', 'sp_help_agent_default', 'sp_addpublication', 'sp_help_agent_parameter',
+ 'sp_addpublication_snapshot', 'sp_help_agent_profile', 'sp_addpublisher70', 'sp_helparticle',
+ 'sp_addpullsubscription', 'sp_helparticlecolumns', 'sp_addpullsubscription_agent', 'sp_helparticledts',
+ 'sp_addscriptexec', 'sp_helpdistpublisher', 'sp_addsubscriber', 'sp_helpdistributiondb',
+ 'sp_addsubscriber_schedule', 'sp_helpdistributor', 'sp_addsubscription', 'sp_helpmergealternatepublisher',
+ 'sp_addsynctriggers', 'sp_helpmergearticle', 'sp_addtabletocontents', 'sp_helpmergearticlecolumn',
+ 'sp_adjustpublisheridentityrange', 'sp_helpmergearticleconflicts', 'sp_article_validation',
+ 'sp_helpmergeconflictrows', 'sp_articlecolumn', 'sp_helpmergedeleteconflictrows', 'sp_articlefilter',
+ 'sp_helpmergefilter', 'sp_articlesynctranprocs', 'sp_helpmergepublication', 'sp_articleview',
+ 'sp_helpmergepullsubscription', 'sp_attachsubscription', 'sp_helpmergesubscription', 'sp_browsesnapshotfolder',
+ 'sp_helppublication', 'sp_browsemergesnapshotfolder', 'sp_help_publication_access', 'sp_browsereplcmds',
+ 'sp_helppullsubscription', 'sp_change_agent_parameter', 'sp_helpreplfailovermode', 'sp_change_agent_profile',
+ 'sp_helpreplicationdboption', 'sp_changearticle', 'sp_helpreplicationoption', 'sp_changedistpublisher',
+ 'sp_helpsubscriberinfo', 'sp_changedistributiondb', 'sp_helpsubscription', 'sp_changedistributor_password',
+ 'sp_ivindexhasnullcols', 'sp_changedistributor_property', 'sp_helpsubscription_properties', 'sp_changemergearticle',
+ 'sp_link_publication', 'sp_changemergefilter', 'sp_marksubscriptionvalidation', 'sp_changemergepublication',
+ 'sp_mergearticlecolumn', 'sp_changemergepullsubscription', 'sp_mergecleanupmetadata', 'sp_changemergesubscription',
+ 'sp_mergedummyupdate', 'sp_changepublication', 'sp_mergesubscription_cleanup', 'sp_changesubscriber',
+ 'sp_publication_validation', 'sp_changesubscriber_schedule', 'sp_refreshsubscriptions', 'sp_changesubscriptiondtsinfo',
+ 'sp_reinitmergepullsubscription', 'sp_changesubstatus', 'sp_reinitmergesubscription', 'sp_change_subscription_properties',
+ 'sp_reinitpullsubscription', 'sp_check_for_sync_trigger', 'sp_reinitsubscription', 'sp_copymergesnapshot',
+ 'sp_removedbreplication', 'sp_copysnapshot', 'sp_repladdcolumn', 'sp_copysubscription', 'sp_replcmds',
+ 'sp_deletemergeconflictrow', 'sp_replcounters', 'sp_disableagentoffload', 'sp_repldone', 'sp_drop_agent_parameter',
+ 'sp_repldropcolumn', 'sp_drop_agent_profile', 'sp_replflush', 'sp_droparticle', 'sp_replicationdboption',
+ 'sp_dropanonymouseagent', 'sp_replication_agent_checkup', 'sp_dropdistpublisher', 'sp_replqueuemonitor',
+ 'sp_dropdistributiondb', 'sp_replsetoriginator', 'sp_dropmergealternatepublisher', 'sp_replshowcmds',
+ 'sp_dropdistributor', 'sp_repltrans', 'sp_dropmergearticle', 'sp_restoredbreplication', 'sp_dropmergefilter',
+ 'sp_revoke_publication_access', 'sp_scriptsubconflicttable', 'sp_dropmergepublication', 'sp_script_synctran_commands',
+ 'sp_dropmergepullsubscription', 'sp_setreplfailovermode', 'sp_showrowreplicainfo', 'sp_dropmergesubscription',
+ 'sp_subscription_cleanup', 'sp_droppublication', 'sp_table_validation', 'sp_droppullsubscription',
+ 'sp_update_agent_profile', 'sp_dropsubscriber', 'sp_validatemergepublication', 'sp_dropsubscription',
+ 'sp_validatemergesubscription', 'sp_dsninfo', 'sp_vupgrade_replication', 'sp_dumpparamcmd',
+
+ //Security Procedures
+ 'sp_addalias', 'sp_droprolemember', 'sp_addapprole', 'sp_dropserver', 'sp_addgroup', 'sp_dropsrvrolemember',
+ 'sp_dropuser', 'sp_addlogin', 'sp_grantdbaccess', 'sp_addremotelogin',
+ 'sp_grantlogin', 'sp_addrole', 'sp_helpdbfixedrole', 'sp_addrolemember', 'sp_helpgroup',
+ 'sp_addserver', 'sp_helplinkedsrvlogin', 'sp_addsrvrolemember', 'sp_helplogins', 'sp_adduser',
+ 'sp_helpntgroup', 'sp_approlepassword', 'sp_helpremotelogin', 'sp_changedbowner', 'sp_helprole',
+ 'sp_changegroup', 'sp_helprolemember', 'sp_changeobjectowner', 'sp_helprotect', 'sp_change_users_login',
+ 'sp_helpsrvrole', 'sp_dbfixedrolepermission', 'sp_helpsrvrolemember', 'sp_defaultdb', 'sp_helpuser',
+ 'sp_defaultlanguage', 'sp_MShasdbaccess', 'sp_denylogin', 'sp_password', 'sp_dropalias', 'sp_remoteoption',
+ 'sp_dropapprole', 'sp_revokedbaccess', 'sp_dropgroup', 'sp_revokelogin', 'sp_droplinkedsrvlogin',
+ 'sp_setapprole', 'sp_droplogin', 'sp_srvrolepermission', 'sp_dropremotelogin', 'sp_validatelogins', 'sp_droprole',
+
+ //SQL Mail Procedures
+ 'sp_processmail', 'xp_sendmail', 'xp_deletemail', 'xp_startmail', 'xp_findnextmsg', 'xp_stopmail', 'xp_readmail',
+
+ //SQL Profiler Procedures
+ 'sp_trace_create', 'sp_trace_setfilter', 'sp_trace_generateevent', 'sp_trace_setstatus', 'sp_trace_setevent',
+
+ //SQL Server Agent Procedures
+ 'sp_add_alert', 'sp_help_jobhistory', 'sp_add_category', 'sp_help_jobschedule', 'sp_add_job',
+ 'sp_help_jobserver', 'sp_add_jobschedule', 'sp_help_jobstep', 'sp_add_jobserver', 'sp_help_notification',
+ 'sp_add_jobstep', 'sp_help_operator', 'sp_add_notification', 'sp_help_targetserver',
+ 'sp_add_operator', 'sp_help_targetservergroup', 'sp_add_targetservergroup', 'sp_helptask',
+ 'sp_add_targetsvrgrp_member', 'sp_manage_jobs_by_login', 'sp_addtask', 'sp_msx_defect',
+ 'sp_apply_job_to_targets', 'sp_msx_enlist', 'sp_delete_alert', 'sp_post_msx_operation',
+ 'sp_delete_category', 'sp_purgehistory', 'sp_delete_job', 'sp_purge_jobhistory', 'sp_delete_jobschedule',
+ 'sp_reassigntask', 'sp_delete_jobserver', 'sp_remove_job_from_targets', 'sp_delete_jobstep',
+ 'sp_resync_targetserver', 'sp_delete_notification', 'sp_start_job', 'sp_delete_operator',
+ 'sp_stop_job', 'sp_delete_targetserver', 'sp_update_alert', 'sp_delete_targetservergroup',
+ 'sp_update_category', 'sp_delete_targetsvrgrp_member', 'sp_update_job', 'sp_droptask',
+ 'sp_update_jobschedule', 'sp_help_alert', 'sp_update_jobstep', 'sp_help_category',
+ 'sp_update_notification', 'sp_help_downloadlist', 'sp_update_operator', 'sp_helphistory',
+ 'sp_update_targetservergroup', 'sp_help_job', 'sp_updatetask', 'xp_sqlagent_proxy_account',
+
+ //System Procedures
+ 'sp_add_data_file_recover_suspect_db', 'sp_helpconstraint', 'sp_addextendedproc',
+ 'sp_helpdb', 'sp_addextendedproperty', 'sp_helpdevice', 'sp_add_log_file_recover_suspect_db',
+ 'sp_helpextendedproc', 'sp_addmessage', 'sp_helpfile', 'sp_addtype', 'sp_helpfilegroup',
+ 'sp_addumpdevice', 'sp_helpindex', 'sp_altermessage', 'sp_helplanguage', 'sp_autostats',
+ 'sp_helpserver', 'sp_attach_db', 'sp_helpsort', 'sp_attach_single_file_db', 'sp_helpstats',
+ 'sp_bindefault', 'sp_helptext', 'sp_bindrule', 'sp_helptrigger', 'sp_bindsession',
+ 'sp_indexoption', 'sp_certify_removable', 'sp_invalidate_textptr', 'sp_configure',
+ 'sp_lock', 'sp_create_removable', 'sp_monitor', 'sp_createstats', 'sp_procoption',
+ 'sp_cycle_errorlog', 'sp_recompile', 'sp_datatype_info', 'sp_refreshview', 'sp_dbcmptlevel',
+ 'sp_releaseapplock', 'sp_dboption', 'sp_rename', 'sp_dbremove', 'sp_renamedb',
+ 'sp_delete_backuphistory', 'sp_resetstatus', 'sp_depends', 'sp_serveroption', 'sp_detach_db',
+ 'sp_setnetname', 'sp_dropdevice', 'sp_settriggerorder', 'sp_dropextendedproc', 'sp_spaceused',
+ 'sp_dropextendedproperty', 'sp_tableoption', 'sp_dropmessage', 'sp_unbindefault', 'sp_droptype',
+ 'sp_unbindrule', 'sp_executesql', 'sp_updateextendedproperty', 'sp_getapplock', 'sp_updatestats',
+ 'sp_getbindtoken', 'sp_validname', 'sp_help', 'sp_who',
+
+ //Web Assistant Procedures
+ 'sp_dropwebtask', 'sp_makewebtask', 'sp_enumcodepages', 'sp_runwebtask',
+
+ //XML Procedures
+ 'sp_xml_preparedocument', 'sp_xml_removedocument',
+
+ //General Extended Procedures
+ 'xp_cmdshellxp_logininfo', 'xp_enumgroups', 'xp_msver', 'xp_findnextmsgxp_revokelogin',
+ 'xp_grantlogin', 'xp_sprintf', 'xp_logevent', 'xp_sqlmaint', 'xp_loginconfig', 'xp_sscanf',
+
+ //API System Stored Procedures
+ 'sp_cursor', 'sp_cursorclose', 'sp_cursorexecute', 'sp_cursorfetch', 'sp_cursoropen',
+ 'sp_cursoroption', 'sp_cursorprepare', 'sp_cursorunprepare', 'sp_execute', 'sp_prepare', 'sp_unprepare',
+
+ //Misc
+ 'sp_createorphan', 'sp_droporphans', 'sp_reset_connection', 'sp_sdidebug'
+ ),
+ 4 => array(
+ //Function/sp's higlighted brown.
+ 'fn_helpcollations', 'fn_listextendedproperty ', 'fn_servershareddrives',
+ 'fn_trace_geteventinfo', 'fn_trace_getfilterinfo', 'fn_trace_getinfo',
+ 'fn_trace_gettable', 'fn_virtualfilestats','fn_listextendedproperty',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '!', '!=', '%', '&', '&&', '(', ')', '*', '+', '-', '/', '<', '<<', '<=',
+ '<=>', '<>', '=', '>', '>=', '>>', '^', 'ALL', 'AND', 'ANY', 'BETWEEN', 'CROSS',
+ 'EXISTS', 'IN', 'JOIN', 'LIKE', 'NOT', 'NULL', 'OR', 'OUTER', 'SOME', '|', '||', '~'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #FF00FF;',
+ 3 => 'color: #AF0000;',
+ 4 => 'color: #AF0000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008080;',
+ 'MULTI' => 'color: #008080;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #808080;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #808080;'
+ ),
+ '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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/typoscript.php b/inc/geshi/typoscript.php
new file mode 100644
index 000000000..525271428
--- /dev/null
+++ b/inc/geshi/typoscript.php
@@ -0,0 +1,300 @@
+<?php
+/*************************************************************************************
+ * typoscript.php
+ * --------
+ * Author: Jan-Philipp Halle (typo3@jphalle.de)
+ * Copyright: (c) 2005 Jan-Philipp Halle (http://www.jphalle.de/)
+ * Release Version: 1.0.8.8
+ * 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(
+ // 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'
+ ),
+
+ // xhtml tag
+ 2 => array(
+ GESHI_SEARCH => '(&lt;[a-zA-Z\!\/].*?&gt;)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 's',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+
+ // 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/inc/geshi/unicon.php b/inc/geshi/unicon.php
new file mode 100644
index 000000000..edad62df3
--- /dev/null
+++ b/inc/geshi/unicon.php
@@ -0,0 +1,210 @@
+<?php
+/*************************************************************************************
+ * unicon.php
+ * --------
+ * Author: Matt Oates (mattoates@gmail.com)
+ * Copyright: (c) 2010 Matt Oates (http://mattoates.co.uk)
+ * Release Version: 1.0.8.8
+ * 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' => '(?<=#)'
+ )
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/vala.php b/inc/geshi/vala.php
new file mode 100644
index 000000000..334398a87
--- /dev/null
+++ b/inc/geshi/vala.php
@@ -0,0 +1,151 @@
+<?php
+/*************************************************************************************
+ * vala.php
+ * ----------
+ * Author: Nicolas Joseph (nicolas.joseph@valaide.org)
+ * Copyright: (c) 2009 Nicolas Joseph
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/vb.php b/inc/geshi/vb.php
new file mode 100644
index 000000000..f24d86505
--- /dev/null
+++ b/inc/geshi/vb.php
@@ -0,0 +1,157 @@
+<?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.8.8
+ * 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 => '/\'.*(?<! _)\n/sU',
+ ),
+ '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', 'For',
+ 'Goto', 'If', 'Is', 'Loop', 'Next', 'Not', 'Or', 'Select', 'Step',
+ 'Then', 'To', 'Until', 'While', 'With', 'Xor', 'WithEvents',
+ 'DoEvents', 'Close', 'Like', 'In', 'End'
+ ),
+ 4 => array(
+ 'As', 'Dim', 'Get', 'Set', 'ReDim', 'Error',
+ 'Resume', 'Declare', 'Let', 'ByRef', 'ByVal',
+ 'Optional', 'Property', 'Control', 'UBound', 'Mod',
+ 'GoSub', '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
+ )
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/vbnet.php b/inc/geshi/vbnet.php
new file mode 100644
index 000000000..f74775214
--- /dev/null
+++ b/inc/geshi/vbnet.php
@@ -0,0 +1,201 @@
+<?php
+/*************************************************************************************
+ * vbnet.php
+ * ---------
+ * Author: Alan Juden (alan@judenware.org)
+ * Copyright: (c) 2004 Alan Juden, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.8.8
+ * 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(
+ 1 => array(
+ '3DDKSHADOW', '3DHIGHLIGHT', '3DLIGHT', 'ABORT', 'ABORTRETRYIGNORE', 'ACTIVEBORDER',
+ 'ACTIVETITLEBAR', 'ALIAS', 'APPLICATIONMODAL', 'APPLICATIONWORKSPACE', 'ARCHIVE',
+ 'BACK', 'BINARYCOMPARE', 'BLACK', 'BLUE', 'BUTTONFACE', 'BUTTONSHADOW', 'BUTTONTEXT',
+ 'CANCEL', 'CDROM', 'CR', 'CRITICAL', 'CRLF', 'CYAN', 'DEFAULT', 'DEFAULTBUTTON1',
+ 'DEFAULTBUTTON2', 'DEFAULTBUTTON3', 'DESKTOP', 'DIRECTORY', 'EXCLAMATION', 'FALSE',
+ 'FIXED', 'FORAPPENDING', 'FORMFEED', 'FORREADING', 'FORWRITING', 'FROMUNICODE',
+ 'GRAYTEXT', 'GREEN', 'HIDDEN', 'HIDE', 'HIGHLIGHT', 'HIGHLIGHTTEXT', 'HIRAGANA',
+ 'IGNORE', 'INACTIVEBORDER', 'INACTIVECAPTIONTEXT', 'INACTIVETITLEBAR', 'INFOBACKGROUND',
+ 'INFORMATION', 'INFOTEXT', 'KATAKANALF', 'LOWERCASE', 'MAGENTA', 'MAXIMIZEDFOCUS',
+ 'MENUBAR', 'MENUTEXT', 'METHOD', 'MINIMIZEDFOCUS', 'MINIMIZEDNOFOCUS', 'MSGBOXRIGHT',
+ 'MSGBOXRTLREADING', 'MSGBOXSETFOREGROUND', 'NARROW', 'NEWLINE', 'NO', 'NORMAL',
+ 'NORMALFOCUS', 'NORMALNOFOCUS', 'NULLSTRING', 'OBJECTERROR', 'OK', 'OKCANCEL', 'OKONLY',
+ 'PROPERCASE', 'QUESTION', 'RAMDISK', 'READONLY', 'RED', 'REMOTE', 'REMOVABLE', 'RETRY',
+ 'RETRYCANCEL', 'SCROLLBARS', 'SYSTEMFOLDER', 'SYSTEMMODAL', 'TEMPORARYFOLDER',
+ 'TEXTCOMPARE', 'TITLEBARTEXT', 'TRUE', 'UNICODE', 'UNKNOWN', 'UPPERCASE', 'VERTICALTAB',
+ 'VOLUME', 'WHITE', 'WIDE', 'WIN16', 'WIN32', 'WINDOWBACKGROUND', 'WINDOWFRAME',
+ 'WINDOWSFOLDER', 'WINDOWTEXT', 'YELLOW', 'YES', 'YESNO', 'YESNOCANCEL'
+ ),
+ 2 => array(
+ 'AndAlso', 'As', 'ADDHANDLER', 'ASSEMBLY', 'AUTO', 'Binary', 'ByRef', 'ByVal', 'BEGINEPILOGUE',
+ 'Else', 'ElseIf', 'Empty', 'Error', 'ENDPROLOGUE', 'EXTERNALSOURCE', 'ENVIRON', 'For',
+ 'Friend', 'Func', 'GET', 'HANDLES', 'Input', 'Is', 'IsNot', 'Len', 'Lock', 'Me', 'Mid', 'MUSTINHERIT', 'MustOverride',
+ 'MYBASE', 'MYCLASS', 'New', 'Next', 'Nothing', 'Null', 'NOTINHERITABLE',
+ 'NOTOVERRIDABLE', 'Of', 'OFF', 'On', 'Option', 'Optional', 'Overloads', 'OVERRIDABLE', 'Overrides', 'ParamArray', 'Predicate',
+ 'Print', 'Private', 'Property', 'Public', 'Resume', 'Return', 'Seek', 'Static', 'Step',
+ 'String', 'SHELL', 'SENDKEYS', 'SET', 'Shared', 'Then', 'Time', 'To', 'THROW', 'WithEvents'
+ ),
+ 3 => array(
+ 'COLLECTION', 'DEBUG', 'DICTIONARY', 'DRIVE', 'DRIVES', 'ERR', 'FILE', 'FILES',
+ 'FILESYSTEMOBJECT', 'FOLDER', 'FOLDERS', 'TEXTSTREAM'
+ ),
+ 4 => array(
+ 'BOOLEAN', 'BYTE', 'DATE', 'DECIMIAL', 'DOUBLE', 'INTEGER', 'LONG', 'OBJECT',
+ 'SINGLE STRING'
+ ),
+ 5 => array(
+ 'ADDRESSOF', 'AND', 'BITAND', 'BITNOT', 'BITOR', 'BITXOR',
+ 'GETTYPE', 'LIKE', 'MOD', 'NOT', 'ORXOR'
+ ),
+ 6 => array(
+ 'APPACTIVATE', 'BEEP', 'CALL', 'CHDIR', 'CHDRIVE', 'CLASS', 'CASE', 'CATCH', 'CONST',
+ 'DECLARE', 'DELEGATE', 'DELETESETTING', 'DIM', 'DO', 'DOEVENTS', 'END', 'ENUM',
+ 'EVENT', 'EXIT', 'EACH', 'FUNCTION', 'FINALLY', 'IF', 'IMPORTS', 'INHERITS',
+ 'INTERFACE', 'IMPLEMENTS', 'KILL', 'LOOP', 'NAMESPACE', 'OPEN', 'PUT',
+ 'RAISEEVENT', 'RANDOMIZE', 'REDIM', 'REM', 'RESET', 'SAVESETTING', 'SELECT',
+ 'SETATTR', 'STOP', 'SUB', 'SYNCLOCK', 'STRUCTURE', 'SHADOWS', 'SWITCH',
+ 'TRY', 'WIDTH', 'WITH', 'WRITE', 'WHILE'
+ ),
+ 7 => array(
+ 'ABS', 'ARRAY', 'ASC', 'ASCB', 'ASCW', 'CALLBYNAME', 'CBOOL', 'CBYTE', 'CCHAR',
+ 'CCHR', 'CDATE', 'CDBL', 'CDEC', 'CHOOSE', 'CHR', 'CHR$', 'CHRB', 'CHRB$', 'CHRW',
+ 'CINT', 'CLNG', 'CLNG8', 'CLOSE', 'COBJ', 'COMMAND', 'COMMAND$', 'CONVERSION',
+ 'COS', 'CREATEOBJECT', 'CSHORT', 'CSTR', 'CURDIR', 'CTYPE', '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'
+ ),
+ 8 => array(
+ 'ANY', 'ATN', 'CALENDAR', 'CIRCLE', 'CURRENCY', 'DEFBOOL', 'DEFBYTE', 'DEFCUR',
+ 'DEFDATE', 'DEFDBL', 'DEFDEC', 'DEFINT', 'DEFLNG', 'DEFOBJ', 'DEFSNG', 'DEFSTR',
+ 'DEFVAR', 'EQV', 'GOSUB', 'IMP', 'INITIALIZE', 'ISMISSING', 'LET', 'LINE', 'LSET',
+ 'RSET', 'SGN', 'SQR', 'TERMINATE', 'VARIANT', 'VARTYPE', 'WEND'
+ ),
+ ),
+ '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;', //Constants
+ 2 => 'color: #FF8000;', //Keywords
+ 3 => 'color: #008000;', //Data Types
+ 4 => 'color: #FF0000;', //Objects
+ 5 => 'color: #804040;', //Operators
+ 6 => 'color: #0600FF;', //Statements
+ 7 => 'color: #0600FF;', //Functions
+ 8 => 'color: #0600FF;' //Deprecated
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008080; font-style: italic;',
+ '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;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.google.com/search?q={FNAMEU}+site:msdn.microsoft.com',
+ 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/verilog.php b/inc/geshi/verilog.php
new file mode 100644
index 000000000..14c1d7172
--- /dev/null
+++ b/inc/geshi/verilog.php
@@ -0,0 +1,173 @@
+<?php
+/**
+ * verilog.php
+ * -----------
+ * Author: G�nter Dannoritzer <dannoritzer@web.de>
+ * Copyright: (C) 2008 Guenter Dannoritzer
+ * Release Version: 1.0.8.8
+ * 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)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GeSHi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General 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('always', 'and', 'assign', 'begin', 'buf', 'bufif0', 'bufif1', 'case',
+ 'casex', 'casez', 'cmos', 'deassign', 'default', 'defparam',
+ 'disable', 'edge', 'else', 'end', 'endcase', 'endfunction',
+ 'endmodule', 'endprimitive', 'endspecify', 'endtable', 'endtask',
+ 'event', 'for', 'force', 'forever', 'function', 'highz0',
+ 'highz1', 'if', 'ifnone', 'initial', 'inout', 'input', 'integer',
+ 'join', 'large', 'macromodule', 'medium', 'module', 'nand',
+ 'negedge', 'nmos', 'nor', 'not', 'notif0', 'notif1', 'or',
+ 'output', 'parameter', 'pmos', 'posedge', 'primitive', 'pull0',
+ 'pull1', 'pulldown', 'pullup', 'rcmos', 'real', 'realtime', 'reg',
+ 'release', 'repeat', 'rnmos', 'rpmos', 'rtran', 'rtranif0',
+ 'rtranif1', 'scalared', 'small', 'specify', 'specparam',
+ 'strong0', 'strong1', 'supply0', 'supply1', 'table', 'task',
+ 'time', 'tran', 'tranif0', 'tranif1', 'tri', 'tri0', 'tri1',
+ 'triand', 'trior', 'trireg', 'vectored', 'wait', 'wand', 'weak0',
+ 'weak1', 'while', 'wire', '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/inc/geshi/vhdl.php b/inc/geshi/vhdl.php
new file mode 100644
index 000000000..6856933c7
--- /dev/null
+++ b/inc/geshi/vhdl.php
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * vhdl.php
+ * --------
+ * Author: Alexander 'E-Razor' Krause (admin@erazor-zone.de)
+ * Copyright: (c) 2005 Alexander Krause
+ * Release Version: 1.0.8.8
+ * Date Started: 2005/06/15
+ *
+ * VHDL (VHSICADL, very high speed integrated circuit HDL) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 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('%' => '%'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /*keywords*/
+ 1 => array(
+ 'access','after','alias','all','assert','attribute','architecture','begin',
+ 'block','body','buffer','bus','case','component','configuration','constant',
+ 'disconnect','downto','else','elsif','end','entity','exit','file','for',
+ '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','pure','range','record','register',
+ 'reject','report','return','select','severity','signal','shared','subtype',
+ 'then','to','transport','type','unaffected','units','until','use','variable',
+ 'wait','when','while','with','note','warning','error','failure','and',
+ 'or','xor','not','nor','used','memory','segments','dff','dffe','help_id',
+ 'mod','info','latch','rising_edge','falling_edge'
+ ),
+ /*types*/
+ 2 => array(
+ 'bit','bit_vector','character','boolean','integer','real','time','string',
+ 'severity_level','positive','natural','signed','unsigned','line','text',
+ 'std_logic','std_logic_vector','std_ulogic','std_ulogic_vector','qsim_state',
+ 'qsim_state_vector','qsim_12state','qsim_12state_vector','qsim_strength',
+ 'mux_bit','mux_vector','reg_bit','reg_vector','wor_bit','wor_vector',
+ 'work','ieee','std_logic_signed','std_logic_1164','std_logic_arith',
+ 'numeric_std'
+
+ ),
+ /*operators*/
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '(', ')',
+ ';',':',
+ '<','>','=','<=',':=','=>','=='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000080; font-weight: bold;',
+ 2 => 'color: #0000ff;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000; font-style: italic;',
+ '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;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Hex numbers and scientific notation for numbers
+ 0 => '(\b0x[0-9a-fA-F]+|\b\d[0-9a-fA-F]+[hH])|'.
+ '(\b\d+?(\.\d+?)?E[+\-]?\d+)|(\bns)|'.
+ "('[0-9a-zA-Z]+(?!'))",
+ //Number characters?
+ 1 => "\b(''\d'')"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
+
+?>
diff --git a/inc/geshi/vim.php b/inc/geshi/vim.php
new file mode 100644
index 000000000..f4f93ad2e
--- /dev/null
+++ b/inc/geshi/vim.php
@@ -0,0 +1,420 @@
+<?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.8.8
+ * 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/inc/geshi/visualfoxpro.php b/inc/geshi/visualfoxpro.php
new file mode 100644
index 000000000..7d804257f
--- /dev/null
+++ b/inc/geshi/visualfoxpro.php
@@ -0,0 +1,456 @@
+<?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.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/visualprolog.php b/inc/geshi/visualprolog.php
new file mode 100644
index 000000000..5afd7de8d
--- /dev/null
+++ b/inc/geshi/visualprolog.php
@@ -0,0 +1,129 @@
+<?php
+/*************************************************************************************
+ * visualprolog.php
+ * ----------
+ * Author: Thomas Linder Puls (puls@pdc.dk)
+ * Copyright: (c) 2008 Thomas Linder Puls (puls@pdc.dk)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/whitespace.php b/inc/geshi/whitespace.php
new file mode 100644
index 000000000..c47775d44
--- /dev/null
+++ b/inc/geshi/whitespace.php
@@ -0,0 +1,121 @@
+<?php
+/*************************************************************************************
+ * whitespace.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/whois.php b/inc/geshi/whois.php
new file mode 100644
index 000000000..9b4b24179
--- /dev/null
+++ b/inc/geshi/whois.php
@@ -0,0 +1,181 @@
+<?php
+/*************************************************************************************
+ * whois.php
+ * --------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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,
+ 'BRACKETS' => GESHI_NEVER,
+ 'STRINGS' => GESHI_NEVER,
+ 'ESCAPE_CHAR' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER,
+ 'METHODS' => GESHI_NEVER,
+ 'SCRIPT' => GESHI_NEVER
+ )
+ ),
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/winbatch.php b/inc/geshi/winbatch.php
new file mode 100644
index 000000000..949e61c14
--- /dev/null
+++ b/inc/geshi/winbatch.php
@@ -0,0 +1,369 @@
+<?php
+/*************************************************************************************
+ * winbatch.php
+ * ------------
+ * Author: Craig Storey (storey.craig@gmail.com)
+ * Copyright: (c) 2004 Craig Storey (craig.xcottawa.ca)
+ * Release Version: 1.0.8.8
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/xbasic.php b/inc/geshi/xbasic.php
new file mode 100644
index 000000000..a2d85a6df
--- /dev/null
+++ b/inc/geshi/xbasic.php
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * xbasic.php
+ * ----------
+ * Author: Jos Gabriel Moya Yangela (josemoya@gmail.com)
+ * Copyright: (c) 2005 Jos Gabriel Moya Yangela (http://aprenderadesaprender.6te.net)
+ * Release Version: 1.0.8.8
+ * Date Started: 2005/11/23
+ * Last Modified: $Date: 2010/01/30 00:42:00 $
+ *
+ * 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(
+ )
+);
+
+?> \ No newline at end of file
diff --git a/inc/geshi/xml.php b/inc/geshi/xml.php
new file mode 100644
index 000000000..efd3e6c33
--- /dev/null
+++ b/inc/geshi/xml.php
@@ -0,0 +1,157 @@
+<?php
+/*************************************************************************************
+ * xml.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/xorg_conf.php b/inc/geshi/xorg_conf.php
new file mode 100644
index 000000000..5cde8e171
--- /dev/null
+++ b/inc/geshi/xorg_conf.php
@@ -0,0 +1,124 @@
+<?php
+/*************************************************************************************
+ * xorg_conf.php
+ * ----------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff (http://milianw.de)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/xpp.php b/inc/geshi/xpp.php
new file mode 100644
index 000000000..216c46eaf
--- /dev/null
+++ b/inc/geshi/xpp.php
@@ -0,0 +1,436 @@
+<?php
+/*************************************************************************************
+ * xpp.php
+ * -------
+ * Author: Simon Butcher (simon@butcher.name)
+ * Copyright: (c) 2007 Simon Butcher (http://simon.butcher.name/)
+ * Release Version: 1.0.8.8
+ * 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/inc/geshi/z80.php b/inc/geshi/z80.php
new file mode 100644
index 000000000..f28593cd2
--- /dev/null
+++ b/inc/geshi/z80.php
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * z80.php
+ * -------
+ * Author: Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2007-2008 Benny Baumann (http://www.omorphia.de/)
+ * Release Version: 1.0.8.8
+ * 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
+);
+
+?> \ No newline at end of file
diff --git a/inc/html.php b/inc/html.php
new file mode 100644
index 000000000..ece26d136
--- /dev/null
+++ b/inc/html.php
@@ -0,0 +1,1869 @@
+<?php
+/**
+ * HTML output functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+if(!defined('NL')) define('NL',"\n");
+
+/**
+ * Convenience function to quickly build a wikilink
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_wikilink($id,$name=null,$search=''){
+ static $xhtml_renderer = null;
+ if(is_null($xhtml_renderer)){
+ $xhtml_renderer = p_get_renderer('xhtml');
+ }
+
+ return $xhtml_renderer->internallink($id,$name,$search,true,'navigation');
+}
+
+/**
+ * Helps building long attribute lists
+ *
+ * @deprecated Use buildAttributes instead
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_attbuild($attributes){
+ $ret = '';
+ foreach ( $attributes as $key => $value ) {
+ $ret .= $key.'="'.formText($value).'" ';
+ }
+ return trim($ret);
+}
+
+/**
+ * The loginform
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_login(){
+ global $lang;
+ global $conf;
+ global $ID;
+
+ print p_locale_xhtml('login');
+ print '<div class="centeralign">'.NL;
+ $form = new Doku_Form(array('id' => 'dw__login'));
+ $form->startFieldset($lang['btn_login']);
+ $form->addHidden('id', $ID);
+ $form->addHidden('do', 'login');
+ $form->addElement(form_makeTextField('u', ((!$_REQUEST['http_credentials']) ? $_REQUEST['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')){
+ $form->addElement('<p>'.$lang['reghere'].': '.tpl_actionlink('register','','','',true).'</p>');
+ }
+
+ if (actionOK('resendpwd')) {
+ $form->addElement('<p>'.$lang['pwdforget'].': '.tpl_actionlink('resendpwd','','','',true).'</p>');
+ }
+
+ html_form('login', $form);
+ print '</div>'.NL;
+}
+
+/**
+ * inserts section edit buttons if wanted or removes the markers
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_secedit($text,$show=true){
+ global $INFO;
+
+ $regexp = '#<!-- EDIT(\d+) ([A-Z_]+) (?:"([^"]*)" )?\[(\d+-\d*)\] -->#';
+
+ if(!$INFO['writable'] || !$show || $INFO['rev']){
+ return preg_replace($regexp,'',$text);
+ }
+
+ return preg_replace_callback($regexp,
+ 'html_secedit_button', $text);
+}
+
+/**
+ * prepares section edit button data for event triggering
+ * used as a callback in html_secedit
+ *
+ * @triggers HTML_SECEDIT_BUTTON
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_secedit_button($matches){
+ $data = array('secid' => $matches[1],
+ 'target' => strtolower($matches[2]),
+ 'range' => $matches[count($matches) - 1]);
+ if (count($matches) === 5) {
+ $data['name'] = $matches[3];
+ }
+
+ return trigger_event('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>
+ */
+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>
+ */
+function html_topbtn(){
+ global $lang;
+
+ $ret = '';
+ $ret = '<a class="nolink" href="#dokuwiki__top"><input type="button" class="button" value="'.$lang['btn_top'].'" onclick="window.scrollTo(0, 0)" title="'.$lang['btn_top'].'" /></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>
+ */
+function html_btn($name,$id,$akey,$params,$method='get',$tooltip='',$label=false){
+ global $conf;
+ global $lang;
+
+ if (!$label)
+ $label = $lang['btn_'.$name];
+
+ $ret = '';
+ $tip = '';
+
+ //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)){
+ reset($params);
+ while (list($key, $val) = each($params)) {
+ $ret .= '<input type="hidden" name="'.$key.'" ';
+ $ret .= 'value="'.htmlspecialchars($val).'" />';
+ }
+ }
+
+ if ($tooltip!='') {
+ $tip = htmlspecialchars($tooltip);
+ }else{
+ $tip = htmlspecialchars($label);
+ }
+
+ $ret .= '<input type="submit" value="'.hsc($label).'" class="button" ';
+ if($akey){
+ $tip .= ' ['.strtoupper($akey).']';
+ $ret .= 'accesskey="'.$akey.'" ';
+ }
+ $ret .= 'title="'.$tip.'" ';
+ $ret .= '/>';
+ $ret .= '</div></form>';
+
+ return $ret;
+}
+
+/**
+ * show a wiki page
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_show($txt=null){
+ global $ID;
+ global $REV;
+ global $HIGH;
+ global $INFO;
+ //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">';
+ $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>';
+
+ }else{
+ if ($REV) print p_locale_xhtml('showrev');
+ $html = p_wiki_xhtml($ID,$REV,true);
+ $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;
+ global $conf;
+ $draft = unserialize(io_readFile($INFO['draft'],false));
+ $text = cleanText(con($draft['prefix'],$draft['text'],$draft['suffix'],true));
+
+ print p_locale_xhtml('draft');
+ $form = new Doku_Form(array('id' => 'dw__editform'));
+ $form->addHidden('id', $ID);
+ $form->addHidden('date', $draft['date']);
+ $form->addElement(form_makeWikiText($text, array('readonly'=>'readonly')));
+ $form->addElement(form_makeOpenTag('div', array('id'=>'draft__status')));
+ $form->addElement($lang['draftdate'].' '. dformat(filemtime($INFO['draft'])));
+ $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>
+ */
+function html_hilight($html,$phrases){
+ $phrases = array_filter((array) $phrases);
+ $regex = join('|',array_map('ft_snippet_re_preprocess', array_map('preg_quote_cb',$phrases)));
+
+ if ($regex === '') return $html;
+ if (!utf8_check($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>
+ */
+function html_hilight_callback($m) {
+ $hlight = unslash($m[0]);
+ if ( !isset($m[2])) {
+ $hlight = '<span class="search_hit">'.$hlight.'</span>';
+ }
+ return $hlight;
+}
+
+/**
+ * Run a search and display the result
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_search(){
+ global $conf;
+ global $QUERY;
+ global $ID;
+ global $lang;
+
+ $intro = p_locale_xhtml('searchpage');
+ // allow use of placeholder in search intro
+ $intro = str_replace(
+ array('@QUERY@','@SEARCH@'),
+ array(hsc(rawurlencode($QUERY)),hsc($QUERY)),
+ $intro);
+ echo $intro;
+ flush();
+
+ //show progressbar
+ print '<div class="centeralign" id="dw__loading">'.NL;
+ print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--'.NL;
+ print 'showLoadBar();'.NL;
+ print '//--><!]]></script>'.NL;
+ print '<br /></div>'.NL;
+ flush();
+
+ //do quick pagesearch
+ $data = array();
+
+ $data = ft_pageLookup($QUERY,true,useHeading('navigation'));
+ if(count($data)){
+ print '<div class="search_quickresult">';
+ print '<h3>'.$lang['quickhits'].':</h3>';
+ print '<ul class="search_quickhits">';
+ foreach($data as $id => $title){
+ print '<li> ';
+ if (useHeading('navigation')) {
+ $name = $title;
+ }else{
+ $ns = getNS($id);
+ if($ns){
+ $name = shorten(noNS($id), ' ('.$ns.')',30);
+ }else{
+ $name = $id;
+ }
+ }
+ print html_wikilink(':'.$id,$name);
+ print '</li> ';
+ }
+ print '</ul> ';
+ //clear float (see http://www.complexspiral.com/publications/containing-floats/)
+ print '<div class="clearer"></div>';
+ print '</div>';
+ }
+ flush();
+
+ //do fulltext search
+ $data = ft_pageSearch($QUERY,$regex);
+ if(count($data)){
+ $num = 1;
+ foreach($data as $id => $cnt){
+ print '<div class="search_result">';
+ print html_wikilink(':'.$id,useHeading('navigation')?null:$id,$regex);
+ if($cnt !== 0){
+ print ': <span class="search_cnt">'.$cnt.' '.$lang['hits'].'</span><br />';
+ if($num < FT_SNIPPET_NUMBER){ // create snippets for the first number of matches only
+ print '<div class="search_snippet">'.ft_snippet($id,$regex).'</div>';
+ }
+ $num++;
+ }
+ print '</div>';
+ flush();
+ }
+ }else{
+ print '<div class="nothing">'.$lang['nothingfound'].'</div>';
+ }
+
+ //hide progressbar
+ print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--'.NL;
+ print 'hideLoadBar("dw__loading");'.NL;
+ print '//--><!]]></script>'.NL;
+ flush();
+}
+
+/**
+ * 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>
+ */
+function html_revisions($first=0, $media_id = false){
+ global $ID;
+ global $INFO;
+ global $conf;
+ global $lang;
+ $id = $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.
+ * see html_recent()
+ */
+ if (!$media_id) $revisions = getRevisions($ID, $first, $conf['recent']+1);
+ else {
+ $revisions = getRevisions($media_id, $first, $conf['recent']+1, 8192, true);
+ $id = $media_id;
+ }
+
+ if(count($revisions)==0 && $first!=0){
+ $first=0;
+ if (!$media_id) $revisions = getRevisions($ID, $first, $conf['recent']+1);
+ else $revisions = getRevisions($media_id, $first, $conf['recent']+1, 8192, true);
+ }
+ $hasNext = false;
+ if (count($revisions)>$conf['recent']) {
+ $hasNext = true;
+ array_pop($revisions); // remove extra log entry
+ }
+
+ if (!$media_id) $date = dformat($INFO['lastmod']);
+ else $date = dformat(@filemtime(mediaFN($id)));
+
+ if (!$media_id) print p_locale_xhtml('revisions');
+
+ $params = array('id' => 'page__revisions');
+ if ($media_id) $params['action'] = media_managerURL(array('image' => $media_id), '&');
+
+ $form = new Doku_Form($params);
+ $form->addElement(form_makeOpenTag('ul'));
+
+ if (!$media_id) $exists = $INFO['exists'];
+ else $exists = @file_exists(mediaFN($id));
+
+ if($exists && $first==0){
+ if (!$media_id && isset($INFO['meta']) && isset($INFO['meta']['last_change']) && $INFO['meta']['last_change']['type']===DOKU_CHANGE_TYPE_MINOR_EDIT)
+ $form->addElement(form_makeOpenTag('li', array('class' => 'minor')));
+ else
+ $form->addElement(form_makeOpenTag('li'));
+ $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="" />');
+
+ if (!$media_id) $href = wl($id);
+ else $href = media_managerURL(array('image' => $id, 'tab_details' => 'view'), '&');
+ $form->addElement(form_makeOpenTag('a', array(
+ 'class' => 'wikilink1',
+ 'href' => $href)));
+ $form->addElement($id);
+ $form->addElement(form_makeCloseTag('a'));
+
+ if ($media_id) $form->addElement(form_makeOpenTag('div'));
+
+ if (!$media_id) {
+ $form->addElement(form_makeOpenTag('span', array('class' => 'sum')));
+ $form->addElement(' &ndash; ');
+ $form->addElement(htmlspecialchars($INFO['sum']));
+ $form->addElement(form_makeCloseTag('span'));
+ }
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'user')));
+ if (!$media_id) $editor = $INFO['editor'];
+ else {
+ $revinfo = getRevisionInfo($id, @filemtime(fullpath(mediaFN($id))), 1024, true);
+ if($revinfo['user']){
+ $editor = $revinfo['user'];
+ }else{
+ $editor = $revinfo['ip'];
+ }
+ }
+ $form->addElement((empty($editor))?('('.$lang['external_edit'].')'):editorinfo($editor));
+ $form->addElement(form_makeCloseTag('span'));
+
+ $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);
+ if (!$media_id) {
+ $info = getRevisionInfo($id,$rev,true);
+ $exists = page_exists($id,$rev);
+ } else {
+ $info = getRevisionInfo($id,$rev,true,true);
+ $exists = @file_exists(mediaFN($id,$rev));
+ }
+
+ if ($info['type']===DOKU_CHANGE_TYPE_MINOR_EDIT)
+ $form->addElement(form_makeOpenTag('li', array('class' => 'minor')));
+ else
+ $form->addElement(form_makeOpenTag('li'));
+ $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('href' => $href, 'class' => 'diff_link')));
+ $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('href' => $href, 'class' => 'wikilink1')));
+ $form->addElement($id);
+ $form->addElement(form_makeCloseTag('a'));
+ }else{
+ $form->addElement('<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />');
+ $form->addElement($id);
+ }
+
+ if ($media_id) $form->addElement(form_makeOpenTag('div'));
+
+ if ($info['sum']) {
+ $form->addElement(form_makeOpenTag('span', array('class' => 'sum')));
+ if (!$media_id) $form->addElement(' &ndash; ');
+ $form->addElement(htmlspecialchars($info['sum']));
+ $form->addElement(form_makeCloseTag('span'));
+ }
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'user')));
+ if($info['user']){
+ $form->addElement(editorinfo($info['user']));
+ if(auth_ismanager()){
+ $form->addElement(' ('.$info['ip'].')');
+ }
+ }else{
+ $form->addElement($info['ip']);
+ }
+ $form->addElement(form_makeCloseTag('span'));
+
+ 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>
+ */
+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'));
+ $form->addHidden('sectok', null);
+ $form->addHidden('do', 'recent');
+ $form->addHidden('id', $ID);
+
+ if ($conf['mediarevisions']) {
+ $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(form_makeOpenTag('ul'));
+
+ foreach($recents as $recent){
+ $date = dformat($recent['date']);
+ if ($recent['type']===DOKU_CHANGE_TYPE_MINOR_EDIT)
+ $form->addElement(form_makeOpenTag('li', array('class' => 'minor')));
+ else
+ $form->addElement(form_makeOpenTag('li'));
+
+ $form->addElement(form_makeOpenTag('div', array('class' => 'li')));
+
+ if ($recent['media']) {
+ $form->addElement(media_printicon($recent['id']));
+ } else {
+ $icon = DOKU_BASE.'lib/images/fileicons/file.png';
+ $form->addElement('<img src="'.$icon.'" alt="'.$filename.'" class="icon" />');
+ }
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'date')));
+ $form->addElement($date);
+ $form->addElement(form_makeCloseTag('span'));
+
+ if ($recent['media']) {
+ $diff = (count(getRevisions($recent['id'], 0, 1, 8192, true)) && @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 ($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 ($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 ($recent['media']) {
+ $href = media_managerURL(array('tab_details' => 'view', 'image' => $recent['id'], 'ns' => getNS($recent['id'])), '&');
+ $class = (file_exists(mediaFN($recent['id']))) ? 'wikilink1' : $class = '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(' &ndash; '.htmlspecialchars($recent['sum']));
+ $form->addElement(form_makeCloseTag('span'));
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'user')));
+ if($recent['user']){
+ $form->addElement(editorinfo($recent['user']));
+ if(auth_ismanager()){
+ $form->addElement(' ('.$recent['ip'].')');
+ }
+ }else{
+ $form->addElement($recent['ip']);
+ }
+ $form->addElement(form_makeCloseTag('span'));
+
+ $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_makeTag('input', array(
+ 'type' => 'submit',
+ 'name' => 'first['.$first.']',
+ 'value' => $lang['btn_newer'],
+ 'accesskey' => 'n',
+ 'title' => $lang['btn_newer'].' [N]',
+ 'class' => 'button show'
+ )));
+ $form->addElement(form_makeCloseTag('div'));
+ }
+ if ($hasNext) {
+ $form->addElement(form_makeOpenTag('div', array('class' => 'pagenav-next')));
+ $form->addElement(form_makeTag('input', array(
+ 'type' => 'submit',
+ 'name' => 'first['.$last.']',
+ 'value' => $lang['btn_older'],
+ 'accesskey' => 'p',
+ 'title' => $lang['btn_older'].' [P]',
+ 'class' => 'button show'
+ )));
+ $form->addElement(form_makeCloseTag('div'));
+ }
+ $form->addElement(form_makeCloseTag('div'));
+ html_form('recent', $form);
+}
+
+/**
+ * Display page index
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_index($ns){
+ global $conf;
+ global $ID;
+ $dir = $conf['datadir'];
+ $ns = cleanID($ns);
+ #fixme use appropriate function
+ if(empty($ns)){
+ $ns = dirname(str_replace(':','/',$ID));
+ if($ns == '.') $ns ='';
+ }
+ $ns = utf8_encodeFN(str_replace(':','/',$ns));
+
+ echo p_locale_xhtml('index');
+ echo '<div id="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>
+ */
+function html_list_index($item){
+ global $ID;
+ $ret = '';
+ $base = ':'.$item['id'];
+ $base = substr($base,strrpos($base,':')+1);
+ if($item['type']=='d'){
+ $ret .= '<a href="'.wl($ID,'idx='.rawurlencode($item['id'])).'" class="idx_dir"><strong>';
+ $ret .= $base;
+ $ret .= '</strong></a>';
+ }else{
+ $ret .= html_wikilink(':'.$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>
+ */
+function html_li_index($item){
+ if($item['type'] == "f"){
+ return '<li class="level'.$item['level'].'">';
+ }elseif($item['open']){
+ return '<li class="open">';
+ }else{
+ return '<li class="closed">';
+ }
+}
+
+/**
+ * Default List item
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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>
+ */
+function html_buildlist($data,$class,$func,$lifunc='html_li_default',$forcewrapper=false){
+ if (count($data) === 0) {
+ return '';
+ }
+
+ $start_level = $data[0]['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 $conf;
+ 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>';
+ }
+}
+
+function html_diff_head($l_rev, $r_rev, $id = null, $media = false) {
+ global $lang;
+ if ($id === null) {
+ global $ID;
+ $id = $ID;
+ }
+ $media_or_wikiFN = $media ? 'mediaFN' : 'wikiFN';
+ $ml_or_wl = $media ? 'ml' : 'wl';
+ $l_minor = $r_minor = '';
+
+ if(!$l_rev){
+ $l_head = '&mdash;';
+ }else{
+ $l_info = getRevisionInfo($id,$l_rev,true, $media);
+ if($l_info['user']){
+ $l_user = editorinfo($l_info['user']);
+ if(auth_ismanager()) $l_user .= ' ('.$l_info['ip'].')';
+ } else {
+ $l_user = $l_info['ip'];
+ }
+ $l_user = '<span class="user">'.$l_user.'</span>';
+ $l_sum = ($l_info['sum']) ? '<span class="sum">'.hsc($l_info['sum']).'</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 = '<a class="wikilink1" href="'.$ml_or_wl($id,"rev=$l_rev").'">'.
+ $l_head_title.'</a>'.
+ '<br />'.$l_user.' '.$l_sum;
+ }
+
+ if($r_rev){
+ $r_info = getRevisionInfo($id,$r_rev,true, $media);
+ if($r_info['user']){
+ $r_user = editorinfo($r_info['user']);
+ if(auth_ismanager()) $r_user .= ' ('.$r_info['ip'].')';
+ } else {
+ $r_user = $r_info['ip'];
+ }
+ $r_user = '<span class="user">'.$r_user.'</span>';
+ $r_sum = ($r_info['sum']) ? '<span class="sum">'.hsc($r_info['sum']).'</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 = '<a class="wikilink1" href="'.$ml_or_wl($id,"rev=$r_rev").'">'.
+ $r_head_title.'</a>'.
+ '<br />'.$r_user.' '.$r_sum;
+ }elseif($_rev = @filemtime($media_or_wikiFN($id))){
+ $_info = getRevisionInfo($id,$_rev,true, $media);
+ if($_info['user']){
+ $_user = editorinfo($_info['user']);
+ if(auth_ismanager()) $_user .= ' ('.$_info['ip'].')';
+ } else {
+ $_user = $_info['ip'];
+ }
+ $_user = '<span class="user">'.$_user.'</span>';
+ $_sum = ($_info['sum']) ? '<span class="sum">'.hsc($_info['sum']).'</span>' : '';
+ if ($_info['type']===DOKU_CHANGE_TYPE_MINOR_EDIT) $r_minor = 'class="minor"';
+
+ $r_head_title = ($media) ? dformat($_rev) : $id.' ['.dformat($_rev).']';
+ $r_head = '<a class="wikilink1" href="'.$ml_or_wl($id).'">'.
+ $r_head_title.'</a> '.
+ '('.$lang['current'].')'.
+ '<br />'.$_user.' '.$_sum;
+ }else{
+ $r_head = '&mdash; ('.$lang['current'].')';
+ }
+
+ return array($l_head, $r_head, $l_minor, $r_minor);
+}
+
+/**
+ * show diff
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $text - compare with this text with most current version
+ * @param bool $intr - display the intro text
+ */
+function html_diff($text='',$intro=true,$type=null){
+ global $ID;
+ global $REV;
+ global $lang;
+ global $conf;
+
+ if(!$type) $type = $_REQUEST['difftype'];
+ if($type != 'inline') $type = 'sidebyside';
+
+ // 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;
+
+ if(is_array($_REQUEST['rev2'])){
+ $rev1 = (int) $_REQUEST['rev2'][0];
+ $rev2 = (int) $_REQUEST['rev2'][1];
+
+ if(!$rev1){
+ $rev1 = $rev2;
+ unset($rev2);
+ }
+ }else{
+ $rev2 = (int) $_REQUEST['rev2'];
+ }
+
+ $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 && $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 = getRevisions($ID, 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);
+ }
+
+ $df = new Diff(explode("\n",htmlspecialchars($l_text)),
+ explode("\n",htmlspecialchars($r_text)));
+
+ if($type == 'inline'){
+ $tdf = new InlineDiffFormatter();
+ } else {
+ $tdf = new TableDiffFormatter();
+ }
+
+
+
+ if($intro) print p_locale_xhtml('diff');
+
+ if (!$text) {
+ ptln('<div class="diffoptions">');
+
+ $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();
+
+
+ $diffurl = wl($ID, array(
+ 'do' => 'diff',
+ 'rev2[0]' => $l_rev,
+ 'rev2[1]' => $r_rev,
+ 'difftype' => $type,
+ ));
+ ptln('<p><a class="wikilink1" href="'.$diffurl.'">'.$lang['difflink'].'</a></p>');
+ ptln('</div>');
+ }
+ ?>
+ <div class="table">
+ <table class="diff diff_<?php echo $type?>">
+ <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 echo $tdf->format($df)?>
+ </table>
+ </div>
+ <?php
+}
+
+/**
+ * show warning on conflict detection
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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;
+ // 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
+ 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 $ID;
+
+ 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', $_POST['login'], $lang['user'], '', 'block', array('size'=>'50')));
+ if (!$conf['autopasswd']) {
+ $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_makeTextField('fullname', $_POST['fullname'], $lang['fullname'], '', 'block', array('size'=>'50')));
+ $form->addElement(form_makeTextField('email', $_POST['email'], $lang['email'], '', 'block', array('size'=>'50')));
+ $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 $ID;
+ global $INFO;
+ global $auth;
+
+ print p_locale_xhtml('updateprofile');
+
+ if (empty($_POST['fullname'])) $_POST['fullname'] = $INFO['userinfo']['name'];
+ if (empty($_POST['email'])) $_POST['email'] = $INFO['userinfo']['mail'];
+ print '<div class="centeralign">'.NL;
+ $form = new Doku_Form(array('id' => 'dw__register'));
+ $form->startFieldset($lang['profile']);
+ $form->addHidden('do', 'profile');
+ $form->addHidden('save', '1');
+ $form->addElement(form_makeTextField('fullname', $_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', $_POST['fullname'], $lang['fullname'], '', 'block', $attr));
+ $attr = array('size'=>'50');
+ if (!$auth->canDo('modMail')) $attr['disabled'] = 'disabled';
+ $form->addElement(form_makeTextField('email', $_POST['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')));
+ }
+ $form->addElement(form_makeButton('submit', '', $lang['btn_save']));
+ $form->addElement(form_makeButton('reset', '', $lang['btn_reset']));
+ $form->endFieldset();
+ html_form('updateprofile', $form);
+ print '</div>'.NL;
+}
+
+/**
+ * Preprocess edit form data
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @triggers HTML_EDITFORM_OUTPUT
+ */
+function html_edit(){
+ global $ID;
+ global $REV;
+ global $DATE;
+ global $PRE;
+ global $SUF;
+ global $INFO;
+ global $SUM;
+ global $lang;
+ global $conf;
+ global $TEXT;
+ global $RANGE;
+
+ if (isset($_REQUEST['changecheck'])) {
+ $check = $_REQUEST['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' => (isset($_REQUEST['target']) && $wr &&
+ $RANGE !== '') ? $_REQUEST['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.
+ trigger_event('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']);
+ $form->addElement(form_makeOpenTag('div', array('id'=>'wiki__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', 'draftdel', $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 type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--'. NL;
+ echo 'textChanged = ' . ($mod ? 'true' : 'false');
+ echo '//--><!]]></script>' . NL;
+ } ?>
+ <div style="width:99%;">
+
+ <div class="toolbar">
+ <div id="draft__status"><?php if(!empty($INFO['draft'])) echo $lang['draftdate'].' '.dformat();?></div>
+ <div id="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>
+ <?php
+
+ html_form('edit', $form);
+ print '</div>'.NL;
+}
+
+/**
+ * Display the default edit form
+ *
+ * Is the default action for HTML_EDIT_FORMSELECTION.
+ */
+function html_edit_form($param) {
+ global $TEXT;
+
+ if ($param['target'] !== 'section') {
+ msg('No editor for edit target ' . $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>
+ */
+function html_minoredit(){
+ global $conf;
+ global $lang;
+ // minor edits are for logged in users only
+ if(!$conf['useacl'] || !$_SERVER['REMOTE_USER']){
+ return false;
+ }
+
+ $p = array();
+ $p['tabindex'] = 3;
+ if(!empty($_REQUEST['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;
+ 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>';
+ print_r($auth->cando);
+ 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>';
+
+ print '</body></html>';
+}
+
+/**
+ * List available Administration Tasks
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ */
+function html_admin(){
+ global $ID;
+ global $INFO;
+ global $lang;
+ global $conf;
+ global $auth;
+
+ // build menu of admin functions from the plugins that handle them
+ $pluginlist = plugin_list('admin');
+ $menu = array();
+ foreach ($pluginlist as $p) {
+ if($obj =& plugin_load('admin',$p) === null) continue;
+
+ // check permissions
+ if($obj->forAdminOnly() && !$INFO['isadmin']) continue;
+
+ $menu[$p] = array('plugin' => $p,
+ 'prompt' => $obj->getMenuText($conf['lang']),
+ 'sort' => $obj->getMenuSort()
+ );
+ }
+
+ // data security check
+ // @todo: could be checked and only displayed if $conf['savedir'] is under the web root
+ echo '<a style="border:none; float:right;"
+ href="http://www.dokuwiki.org/security#web_access_security">
+ <img src="data/security.png" alt="Your data directory seems to be protected properly."
+ onerror="this.parentNode.style.display=\'none\'" /></a>';
+
+ print p_locale_xhtml('admin');
+
+ // Admin Tasks
+ if($INFO['isadmin']){
+ ptln('<ul class="admin_tasks">');
+
+ if($menu['usermanager'] && $auth && $auth->canDo('getUsers')){
+ ptln(' <li class="admin_usermanager"><div class="li">'.
+ '<a href="'.wl($ID, array('do' => 'admin','page' => 'usermanager')).'">'.
+ $menu['usermanager']['prompt'].'</a></div></li>');
+ }
+ unset($menu['usermanager']);
+
+ if($menu['acl']){
+ ptln(' <li class="admin_acl"><div class="li">'.
+ '<a href="'.wl($ID, array('do' => 'admin','page' => 'acl')).'">'.
+ $menu['acl']['prompt'].'</a></div></li>');
+ }
+ unset($menu['acl']);
+
+ if($menu['plugin']){
+ ptln(' <li class="admin_plugin"><div class="li">'.
+ '<a href="'.wl($ID, array('do' => 'admin','page' => 'plugin')).'">'.
+ $menu['plugin']['prompt'].'</a></div></li>');
+ }
+ unset($menu['plugin']);
+
+ if($menu['config']){
+ ptln(' <li class="admin_config"><div class="li">'.
+ '<a href="'.wl($ID, array('do' => 'admin','page' => 'config')).'">'.
+ $menu['config']['prompt'].'</a></div></li>');
+ }
+ unset($menu['config']);
+ }
+ ptln('</ul>');
+
+ // Manager Tasks
+ ptln('<ul class="admin_tasks">');
+
+ if($menu['revert']){
+ ptln(' <li class="admin_revert"><div class="li">'.
+ '<a href="'.wl($ID, array('do' => 'admin','page' => 'revert')).'">'.
+ $menu['revert']['prompt'].'</a></div></li>');
+ }
+ unset($menu['revert']);
+
+ if($menu['popularity']){
+ ptln(' <li class="admin_popularity"><div class="li">'.
+ '<a href="'.wl($ID, array('do' => 'admin','page' => 'popularity')).'">'.
+ $menu['popularity']['prompt'].'</a></div></li>');
+ }
+ unset($menu['popularity']);
+
+ // print DokuWiki version:
+ ptln('</ul>');
+ echo '<div id="admin__version">';
+ echo getVersion();
+ echo '</div>';
+
+ // print the rest as sorted list
+ if(count($menu)){
+ usort($menu, 'p_sort_modes');
+ // output the menu
+ ptln('<div class="clearer"></div>');
+ print p_locale_xhtml('adminplugins');
+ ptln('<ul>');
+ foreach ($menu as $item) {
+ if (!$item['prompt']) continue;
+ ptln(' <li><div class="li"><a href="'.wl($ID, 'do=admin&amp;page='.$item['plugin']).'">'.$item['prompt'].'</a></div></li>');
+ }
+ ptln('</ul>');
+ }
+}
+
+/**
+ * Form to request a new password for an existing account
+ *
+ * @author Benoit Chesneau <benoit@bchesneau.info>
+ */
+function html_resendpwd() {
+ global $lang;
+ global $conf;
+ global $ID;
+
+ 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', $_POST['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>
+ */
+function html_TOC($toc){
+ if(!count($toc)) return '';
+ global $lang;
+ $out = '<!-- TOC START -->'.DOKU_LF;
+ $out .= '<div class="toc">'.DOKU_LF;
+ $out .= '<div class="tocheader toctoggle" id="toc__header">';
+ $out .= $lang['toc'];
+ $out .= '</div>'.DOKU_LF;
+ $out .= '<div id="toc__inside">'.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
+ */
+function html_list_toc($item){
+ if(isset($item['hid'])){
+ $link = '#'.$item['hid'];
+ }else{
+ $link = $item['link'];
+ }
+
+ return '<span class="li"><a href="'.$link.'" class="toc">'.
+ hsc($item['title']).'</a></span>';
+}
+
+/**
+ * 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
+ */
+function html_mktocitem($link, $text, $level, $hash='#'){
+ global $conf;
+ 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>
+ */
+function html_form($name, &$form) {
+ // Safety check in case the caller forgets.
+ $form->endFieldset();
+ trigger_event('HTML_'.strtoupper($name).'FORM_OUTPUT', $form, 'html_form_output', false);
+}
+
+/**
+ * Form print function.
+ * Just calls printForm() on the data object.
+ */
+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!)
+ * @returns 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;
+}
+
+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;
+}
+
diff --git a/inc/httputils.php b/inc/httputils.php
new file mode 100644
index 000000000..0ad97a9a1
--- /dev/null
+++ b/inc/httputils.php
@@ -0,0 +1,251 @@
+<?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 timestamp $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 vi x-sendfile method
+ *
+ * @author Chris Smith <chris.eureka@jalakai.co.uk>
+ * @returns void or exits with previously header() commands executed
+ */
+function http_sendfile($file) {
+ global $conf;
+
+ //use x-sendfile header to pass the delivery to compatible webservers
+ 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){
+ header("X-Accel-Redirect: $file");
+ ob_end_clean();
+ exit;
+ }
+
+ return false;
+}
+
+/**
+ * Send file contents supporting rangeRequests
+ *
+ * This function exits the running script
+ *
+ * @param ressource $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
+ 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>
+ */
+function http_gzip_valid($uncompressed_file) {
+ $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 scrpt is terminated.
+ */
+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 {
+ if (!http_sendfile($cache)) readfile($cache);
+ }
+ exit;
+ }
+
+ http_conditionalRequest(time());
+}
+
+/**
+ * Cache content and print it
+ */
+function http_cached_finish($file, $content) {
+ global $conf;
+
+ // save cache file
+ io_saveFile($file, $content);
+ if(function_exists('gzopen')) io_saveFile("$file.gz",$content);
+
+ // finally send output
+ if ($conf['gzip_output']) {
+ header('Vary: Accept-Encoding');
+ header('Content-Encoding: gzip');
+ print gzencode($content,9,FORCE_GZIP);
+ } else {
+ print $content;
+ }
+}
diff --git a/inc/indexer.php b/inc/indexer.php
new file mode 100644
index 000000000..9d8d6f99b
--- /dev/null
+++ b/inc/indexer.php
@@ -0,0 +1,1395 @@
+<?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>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+// Version tag used to force rebuild on upgrade
+define('INDEXER_VERSION', 5);
+
+// 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);
+
+// Asian characters are handled as words. The following regexp defines the
+// Unicode-Ranges for Asian characters
+// Ranges taken from http://en.wikipedia.org/wiki/Unicode_block
+// I'm no language expert. If you think some ranges are wrongly chosen or
+// a range is missing, please contact me
+define('IDX_ASIAN1','[\x{0E00}-\x{0E7F}]'); // Thai
+define('IDX_ASIAN2','['.
+ '\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
+ ']');
+define('IDX_ASIAN3','['. // 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}'.
+ ']?');
+define('IDX_ASIAN', '(?:'.IDX_ASIAN1.'|'.IDX_ASIAN2.'|'.IDX_ASIAN3.')');
+
+/**
+ * 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>
+ */
+function idx_get_version(){
+ static $indexer_version = null;
+ if ($indexer_version == null) {
+ global $conf;
+ $version = INDEXER_VERSION;
+
+ // DokuWiki version is included for the convenience of plugins
+ $data = array('dokuwiki'=>$version);
+ trigger_event('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>
+ */
+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;
+}
+
+/**
+ * Class that encapsulates operations on the indexer database.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+class Doku_Indexer {
+
+ /**
+ * 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 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->addIndexKey('page', '', $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) {
+ global $conf;
+
+ $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) {
+ $wid = array_search($word, $word_idx);
+ 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 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->addIndexKey('page', '', $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);
+ if ($id === false) {
+ $id = count($metawords);
+ $metawords[$id] = $val;
+ $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;
+ }
+
+ /**
+ * Remove a page from the index
+ *
+ * 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>
+ */
+ public function deletePage($page) {
+ if (!$this->lock())
+ return "locked";
+
+ // load known documents
+ $pid = $this->getIndexKey('page', '', $page);
+ if ($pid === false) {
+ $this->unlock();
+ 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, "")) {
+ $this->unlock();
+ 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) {
+ $meta_idx[$id] = $this->updateTuple($meta_idx[$id], $pid, 0);
+ }
+ $this->saveIndex($metaname.'_i', '', $meta_idx);
+ $this->saveIndexKey($metaname.'_p', '', $pid, '');
+ }
+
+ $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) {
+ global $conf;
+ $words = array();
+ $wc = ($wc) ? '' : '\*';
+ $stopwords =& idx_get_stopwords();
+
+ // prepare the text to be tokenized
+ $evt = new Doku_Event('INDEXER_TEXT_PREPARE', $text);
+ if ($evt->advise_before(true)) {
+ if (preg_match('/[^0-9A-Za-z ]/u', $text)) {
+ // handle asian chars as single words (may fail on older PHP version)
+ $asia = @preg_replace('/('.IDX_ASIAN.')/u', ' \1 ', $text);
+ if (!is_null($asia)) $text = $asia; // recover from regexp falure
+ }
+ }
+ $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 = utf8_stripspecials($text, ' ', '\._\-:'.$wc);
+
+ $wordlist = explode(' ', $text);
+ foreach ($wordlist as $i => $word) {
+ $wordlist[$i] = (preg_match('/[^0-9A-Za-z]/u', $word)) ?
+ utf8_strtolower($word) : strtolower($word);
+ }
+
+ foreach ($wordlist as $i => $word) {
+ if ((!is_numeric($word) && strlen($word) < IDX_MINWORDLENGTH)
+ || array_search($word, $stopwords) !== false)
+ unset($wordlist[$i]);
+ }
+ return array_values($wordlist);
+ }
+
+ /**
+ * 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 arrayref $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)) !== 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 arrayref $words The query terms.
+ * @param arrayref $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);
+ 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 $length 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) && strlen($val) >= $minlen)
+ $val_idx[$wid] = $freq;
+ }
+ if (!empty($val_idx)) {
+ $words = $this->getIndex($metaname.'_w', '');
+ foreach ($val_idx as $wid => $freq)
+ $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>
+ */
+ 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 ($conf['dperm'])
+ chmod($lock, $conf['dperm']);
+ return $status;
+ }
+
+ /**
+ * Release the indexer lock.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ 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 arrayref $linex list of lines without LF
+ * @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 (isset($conf['fperm']))
+ chmod($fn.'.tmp', $conf['fperm']);
+ io_rename($fn.'.tmp', $fn.'.idx');
+ if ($suffix !== '')
+ $this->cacheIndexDir($idx, $suffix, empty($lines));
+ 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
+ * @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 (isset($conf['fperm']))
+ chmod($fn.'.tmp', $conf['fperm']);
+ io_rename($fn.'.tmp', $fn.'.idx');
+ if ($suffix !== '')
+ $this->cacheIndexDir($idx, $suffix);
+ 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 line number of the value in the index
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function addIndexKey($idx, $suffix, $value) {
+ $index = $this->getIndex($idx, $suffix);
+ $id = array_search($value, $index);
+ 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;
+ }
+
+ protected function cacheIndexDir($idx, $suffix, $delete=false) {
+ global $conf;
+ if ($idx == 'i')
+ $cachename = $conf['indexdir'].'/lengths';
+ else
+ $cachename = $conf['indexdir'].'/'.$idx.'lengths';
+ $lengths = @file($cachename.'.idx', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ if ($lengths === false) $lengths = array();
+ $old = array_search((string)$suffix, $lengths);
+ if (empty($lines)) {
+ if ($old === false) return;
+ unset($lengths[$old]);
+ } else {
+ if ($old !== false) return;
+ $lengths[] = $suffix;
+ sort($lengths);
+ }
+ $fh = @fopen($cachename.'.tmp', 'w');
+ if (!$fh) {
+ trigger_error("Failed to write index cache", E_USER_ERROR);
+ return;
+ }
+ @fwrite($fh, implode("\n", $lengths));
+ @fclose($fh);
+ if (isset($conf['fperm']))
+ chmod($cachename.'.tmp', $conf['fperm']);
+ io_rename($cachename.'.tmp', $cachename.'.idx');
+ }
+
+ /**
+ * 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>
+ */
+ protected function listIndexLengths() {
+ global $conf;
+ $cachename = $conf['indexdir'].'/lengths';
+ clearstatcache();
+ if (@file_exists($cachename.'.idx')) {
+ $lengths = @file($cachename.'.idx', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ if ($lengths !== false) {
+ $idx = array();
+ foreach ($lengths as $length)
+ $idx[] = (int)$length;
+ return $idx;
+ }
+ }
+
+ $dir = @opendir($conf['indexdir']);
+ if ($dir === false)
+ return array();
+ $lengths[] = 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))
+ $lengths[] = (int)$i;
+ }
+ }
+ closedir($dir);
+ sort($lengths);
+ // save this in a file
+ $fh = @fopen($cachename.'.tmp', 'w');
+ if (!$fh) {
+ trigger_error("Failed to write index cache", E_USER_ERROR);
+ return;
+ }
+ @fwrite($fh, implode("\n", $lengths));
+ @fclose($fh);
+ if (isset($conf['fperm']))
+ chmod($cachename.'.tmp', $conf['fperm']);
+ io_rename($cachename.'.tmp', $cachename.'.idx');
+
+ return $lengths;
+ }
+
+ /**
+ * 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>
+ */
+ 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>
+ */
+ protected function updateTuple($line, $id, $count) {
+ $newLine = $line;
+ if ($newLine !== '')
+ $newLine = preg_replace('/(^|:)'.preg_quote($id,'/').'\*\d*/', '', $newLine);
+ $newLine = trim($newLine, ':');
+ if ($count) {
+ if (strlen($newLine) > 0)
+ return "$id*$count:".$newLine;
+ else
+ return "$id*$count".$newLine;
+ }
+ return $newLine;
+ }
+
+ /**
+ * Split a line into an array of tuples.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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) continue;
+ $result[$key] = $cnt;
+ }
+ return $result;
+ }
+
+ /**
+ * Sum the counts in a list of tuples.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ 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;
+ }
+}
+
+/**
+ * Create an instance of the indexer.
+ *
+ * @return object a Doku_Indexer
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function idx_get_indexer() {
+ static $Indexer = null;
+ if (is_null($Indexer)) {
+ $Indexer = new Doku_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 boolean the function completed successfully
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function idx_addPage($page, $verbose=false, $force=false) {
+ // check if indexing needed
+ $idxtag = metaFN($page,'.indexed');
+ 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;
+ }
+ }
+ }
+
+ 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;
+ }
+ $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;
+ }
+
+ $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();
+ $data = compact('page', 'body', 'metadata');
+ $evt = new Doku_Event('INDEXER_PAGE_ADD', $data);
+ if ($evt->advise_before()) $data['body'] = $data['body'] . " " . rawWiki($page);
+ $evt->advise_after();
+ unset($evt);
+ extract($data);
+
+ $Indexer = idx_get_indexer();
+ $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 arrayref $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
+ *
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+function idx_cleanName($name) {
+ $name = utf8_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/inc/infoutils.php b/inc/infoutils.php
new file mode 100644
index 000000000..2b8486906
--- /dev/null
+++ b/inc/infoutils.php
@@ -0,0 +1,423 @@
+<?php
+/**
+ * Information and debugging functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+if(!defined('DOKU_INC')) die('meh.');
+if(!defined('DOKU_MESSAGEURL')) 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 = $conf['cachedir'].'/messages.txt';
+ $lm = @filemtime($cf);
+
+ // check if new messages needs to be fetched
+ if($lm < time()-(60*60*24) || $lm < @filemtime(DOKU_INC.DOKU_SCRIPT)){
+ $http = new DokuHTTPClient();
+ $http->timeout = 8;
+ $data = $http->get(DOKU_MESSAGEURL.$updateVersion);
+ io_saveFile($cf,$data);
+ }else{
+ $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{
+ $version['date'] = 'unknown';
+ $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;
+
+ if ($INFO['isadmin'] || $INFO['ismanager']){
+ msg('DokuWiki version: '.getVersion(),1);
+ }
+
+ if(version_compare(phpversion(),'5.1.2','<')){
+ msg('Your PHP version is too old ('.phpversion().' vs. 5.1.2+ needed)',-1);
+ }else{
+ msg('PHP version '.phpversion(),1);
+ }
+
+ $mem = (int) php_to_byte(ini_get('memory_limit'));
+ if($mem){
+ if($mem < 16777216){
+ msg('PHP is limited to less than 16MB RAM ('.$mem.' bytes). Increase memory_limit in php.ini',-1);
+ }elseif($mem < 20971520){
+ msg('PHP is limited to less than 20MB RAM ('.$mem.' bytes), you might encounter problems with bigger pages. Increase memory_limit in php.ini',-1);
+ }elseif($mem < 33554432){
+ msg('PHP is limited to less than 32MB RAM ('.$mem.' bytes), but that should be enough in most cases. If not, increase memory_limit in php.ini',0);
+ }else{
+ msg('More than 32MB RAM ('.$mem.' bytes) 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($conf['datadir'])){
+ msg('Datadir is writable',1);
+ }else{
+ msg('Datadir is not writable',-1);
+ }
+
+ if(is_writable($conf['olddir'])){
+ msg('Attic is writable',1);
+ }else{
+ msg('Attic is not writable',-1);
+ }
+
+ if(is_writable($conf['mediadir'])){
+ msg('Mediadir is writable',1);
+ }else{
+ msg('Mediadir is not writable',-1);
+ }
+
+ if(is_writable($conf['cachedir'])){
+ msg('Cachedir is writable',1);
+ }else{
+ msg('Cachedir is not writable',-1);
+ }
+
+ if(is_writable($conf['lockdir'])){
+ msg('Lockdir is writable',1);
+ }else{
+ msg('Lockdir is not writable',-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($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 '.$_SERVER['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(is_writable($INFO['filepath'])){
+ msg('The current page is writable by the webserver',0);
+ }else{
+ msg('The current page is not writable by the webserver',0);
+ }
+
+ if($INFO['writable']){
+ msg('The current page is writable by you',0);
+ }else{
+ msg('The current page is not writable by you',0);
+ }
+
+ $check = wl('','',true).'data/_dummy';
+ $http = new DokuHTTPClient();
+ $http->timeout = 6;
+ $res = $http->get($check);
+ if(strpos($res,'data directory') !== false){
+ msg('It seems like the data directory is accessible from the web.
+ Make sure this directory is properly protected
+ (See <a href="http://www.dokuwiki.org/security">security</a>)',-1);
+ }elseif($http->status == 404 || $http->status == 403){
+ msg('The data directory seems to be properly protected',1);
+ }else{
+ msg('Failed to check if the data directory is accessible from the web.
+ Make sure this directory is properly protected
+ (See <a href="http://www.dokuwiki.org/security">security</a>)',-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.');
+}
+
+/**
+ * print a message
+ *
+ * If HTTP headers were not sent yet the message is added
+ * to the global message array else it's printed directly
+ * using html_msgarea()
+ *
+ *
+ * Levels can be:
+ *
+ * -1 error
+ * 0 info
+ * 1 success
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see html_msgarea
+ */
+function msg($message,$lvl=0,$line='',$file=''){
+ global $MSG, $MSG_shown;
+ $errors[-1] = 'error';
+ $errors[0] = 'info';
+ $errors[1] = 'success';
+ $errors[2] = 'notify';
+
+ if($line || $file) $message.=' ['.basename($file).':'.$line.']';
+
+ if(!isset($MSG)) $MSG = array();
+ $MSG[]=array('lvl' => $errors[$lvl], 'msg' => $message);
+ if(isset($MSG_shown) || headers_sent()){
+ if(function_exists('html_msgarea')){
+ html_msgarea();
+ }else{
+ print "ERROR($lvl) $message";
+ }
+ unset($GLOBALS['MSG']);
+ }
+}
+
+/**
+ * print debug messages
+ *
+ * little function to print the content of a var
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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>
+ */
+function dbglog($msg,$header=''){
+ global $conf;
+ // 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 ').$_SERVER['REMOTE_ADDR'].': '.$msg."\n");
+ fclose($fh);
+ }
+}
+
+/**
+ * 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)){
+ $param[] = '[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>
+ */
+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/inc/init.php b/inc/init.php
new file mode 100644
index 000000000..3aab0587b
--- /dev/null
+++ b/inc/init.php
@@ -0,0 +1,561 @@
+<?php
+/**
+ * Initialize some defaults needed for DokuWiki
+ */
+
+// start timing Dokuwiki execution
+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')) {
+ if(defined('E_DEPRECATED')){ // since php 5.3, since php 5.4 E_STRICT is part of E_ALL
+ error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT);
+ }else{
+ error_reporting(E_ALL ^ E_NOTICE);
+ }
+} else {
+ error_reporting(DOKU_E_LEVEL);
+}
+
+// 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 language array
+global $lang;
+$lang = array();
+
+//load the language files
+require_once(DOKU_INC.'inc/lang/en/lang.php');
+if ( $conf['lang'] && $conf['lang'] != 'en' ) {
+ require_once(DOKU_INC.'inc/lang/'.$conf['lang'].'/lang.php');
+}
+
+//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('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')) define('DOKU_COOKIE', 'DW'.md5(DOKU_REL.(($conf['securecookie'])?$_SERVER['SERVER_PORT']:'')));
+
+
+// define main script
+if(!defined('DOKU_SCRIPT')) define('DOKU_SCRIPT','doku.php');
+
+// DEPRECATED, use tpl_basedir() instead
+if(!defined('DOKU_TPL')) define('DOKU_TPL',
+ DOKU_BASE.'lib/tpl/'.$conf['template'].'/');
+
+// DEPRECATED, use tpl_incdir() instead
+if(!defined('DOKU_TPLINC')) 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
+$conf['gzip_output'] &= (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false);
+if ($conf['gzip_output'] &&
+ !defined('DOKU_DISABLE_GZIP_OUTPUT') &&
+ function_exists('ob_gzhandler')) {
+ ob_start('ob_gzhandler');
+}
+
+// init session
+if (!headers_sent() && !defined('NOSESSION')){
+ session_name("DokuWiki");
+ $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
+ if (version_compare(PHP_VERSION, '5.2.0', '>')) {
+ session_set_cookie_params(0,$cookieDir,'',($conf['securecookie'] && is_ssl()),true);
+ }else{
+ session_set_cookie_params(0,$cookieDir,'',($conf['securecookie'] && is_ssl()));
+ }
+ session_start();
+
+ // load left over messages
+ if(isset($_SESSION[DOKU_COOKIE]['msg'])){
+ $MSG = $_SESSION[DOKU_COOKIE]['msg'];
+ unset($_SESSION[DOKU_COOKIE]['msg']);
+ }
+}
+
+// kill magic quotes
+if (get_magic_quotes_gpc() && !defined('MAGIC_QUOTES_STRIPPED')) {
+ if (!empty($_GET)) remove_magic_quotes($_GET);
+ if (!empty($_POST)) remove_magic_quotes($_POST);
+ if (!empty($_COOKIE)) remove_magic_quotes($_COOKIE);
+ if (!empty($_REQUEST)) remove_magic_quotes($_REQUEST);
+ @ini_set('magic_quotes_gpc', 0);
+ define('MAGIC_QUOTES_STRIPPED',1);
+}
+@set_magic_quotes_runtime(0);
+@ini_set('magic_quotes_sybase',0);
+
+// 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']) && $_SERVER['HTTP_REFERER']) unset($_REQUEST['purge']);
+
+// disable gzip if not available
+if($conf['compression'] == 'bz2' && !function_exists('bzopen')){
+ $conf['compression'] = 'gz';
+}
+if($conf['compression'] == 'gz' && !function_exists('gzopen')){
+ $conf['compression'] = 0;
+}
+
+// fix dateformat for upgraders
+if(strpos($conf['dformat'],'%') === false){
+ $conf['dformat'] = '%Y/%m/%d %H:%M';
+}
+
+// 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)
+$plugin_types = array('admin','syntax','action','renderer', 'helper');
+global $plugin_controller_class, $plugin_controller;
+if (empty($plugin_controller_class)) $plugin_controller_class = 'Doku_Plugin_Controller';
+
+// load libraries
+require_once(DOKU_INC.'inc/load.php');
+
+// initialize plugin controller
+$plugin_controller = new $plugin_controller_class();
+
+// initialize the event handler
+global $EVENT_HANDLER;
+$EVENT_HANDLER = new Doku_Event_Handler();
+
+// setup authentication system
+if (!defined('NOSESSION')) {
+ auth_setup();
+}
+
+// setup mail system
+mail_setup();
+
+/**
+ * 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){
+ if(empty($conf[$c])) $conf[$c] = $conf['savedir'].'/'.$p;
+ $conf[$c] = init_path($conf[$c]);
+ if(empty($conf[$c])) nice_die("The $c ('$p') does not exist, 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';
+}
+
+/**
+ * Checks the existance 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!");
+ }
+ }
+ }
+
+ # create title index (needs to have same length as page.idx)
+ /*
+ $file = $conf['indexdir'].'/title.idx';
+ if(!@file_exists($file)){
+ $pages = file($conf['indexdir'].'/page.idx');
+ $pages = count($pages);
+ $fh = @fopen($file,'a');
+ if($fh){
+ for($i=0; $i<$pages; $i++){
+ fwrite($fh,"\n");
+ }
+ fclose($fh);
+ }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 accessability on directories as well.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function init_path($path){
+ // check existance
+ $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 = 0666 & ~$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'];
+}
+
+/**
+ * remove magic quotes recursivly
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function remove_magic_quotes(&$array) {
+ foreach (array_keys($array) as $key) {
+ // handle magic quotes in keynames (breaks order)
+ $sk = stripslashes($key);
+ if($sk != $key){
+ $array[$sk] = $array[$key];
+ unset($array[$key]);
+ $key = $sk;
+ }
+
+ // do recursion if needed
+ if (is_array($array[$key])) {
+ remove_magic_quotes($array[$key]);
+ }else {
+ $array[$key] = stripslashes($array[$key]);
+ }
+ }
+}
+
+/**
+ * Returns the full absolute URL to the directory where
+ * DokuWiki is installed in (includes a trailing slash)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function getBaseURL($abs=null){
+ global $conf;
+ //if canonical url enabled always return absolute
+ if(is_null($abs)) $abs = $conf['canonical'];
+
+ if($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 option if available, trim any slash from end of baseurl to avoid multiple consecutive slashes in the path
+ if($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 = $parsed_host['host'];
+ $port = $parsed_host['port'];
+ }elseif(isset($_SERVER['SERVER_NAME'])){
+ $parsed_host = parse_url('http://'.$_SERVER['SERVER_NAME']);
+ $host = $parsed_host['host'];
+ $port = $parsed_host['port'];
+ }else{
+ $host = php_uname('n');
+ $port = '';
+ }
+
+ if(!$port && isset($_SERVER['SERVER_PORT'])) {
+ $port = $_SERVER['SERVER_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(){
+ if (!isset($_SERVER['HTTPS']) ||
+ preg_match('/^(|off|false|disabled)$/i',$_SERVER['HTTPS'])){
+ return false;
+ }else{
+ return true;
+ }
+}
+
+/**
+ * print a nice message even if no styles are loaded yet.
+ */
+function nice_die($msg){
+ echo<<<EOT
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<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;
+ exit;
+}
+
+/**
+ * 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://de3.php.net/manual/en/function.realpath.php#75992
+ */
+function fullpath($path,$exists=false){
+ static $run = 0;
+ $root = '';
+ $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || @$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 existance when needed (except when unit testing)
+ if($exists && !defined('DOKU_UNITTEST') && !@file_exists($finalpath)) {
+ return false;
+ }
+ return $finalpath;
+}
+
diff --git a/inc/io.php b/inc/io.php
new file mode 100644
index 000000000..034ac650e
--- /dev/null
+++ b/inc/io.php
@@ -0,0 +1,610 @@
+<?php
+/**
+ * File IO functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * 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.
+ *
+ * @todo use safemode hack
+ * @param string $id - a pageid, the namespace of that id will be tried to deleted
+ * @param string $basadir - the config name of the type to delete (datadir or mediadir usally)
+ * @returns 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
+ trigger_event('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>
+ */
+function io_readWikiPage($file, $id, $rev=false) {
+ if (empty($rev)) { $rev = false; }
+ $data = array(array($file, false), getNS($id), noNS($id), $rev);
+ return trigger_event('IO_WIKIPAGE_READ', $data, '_io_readWikiPage_action', false);
+}
+
+/**
+ * Callback adapter for io_readFile().
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+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>
+ */
+function io_readFile($file,$clean=true){
+ $ret = '';
+ if(@file_exists($file)){
+ if(substr($file,-3) == '.gz'){
+ $ret = join('',gzfile($file));
+ }else if(substr($file,-4) == '.bz2'){
+ $ret = bzfile($file);
+ }else{
+ $ret = file_get_contents($file);
+ }
+ }
+ if($clean){
+ return cleanText($ret);
+ }else{
+ return $ret;
+ }
+}
+/**
+ * Returns the content of a .bz2 compressed file as string
+ * @author marcel senf <marcel@rucksackreinigung.de>
+ */
+
+function bzfile($file){
+ $bz = bzopen($file,"r");
+ while (!feof($bz)){
+ //8192 seems to be the maximum buffersize?
+ $str = $str . bzread($bz,8192);
+ }
+ bzclose($bz);
+ 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>
+ */
+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 trigger_event('IO_WIKIPAGE_WRITE', $data, '_io_writeWikiPage_action', false);
+}
+
+/**
+ * Callback adapter for io_saveFile().
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function _io_writeWikiPage_action($data) {
+ if (is_array($data) && is_array($data[0]) && count($data[0])===3) {
+ return call_user_func_array('io_saveFile', $data[0]);
+ } else {
+ return false; //callback error
+ }
+}
+
+/**
+ * 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>
+ * @return bool true on success
+ */
+function io_saveFile($file,$content,$append=false){
+ global $conf;
+ $mode = ($append) ? 'ab' : 'wb';
+
+ $fileexists = @file_exists($file);
+ io_makeFileDir($file);
+ io_lock($file);
+ if(substr($file,-3) == '.gz'){
+ $fh = @gzopen($file,$mode.'9');
+ if(!$fh){
+ msg("Writing $file failed",-1);
+ io_unlock($file);
+ return false;
+ }
+ gzwrite($fh, $content);
+ gzclose($fh);
+ }else if(substr($file,-4) == '.bz2'){
+ $fh = @bzopen($file,$mode{0});
+ if(!$fh){
+ msg("Writing $file failed", -1);
+ io_unlock($file);
+ return false;
+ }
+ bzwrite($fh, $content);
+ bzclose($fh);
+ }else{
+ $fh = @fopen($file,$mode);
+ if(!$fh){
+ msg("Writing $file failed",-1);
+ io_unlock($file);
+ return false;
+ }
+ fwrite($fh, $content);
+ fclose($fh);
+ }
+
+ if(!$fileexists and !empty($conf['fperm'])) chmod($file, $conf['fperm']);
+ io_unlock($file);
+ return true;
+}
+
+/**
+ * Delete exact linematch for $badline from $file.
+ *
+ * Be sure to include the trailing newline in $badline
+ *
+ * Uses gzip if extension is .gz
+ *
+ * 2005-10-14 : added regex option -- Christopher Smith <chris@jalakai.co.uk>
+ *
+ * @author Steven Danz <steven-danz@kc.rr.com>
+ * @return bool true on success
+ */
+function io_deleteFromFile($file,$badline,$regex=false){
+ if (!@file_exists($file)) return true;
+
+ io_lock($file);
+
+ // load into array
+ if(substr($file,-3) == '.gz'){
+ $lines = gzfile($file);
+ }else{
+ $lines = file($file);
+ }
+
+ // remove all matching lines
+ if ($regex) {
+ $lines = preg_grep($badline,$lines,PREG_GREP_INVERT);
+ } else {
+ $pos = array_search($badline,$lines); //return null or false if not found
+ while(is_int($pos)){
+ unset($lines[$pos]);
+ $pos = array_search($badline,$lines);
+ }
+ }
+
+ if(count($lines)){
+ $content = join('',$lines);
+ if(substr($file,-3) == '.gz'){
+ $fh = @gzopen($file,'wb9');
+ if(!$fh){
+ msg("Removing content from $file failed",-1);
+ io_unlock($file);
+ return false;
+ }
+ gzwrite($fh, $content);
+ gzclose($fh);
+ }else{
+ $fh = @fopen($file,'wb');
+ if(!$fh){
+ msg("Removing content from $file failed",-1);
+ io_unlock($file);
+ return false;
+ }
+ fwrite($fh, $content);
+ fclose($fh);
+ }
+ }else{
+ @unlink($file);
+ }
+
+ io_unlock($file);
+ return true;
+}
+
+/**
+ * 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>
+ */
+function io_lock($file){
+ global $conf;
+ // no locking if safemode hack
+ if($conf['safemodehack']) return;
+
+ $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>
+ */
+function io_unlock($file){
+ global $conf;
+ // no locking if safemode hack
+ if($conf['safemodehack']) return;
+
+ $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>
+ */
+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);
+ trigger_event('IO_NAMESPACE_CREATED', $data);
+ }
+}
+
+/**
+ * Create the directory needed for the given file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function io_makeFileDir($file){
+ global $conf;
+
+ $dir = dirname($file);
+ if(!@is_dir($dir)){
+ io_mkdir_p($dir) || msg("Creating directory $dir failed",-1);
+ }
+}
+
+/**
+ * Creates a directory hierachy.
+ *
+ * @link http://www.php.net/manual/en/function.mkdir.php
+ * @author <saint@corenova.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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,'/')))){
+ if($conf['safemodehack']){
+ $dir = preg_replace('/^'.preg_quote(fullpath($conf['ftp']['root']),'/').'/','', $target);
+ return io_mkdir_ftp($dir);
+ }else{
+ $ret = @mkdir($target,$conf['dmode']); // crawl back up & create dir tree
+ if($ret && $conf['dperm']) chmod($target, $conf['dperm']);
+ return $ret;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Creates a directory using FTP
+ *
+ * This is used when the safemode workaround is enabled
+ *
+ * @author <andi@splitbrain.org>
+ */
+function io_mkdir_ftp($dir){
+ global $conf;
+
+ if(!function_exists('ftp_connect')){
+ msg("FTP support not found - safemode workaround not usable",-1);
+ return false;
+ }
+
+ $conn = @ftp_connect($conf['ftp']['host'],$conf['ftp']['port'],10);
+ if(!$conn){
+ msg("FTP connection failed",-1);
+ return false;
+ }
+
+ if(!@ftp_login($conn, $conf['ftp']['user'], conf_decodeString($conf['ftp']['pass']))){
+ msg("FTP login failed",-1);
+ return false;
+ }
+
+ //create directory
+ $ok = @ftp_mkdir($conn, $dir);
+ //set permissions
+ @ftp_site($conn,sprintf("CHMOD %04o %s",$conf['dmode'],$dir));
+
+ @ftp_close($conn);
+ return $ok;
+}
+
+/**
+ * Creates a unique temporary directory and returns
+ * its path.
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+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>
+ */
+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
+
+ $data = $http->get($url);
+ if(!$data) return false;
+
+ if ($useAttachment) {
+ $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 = 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
+ */
+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 and returns its output as string
+ *
+ * @author Harry Brueckner <harry_b@eml.cc>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @deprecated
+ */
+function io_runcmd($cmd){
+ $fh = popen($cmd, "r");
+ if(!$fh) return false;
+ $ret = '';
+ while (!feof($fh)) {
+ $ret .= fread($fh, 8192);
+ }
+ pclose($fh);
+ return $ret;
+}
+
+/**
+ * Runs an external command with input and output pipes.
+ * Returns the exit code from the process.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+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 $baxkref When true returns array with backreferences instead of lines
+ * @return 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;
+}
+
diff --git a/inc/lang/.htaccess b/inc/lang/.htaccess
new file mode 100644
index 000000000..572f5156f
--- /dev/null
+++ b/inc/lang/.htaccess
@@ -0,0 +1,4 @@
+## no access to the lang directory
+order allow,deny
+deny from all
+Satisfy All
diff --git a/inc/lang/af/lang.php b/inc/lang/af/lang.php
new file mode 100644
index 000000000..16e9a2822
--- /dev/null
+++ b/inc/lang/af/lang.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * af language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesAf.php?view=co
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['btn_edit'] = 'Wysig hierdie bladsy';
+$lang['btn_source'] = 'Bekyk bronteks';
+$lang['btn_search'] = 'Soek';
+$lang['btn_preview'] = 'Voorskou';
+$lang['btn_revs'] = 'geskiedenis';
+$lang['btn_recent'] = 'Onlangse wysigings';
+$lang['btn_cancel'] = 'Kanselleer';
+$lang['btn_secedit'] = 'Wysig';
+$lang['btn_login'] = 'Teken in';
+$lang['btn_logout'] = 'Teken uit';
+$lang['btn_back'] = 'Terug';
+$lang['btn_backlink'] = 'Wat skakel hierheen';
+$lang['btn_subscribe'] = 'Hou bladsy dop';
+$lang['btn_unsubscribe'] = 'Verwyder van bladsy dophoulys';
+$lang['btn_resendpwd'] = 'E-pos nuwe wagwoord';
+$lang['btn_register'] = 'Skep gerus \'n rekening';
+$lang['loggedinas'] = 'Ingeteken as';
+$lang['user'] = 'Gebruikernaam';
+$lang['pass'] = 'Wagwoord';
+$lang['newpass'] = 'Nuive wagwoord';
+$lang['oldpass'] = 'Ou wagwoord';
+$lang['passchk'] = 'Herhaal wagwoord';
+$lang['remember'] = 'Onthou my wagwoord oor sessies';
+$lang['fullname'] = 'Regte naam';
+$lang['email'] = 'E-pos';
+$lang['badlogin'] = 'Intekenfout';
+$lang['minoredit'] = 'Klein wysiging';
+$lang['reguexists'] = 'Die gebruikersnaam wat jy gebruik het, is alreeds gebruik. Kies asseblief \'n ander gebruikersnaam.';
+$lang['regsuccess2'] = 'Rekening geskep';
+$lang['regbadpass'] = 'Die ingetikte wagwoorde is nie dieselfde nie.';
+$lang['regpwmail'] = 'Jo DokuWiki wagwoord';
+$lang['profnoempty'] = 'Jy moet \'n name en a e-posadres in sit';
+$lang['resendpwd'] = 'Stuir vir a niwe wagwoord';
+$lang['resendpwdmissing'] = 'Jammer, jy moet ales in fil';
+$lang['resendpwdconfirm'] = '\'n Bevestigingpos is gestuur na die gekose e-posadres.';
+$lang['resendpwdsuccess'] = 'Jou nuive wagwoord was deur e-pos gesteur';
+$lang['fileupload'] = 'Laai lêer';
+$lang['uploadsucc'] = 'Laai suksesvol';
+$lang['uploadfail'] = 'Laai fout';
+$lang['js']['hidedetails'] = 'Steek weg';
+$lang['mediaroot'] = 'root';
+$lang['toc'] = 'Inhoud';
+$lang['current'] = 'huidige';
+$lang['line'] = 'Streak';
+$lang['youarehere'] = 'Jy is hier';
+$lang['by'] = 'by';
+$lang['restored'] = 'Het terug gegaan na vroeëre weergawe';
+$lang['summary'] = 'Voorskou';
+$lang['qb_bold'] = 'Vetdruk';
+$lang['qb_italic'] = 'Skuinsdruk';
+$lang['qb_link'] = 'Interne skakel';
+$lang['qb_extlink'] = 'Eksterne skakel';
+$lang['qb_hr'] = 'Horisontale streep';
+$lang['qb_sig'] = 'Handtekening met datum';
+$lang['admin_register'] = 'Skep gerus \'n rekening';
+$lang['img_backto'] = 'Terug na';
+$lang['img_date'] = 'Datem';
+$lang['img_camera'] = 'Camera';
+$lang['i_wikiname'] = 'Wiki Naam';
+$lang['i_funcna'] = 'PHP funksie <code>%s</code> is nie beskibaar nie. Miskien is dit af gehaal.';
diff --git a/inc/lang/ar/admin.txt b/inc/lang/ar/admin.txt
new file mode 100644
index 000000000..bbb443886
--- /dev/null
+++ b/inc/lang/ar/admin.txt
@@ -0,0 +1,3 @@
+====== الأدارة ======
+
+قائمة بالمهام الإدارية المتاحة فى دوكو ويكي. \ No newline at end of file
diff --git a/inc/lang/ar/adminplugins.txt b/inc/lang/ar/adminplugins.txt
new file mode 100644
index 000000000..44790a04b
--- /dev/null
+++ b/inc/lang/ar/adminplugins.txt
@@ -0,0 +1 @@
+===== إضافات إضافية ===== \ No newline at end of file
diff --git a/inc/lang/ar/backlinks.txt b/inc/lang/ar/backlinks.txt
new file mode 100644
index 000000000..f6d24f413
--- /dev/null
+++ b/inc/lang/ar/backlinks.txt
@@ -0,0 +1,3 @@
+====== إرتباطات ======
+
+هذه قائمة بالصفحات المرتبطة بالصفحة الحالية. \ No newline at end of file
diff --git a/inc/lang/ar/conflict.txt b/inc/lang/ar/conflict.txt
new file mode 100644
index 000000000..4d7c4e8e7
--- /dev/null
+++ b/inc/lang/ar/conflict.txt
@@ -0,0 +1,5 @@
+====== يوجد نسخة أحدث ======
+
+يوجد نسخة أحدث من هذه الصفحة. يحدث هذا عندما يحرر مشترك آخر الصفحة أثناء تعديلك لها.
+
+افحص الاختلافات جيداً، ثم حدد أية نسخة تحفظ. بالضغط على "حفظ" ستحفظ نسختك. أما بالضغط على "إلغاء" فستحافظ على النسخة الحالية. \ No newline at end of file
diff --git a/inc/lang/ar/denied.txt b/inc/lang/ar/denied.txt
new file mode 100644
index 000000000..11405233c
--- /dev/null
+++ b/inc/lang/ar/denied.txt
@@ -0,0 +1,3 @@
+====== لا صلاحيات ======
+
+عذرا، ليس مصرح لك الاستمرار، لعلك نسيت تسجيل الدخول؟ \ No newline at end of file
diff --git a/inc/lang/ar/diff.txt b/inc/lang/ar/diff.txt
new file mode 100644
index 000000000..ed1937c2f
--- /dev/null
+++ b/inc/lang/ar/diff.txt
@@ -0,0 +1,3 @@
+====== اختلافات ======
+
+عرض الاختلافات بين النسخة المختارة و النسخة الحالية من الصفحة. \ No newline at end of file
diff --git a/inc/lang/ar/draft.txt b/inc/lang/ar/draft.txt
new file mode 100644
index 000000000..50c07f2ef
--- /dev/null
+++ b/inc/lang/ar/draft.txt
@@ -0,0 +1,5 @@
+====== وجدت مسوّدة ======
+
+إن تعديلك لهذه الصفحة في المرة الماضية لم يتم بشكل صحيح، حفظت دوكو ويكي آلياً مسوّدة من عملك الأخير الذي يمكنك استخدامه الآن لمتابعة التعديل. فيما يلي البيانات التي حفظت من المرة الماضية.
+
+يرجى أن تقرر إن كنت تريد //استعادة// عملك السابق أو //حذف// المسوّدة أو //إلغاء// عملية التحرير.
diff --git a/inc/lang/ar/edit.txt b/inc/lang/ar/edit.txt
new file mode 100644
index 000000000..d4e1eb43b
--- /dev/null
+++ b/inc/lang/ar/edit.txt
@@ -0,0 +1 @@
+حرر هذه الصفحة ثم اضغط على "حفظ". انظر [[wiki:syntax|دليل الصياغة]] لمعرفة صيغة الويكي. يرجى تعديل الصفحة فقط إذا كنت ستحسنها. إذا رغبت فى اختبار شيء ما، تعلم الخطوات الأولى فى [[playground:playground|الملعب]]. \ No newline at end of file
diff --git a/inc/lang/ar/editrev.txt b/inc/lang/ar/editrev.txt
new file mode 100644
index 000000000..a51fe9436
--- /dev/null
+++ b/inc/lang/ar/editrev.txt
@@ -0,0 +1,2 @@
+**لقد حملت نسخة قديمة من الصفحة!** إذا حفظتها، سيتم إنشاء نسخة جديدة بهذه المعلومات.
+---- \ No newline at end of file
diff --git a/inc/lang/ar/index.txt b/inc/lang/ar/index.txt
new file mode 100644
index 000000000..43840ec26
--- /dev/null
+++ b/inc/lang/ar/index.txt
@@ -0,0 +1,3 @@
+====== فهرس ======
+
+هذا فهرس لجميع الصفحات مرتبة حسب [[doku>namespaces|namespaces]].
diff --git a/inc/lang/ar/install.html b/inc/lang/ar/install.html
new file mode 100644
index 000000000..1daf507c5
--- /dev/null
+++ b/inc/lang/ar/install.html
@@ -0,0 +1,12 @@
+<p>تساعد هذه الصفحة في التثبيت والإعداد الأوليين ل <a href="http://dokuwiki.org">دوكو ويكي</a>. مزيد من المعلومات عن هذا المثبت في
+<a href="http://dokuwiki.org/installer">صفحة التوثيق</a> الخاصة به.</p>
+
+<p>دوكو ويكي تستخدم ملفات عادية لتخزين الصفحات و المعلومات المرتبطة بها (مثل. الصور , وفهارس البحث, والنسخ القديمة, إلخ). لكي تعمل بنجاح دوكو ويكي <strong>يجب</strong> ان يكون لديها اذن بالكتابة على المجلدات التي تحوي هذه الملفات. هذا المثبت غير قادر على اعداد اذونات المجلدات. عادة يجب عمل هذا مباشرة باستخدام أمر في محث الاوامر أو إن كنت تستخدم استضافة، عن طريقة FTP في لوحة تحكم الاستضافة (مثل. cPanel).</p>
+
+<p>سيُعد هذا المثبت اعدادات دوكو ويكي ل
+<acronym title="قائمة التحكم بالوصول">ACL</acronym>, الذي سيسمح للمدير بالولوج و الوصول لقائمة إدارة دوكو ويكي لتثبيت الإضافات، وإدارة المستخدمين، و التحكم بالوصول لصفحات الويكي، وتعديل الاعدادات.
+ليس مطلوبا لأجل عمل دوكو ويكي, لكنه سيجعل دوكو ويكي أسهل على المدير.</p>
+
+<p>المستخدمين الخبراء و المستخدمين مع متطلبات خاصة عليهم استخدام هذا الرابط لتفاصيل تتعلق ب
+<a href="http://dokuwiki.org/install">توجيهات التثبيت</a>
+و <a href="http://dokuwiki.org/config">ضبط الإعدادات</a>.</p> \ No newline at end of file
diff --git a/inc/lang/ar/lang.php b/inc/lang/ar/lang.php
new file mode 100644
index 000000000..11c111505
--- /dev/null
+++ b/inc/lang/ar/lang.php
@@ -0,0 +1,277 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Mostafa Hussein <mostafa@gmail.com>
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'rtl';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '؛';
+$lang['btn_edit'] = 'حرر هذه الصفحة';
+$lang['btn_source'] = 'اعرض مصدر الصفحة';
+$lang['btn_show'] = 'اعرض الصفحة';
+$lang['btn_create'] = 'أنشئ هذه الصفحة';
+$lang['btn_search'] = 'ابحث';
+$lang['btn_save'] = 'احفظ';
+$lang['btn_preview'] = 'عاين';
+$lang['btn_top'] = 'ارجع للأعلى';
+$lang['btn_newer'] = '<< أحدث';
+$lang['btn_older'] = 'أقدم >>';
+$lang['btn_revs'] = 'نسخ قديمة';
+$lang['btn_recent'] = 'أحدث التغييرات';
+$lang['btn_upload'] = 'ارفع';
+$lang['btn_cancel'] = 'ألغ';
+$lang['btn_index'] = 'خريطة موقع';
+$lang['btn_secedit'] = 'حرر';
+$lang['btn_login'] = 'لج';
+$lang['btn_logout'] = 'اخرج';
+$lang['btn_admin'] = 'المدير';
+$lang['btn_update'] = 'حدّث';
+$lang['btn_delete'] = 'احذف';
+$lang['btn_back'] = 'ارجع';
+$lang['btn_backlink'] = 'ارتباطات';
+$lang['btn_backtomedia'] = 'ارجع إلى اختيار ملف الوسائط';
+$lang['btn_subscribe'] = 'ادر الاشتراكات';
+$lang['btn_profile'] = 'حدث الملف الشخصي';
+$lang['btn_reset'] = 'صفّر';
+$lang['btn_resendpwd'] = 'ارسل كلمة سر جديدة';
+$lang['btn_draft'] = 'حرر المسودة';
+$lang['btn_recover'] = 'استرجع المسودة';
+$lang['btn_draftdel'] = 'احذف المسوّدة';
+$lang['btn_revert'] = 'استعد';
+$lang['btn_register'] = 'سجّل';
+$lang['loggedinas'] = 'داخل باسم';
+$lang['user'] = 'اسم المستخدم';
+$lang['pass'] = 'كلمة السر';
+$lang['newpass'] = 'كلمة سر جديدة';
+$lang['oldpass'] = 'أكد كلمة السر الحالية';
+$lang['passchk'] = 'مرة أخرى';
+$lang['remember'] = 'تذكرني';
+$lang['fullname'] = 'الاسم الحقيقي';
+$lang['email'] = 'البريد الإلكتروني';
+$lang['profile'] = 'الملف الشخصي';
+$lang['badlogin'] = 'عذرا، اسم المشترك أو كلمة السر غير صحيحة';
+$lang['minoredit'] = 'تعديلات طفيفة';
+$lang['draftdate'] = 'حفظ المسودات آليا مفعّل';
+$lang['nosecedit'] = 'غُيرت الصفحة في هذه الأثناء، معلومات الجزء اصبحت قديمة. حُمُلت كل الصفحة بدلا.';
+$lang['regmissing'] = 'عذرا، عليك ملء جميع الحقول.';
+$lang['reguexists'] = 'عذرا، يوجد مشترك بنفس الاسم.';
+$lang['regsuccess'] = 'أنشئ المستخدم و ارسلت كلمة السر بالبريد.';
+$lang['regsuccess2'] = 'أنشئ المستخدم.';
+$lang['regmailfail'] = 'حدث خطأ فى إرسال رسالة كلمة السر. يرجى مراسلة المدير!';
+$lang['regbadmail'] = 'يبدو البريد الإلكتروني المعطى غيرَ صحيح، إن كنت تظن أن هذا خطأ، راسل المدير';
+$lang['regbadpass'] = 'كلمتا المرور غير متطابقتين، حاول مرة أخرى.';
+$lang['regpwmail'] = 'كلمة مرورك إلى دوكو ويكي';
+$lang['reghere'] = 'ليس لديك حساب بعد؟ احصل على واحد';
+$lang['profna'] = 'هذه الويكي لا تدعم تعديل الملف الشخصي';
+$lang['profnochange'] = 'لا تغييرات، لا شيء ليُعمل.';
+$lang['profnoempty'] = 'غير مسموح باسم مستخدم أو بريد فارغ.';
+$lang['profchanged'] = 'حُدث الملف الشخصي للمستخدم بنجاح.';
+$lang['pwdforget'] = 'أنسيت كلمة السر؟ احصل على واحدة جديدة';
+$lang['resendna'] = 'هذه الويكي لا تدعم إعادة إرسال كلمة المرور.';
+$lang['resendpwd'] = 'إرسال كلمة مرور';
+$lang['resendpwdmissing'] = 'عذراّ، يجب أن تملأ كل الحقول.';
+$lang['resendpwdnouser'] = 'عذراً، لم نجد المستخدم هذا في قاعدة بياناتنا.';
+$lang['resendpwdbadauth'] = 'عذراً، رمز التفعيل هذا غير صحيح. نأكد من استخدامك كامل وصلة التأكيد.';
+$lang['resendpwdconfirm'] = 'اُرسل رابط التأكيد بواسطة البريد.';
+$lang['resendpwdsuccess'] = 'كلمة السرالجديدة اُرسلت عبر البريد.';
+$lang['license'] = 'مالم يشر لخلاف ذلك، فإن المحتوى في هذه الويكي مرخص وفق الرخصة التالية:';
+$lang['licenseok'] = 'لاحظ: بتحرير هذه الصفحة أنت توافق على ترخيص محتواها تحت الرخصة التالية:';
+$lang['searchmedia'] = 'ابحث في أسماء الملفات:';
+$lang['searchmedia_in'] = 'ابحث في %s';
+$lang['txt_upload'] = 'اختر ملفاً للرفع';
+$lang['txt_filename'] = 'رفع كـ (اختياري)';
+$lang['txt_overwrt'] = 'اكتب على ملف موجود';
+$lang['lockedby'] = 'مقفلة حاليا لـ';
+$lang['lockexpire'] = 'ينتهي القفل في';
+$lang['js']['willexpire'] = 'سينتهي قفل تحرير هذه الصفحه خلال دقيقة.\nلتجنب التعارض استخدم زر المعاينة لتصفير مؤقت القفل.';
+$lang['js']['notsavedyet'] = 'التعديلات غير المحفوظة ستفقد.';
+$lang['js']['searchmedia'] = 'ابحث عن ملفات';
+$lang['js']['keepopen'] = 'أبقي النافذة مفتوحة أثناء الاختيار';
+$lang['js']['hidedetails'] = 'أخف التفاصيل';
+$lang['js']['mediatitle'] = 'إعدادات الرابط';
+$lang['js']['mediadisplay'] = 'نوع الرابط';
+$lang['js']['mediaalign'] = 'المحاذاة';
+$lang['js']['mediasize'] = 'حجم الصورة';
+$lang['js']['mediatarget'] = 'هدف الرابط';
+$lang['js']['mediaclose'] = 'أغلق';
+$lang['js']['mediainsert'] = 'أدرج';
+$lang['js']['mediadisplayimg'] = 'أظهر الصورة.';
+$lang['js']['mediadisplaylnk'] = 'اظهر الرابط فقط.';
+$lang['js']['mediasmall'] = 'نسخة مصغرة';
+$lang['js']['mediamedium'] = 'نسخة متوسطة';
+$lang['js']['medialarge'] = 'نسخة كبيرة';
+$lang['js']['mediaoriginal'] = 'النسخة الأصلية';
+$lang['js']['medialnk'] = 'الرابط لصفحة التفاصيل';
+$lang['js']['mediadirect'] = 'رابط مباشر للأصل';
+$lang['js']['medianolnk'] = 'لا رابط';
+$lang['js']['medianolink'] = 'لا تربط الصورة';
+$lang['js']['medialeft'] = 'حاذي الصورة إلى اليسار.';
+$lang['js']['mediaright'] = 'حاذي الصورة إلى اليمين.';
+$lang['js']['mediacenter'] = 'حاذي الصورة إلى الوسط.';
+$lang['js']['medianoalign'] = 'لا تستعمل المحاذاة.';
+$lang['js']['nosmblinks'] = 'الروابط لمجلدات مشاركة وندز تعمل فقط مع متصفح مايكروسفت Internet Explorer.
+ما زال بإمكانك قص و لصق الرابط.';
+$lang['js']['linkwiz'] = 'مرشد الروابط';
+$lang['js']['linkto'] = 'الرابط إلى :';
+$lang['js']['del_confirm'] = 'هل حقاً تريد حذف البنود المختارة؟';
+$lang['rssfailed'] = 'خطأ ما حدث أثناء جلب ملف التغذية:';
+$lang['nothingfound'] = 'لا يوجد شيء';
+$lang['mediaselect'] = 'ملفات الوسائط';
+$lang['fileupload'] = 'تحميل ملف وسائط';
+$lang['uploadsucc'] = 'تم الرفع بنجاح';
+$lang['uploadfail'] = 'فشل الرفع، ربما خطأ تراخيص؟';
+$lang['uploadwrong'] = 'الرفع ممنوع، نوع الملف مرفوض!';
+$lang['uploadexist'] = 'الملف موجود أصلاً. لم يُعمل شيئ.';
+$lang['uploadbadcontent'] = 'المحتوى المرفوع لم يطابق لاحقة ملفات %s.';
+$lang['uploadspam'] = 'الرفع محجوب بواسطة القائمة السوداء لبرنامج تقفي التطفل.';
+$lang['uploadxss'] = 'رُفض الرفع للإشتباه بمحتوى ضار.';
+$lang['uploadsize'] = 'الملف المرفوع كان كبيرا جدا . ( الحد %s )';
+$lang['deletesucc'] = 'حُذف الملف "%s".';
+$lang['deletefail'] = 'تعذر حذف "%s" - تأكد من الصلاحيات.';
+$lang['mediainuse'] = 'لم يحذف الملف "%s" - مازال مستخدما.';
+$lang['namespaces'] = 'فضاء التسمية';
+$lang['mediafiles'] = 'ملفات موجودة في';
+$lang['accessdenied'] = 'لا يسمح لك برؤية هذه الصفحة.';
+$lang['mediausage'] = 'استخدم هذه الصياغة للدلالة على هذا الملف:';
+$lang['mediaview'] = 'اعرض الملف الأصلي';
+$lang['mediaroot'] = 'الجذر';
+$lang['mediaupload'] = 'تحميل ملف إلى فضاء التسمية هنا. لإنشاء فضاءات تسمية فرعية، أضفها إلى بداية خانة تحميل باسم وافصل بينها باستخدام الفاصلتان الرأسيتان.';
+$lang['mediaextchange'] = 'غُيرت لاحقة الملف من .%s إلى .%s!';
+$lang['reference'] = 'مراجع لـ';
+$lang['ref_inuse'] = 'لا يمكن حذف الملف، لأنه مستخدم من قبل الصفحات التالية:';
+$lang['ref_hidden'] = 'بعض المراجع على صفحات لا تملك صلاحيات قراءتها';
+$lang['hits'] = 'مرة';
+$lang['quickhits'] = 'صفحات مطابقة';
+$lang['toc'] = 'جدول المحتويات';
+$lang['current'] = 'حالي';
+$lang['yours'] = 'نسختك';
+$lang['diff'] = 'أظهر الاختلافات مع النسخة الحالية';
+$lang['diff2'] = 'أظهر الاختلافات بين النسخ المحددة';
+$lang['difflink'] = 'رابط إلى هذه المقارنة';
+$lang['diff_type'] = 'أظهر الفروق:';
+$lang['diff_inline'] = 'ضمنا';
+$lang['diff_side'] = 'جنبا إلى جنب';
+$lang['line'] = 'سطر';
+$lang['breadcrumb'] = 'أثر';
+$lang['youarehere'] = 'أنت هنا';
+$lang['lastmod'] = 'آخر تعديل';
+$lang['by'] = 'بواسطة';
+$lang['deleted'] = 'حذفت';
+$lang['created'] = 'اُنشئت';
+$lang['restored'] = 'استعيدت نسخة قديمة';
+$lang['external_edit'] = 'تحرير خارجي';
+$lang['summary'] = 'ملخص التحرير';
+$lang['noflash'] = 'تحتاج إلى<a href="http://www.adobe.com/products/flashplayer/">ملحق فلاش أدوبي</a> لعرض هذا المحتوى.';
+$lang['download'] = 'نزل Snippet';
+$lang['mail_newpage'] = 'إضافة صفحة:';
+$lang['mail_changed'] = 'تعديل صفحة:';
+$lang['mail_subscribe_list'] = 'صفحات غيرت في النطاق:';
+$lang['mail_new_user'] = 'مشترك جديد:';
+$lang['mail_upload'] = 'رفع ملف:';
+$lang['qb_bold'] = 'نص عريض';
+$lang['qb_italic'] = 'نص مائل';
+$lang['qb_underl'] = 'نص مسطر';
+$lang['qb_code'] = 'نص برمجي';
+$lang['qb_strike'] = 'نص مشطوب';
+$lang['qb_h1'] = 'عنوان مستوى ١';
+$lang['qb_h2'] = 'عنوان مستوى ٢';
+$lang['qb_h3'] = 'عنوان مستوى ٣';
+$lang['qb_h4'] = 'عنوان مستوى ٤';
+$lang['qb_h5'] = 'عنوان مستوى ٥';
+$lang['qb_h'] = 'الترويسة';
+$lang['qb_hs'] = 'حدد الترويسة';
+$lang['qb_hplus'] = 'ترويسة أعلى';
+$lang['qb_hminus'] = 'ترويسة أخفض';
+$lang['qb_hequal'] = 'ترويسة بنفس المستوى';
+$lang['qb_link'] = 'رابط داخلي';
+$lang['qb_extlink'] = 'رابط خارجي';
+$lang['qb_hr'] = 'سطر أفقي';
+$lang['qb_ol'] = 'بند فى قائمة مرتبة';
+$lang['qb_ul'] = 'بند فى قائمة غير مرتبة';
+$lang['qb_media'] = 'أضف صورا و ملفات أخرى';
+$lang['qb_sig'] = 'أدرج التوقيع';
+$lang['qb_smileys'] = 'الإبتسامات';
+$lang['qb_chars'] = 'محارف خاصة';
+$lang['upperns'] = 'انتقل للنطاق الأب';
+$lang['admin_register'] = 'أضف مستخدما جديدا';
+$lang['metaedit'] = 'تحرير البيانات الشمولية ';
+$lang['metasaveerr'] = 'فشلت كتابة البيانات الشمولية';
+$lang['metasaveok'] = 'حُفظت البيانات الشمولية';
+$lang['img_backto'] = 'عودة إلى';
+$lang['img_title'] = 'العنوان';
+$lang['img_caption'] = 'وصف';
+$lang['img_date'] = 'التاريخ';
+$lang['img_fname'] = 'اسم الملف';
+$lang['img_fsize'] = 'الحجم';
+$lang['img_artist'] = 'المصور';
+$lang['img_copyr'] = 'حقوق النسخ';
+$lang['img_format'] = 'الهيئة';
+$lang['img_camera'] = 'الكمرا';
+$lang['img_keywords'] = 'كلمات مفتاحية';
+$lang['subscr_subscribe_success'] = 'اضيف %s لقائمة اشتراك %s';
+$lang['subscr_subscribe_error'] = 'خطأ في إضافة %s لقائمة اشتراك %s';
+$lang['subscr_subscribe_noaddress'] = 'ليس هناك عنوان مرتبط بولوجك، لا يمكن اضافتك لقائمة الاشتراك';
+$lang['subscr_unsubscribe_success'] = 'أزيل %s من قائمة اشتراك %s';
+$lang['subscr_unsubscribe_error'] = 'خطأ في إزالة %s من قائمة اشتراك %s';
+$lang['subscr_already_subscribed'] = '%s مشترك مسبقا في %s';
+$lang['subscr_not_subscribed'] = '%s ليس مشتركا في %s';
+$lang['subscr_m_not_subscribed'] = 'لست مشتركا حاليا بالصفحة او النطاق الحاليين';
+$lang['subscr_m_new_header'] = 'أضف اشتراكا';
+$lang['subscr_m_current_header'] = 'الاشتراكات الحالية';
+$lang['subscr_m_unsubscribe'] = 'ألغ الاشتراك';
+$lang['subscr_m_subscribe'] = 'اشترك';
+$lang['subscr_m_receive'] = 'استقبال';
+$lang['subscr_style_every'] = 'بريدا على كل تغيير';
+$lang['subscr_style_digest'] = 'بريد ملخص عن تغييرات كل صفحة';
+$lang['subscr_style_list'] = 'قائمة بالصفحات المتغيرة منذ آخر بريد';
+$lang['authmodfailed'] = 'إعدادات تصريح فاسدة، يرجى مراسلة المدير.';
+$lang['authtempfail'] = 'تصريح المشترك غير متوفر مؤقتاً، إن استمرت هذه الحالة يرجى مراسلة المدير';
+$lang['i_chooselang'] = 'اختر لغتك';
+$lang['i_installer'] = 'برنامج تنصيب دوكو ويكي';
+$lang['i_wikiname'] = 'اسم الويكي';
+$lang['i_enableacl'] = 'تفعيل ACL - مفضل';
+$lang['i_superuser'] = 'مشرف';
+$lang['i_problems'] = 'وجد برنامج التنصيب المشاكل التالية، لا يمكنك المتابعة قبل حلها.';
+$lang['i_modified'] = 'لأسباب أمنية هذا البرنامج سيعمل فقط مع تنصيب دوكو ويكي جديد و غير معدّل.
+يجب أن تعيد فك ضغط الملفات مرة أخرى من المكتبة المضغوطة، أو راجع <a href="http://dokuwiki.org/install"> تعليمات تنصيب دوكو ويكي </a> ';
+$lang['i_funcna'] = 'دالة PHP التالية غير متوفرة.
+<code>%s</code>
+قد يكون مزود خدمة الاستفادة قد حجبها لسبب ما.';
+$lang['i_phpver'] = 'نسخة PHP التي لديك هي
+<code>%s</code>
+وهي أقل من النسخة المطلوبة
+<code>%s</code>
+عليك تحديث نسخة PHP';
+$lang['i_permfail'] = 'إن <code>%s</code> غير قابل للكتابة بواسطة دوكو ويكي، عليك تعديل إعدادات الصلاحيات لهذا المجلد!';
+$lang['i_confexists'] = 'إن <code>%s</code> موجود أصلاً';
+$lang['i_writeerr'] = 'لا يمكن إنشاء <code>%s</code>، عليك التأكد من صلاحيات الملف أو المجلد وإنشاء الملف يدوياً.';
+$lang['i_badhash'] = 'الملف dokuwiki.php غير مصنف أو قد تم تعديله
+(hash=<code>%s</code>)';
+$lang['i_badval'] = 'القيمة <code>%s</code> غير شرعية أو فارغة';
+$lang['i_success'] = 'الإعدادات تمت بنجاح، يرجى حذف الملف install.php الآن.
+ثم تابع إلى <a href="doku.php"> دوكو ويكي الجديدة</a>';
+$lang['i_failure'] = 'بعض الأخطاء حدثت أثنا كتابة ملفات الإعدادات، عليك تعديلها يدوياً قبل أن تستطيع استخدام <a href="doku.php"> دوكو ويكي الجديدة</a>';
+$lang['i_policy'] = 'تصريح ACL مبدئي';
+$lang['i_pol0'] = 'ويكي مفتوحة؛ أي القراءة والكتابة والتحميل مسموحة للجميع';
+$lang['i_pol1'] = 'ويكي عامة؛ أي القراءة للجميع ولكن الكتابة والتحميل للمشتركين المسجلين فقط';
+$lang['i_pol2'] = 'ويكي مغلقة؛ أي القراءة والكتابة والتحميل للمشتركين المسجلين فقط';
+$lang['i_retry'] = 'إعادة المحاولة';
+$lang['i_license'] = 'اختر الرخصة التي تريد وضع المحتوى تحتها:';
+$lang['recent_global'] = 'انت تراقب حاليا التغييرات داخل نطاق <b>%s</b>. يمكنك أيضا <a href="%s">عرض أحدث تغييرات الويكي كلها</a>.';
+$lang['years'] = '%d سنة مضت';
+$lang['months'] = '%d شهرا مضى';
+$lang['weeks'] = '%d اسبوعا مضى';
+$lang['days'] = '%d يوما مضى';
+$lang['hours'] = '%d ساعة مضت';
+$lang['minutes'] = '%d دقيقة مضت';
+$lang['seconds'] = '%d ثانية مضت';
+$lang['wordblock'] = 'لم تحفظ تغييراتك لاحتوائها على نص ممنوع )غثاء(';
diff --git a/inc/lang/ar/locked.txt b/inc/lang/ar/locked.txt
new file mode 100644
index 000000000..72e9be535
--- /dev/null
+++ b/inc/lang/ar/locked.txt
@@ -0,0 +1,3 @@
+====== الصفحة مقفلة ======
+
+هذه الصفحة مقفلة للتحرير بواسطة مستخدم أخر. عليك أن تنتظر حتى ينتهى من تعديلاتة أو تتنتهى مدة القفل. \ No newline at end of file
diff --git a/inc/lang/ar/login.txt b/inc/lang/ar/login.txt
new file mode 100644
index 000000000..00ffccdd0
--- /dev/null
+++ b/inc/lang/ar/login.txt
@@ -0,0 +1,3 @@
+====== دخول ======
+
+أنت لست مسجل دخولك. أدخل بيانات تسجيلك للدخول. يجب أن يكون مسموح للمتصفح بأستخدام الكوكي.
diff --git a/inc/lang/ar/mailtext.txt b/inc/lang/ar/mailtext.txt
new file mode 100644
index 000000000..21d416566
--- /dev/null
+++ b/inc/lang/ar/mailtext.txt
@@ -0,0 +1,17 @@
+تم تغيير أو أضافة صفحة فى دوكو ويكي. اليك التفاصيل:
+
+التاريخ : @DATE@
+المتصفح : @BROWSER@
+عنوان الـIP : @IPADDRESS@
+أسم الجهاز : @HOSTNAME@
+النسخة القديمة: @OLDPAGE@
+النسخة الجديدة: @NEWPAGE@
+ملخص التحرير: @SUMMARY@
+مستخدم : @USER@
+
+@DIFF@
+
+
+--
+تم أرسال هذه الرسالة من دوكو ويكي فى
+@DOKUWIKIURL@
diff --git a/inc/lang/ar/newpage.txt b/inc/lang/ar/newpage.txt
new file mode 100644
index 000000000..ecaa7fa38
--- /dev/null
+++ b/inc/lang/ar/newpage.txt
@@ -0,0 +1,3 @@
+====== لا يوجد هذا الموضوع بعد ======
+
+لقد تابعت رابط لموضوع غير متواجد بعد. يمكنك إنشائة بالضعط على زر "انشيء هذه الصفحة".
diff --git a/inc/lang/ar/norev.txt b/inc/lang/ar/norev.txt
new file mode 100644
index 000000000..2aa2330e1
--- /dev/null
+++ b/inc/lang/ar/norev.txt
@@ -0,0 +1,3 @@
+====== لا توجد تلك النسخة ======
+
+النسخة المختارة ليست موجودة. أسبخدم زر "نسخ قديمة" لعرض قائمة بالنسخ القديمة من هذه الصفحة.
diff --git a/inc/lang/ar/password.txt b/inc/lang/ar/password.txt
new file mode 100644
index 000000000..c8530bb02
--- /dev/null
+++ b/inc/lang/ar/password.txt
@@ -0,0 +1,10 @@
+أهلاً @FULLNAME@!
+
+ها هى معلومات المستخدم لـ @TITLE@ الموجودة على العنوان @DOKUWIKIURL@
+
+أسم المستخدم : @LOGIN@
+كلمة السر : @PASSWORD@
+
+--
+تم أرسال هذه الرسالة من دوكو ويكي
+@DOKUWIKIURL@
diff --git a/inc/lang/ar/preview.txt b/inc/lang/ar/preview.txt
new file mode 100644
index 000000000..c537e6b26
--- /dev/null
+++ b/inc/lang/ar/preview.txt
@@ -0,0 +1,3 @@
+====== عرض التعديلات ======
+
+هذا عرض لما سيصبح علية نص الصفحة. تذكر أن التعديلات **لم تحفظ** بعد!
diff --git a/inc/lang/ar/pwconfirm.txt b/inc/lang/ar/pwconfirm.txt
new file mode 100644
index 000000000..401053ea0
--- /dev/null
+++ b/inc/lang/ar/pwconfirm.txt
@@ -0,0 +1,8 @@
+مرحبا @FULLNAME@
+
+شخص ما طلب كلمة سر جديدة لـحسابك @TITLE@ في @DOKUWIKIURL@
+إذا لم تكن قد طلبت كلمة سر جديدة رجاء قم بتجاهل هذه الرسالة .
+لتأكيد أنك أنت قمت بطلب كلمة السر الجديدة . نرجو منك الضغط على الرابط في الأسفل .
+@CONFIRM@
+ --
+لقد تم عمل هذه الرسالة من قبل DokuWiki .. في @DOKUWIKIURL@
diff --git a/inc/lang/ar/read.txt b/inc/lang/ar/read.txt
new file mode 100644
index 000000000..3e6c504ff
--- /dev/null
+++ b/inc/lang/ar/read.txt
@@ -0,0 +1 @@
+هذه الصفحة للقراءة فقط. يمكنك تصفح مصدرها، ولكن لا يمكنك تعديلها. إن كنت تتعتفد أن هناك خطأ ما خاطب المدير. \ No newline at end of file
diff --git a/inc/lang/ar/recent.txt b/inc/lang/ar/recent.txt
new file mode 100644
index 000000000..94d68401e
--- /dev/null
+++ b/inc/lang/ar/recent.txt
@@ -0,0 +1,3 @@
+====== احدث التغييرات ======
+
+تم تعديل الصفحات التالية حديثا. \ No newline at end of file
diff --git a/inc/lang/ar/register.txt b/inc/lang/ar/register.txt
new file mode 100644
index 000000000..57406ddd4
--- /dev/null
+++ b/inc/lang/ar/register.txt
@@ -0,0 +1,3 @@
+====== سجل كمستخدم جديد ======
+
+أملئ البيانات التالية لتسجيل حساب جديد على الويكي. تأكد من كتابة **بريد إلكترونى صحيح** - سترسل اليك كلمة سر جديدة. أسم الدخول يجب أن يكون [[doku>pagename|أسم صفحة]] صحيح.
diff --git a/inc/lang/ar/registermail.txt b/inc/lang/ar/registermail.txt
new file mode 100644
index 000000000..f04801f20
--- /dev/null
+++ b/inc/lang/ar/registermail.txt
@@ -0,0 +1,14 @@
+سجل مستخدم جديد. هذه هي التفاصيل:
+
+اسم المستخدم : @NEWUSER@
+الاسم الكامل : @NEWNAME@
+البريد: @NEWEMAIL@
+
+التاريخ : @DATE@
+المتصفح : @BROWSER@
+عنوان-IP: @IPADDRESS@
+اسم المضيف: @HOSTNAME@
+
+--
+وُلد هذا البريد من دوكو ويكي في
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ar/resendpwd.txt b/inc/lang/ar/resendpwd.txt
new file mode 100644
index 000000000..c69713706
--- /dev/null
+++ b/inc/lang/ar/resendpwd.txt
@@ -0,0 +1,3 @@
+==== إرسال كلمة سر جديدة ====
+
+رجاء اكتب اسم المستخدم في الاستمارة الموجودة في الأسفل ليتم طلب رقم سري جديد لحسابك في هذا الويكي . سيرسل رابط لتأكيد طلبك إلى بريدك الإلكتروني المسجل . \ No newline at end of file
diff --git a/inc/lang/ar/revisions.txt b/inc/lang/ar/revisions.txt
new file mode 100644
index 000000000..930a4ef5c
--- /dev/null
+++ b/inc/lang/ar/revisions.txt
@@ -0,0 +1,2 @@
+====== النسخ القديمة ======
+النسخ القديمة للصفحة الحالية. لإستعادة نسخة قديمة: أخترها من المعروض، ثم إضغط على زر "عدل هذه الصفحة" و أحفظها. \ No newline at end of file
diff --git a/inc/lang/ar/searchpage.txt b/inc/lang/ar/searchpage.txt
new file mode 100644
index 000000000..62c05f5e4
--- /dev/null
+++ b/inc/lang/ar/searchpage.txt
@@ -0,0 +1,5 @@
+====== بحث ======
+
+نتائج البحث . إن لم تجد ما تبحث عنه، يمكنك إنشاء صفحة جديدة بعنوان ما تبحث عنة بالضغط على زر "حرر هذه الصفحة".
+
+===== نتائج البحث ===== \ No newline at end of file
diff --git a/inc/lang/ar/showrev.txt b/inc/lang/ar/showrev.txt
new file mode 100644
index 000000000..30129071c
--- /dev/null
+++ b/inc/lang/ar/showrev.txt
@@ -0,0 +1,2 @@
+**هذه نسخة قديمة من الصفحة!**
+---- \ No newline at end of file
diff --git a/inc/lang/ar/stopwords.txt b/inc/lang/ar/stopwords.txt
new file mode 100644
index 000000000..bc6eb48ae
--- /dev/null
+++ b/inc/lang/ar/stopwords.txt
@@ -0,0 +1,29 @@
+# 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
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/ar/subscr_digest.txt b/inc/lang/ar/subscr_digest.txt
new file mode 100644
index 000000000..6e8c2fa94
--- /dev/null
+++ b/inc/lang/ar/subscr_digest.txt
@@ -0,0 +1,20 @@
+مرحبا!
+
+تغيرت الصفحة @PAGE@ في ويكي @TITLE@.
+هذه هي التغيرات:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+النسخة القديمة: @OLDPAGE@
+النسخة الحديثة: @NEWPAGE@
+
+لإلغاء تنبيه الصفحة, لج الويكي في
+@DOKUWIKIURL@ ثم زُر
+@SUBSCRIBE@
+وألغ اشتراكك من الصفحات أو النظاقات
+
+--
+أنشئت هذه الرسالة من دوكو ويكي في
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ar/subscr_form.txt b/inc/lang/ar/subscr_form.txt
new file mode 100644
index 000000000..919d256fb
--- /dev/null
+++ b/inc/lang/ar/subscr_form.txt
@@ -0,0 +1,3 @@
+====== إدارة الإشتراكات ======
+
+تمكنك هذه الصفحة من إدارة اشتراكاتك للصفحة و النطاق الحاليين. \ No newline at end of file
diff --git a/inc/lang/ar/subscr_list.txt b/inc/lang/ar/subscr_list.txt
new file mode 100644
index 000000000..22773a8e4
--- /dev/null
+++ b/inc/lang/ar/subscr_list.txt
@@ -0,0 +1,17 @@
+مرحبا!
+
+صفحات في النطاق @PAGE@ في ويكي @TITLE@ غُيرت.
+هذه هي الصفحات المتغيرة:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+لإلغاء إشعارات الصفحة, لُج الويكي في
+@DOKUWIKIURL@ ثم زُر
+@SUBSCRIBE@
+ثم ألغ اشتراك تغييرات الصفحة و/أو النطاق.
+
+--
+وُلد هذا البريد من دوكو ويكي في
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ar/subscr_single.txt b/inc/lang/ar/subscr_single.txt
new file mode 100644
index 000000000..5c62aeaeb
--- /dev/null
+++ b/inc/lang/ar/subscr_single.txt
@@ -0,0 +1,23 @@
+مرحبا!
+
+الصفحة @PAGE@ في ويكي @TITLE@ تغيرت.
+هذه هي التغييرات:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+التاريخ : @DATE@
+المستخدم : @USER@
+ملخص التحرير: @SUMMARY@
+الاصدار القديم: @OLDPAGE@
+الاصدار الحديث: @NEWPAGE@
+
+لإلغاء إشعارات الصفحة,لُج الويكي في
+@DOKUWIKIURL@ ثم زُر
+@NEWPAGE@
+وألغ الاشتراك من تغييرات الصفحة و/أو النطاق.
+
+--
+ولد هذا البريد باستخدام دوكو ويكي في
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ar/updateprofile.txt b/inc/lang/ar/updateprofile.txt
new file mode 100644
index 000000000..04a5a09d5
--- /dev/null
+++ b/inc/lang/ar/updateprofile.txt
@@ -0,0 +1,3 @@
+==== تحديث بيانات حسابك ====
+
+عليك فقط أن تكمل كتابة الحقول التي تريد أن تغيرها . لا تستطيع تغيير اسم المستخدم . \ No newline at end of file
diff --git a/inc/lang/ar/uploadmail.txt b/inc/lang/ar/uploadmail.txt
new file mode 100644
index 000000000..e4f16c7a5
--- /dev/null
+++ b/inc/lang/ar/uploadmail.txt
@@ -0,0 +1,14 @@
+رُفع ملف إلى دوكو ويكي خاصتك. هذه هي التفاصيل:
+
+الملف : @MEDIA@
+التاريخ : @DATE@
+المستعرض : @BROWSER@
+عنوان-IP: @IPADDRESS@
+اسم المضيف: @HOSTNAME@
+الحجم : @SIZE@
+نوع MIME : @MIME@
+المستخدم: @USER@
+
+--
+ولد هذا البريد من دوكو ويكي في
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/az/admin.txt b/inc/lang/az/admin.txt
new file mode 100644
index 000000000..000caa06d
--- /dev/null
+++ b/inc/lang/az/admin.txt
@@ -0,0 +1,4 @@
+====== İdarəetmə ======
+
+Aşağıda Dokuwiki-də mümkün olan administrativ əməliyyatların siyahısı göstərilib.
+
diff --git a/inc/lang/az/adminplugins.txt b/inc/lang/az/adminplugins.txt
new file mode 100644
index 000000000..62b1f8793
--- /dev/null
+++ b/inc/lang/az/adminplugins.txt
@@ -0,0 +1 @@
+===== Əlavə Plugin-lər =====
diff --git a/inc/lang/az/backlinks.txt b/inc/lang/az/backlinks.txt
new file mode 100644
index 000000000..72a7c858d
--- /dev/null
+++ b/inc/lang/az/backlinks.txt
@@ -0,0 +1,4 @@
+====== Əks linklər ======
+
+Bu, bu səhifəyə link saxlayan səhifələrin siyahısıdır.
+
diff --git a/inc/lang/az/conflict.txt b/inc/lang/az/conflict.txt
new file mode 100644
index 000000000..908be09f1
--- /dev/null
+++ b/inc/lang/az/conflict.txt
@@ -0,0 +1,5 @@
+====== Daha yeni versiya var ======
+
+Düzəliş etdiyiniz sənədin daha yeni versiyası var. Siz və başqa istifadəçi eyni zamanda eyni sənədi düzəliş edən zaman belə vəziyyət yaranır.
+
+Aşağıda göstərilən fərqlər ilə tanış olun və lazım olan versiyanı təyin edin. Əgər ''Yadda Saxla'' düyməsini sıxsanız, onda sizin versiya seçilmiş olur. ''İmtina'' düyməsini sıxsanız isə onda hazırki versiya seçilmiş olur.
diff --git a/inc/lang/az/denied.txt b/inc/lang/az/denied.txt
new file mode 100644
index 000000000..a68b08c8c
--- /dev/null
+++ b/inc/lang/az/denied.txt
@@ -0,0 +1,3 @@
+====== Müraciət qadağan edilmişdir ======
+
+Sizin bu əməliyyat üçün kifayət qədər haqqınız yoxdur. Bəlkə, Siz sistemə oz istifadəçi adınız ilə girməyi unutmusunuz?
diff --git a/inc/lang/az/diff.txt b/inc/lang/az/diff.txt
new file mode 100644
index 000000000..a944f84f4
--- /dev/null
+++ b/inc/lang/az/diff.txt
@@ -0,0 +1,4 @@
+====== Fərqlər ======
+
+Burada bu səhifənin seçilmiş və hazırki versiyaların arasında olan fərqlər göstərilib.
+
diff --git a/inc/lang/az/draft.txt b/inc/lang/az/draft.txt
new file mode 100644
index 000000000..65c743de3
--- /dev/null
+++ b/inc/lang/az/draft.txt
@@ -0,0 +1,5 @@
+====== Qaralama tapılıb ======
+
+Bu səhifənin son düzəlişi düzgün başa çatdırılmamışdir. Düzəliş zamanı qaralama avtomatik yadda saxlanılmışdır. İndi Siz onu açıb düzəlişi davam edə bilərsiniz. Qaralama versiyası aşağıda göstərilib.
+
+İtmiş versiyanı //qaytarmaq//, qaralamanı //silmək//, və ya düzəlişi //imtina// etmək istədiyinizi təyin edin.
diff --git a/inc/lang/az/edit.txt b/inc/lang/az/edit.txt
new file mode 100644
index 000000000..7ce66307e
--- /dev/null
+++ b/inc/lang/az/edit.txt
@@ -0,0 +1 @@
+Səhifədə düzəliş edin və ''Yadda Saxla'' düyməsini sıxın. Sintaksis ilə tanış olmaq üçün [[wiki:syntax]] səhifəsini oxuyun. Ançaq səhifəni **daha yaxşı** etməki istədiyiniz halda düzəliş etməyinizi xahiş edirik. Əgər Siz nəyi isə ancaq test etmək istəyirsiniz sə, onda [[playground:playground]] xüsusi səhifədən istifadə edin.
diff --git a/inc/lang/az/editrev.txt b/inc/lang/az/editrev.txt
new file mode 100644
index 000000000..8e98d2ff3
--- /dev/null
+++ b/inc/lang/az/editrev.txt
@@ -0,0 +1,2 @@
+**Sənədin köhnə versiyasını açmısınız!** Bu versiyanı yadda saxlasanız, bu mətn ilə olan yeni hazırki versiya yaratmış olarsınız.
+----
diff --git a/inc/lang/az/index.txt b/inc/lang/az/index.txt
new file mode 100644
index 000000000..dc3ffa3b0
--- /dev/null
+++ b/inc/lang/az/index.txt
@@ -0,0 +1,4 @@
+====== Mündəricat ======
+
+Burada mövcud olan səhifələr Namespace-lərə ([[doku>namespaces|namespaces]]) görə sıralanmış halda göstərilib.
+
diff --git a/inc/lang/az/install.html b/inc/lang/az/install.html
new file mode 100644
index 000000000..d41511438
--- /dev/null
+++ b/inc/lang/az/install.html
@@ -0,0 +1,7 @@
+<p>Bu səhifə Sizə <a href="http://dokuwiki.org">DokuWiki</a>-ni quraşdırmaqa kömək etmək üçündür. Quraşdırma haqqına əlavə məlumatı onun <a href="http://dokuwiki.org/installer">dokumentasiya səhifəsində</a> var.</p>
+
+<p>Səhifələri və əlavə məlumatları (məsələn, şəkillər, axtarış indeksi, səhifələrin əvvəlki versiyaları, və sairə) saxlamaq üçün DokuWiki adi fayllardan istifadə edir. DokuWiki-nin uğurlu işləməsi üçün bu faylların yerləşən qovluqa yazı imkanı vacib <strong>lazımdır</strong>. Bu quraşdırma proqramı sistemin qovluqlarına olan haqları dəyişə bilmir. Çox vaxt bu birbaşa shell-dən, və ya, əgər Siz hostinq-dən istifadə edirsinizsə, FTP vasitəsi ya idarəetmə paneli vasitəsi (məsələn, cPanel) ilə edilir.</p>
+
+<p>Quraşdırma proqramı sizin DokuWiki-nizdə haqlar kontrolu siyahısını (<acronym title="access control list">ACL</acronym>) quracaq. Bu, sistemə girdikdən sonra, administratora xüsusi menü vasitəsi ilə plugin-ləri quraşdırmaq, istifadiçiləri və səhifələrə giriş haqlarını idarəetmək, və həmçinin sistemin konfiqurasiyasını quraşdırmağa imkan verəcək. Haqlar kontrolu siyahısı DokuWiki-yə mütləq lazım deyil, amma o Sizə DokuWiki-nin idarəetməsini asanlaşdırır.</p>
+
+<p>Təcrübəli istifadəçilər və xüsusi tələbləri olan istifadəçilərə əlavə məlumat üçün <a href="http://dokuwiki.org/install">quraşdırılma prosesi</a> və <a href="http://dokuwiki.org/config">konfiqurasiya parametrləri</a> link-lərinə muraciyət etməsk tövsiyyə olunur.</p>
diff --git a/inc/lang/az/lang.php b/inc/lang/az/lang.php
new file mode 100644
index 000000000..25b44efdc
--- /dev/null
+++ b/inc/lang/az/lang.php
@@ -0,0 +1,227 @@
+<?php
+/**
+ * Azerbaijani language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Pasha L. Topchiyev <pasha@itopchiyev.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '«';
+$lang['doublequoteclosing'] = '»';
+$lang['singlequoteopening'] = '„';
+$lang['singlequoteclosing'] = '“';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Səhifəyə düzəliş et';
+$lang['btn_source'] = 'Səhifənin ilkin mətnini göstər';
+$lang['btn_show'] = 'Səhifəni göstər';
+$lang['btn_create'] = 'Səhifəni yarat';
+$lang['btn_search'] = 'Axtarış';
+$lang['btn_save'] = 'Yadda saxla';
+$lang['btn_preview'] = 'Baxış';
+$lang['btn_top'] = 'Yuxarı';
+$lang['btn_newer'] = '<< daha təzələr';
+$lang['btn_older'] = 'daha köhnələr >>';
+$lang['btn_revs'] = 'Səhifənin tarixçəsi';
+$lang['btn_recent'] = 'Yaxın dəyişiklər';
+$lang['btn_upload'] = 'Serverə yükə';
+$lang['btn_cancel'] = 'İmtina';
+$lang['btn_index'] = 'Bütün səhifələr';
+$lang['btn_secedit'] = 'Düzəliş et';
+$lang['btn_login'] = 'Giriş';
+$lang['btn_logout'] = 'Cıxış';
+$lang['btn_admin'] = 'İdarəetmə';
+$lang['btn_update'] = 'Yenilə';
+$lang['btn_delete'] = 'Sil';
+$lang['btn_back'] = 'Geri';
+$lang['btn_backlink'] = 'Bura olan link-lər';
+$lang['btn_backtomedia'] = 'media-fayl seçiminə qayıt';
+$lang['btn_subscribe'] = 'Abunə ol (bütün dəyişiklər)';
+$lang['btn_unsubscribe'] = 'Abunəlikdən çıx (bütün dəyişiklər)';
+$lang['btn_profile'] = 'Profil';
+$lang['btn_reset'] = 'Boşalt';
+$lang['btn_resendpwd'] = 'Yeni şifrəni göndər';
+$lang['btn_draft'] = 'Qaralamada düzəliş etmək';
+$lang['btn_recover'] = 'Qaralamanı qaytar';
+$lang['btn_draftdel'] = 'Qaralamanı sil';
+$lang['btn_revert'] = 'Qaytar';
+$lang['btn_register'] = 'Qeydiyyatdan keç';
+$lang['loggedinas'] = 'İstifadəcinin adı';
+$lang['user'] = 'istifadəci adı';
+$lang['pass'] = 'Şifrə';
+$lang['newpass'] = 'Yeni şifrə';
+$lang['oldpass'] = 'Hazırki şifrəni daxil edin';
+$lang['passchk'] = 'təkrarlayın';
+$lang['remember'] = 'Məni yadda saxla';
+$lang['fullname'] = 'Tam ad';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'İstifadəçi profili';
+$lang['badlogin'] = 'Təssüf ki istifadəçi adı və ya şifrə səhvdir.';
+$lang['minoredit'] = 'Az dəyişiklər';
+$lang['draftdate'] = 'Qaralama yadda saxlandı';
+$lang['nosecedit'] = 'Bu vaxt ərzində səhifə dəyişilmişdir, və bölmə haqqında məlumat köhnəlmişdir. Səhifənin tam versiyası yüklənmişdir.';
+$lang['regmissing'] = 'Təssüf ki Siz bütün xanələri doldurmalısınız.';
+$lang['reguexists'] = 'Təssüf ki bu ad ilə istifadəçi artıq mövcuddur.';
+$lang['regsuccess'] = 'İstivadəci yaradıldı və şifrə sizin e-maila göndərildi.';
+$lang['regsuccess2'] = 'İstifadəçi yaradıldı.';
+$lang['regmailfail'] = 'Deyəsən, xəta şifrə e-maila göndərildikdə baş verdi. Xaiş olunur, ki administrator ilə əlaqə saxlayasınız!';
+$lang['regbadmail'] = 'Deyəsən, daxil edilmiş e-mail ünvanı səhvdir. Əgər şübhəniz var isə administrator ilə əlaqə saxlayın.';
+$lang['regbadpass'] = 'Daxil edilmiş iki şifrə fərqlidir. Xaiş olunur ki, yenidən daxil edəsiniz.';
+$lang['regpwmail'] = 'Sizin DokuWiki sistemi üçün şifrəniz';
+$lang['reghere'] = 'Sizin hələ istifadəçi adınız yoxdur? Buyurun əldə edin';
+$lang['profna'] = 'Bu wiki profilin dəyişdirilməsini dəstəkləmir';
+$lang['profnochange'] = 'Dəyişiklər edilmədi, profil yenilənmədi.';
+$lang['profnoempty'] = 'istifadəci adı və e-mail ünvanı boş ola bilməz.';
+$lang['profchanged'] = 'İstifadəçi profili uğurla yeniləndi.';
+$lang['pwdforget'] = 'Şifrəni yaddan çıxartmısız? Buyurun yenisini əldə edin';
+$lang['resendna'] = 'Bu wiki şifrəni yenidən göndərməyi dəstəkləmir.';
+$lang['resendpwd'] = 'Yeni şifrəni göndər:';
+$lang['resendpwdmissing'] = 'Formanın bütün xanəlırini doldurun.';
+$lang['resendpwdnouser'] = 'Verilənlər bazasında bu ad ilə istifadəçi tapılmadı.';
+$lang['resendpwdbadauth'] = 'Ativləşdirmə kodu səhvdir. Link-i tam olaraq köçürdüyünüzü yoxlayın. ';
+$lang['resendpwdconfirm'] = 'Şifrəni təstiqləmək üçün sizin e-maila link göndərilmişdir. ';
+$lang['resendpwdsuccess'] = 'Yeni şifrəniz e-maila göndərildi.';
+$lang['license'] = 'Fərqli şey göstərilmiş hallardan başqa, bu wiki-nin mətni aşağıda göstərilmiş lisenziyanın şərtlərinə uyğun təqdim olunur:';
+$lang['licenseok'] = 'Qeyd: bu səhifəni düzəliş edərək, Siz elədiyiniz düzəlişi aşağıda göstərilmiş lisenziyanın şərtlərinə uyğun istifadəsinə razılıq verirsiniz:';
+$lang['searchmedia'] = 'Faylın adına görə axtarış:';
+$lang['searchmedia_in'] = '%s-ın içində axtarış';
+$lang['txt_upload'] = 'Serverə yükləmək üçün fayl seçin';
+$lang['txt_filename'] = 'Faylın wiki-də olan adını daxil edin (mütləq deyil)';
+$lang['txt_overwrt'] = 'Mövcud olan faylın üstündən yaz';
+$lang['lockedby'] = 'В данный момент заблокирован Bu an blokdadır';
+$lang['lockexpire'] = 'Blok bitir:';
+$lang['js']['willexpire'] = 'Sizin bu səhifədə dəyişik etmək üçün blokunuz bir dəqiqə ərzində bitəcək.\nMünaqişələrdən yayınmaq və blokun taymerini sıfırlamaq üçün, baxış düyməsini sıxın.';
+$lang['notsavedyet'] = 'Yaddaşa yazılmamış dəyişiklər itəcəklər.\nSiz davam etmək istəyirsiz?';
+$lang['rssfailed'] = 'Aşağıda göstərilmiş xəbər lentini əldə edən zaman xəta baş verdi: ';
+$lang['nothingfound'] = 'Heçnə tapılmadı.';
+$lang['mediaselect'] = 'Mediya-faylın seçilməsi';
+$lang['fileupload'] = 'Mediya-faylın serverə yüklənməsi';
+$lang['uploadsucc'] = 'Yüklənmə uğur ilə başa çatdı';
+$lang['uploadfail'] = 'Yüklənmə zamanı xəta baş veri. Bəlkə giriş haqları ilə problem var?';
+$lang['uploadwrong'] = 'Yuklənməyə qadağa qoyuldu. Belə növlu faylları serverə yükləmək olmaz. ';
+$lang['uploadexist'] = 'Bu adlı fayl artıq serverdə var. Yükləmə alınmadı .';
+$lang['uploadbadcontent'] = 'Faylın tərkibi %s növünə uyğun gəlmir.';
+$lang['uploadspam'] = 'Yüklənmə spam-filtri tərəfindən dayandırıldı.';
+$lang['uploadxss'] = 'Yüklənmə təhlükəsizlik nəzərindən dayandırılmışdır.';
+$lang['uploadsize'] = 'Yüklənilmiş fayl çox boyükdür. (maks. %s)';
+$lang['deletesucc'] = '"%s" adlı fayl silindi.';
+$lang['deletefail'] = '"%s" adlı fayl silinmədi. Faylın giriş haqlarını yoxlayın.';
+$lang['mediainuse'] = '"%s" adlı fayl silinmədi. Fayl hələ istifadə olunur';
+$lang['namespaces'] = 'Namespace-lər';
+$lang['mediafiles'] = 'Mövcud olan fayllar';
+$lang['js']['searchmedia'] = 'Faylların axtarışı';
+$lang['js']['keepopen'] = 'Seçimdən sonra pəncərəni açıq saxlamaq';
+$lang['js']['hidedetails'] = 'Təfərruatı gizlət';
+$lang['js']['nosmblinks'] = 'Windows-un şəbəkə qovluqlarına link ancaq Internet Explorer-dən işləyir. \nAmma Siz linki köçürə bilərsiniz.';
+$lang['js']['linkwiz'] = 'Linklər köməkçisi';
+$lang['js']['linkto'] = 'Link göstərir:';
+$lang['js']['del_confirm'] = 'Siz əminsiz ki, seçilmişləri silmək istəyirsiniz?';
+$lang['mediausage'] = 'Bu fayla link yaratmaq üçün aşağıdakı sintaksisdən istifadə edin:';
+$lang['mediaview'] = 'Bu faylın ilkinə bax';
+$lang['mediaroot'] = 'kök';
+$lang['mediaupload'] = 'Burda faylı hazırki qovluqa yükləmək olar ("namespace"). Alt qovluqlar yaratmaq üçün, onların adlarını faylın adının avvəlinə artırın ("Adla yükləmək"). Alt qovluqların adları çütnöqtə ilə ayrılır. ';
+$lang['mediaextchange'] = 'Faylın nüvü .%s -dan .%s -ya dəyişdi!';
+$lang['reference'] = 'Linklər göstərir';
+$lang['ref_inuse'] = 'Bu fayl silinə bilməz, çünki o aşağıdaki səhifələr tərəfindən istifadə olunur:';
+$lang['ref_hidden'] = 'Bəzi link-lər sizin oxumaq haqqınız olmayan səhifələrdə yerləşir';
+$lang['hits'] = 'uyğunluqlar';
+$lang['quickhits'] = 'Səhifələrin adlarında uyğunluqlar';
+$lang['toc'] = 'Mündəricat';
+$lang['current'] = 'hazırki';
+$lang['yours'] = 'Sizin versiyanız';
+$lang['diff'] = 'hazırki versiyadan fərqləri göstər';
+$lang['diff2'] = 'Versiyaların arasındaki fərqləri göstər ';
+$lang['line'] = 'Sətr';
+$lang['breadcrumb'] = 'Siz ziyarət etdiniz';
+$lang['youarehere'] = 'Siz burdasınız';
+$lang['lastmod'] = 'Son dəyişiklər';
+$lang['by'] = ' Kimdən';
+$lang['deleted'] = 'silinib';
+$lang['created'] = 'yaranıb';
+$lang['restored'] = 'köhnə versiya qaytarıldı';
+$lang['external_edit'] = 'bayırdan dəyişik';
+$lang['summary'] = 'Dəyişiklər xülasəsi';
+$lang['noflash'] = 'Bu məzmuna baxmaq üçün <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> tələb olunur.';
+$lang['download'] = 'Kodu yüklə';
+$lang['mail_newpage'] = 'səhifə əlavə olundu:';
+$lang['mail_changed'] = 'səhifəyə düzəliş edildi:';
+$lang['mail_new_user'] = 'yeni istifadəçi:';
+$lang['mail_upload'] = 'fayl yükləndi:';
+$lang['qb_bold'] = 'Qalın şrift';
+$lang['qb_italic'] = 'Maili şrift';
+$lang['qb_underl'] = 'Alt-xətt';
+$lang['qb_code'] = 'Kodun mətni';
+$lang['qb_strike'] = 'Pozulmuş şrift';
+$lang['qb_h1'] = '1 dərəcəli başlıq';
+$lang['qb_h2'] = '2 dərəcəli başlıq';
+$lang['qb_h3'] = '3 dərəcəli başlıq';
+$lang['qb_h4'] = '4 dərəcəli başlıq';
+$lang['qb_h5'] = '5 dərəcəli başlıq';
+$lang['qb_h'] = 'Başlıq';
+$lang['qb_hs'] = 'Başlıq seçimi';
+$lang['qb_hplus'] = 'Daha yüksək dərəcəli başlıq';
+$lang['qb_hminus'] = 'Daha aşağı dərəcəli başlıq (altbaşlıq)';
+$lang['qb_hequal'] = 'Hazırki dərəcəli başlıq';
+$lang['qb_link'] = 'İç link';
+$lang['qb_extlink'] = 'Bayır link';
+$lang['qb_hr'] = 'Bölücü';
+$lang['qb_ol'] = 'Nömrələnmiş siyahının element';
+$lang['qb_ul'] = 'Nömrələnməmiş siyahının element';
+$lang['qb_media'] = 'Şəkillər və başqa fayllar əlavə et';
+$lang['qb_sig'] = 'İmza at';
+$lang['qb_smileys'] = 'Smayllar';
+$lang['qb_chars'] = 'Xüsusi simvollar';
+$lang['upperns'] = 'Ana namespace-ə keç';
+$lang['admin_register'] = 'İstifadəçi əlavə et';
+$lang['metaedit'] = 'Meta-məlumatlarda düzəliş et';
+$lang['metasaveerr'] = 'Meta-məlumatları yazan zamanı xəta';
+$lang['metasaveok'] = 'Meta-məlumatlar yadda saxlandı';
+$lang['img_backto'] = 'Qayıd';
+$lang['img_title'] = 'Başlıq';
+$lang['img_caption'] = 'İmza';
+$lang['img_date'] = 'Tarix';
+$lang['img_fname'] = 'Faylın adı';
+$lang['img_fsize'] = 'Boy';
+$lang['img_artist'] = 'Şkilin müəllifi';
+$lang['img_copyr'] = 'Müəllif hüquqları';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Model';
+$lang['img_keywords'] = 'Açar sözlər';
+$lang['subscribe_success'] = '%s adlı istifadəçi %s səhifənin paylanma siyahısına əlavə olundu';
+$lang['subscribe_error'] = '%s adlı istifadəçini %s səhifənin paylanma siyahısına əlavə etmə zamanı səhv baş verdi';
+$lang['subscribe_noaddress'] = 'Sizin profilinizdə e-mail göstərilməyib.Ona görə siz paylnma siyahılarına əlavə edilə bilməzsiniz.';
+$lang['unsubscribe_success'] = '%s adlı istifadəçi %s səhifənin paylanma siyahısından silinmişdir';
+$lang['unsubscribe_error'] = '%s adlı istifadəçini %s səhifənin paylanma siyahısından silən zaman xəta baş verdi.';
+$lang['authmodfailed'] = 'İstifadəçinin autentifikasiyasının konfiqurasiyası səhfdir. Xaiş olunur ki wiki-nin administratoru ilə əlaqə saxlayasınız.';
+$lang['authtempfail'] = 'İstifadəçilərin autentifikasiyası müvəqqəti dayandırılıb. Əgər bu problem uzun müddət davam edir sə, administrator ilə əlaqə saxlayın.';
+$lang['i_chooselang'] = 'Dili seçin/Language';
+$lang['i_installer'] = 'DokuWiki quraşdırılır';
+$lang['i_wikiname'] = 'wiki-nin adı';
+$lang['i_enableacl'] = 'Haqlar kontrolu siyahısının istifadəsinə icazə ver (tövsiyə edilir)';
+$lang['i_superuser'] = 'Super-istifadəci';
+$lang['i_problems'] = 'Quraşdırma proqramı aşağıdakı problemlər ilə üzləşdi. Davam etmək üçün onları həll etmək lazımdır. ';
+$lang['i_modified'] = 'Təhlükəsizlik baxımından bu proqram ancaq yeni, dəyişməmiş halda olan DokuWiki üzərində işləyir.
+ Siz ya yüklənmiş quraşdırma paketini yenidən açmalısınız, ya da <a href="http://dokuwiki.org/install">DokuWiki-nin tam quraşdırma instruksiyasına</a> müraciyət etməlisiniz';
+$lang['i_funcna'] = 'PHP-nin <code>%s</code> funksiyası mövcud deyil. Bəlkə, o hansı sa səbəbdən sizin host-unuz tərəfindən blok edilib?';
+$lang['i_phpver'] = 'Sizin PHP-nin versiyası (<code>%s</code>) tələb olunan versiyadan aşagıdır (<code>%s</code>). Quraşdırılmış PHP-nin versiyasını yeniləyin.';
+$lang['i_permfail'] = '<code>%s</code> DokuWiki-yə yazı üçün bağlıdır. Bu qovluğun giriş haqlarını yoxlamaq lazımdır!';
+$lang['i_confexists'] = '<code>%s</code> artıq mövcuddur';
+$lang['i_writeerr'] = '<code>%s</code> yaradıla bilmədi. Faylın/qovluqların giriş haqlarını yaxlamaq lazımdır. Və faylı əl ilə yaradın. ';
+$lang['i_badhash'] = 'dokuwiki.php tanıla bilmir və ya dəyişdirilmişdir (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - səhv ya boş qiymətdir';
+$lang['i_success'] = 'Konfiqurasiya uğurla başa çatdı. İndi siz install.php faylını silə bilərsiniz.
+ <a href="doku.php">Yeni DokuWiki-nizə</a> xoş gəlmişsiniz!';
+$lang['i_failure'] = 'Konfiqurasiya fayllarına məlumat yazan zaman səhvlər tapıldı. Yəgin ki, <a href="doku.php">yeni DokuWiki-nizi</a> istifadə etmədən öncə, Siz o xətaları əl ilə düzəltməli olacaqsınız.';
+$lang['i_policy'] = 'İlkin giriş haqları siyasəti';
+$lang['i_pol0'] = 'Tam açıq wiki (oxumaq, yazmaq, fayl yükləmək hamıya olar)';
+$lang['i_pol1'] = 'Acıq wiki (oxumaq hamıya olar, yazmaq və fayl yükləmək ancaq üzv olan istifadəçilərə olar)';
+$lang['i_pol2'] = 'Bağlı wiki (uxumaq, yazmaq və yükləmək ancaq üzv olan istifadəçilərə olar)';
+$lang['i_retry'] = 'Cəhdi təkrarla';
+$lang['recent_global'] = '<b>%s</b> namespace-də baş vermiş dəyışıklərə baxırsınız. Siz həmçinin <a href="%s">wiki-də bu yaxında baş vermiş bütün dəyişiklərə</a> baxa bilərsiniz.';
+$lang['years'] = '%d il əvvəl';
+$lang['months'] = '%d ay əvvəl';
+$lang['weeks'] = '%d həftə əvvəl';
+$lang['days'] = '%d gün əvvəl';
+$lang['hours'] = '%d saat əvvəl';
+$lang['minutes'] = '%d dəqiqə əvvəl';
+$lang['seconds'] = '%d saniyə əvvəl';
diff --git a/inc/lang/az/locked.txt b/inc/lang/az/locked.txt
new file mode 100644
index 000000000..8ab934443
--- /dev/null
+++ b/inc/lang/az/locked.txt
@@ -0,0 +1,3 @@
+====== Səhifə blok edilmişdir ======
+
+Bu səhifə başqa istifadəçi tərəfindən dəyişdirilmə üçün blok edilmişdir. O istifadəçi dəyişdirməni başa çatdırınca ya blokun vaxtı bitincə, Siz gözləməlisiniz.
diff --git a/inc/lang/az/login.txt b/inc/lang/az/login.txt
new file mode 100644
index 000000000..e0a559bc1
--- /dev/null
+++ b/inc/lang/az/login.txt
@@ -0,0 +1,4 @@
+====== Avtorizasiya ======
+
+Hazırda Siz sistemə daxil olmamısınız. Aşağıdakı formanı istifadə edib sistemə daxil olun. //Qeyd:// cookies qurlu olmalıdır.
+
diff --git a/inc/lang/az/mailtext.txt b/inc/lang/az/mailtext.txt
new file mode 100644
index 000000000..439458658
--- /dev/null
+++ b/inc/lang/az/mailtext.txt
@@ -0,0 +1,18 @@
+Sizin DokuWiki-də səhifə yaradılıb ya dəyişdirilib. Ətraflı məlumat:
+
+Tarix : @DATE@
+Brauzer : @BROWSER@
+IP-adres : @IPADDRESS@
+Host : @HOSTNAME@
+Köhnə versiya : @OLDPAGE@
+Yeni versiya : @NEWPAGE@
+Dəyişiklərin xülasəsi : @SUMMARY@
+İstifadəçi : @USER@
+
+@DIFF@
+
+
+--
+Bu məktub DokuWiki tərəfindən yaradıldı.
+DokuWiki aşağıdakı adresdə yerləşir:
+@DOKUWIKIURL@
diff --git a/inc/lang/az/newpage.txt b/inc/lang/az/newpage.txt
new file mode 100644
index 000000000..c749f20af
--- /dev/null
+++ b/inc/lang/az/newpage.txt
@@ -0,0 +1,3 @@
+====== Bu səhifə hələ mövcud deyil ======
+
+Siz yaradılmamış səhifənin link-ini acmısınız. Əgər sizin giriş haqlarınız çatırsa, siz "Səhifəni yarat" düyməsini sixib, o səhifəni yarada bilərsiniz.
diff --git a/inc/lang/az/norev.txt b/inc/lang/az/norev.txt
new file mode 100644
index 000000000..453dad56b
--- /dev/null
+++ b/inc/lang/az/norev.txt
@@ -0,0 +1,4 @@
+====== Belə versiya mövcud deyil ======
+
+Bu səhifənin göstərilmiş versiyası mövcud deyil. Səhifənin bütün versiyalaraının siyahısını görmək üçün, ''Səhifənin tarixçəsi'' düyməsini sıxın.
+
diff --git a/inc/lang/az/password.txt b/inc/lang/az/password.txt
new file mode 100644
index 000000000..31bf387da
--- /dev/null
+++ b/inc/lang/az/password.txt
@@ -0,0 +1,11 @@
+Salam @FULLNAME@!
+
+Sizin @TITLE@ (@DOKUWIKIURL@) üçün olan məlumatlarınız
+
+İstifadəçi adı : @LOGIN@
+Şifrə : @PASSWORD@
+
+--
+Bu məktub DokuWiki tərəfindən yaradıldı.
+DokuWiki aşağıdakı adresdə yerləşir:
+@DOKUWIKIURL@
diff --git a/inc/lang/az/preview.txt b/inc/lang/az/preview.txt
new file mode 100644
index 000000000..dbeaa44f5
--- /dev/null
+++ b/inc/lang/az/preview.txt
@@ -0,0 +1,4 @@
+====== Baxış ======
+
+Burda daxil elədiyiniz mətnin necə görünəcəyi göstərilir. Qeyd: mətn hələ **yadda saxlanılmayıb!**
+
diff --git a/inc/lang/az/pwconfirm.txt b/inc/lang/az/pwconfirm.txt
new file mode 100644
index 000000000..177e5a1fa
--- /dev/null
+++ b/inc/lang/az/pwconfirm.txt
@@ -0,0 +1,14 @@
+Salam @FULLNAME@!
+
+Kimsə @DOKUWIKIURL@ adresində yerləşən @TITLE@ adlı wiki-yə giriş üçün yeni şifrə tələb eləyib.
+
+Əgər o şəxs siz deyildinizsə, bu məktuba fikir verməyin.
+
+Tələbi təsdiq etmək üçün, aşağıdakı link-ə keçin.
+
+@CONFIRM@
+
+--
+Bu məktub DokuWiki tərəfindən yaradıldı.
+DokuWiki aşağıdakı adresdə yerləşir:
+@DOKUWIKIURL@
diff --git a/inc/lang/az/read.txt b/inc/lang/az/read.txt
new file mode 100644
index 000000000..39b31f108
--- /dev/null
+++ b/inc/lang/az/read.txt
@@ -0,0 +1,2 @@
+Bu səhifəni ancaq oxumaq olar. Siz səhifənin ilkin mətninə baxa bilərsiniz, amma dəyişə bilməzsiniz. Əgər bunun düzgün olmadığını fikirləşirsinizsə onda administrator ilə əlaqə saxlayın.
+
diff --git a/inc/lang/az/recent.txt b/inc/lang/az/recent.txt
new file mode 100644
index 000000000..8766d9953
--- /dev/null
+++ b/inc/lang/az/recent.txt
@@ -0,0 +1,5 @@
+====== Son dəyişiklər ======
+
+Bu səhifələr yaxında dəyismişdirlər.
+
+
diff --git a/inc/lang/az/register.txt b/inc/lang/az/register.txt
new file mode 100644
index 000000000..eb6386f72
--- /dev/null
+++ b/inc/lang/az/register.txt
@@ -0,0 +1,3 @@
+====== Регистрация нового пользователя ======
+
+Qeydiyyat üçün bütün aşağıdaı xanalari doldurun. **e-mail adresinizin duz olduguna** fikir verin. Əgər şıfrəni əl ilə daxil etməyiniz xaiş olunmursa, onda şifrə e-mail adresinizə göndəriləcək. İstifadəçi adı [[doku>pagename|səhifənin identifikatorunun]] məhdudiyyətlərinə uyğun olmalıdır.
diff --git a/inc/lang/az/registermail.txt b/inc/lang/az/registermail.txt
new file mode 100644
index 000000000..51919756f
--- /dev/null
+++ b/inc/lang/az/registermail.txt
@@ -0,0 +1,15 @@
+Yeni istifadəçi qeydiyyatdan keçdi. Ətraflı məlumat:
+
+İstifadəçi adı : @NEWUSER@
+Tam adı : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Tarix : @DATE@
+Brauzer : @BROWSER@
+IP adres : @IPADDRESS@
+Host : @HOSTNAME@
+
+--
+Bu məktub DokuWiki tərəfindən yaradıldı.
+DokuWiki aşağıdakı adresdə yerləşir:
+@DOKUWIKIURL@
diff --git a/inc/lang/az/resendpwd.txt b/inc/lang/az/resendpwd.txt
new file mode 100644
index 000000000..cc286174a
--- /dev/null
+++ b/inc/lang/az/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Yeni şifrənin göndərilməsi ======
+
+Yeni şifrə əldə etmək üçün aşağıda tələb olunan məlumatları daxil edin. Yeni şifrə sizin istifadəçi adınıza aid olan e-mail adresə göndəriləcək. Aşagıda daxil olunan ad - sizin bu wiki-də olan istifadəçi adınız olmalıdır.
diff --git a/inc/lang/az/revisions.txt b/inc/lang/az/revisions.txt
new file mode 100644
index 000000000..7164a9959
--- /dev/null
+++ b/inc/lang/az/revisions.txt
@@ -0,0 +1,3 @@
+====== Səhifənin tarixçəsi ======
+
+Qarşınızda - hazırki sənədin dəyişiklər tarixçəsidir. Əvvəlki versiyaların birinə qayıtmaq üçün, lazım olan versiyanı seçin, ''Səhifəni düzəliş et'' düyməsini sıxın və yaddaşa yazın.
diff --git a/inc/lang/az/searchpage.txt b/inc/lang/az/searchpage.txt
new file mode 100644
index 000000000..4f8efe007
--- /dev/null
+++ b/inc/lang/az/searchpage.txt
@@ -0,0 +1,5 @@
+====== Axtarış ======
+
+Qarşınızda - axtarışın nəticələridir. Əgər Siz axtardığınızı tapa bilmədinizsə, onda Siz adı axtarışınız ilə uyğun düşən yeni səhifə yarada bilərsiniz. Bunu eləmək üçün, sadəcə ''Səhifəni yarat'' düyməsini sıxın.
+
+===== Nəticələr =====
diff --git a/inc/lang/az/showrev.txt b/inc/lang/az/showrev.txt
new file mode 100644
index 000000000..dd398704b
--- /dev/null
+++ b/inc/lang/az/showrev.txt
@@ -0,0 +1,2 @@
+**Bu - sənədin köhnə versiyasıdır!**
+----
diff --git a/inc/lang/az/stopwords.txt b/inc/lang/az/stopwords.txt
new file mode 100644
index 000000000..04eb312eb
--- /dev/null
+++ b/inc/lang/az/stopwords.txt
@@ -0,0 +1,64 @@
+# 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
+amma
+arada
+arasında
+başqa
+başqalar
+başqaların
+başqanın
+belə
+birdən
+bugün
+bunu
+burada
+bəlkə
+cəmi
+dedi
+dedilər
+dedim
+dediniz
+demək
+deyəsən
+görə
+hamını
+hansı
+hansılar
+hansınız
+həmçinin
+həmişə
+hərdən
+hətta
+həyat
+indi
+lazım
+lazımdır
+məncə
+məni
+niyə
+nəyi
+olacaq
+olar
+oldu
+oldum
+olmaq
+olmaz
+olub
+onda
+onlar
+onları
+onun
+ozunun
+qabaq
+quya
+sabağ
+sizcə
+sizi
+sonra
+sözsüz
+şübhəsiz
+səni
+yaxşı
+yenə
+əgər
diff --git a/inc/lang/az/updateprofile.txt b/inc/lang/az/updateprofile.txt
new file mode 100644
index 000000000..569e425d4
--- /dev/null
+++ b/inc/lang/az/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Profili yenilə ======
+
+İstədiyiniz xanaları dəyiştirin. İstifadəşi adı dəyiştirilə bilməz.
+
+
diff --git a/inc/lang/az/uploadmail.txt b/inc/lang/az/uploadmail.txt
new file mode 100644
index 000000000..d538f8258
--- /dev/null
+++ b/inc/lang/az/uploadmail.txt
@@ -0,0 +1,15 @@
+Sizin DokuWiki-yə fayl yuklənildi. Ətraflı məlumat:
+
+Fayl : @MEDIA@
+Tarix : @DATE@
+Brauzer : @BROWSER@
+IP Adres : @IPADDRESS@
+Host : @HOSTNAME@
+Həcm : @SIZE@
+MIME Növ : @MIME@
+İstifadəçi : @USER@
+
+--
+Bu məktub DokuWiki tərəfindən yaradıldı.
+DokuWiki aşağıdakı adresdə yerləşir:
+@DOKUWIKIURL@
diff --git a/inc/lang/az/wordblock.txt b/inc/lang/az/wordblock.txt
new file mode 100644
index 000000000..ec8b102af
--- /dev/null
+++ b/inc/lang/az/wordblock.txt
@@ -0,0 +1,3 @@
+====== SPAM-ın qarşısı alındı ======
+
+Sizin dəyişiklər **yaddaşa saxlanmadı**, çünki onların içində bir və ya daha çox içazəsiz sözlər var idi. Əgər siz wiki-yə spam əlavə etmək istəyirdinizsə, onda utanmırsız?! Əgər siz bunu səhv hesab edirsinizsə, onda administrator ilə əlaqə saxlayın.
diff --git a/inc/lang/bg/admin.txt b/inc/lang/bg/admin.txt
new file mode 100644
index 000000000..d3c14a0da
--- /dev/null
+++ b/inc/lang/bg/admin.txt
@@ -0,0 +1,3 @@
+====== Администриране ======
+
+Отдолу ще намерите списъка с администраторските задачи в DokuWiki. \ No newline at end of file
diff --git a/inc/lang/bg/adminplugins.txt b/inc/lang/bg/adminplugins.txt
new file mode 100644
index 000000000..df24b0538
--- /dev/null
+++ b/inc/lang/bg/adminplugins.txt
@@ -0,0 +1 @@
+===== Допълнителни приставки ===== \ No newline at end of file
diff --git a/inc/lang/bg/backlinks.txt b/inc/lang/bg/backlinks.txt
new file mode 100644
index 000000000..dd633d94d
--- /dev/null
+++ b/inc/lang/bg/backlinks.txt
@@ -0,0 +1,3 @@
+====== Обратни препратки ======
+
+Това е списък на страниците, които препращат обратно към текущата страница.
diff --git a/inc/lang/bg/conflict.txt b/inc/lang/bg/conflict.txt
new file mode 100644
index 000000000..8c62a3787
--- /dev/null
+++ b/inc/lang/bg/conflict.txt
@@ -0,0 +1,6 @@
+====== Съществува по-нова версия ======
+
+Съществува по-нова версия на документа, който сте редактирали. Това се случва когато друг потребител е променил документа докато сте го редактирали.
+
+Разгледайте внимателно разликите, след това решете коя версия да бъде запазена. Ако натиснете ''Запис'', ще бъде запазена вашата версия. Натиснете ли ''Отказ'', ще бъде запазена текущата версия.
+
diff --git a/inc/lang/bg/denied.txt b/inc/lang/bg/denied.txt
new file mode 100644
index 000000000..45ce63769
--- /dev/null
+++ b/inc/lang/bg/denied.txt
@@ -0,0 +1,4 @@
+====== Отказан достъп ======
+
+Нямате достатъчно права, за да продължите. Може би сте забравили да се впишете?
+
diff --git a/inc/lang/bg/diff.txt b/inc/lang/bg/diff.txt
new file mode 100644
index 000000000..a22031e93
--- /dev/null
+++ b/inc/lang/bg/diff.txt
@@ -0,0 +1,3 @@
+====== Разлики ======
+
+Тук са показани разликите между избраната и текущата версия на страницата.
diff --git a/inc/lang/bg/draft.txt b/inc/lang/bg/draft.txt
new file mode 100644
index 000000000..a59201130
--- /dev/null
+++ b/inc/lang/bg/draft.txt
@@ -0,0 +1,6 @@
+====== Намерена чернова ======
+
+Последната редакционна сесия на страницата не е завършена правилно. Dokuwiki автоматично запазва чернова по време на редактирането, която можете да ползвате сега, за да продължите работата си. Отдолу може да видите данните, които бяха запазени от последната сесия.
+
+Моля решете, дали искате да //възстановите// последната си редакционна сесия, //изтриете// автоматично запазената чернова или //откажете// редакцията.
+
diff --git a/inc/lang/bg/edit.txt b/inc/lang/bg/edit.txt
new file mode 100644
index 000000000..086d9978e
--- /dev/null
+++ b/inc/lang/bg/edit.txt
@@ -0,0 +1,2 @@
+Редактирайте и натиснете ''Запис''. За информация относно ползвания синтаксис прочетете [[wiki:syntax]]. Моля, редактирайте само когато може да **подобрите** съдържанието. Ако ще пробвате разни неща, може да експериментирате в [[playground:playground|пясъчника]].
+
diff --git a/inc/lang/bg/editrev.txt b/inc/lang/bg/editrev.txt
new file mode 100644
index 000000000..ba97f253a
--- /dev/null
+++ b/inc/lang/bg/editrev.txt
@@ -0,0 +1,2 @@
+**Заредена е стара версия на документа!** Ако я запазите, ще създадете нова версия с текущите данни.
+----
diff --git a/inc/lang/bg/index.txt b/inc/lang/bg/index.txt
new file mode 100644
index 000000000..7dabac6af
--- /dev/null
+++ b/inc/lang/bg/index.txt
@@ -0,0 +1,4 @@
+====== Индекс ======
+
+Това е списък на всички налични страници подредени по [[doku>namespaces|именни пространства]].
+
diff --git a/inc/lang/bg/install.html b/inc/lang/bg/install.html
new file mode 100644
index 000000000..44f02f4c2
--- /dev/null
+++ b/inc/lang/bg/install.html
@@ -0,0 +1,15 @@
+<p>Страницата помага при инсталиране за първи път и настройване на
+<a href="http://dokuwiki.org">Dokuwiki</a>. Повече информация
+за инсталатора ще намерите в <a href="http://dokuwiki.org/installer">документацията му</a>.</p>
+
+<p>Dokuwiki ползва обикновени файлове за съхраняване на страниците и информацията свързана с тях (примерно картинки, търсения, стари версии, и др.).
+За да функционира нормално DokuWiki
+<strong>трябва</strong> да има право за писане в директориите, които съдържат тези
+файлове. Инсталаторът не може да настройва правата на директориите.
+Вие трябва да направите това директно от командният ред или ако ползвате хостинг през FTP или контролния панела на хоста (примерно cPanel).</p>
+
+<p>Инсталаторът ще настрои вашата DokuWiki конфигурация на
+<acronym title="списъка за достъп">ACL</acronym>, което ще позволи на администратора да се впише и ползва администраторското меню в DokuWiki за инсталиране на приставки, контрол на потребителите, управление на достъпа до страниците и промяна на останалите настройки. Това не е необходимо за функционирането на DokuWiki, но прави администрирането по-лесно.</p>
+
+<p>Опитните потребители и потребителите със специални изисквания към настройките имат на разположение допълнителна информация относно <a href="http://dokuwiki.org/install">инсталирането</a>
+и <a href="http://dokuwiki.org/config">настройването</a>.</p>
diff --git a/inc/lang/bg/lang.php b/inc/lang/bg/lang.php
new file mode 100644
index 000000000..b21fed9af
--- /dev/null
+++ b/inc/lang/bg/lang.php
@@ -0,0 +1,311 @@
+<?php
+/**
+ * Bulgarian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Редактиране';
+$lang['btn_source'] = 'Преглед на кода';
+$lang['btn_show'] = 'Преглед на страницата';
+$lang['btn_create'] = 'Създаване на страница';
+$lang['btn_search'] = 'Търсене';
+$lang['btn_save'] = 'Запис';
+$lang['btn_preview'] = 'Преглед';
+$lang['btn_top'] = 'Към началото';
+$lang['btn_newer'] = '<< по-нови';
+$lang['btn_older'] = 'по-стари >>';
+$lang['btn_revs'] = 'История';
+$lang['btn_recent'] = 'Скорошни промени';
+$lang['btn_upload'] = 'Качване';
+$lang['btn_cancel'] = 'Отказ';
+$lang['btn_index'] = 'Индекс';
+$lang['btn_secedit'] = 'Редактиране';
+$lang['btn_login'] = 'Вписване';
+$lang['btn_logout'] = 'Отписване';
+$lang['btn_admin'] = 'Настройки';
+$lang['btn_update'] = 'Актуализиране';
+$lang['btn_delete'] = 'Изтриване';
+$lang['btn_back'] = 'Назад';
+$lang['btn_backlink'] = 'Обратни препратки';
+$lang['btn_backtomedia'] = 'Назад към избора на файл';
+$lang['btn_subscribe'] = 'Абонаменти';
+$lang['btn_profile'] = 'Профил';
+$lang['btn_reset'] = 'Изчистване';
+$lang['btn_resendpwd'] = 'Пращане на нова парола';
+$lang['btn_draft'] = 'Редактиране на чернова';
+$lang['btn_recover'] = 'Възстановяване на чернова';
+$lang['btn_draftdel'] = 'Изтриване на чернова';
+$lang['btn_revert'] = 'Възстановяване';
+$lang['btn_register'] = 'Регистриране';
+$lang['btn_apply'] = 'Прилагане';
+$lang['btn_media'] = 'Диспечер на файлове';
+$lang['loggedinas'] = 'Вписани сте като';
+$lang['user'] = 'Потребител';
+$lang['pass'] = 'Парола';
+$lang['newpass'] = 'Нова парола';
+$lang['oldpass'] = 'Потвърждение на текуща парола';
+$lang['passchk'] = 'още веднъж';
+$lang['remember'] = 'Запомни ме';
+$lang['fullname'] = 'Истинско име';
+$lang['email'] = 'Електронна поща';
+$lang['profile'] = 'Потребителски профил';
+$lang['badlogin'] = 'Грешно потребителско име или парола.';
+$lang['minoredit'] = 'Незначителни промени';
+$lang['draftdate'] = 'Черновата е автоматично записана на';
+$lang['nosecedit'] = 'Страницата бе междувременно променена, презареждане на страницата поради неактуална информация.';
+$lang['regmissing'] = 'Моля, попълнете всички полета.';
+$lang['reguexists'] = 'Вече съществува потребител с избраното име.';
+$lang['regsuccess'] = 'Потребителят е създаден, а паролата е пратена по електронната поща.';
+$lang['regsuccess2'] = 'Потребителят е създаден.';
+$lang['regmailfail'] = 'Изглежда, че има проблем с пращането на писмото с паролата. Моля, свържете се с администратора!';
+$lang['regbadmail'] = 'Въведеният адрес изглежда невалиден - ако мислите, че това е грешка, свържете се с администратора.';
+$lang['regbadpass'] = 'Двете въведени пароли не съвпадат, моля опитайте отново.';
+$lang['regpwmail'] = 'Паролата ви за DokuWiki';
+$lang['reghere'] = 'Все още нямате профил? Направете си';
+$lang['profna'] = 'Wiki-то не поддържа промяна на профила';
+$lang['profnochange'] = 'Няма промени.';
+$lang['profnoempty'] = 'Въвеждането на име и ел. поща е задължително';
+$lang['profchanged'] = 'Потребителският профил е обновен успешно.';
+$lang['pwdforget'] = 'Забравили сте паролата си? Получете нова';
+$lang['resendna'] = 'Wiki-то не поддържа повторно пращане на паролата.';
+$lang['resendpwd'] = 'Изпращане на нова парола за';
+$lang['resendpwdmissing'] = 'Моля, попълнете всички полета.';
+$lang['resendpwdnouser'] = 'Потребителят не е намерен в базата от данни.';
+$lang['resendpwdbadauth'] = 'Кодът за потвърждение е невалиден. Проверете дали сте използвали целия линк за потвърждение.';
+$lang['resendpwdconfirm'] = 'Линк за потвърждение е пратен по електронната поща.';
+$lang['resendpwdsuccess'] = 'Новата ви паролата е пратена по електронната поща.';
+$lang['license'] = 'Ако не е посочено друго, съдържанието на Wiki-то е лицензирано под следния лиценз:';
+$lang['licenseok'] = 'Бележка: Редактирайки страницата, вие се съгласявате да лицензирате промените (които сте направили) под следния лиценз:';
+$lang['searchmedia'] = 'Търсене на файл: ';
+$lang['searchmedia_in'] = 'Търсене в %s';
+$lang['txt_upload'] = 'Изберете файл за качване';
+$lang['txt_filename'] = 'Качи като (незадължително)';
+$lang['txt_overwrt'] = 'Презапиши съществуващите файлове';
+$lang['lockedby'] = 'В момента е заключена от';
+$lang['lockexpire'] = 'Ще бъде отключена на';
+$lang['js']['willexpire'] = 'Страницата ще бъде отключена за редактиране след минута.\nЗа предотвратяване на конфликти, ползвайте бутона "Преглед", за рестартиране на брояча за заключване.';
+$lang['js']['notsavedyet'] = 'Незаписаните промени ще бъдат загубени. Желаете ли да продължите?';
+$lang['js']['searchmedia'] = 'Търсене на файлове';
+$lang['js']['keepopen'] = 'Без затваряне на прозореца след избор';
+$lang['js']['hidedetails'] = 'Без подробности';
+$lang['js']['mediatitle'] = 'Настройки на препратката';
+$lang['js']['mediadisplay'] = 'Тип на препратката';
+$lang['js']['mediaalign'] = 'Подреждане';
+$lang['js']['mediasize'] = 'Размер на изображението';
+$lang['js']['mediatarget'] = 'Препращане към';
+$lang['js']['mediaclose'] = 'Затваряне';
+$lang['js']['mediainsert'] = 'Вмъкване';
+$lang['js']['mediadisplayimg'] = 'Показвай изображението.';
+$lang['js']['mediadisplaylnk'] = 'Показвай само препратката.';
+$lang['js']['mediasmall'] = 'Малка версия';
+$lang['js']['mediamedium'] = 'Средна версия';
+$lang['js']['medialarge'] = 'Голяма версия';
+$lang['js']['mediaoriginal'] = 'Оригинална версия';
+$lang['js']['medialnk'] = 'Препратка към подробна страница';
+$lang['js']['mediadirect'] = 'Директна препратка към оригинала';
+$lang['js']['medianolnk'] = 'Без препратка';
+$lang['js']['medianolink'] = 'Без препратка към изображението';
+$lang['js']['medialeft'] = 'Подреди изображението отляво.';
+$lang['js']['mediaright'] = 'Подреди изображението отдясно.';
+$lang['js']['mediacenter'] = 'Подреди изображението по средата.';
+$lang['js']['medianoalign'] = 'Без подреждане.';
+$lang['js']['nosmblinks'] = 'Връзките към Windows shares работят само под Internet Explorer.
+Можете да копирате и поставите връзката.';
+$lang['js']['linkwiz'] = 'Помощник за препратки';
+$lang['js']['linkto'] = 'Препратка към: ';
+$lang['js']['del_confirm'] = 'Да бъдат ли изтрити избраните елементи?';
+$lang['js']['restore_confirm'] = 'Наистина ли желаете да бъде възстановена тази версия?';
+$lang['js']['media_diff'] = 'Преглед на разликите:';
+$lang['js']['media_diff_both'] = 'Един до друг';
+$lang['js']['media_diff_opacity'] = 'Наслагване (и прозиране)';
+$lang['js']['media_diff_portions'] = 'По половинка';
+$lang['js']['media_select'] = 'Изберете файлове...';
+$lang['js']['media_upload_btn'] = 'Качване';
+$lang['js']['media_done_btn'] = 'Готово';
+$lang['js']['media_drop'] = 'Влачете и пуснете файливе тук, за да бъдат качени';
+$lang['js']['media_cancel'] = 'премахване';
+$lang['js']['media_overwrt'] = 'Презапиши съществуващите файлове';
+$lang['rssfailed'] = 'Възникна грешка при получаването на емисията: ';
+$lang['nothingfound'] = 'Нищо не е открито.';
+$lang['mediaselect'] = 'Файлове';
+$lang['fileupload'] = 'Качване на файлове';
+$lang['uploadsucc'] = 'Качването е успешно';
+$lang['uploadfail'] = 'Качването се провали. Може би поради грешни права?';
+$lang['uploadwrong'] = 'Качването е отказано. Файлово разширение е забранено!';
+$lang['uploadexist'] = 'Файлът вече съществува. Нищо не е направено.';
+$lang['uploadbadcontent'] = 'Каченото съдържание не съответства на файлово разширение %s .';
+$lang['uploadspam'] = 'Качването е блокирано от SPAM списъка.';
+$lang['uploadxss'] = 'Качването е блокирано, поради възможно зловредно съдържание.';
+$lang['uploadsize'] = 'Файлът за качване е прекалено голям. (макс. %s)';
+$lang['deletesucc'] = 'Файлът "%s" бе изтрит.';
+$lang['deletefail'] = '"%s" не може да бъде изтрит - проверете правата.';
+$lang['mediainuse'] = 'Файлът "%s" не бе изтрит - все още се ползва.';
+$lang['namespaces'] = 'Именни пространства';
+$lang['mediafiles'] = 'Налични файлове в';
+$lang['accessdenied'] = 'Нямате разрешение да преглеждате страницата.';
+$lang['mediausage'] = 'Ползвайте следния синтаксис, за да упоменете файла:';
+$lang['mediaview'] = 'Преглед на оригиналния файл';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Качете файл в текущото именно пространство. За създаване на подимено пространство, добавете име преди това на файла като ги разделите с двоеточие в полето "Качи като"';
+$lang['mediaextchange'] = 'Разширението на файла е сменено от .%s на .%s!';
+$lang['reference'] = 'Връзки за';
+$lang['ref_inuse'] = 'Файлът не може да бъде изтрит, защото все още се ползва от следните страници:';
+$lang['ref_hidden'] = 'Някои връзки са към страници, които нямате права да четете';
+$lang['hits'] = 'Съвпадения';
+$lang['quickhits'] = 'Съвпадащи имена на страници';
+$lang['toc'] = 'Съдържание';
+$lang['current'] = 'текуща';
+$lang['yours'] = 'Вашата версия';
+$lang['diff'] = 'Преглед на разликите с текущата версия';
+$lang['diff2'] = 'Показване на разликите между избрани версии';
+$lang['difflink'] = 'Препратка към сравнението на версиите';
+$lang['diff_type'] = 'Преглед на разликите:';
+$lang['diff_inline'] = 'Вграден';
+$lang['diff_side'] = 'Един до друг';
+$lang['line'] = 'Ред';
+$lang['breadcrumb'] = 'Следа';
+$lang['youarehere'] = 'Намирате се в';
+$lang['lastmod'] = 'Последна промяна';
+$lang['by'] = 'от';
+$lang['deleted'] = 'изтрита';
+$lang['created'] = 'създадена';
+$lang['restored'] = 'възстановена предишна версия';
+$lang['external_edit'] = 'външна редакция';
+$lang['summary'] = 'Обобщение';
+$lang['noflash'] = 'Необходим е <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> за изобразяване на съдържанието.';
+$lang['download'] = 'Изтегляне на фрагмент';
+$lang['mail_newpage'] = 'добавена страница: ';
+$lang['mail_changed'] = 'променена страница: ';
+$lang['mail_subscribe_list'] = 'променени страници в именно пространство: ';
+$lang['mail_new_user'] = 'нов потребител: ';
+$lang['mail_upload'] = 'качен файл: ';
+$lang['changes_type'] = 'Преглед на променените';
+$lang['pages_changes'] = 'Страници';
+$lang['media_changes'] = 'Файлове';
+$lang['both_changes'] = 'Страници и файлове';
+$lang['qb_bold'] = 'Удебелен текст';
+$lang['qb_italic'] = 'Курсив текст';
+$lang['qb_underl'] = 'Подчертан текст';
+$lang['qb_code'] = 'Код';
+$lang['qb_strike'] = 'Зачеркнат текст';
+$lang['qb_h1'] = 'Заглавие от 1 ниво';
+$lang['qb_h2'] = 'Заглавие от 2 ниво';
+$lang['qb_h3'] = 'Заглавие от 3 ниво';
+$lang['qb_h4'] = 'Заглавие от 4 ниво';
+$lang['qb_h5'] = 'Заглавие от 5 ниво';
+$lang['qb_h'] = 'Заглавие';
+$lang['qb_hs'] = 'Изберете заглавие';
+$lang['qb_hplus'] = 'Надзаглавие';
+$lang['qb_hminus'] = 'Подзаглавие';
+$lang['qb_hequal'] = 'Заглавие от същото ниво';
+$lang['qb_link'] = 'Вътрешна препратка';
+$lang['qb_extlink'] = 'Външна препратка';
+$lang['qb_hr'] = 'Хоризонтална линия';
+$lang['qb_ol'] = 'Номериран списък';
+$lang['qb_ul'] = 'Неномериран списък';
+$lang['qb_media'] = 'Добавяне на изображения и други файлове';
+$lang['qb_sig'] = 'Вмъкване на подпис';
+$lang['qb_smileys'] = 'Усмивчици';
+$lang['qb_chars'] = 'Специални знаци';
+$lang['upperns'] = 'към майчиното именно пространство';
+$lang['admin_register'] = 'Добавяне на нов потребител';
+$lang['metaedit'] = 'Редактиране на метаданни';
+$lang['metasaveerr'] = 'Записването на метаданните се провали';
+$lang['metasaveok'] = 'Метаданните са запазени успешно';
+$lang['img_backto'] = 'Назад към';
+$lang['img_title'] = 'Заглавие';
+$lang['img_caption'] = 'Надпис';
+$lang['img_date'] = 'Дата';
+$lang['img_fname'] = 'Име на файла';
+$lang['img_fsize'] = 'Размер';
+$lang['img_artist'] = 'Фотограф';
+$lang['img_copyr'] = 'Авторско право';
+$lang['img_format'] = 'Формат';
+$lang['img_camera'] = 'Фотоапарат';
+$lang['img_keywords'] = 'Ключови думи';
+$lang['img_width'] = 'Ширина';
+$lang['img_height'] = 'Височина';
+$lang['img_manager'] = 'Преглед в диспечера на файлове';
+$lang['subscr_subscribe_success'] = '%s е добавен към списъка с абониралите се за %s';
+$lang['subscr_subscribe_error'] = 'Грешка при добавянето на %s към списъка с абониралите се за %s';
+$lang['subscr_subscribe_noaddress'] = 'Добавянето ви към списъка с абонати не е възможно поради липсата на свързан адрес (на ел. поща) с профила ви.';
+$lang['subscr_unsubscribe_success'] = '%s е премахнат от списъка с абониралите се за %s';
+$lang['subscr_unsubscribe_error'] = 'Грешка при премахването на %s от списъка с абониралите се за %s';
+$lang['subscr_already_subscribed'] = '%s е вече абониран за %s';
+$lang['subscr_not_subscribed'] = '%s не е абониран за %s';
+$lang['subscr_m_not_subscribed'] = 'Не сте абониран за текущата страницата или именно пространство.';
+$lang['subscr_m_new_header'] = 'Добави абонамент';
+$lang['subscr_m_current_header'] = 'Текущи абонаменти';
+$lang['subscr_m_unsubscribe'] = 'Прекратяване на абонамента';
+$lang['subscr_m_subscribe'] = 'Абониране';
+$lang['subscr_m_receive'] = 'Получаване';
+$lang['subscr_style_every'] = 'на ел. писмо при всяка промяна';
+$lang['subscr_style_digest'] = 'на ел. писмо с обобщение на промените във всяка страница (всеки %.2f дни)';
+$lang['subscr_style_list'] = 'на списък с променените страници от последното ел. писмо (всеки %.2f дни)';
+$lang['authmodfailed'] = 'Лоша настройки за удостоверяване. Моля, уведомете администратора на Wiki страницата.';
+$lang['authtempfail'] = 'Удостоверяването на потребители не е възможно за момента. Ако продължи дълго, моля уведомете администратора на Wiki страницата.';
+$lang['i_chooselang'] = 'Изберете вашия изик';
+$lang['i_installer'] = 'Инсталатор на DokuWiki';
+$lang['i_wikiname'] = 'Име на Wiki-то';
+$lang['i_enableacl'] = 'Ползване на списък за достъп (ACL) [препоръчително]';
+$lang['i_superuser'] = 'Супер потребител';
+$lang['i_problems'] = 'Открити са проблеми, които възпрепятстват инсталирането. Ще можете да продължите след като отстраните долуизброените проблеми.';
+$lang['i_modified'] = 'Поради мерки за сигурност инсталаторът работи само с нови и непроменени инсталационни файлове. Трябва да разархивирате отново файловете от сваления архив или да се посъветвате с <a href="http://dokuwiki.org/install">Инструкциите за инсталиране на Dokuwiki</a>.';
+$lang['i_funcna'] = 'PHP функцията <code>%s</code> не е достъпна. Може би е забранена от доставчика на хостинг.';
+$lang['i_phpver'] = 'Инсталираната версия <code>%s</code> на PHP е по-стара от необходимата <code>%s</code>. Актуализирайте PHP инсталацията.';
+$lang['i_permfail'] = '<code>%s</code> не е достъпна за писане от DokuWiki. Трябва да промените правата за достъп до директорията!';
+$lang['i_confexists'] = '<code>%s</code> вече съществува';
+$lang['i_writeerr'] = '<code>%s</code> не можа да бъде създаден. Трябва да проверите правата за достъп до директорията/файла и да създадете файла ръчно.';
+$lang['i_badhash'] = 'Файлът dokuwiki.php не може да бъде разпознат или е променен (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - непозволена или празна стойност';
+$lang['i_success'] = 'Настройването приключи успешно. Вече можете да изтриете файла install.php. Продължете към <a href="doku.php">Вашето ново DokuWiki</a>.';
+$lang['i_failure'] = 'Възникнаха грешки при записването на файловете с настройки. Вероятно ще се наложи да ги поправите ръчно, за да можете да ползвате <a href="doku.php">Вашето ново DokuWiki</a>.';
+$lang['i_policy'] = 'Първоначална политика за достъп';
+$lang['i_pol0'] = 'Отворено Wiki (всеки може да чете, пише и качва)';
+$lang['i_pol1'] = 'Публично Wiki (всеки може да чете, само регистрирани пишат и качват)';
+$lang['i_pol2'] = 'Затворено Wiki (само регистрирани четат, пишат и качват)';
+$lang['i_retry'] = 'Повторен опит';
+$lang['i_license'] = 'Моля, изберете лиценз под който желаете да публикувате съдържанието:';
+$lang['recent_global'] = 'В момента преглеждате промените в именно пространство <b>%s</b>. Може да прегледате и <a href="%s">промените в цялото Wiki</a>.';
+$lang['years'] = 'преди %d години';
+$lang['months'] = 'преди %d месеца';
+$lang['weeks'] = 'преди %d седмици';
+$lang['days'] = 'преди %d дни';
+$lang['hours'] = 'преди %d часа';
+$lang['minutes'] = 'преди %d минути';
+$lang['seconds'] = 'преди %d секунди';
+$lang['wordblock'] = 'Направените от вас промени не са съхранени, защото съдържат забранен текст (SPAM).';
+$lang['media_uploadtab'] = 'Качване';
+$lang['media_searchtab'] = 'Търсене';
+$lang['media_file'] = 'Файл';
+$lang['media_viewtab'] = 'Преглед';
+$lang['media_edittab'] = 'Редактиране';
+$lang['media_historytab'] = 'История';
+$lang['media_list_thumbs'] = 'Миниатюри';
+$lang['media_list_rows'] = 'Редове';
+$lang['media_sort_name'] = 'Име';
+$lang['media_sort_date'] = 'Дата';
+$lang['media_namespaces'] = 'Изберете:';
+$lang['media_files'] = 'Файлове в %s';
+$lang['media_upload'] = 'Качване в %s';
+$lang['media_search'] = 'Търсене в %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s в %s';
+$lang['media_edit'] = 'Редактиране на %s';
+$lang['media_history'] = 'История на %s';
+$lang['media_meta_edited'] = 'редактиране на метаданните';
+$lang['media_perm_read'] = 'За съжаление нямате достатъчно права, за да можете да прочетете файла.';
+$lang['media_perm_upload'] = 'За съжаление нямате достатъчно права, за да можете да качите файла.';
+$lang['media_update'] = 'Качване на нова версия';
+$lang['media_restore'] = 'Възстановяване на тази версия';
+$lang['plugin_install_err'] = 'Неправилно инсталирана приставка. Моля, преименувайте директорията \'%s\' на \'%s\'.';
diff --git a/inc/lang/bg/locked.txt b/inc/lang/bg/locked.txt
new file mode 100644
index 000000000..7cdfba786
--- /dev/null
+++ b/inc/lang/bg/locked.txt
@@ -0,0 +1,3 @@
+====== Страницата е заключена ======
+
+В момента страницата е заключена за редактиране от друг потребител. Трябва да изчакате потребителя да приключи с редактирането на страницата или автоматичното отключване на страницата.
diff --git a/inc/lang/bg/login.txt b/inc/lang/bg/login.txt
new file mode 100644
index 000000000..e5061c3d3
--- /dev/null
+++ b/inc/lang/bg/login.txt
@@ -0,0 +1,3 @@
+====== Вписване ======
+
+Не сте се вписали! Въведете данните си за удостоверяване отдолу, за да го направите. Бисквитките (cookies) трябва да са включени.
diff --git a/inc/lang/bg/mailtext.txt b/inc/lang/bg/mailtext.txt
new file mode 100644
index 000000000..ad0024a8d
--- /dev/null
+++ b/inc/lang/bg/mailtext.txt
@@ -0,0 +1,16 @@
+Страница във DokuWiki е добавена или променена. Ето детайлите:
+
+Дата : @DATE@
+Браузър : @BROWSER@
+IP адрес : @IPADDRESS@
+Име на хоста : @HOSTNAME@
+Стара версия: @OLDPAGE@
+Нова версия: @NEWPAGE@
+Обобщение: @SUMMARY@
+Потребител : @USER@
+
+@DIFF@
+
+
+--
+Писмото е генерирано от DokuWiki на адрес @DOKUWIKIURL@
diff --git a/inc/lang/bg/newpage.txt b/inc/lang/bg/newpage.txt
new file mode 100644
index 000000000..22d3bb6d1
--- /dev/null
+++ b/inc/lang/bg/newpage.txt
@@ -0,0 +1,4 @@
+====== Несъществуваща тема ======
+
+Последвали сте препратка към тема, която не съществува. Ако правата ви позволяват, може да я създадете чрез бутона ''Създаване на страница''.
+
diff --git a/inc/lang/bg/norev.txt b/inc/lang/bg/norev.txt
new file mode 100644
index 000000000..fb7aeef89
--- /dev/null
+++ b/inc/lang/bg/norev.txt
@@ -0,0 +1,4 @@
+====== Няма такава версия ======
+
+Избраната версия не съществува. Натиснете бутона ''История'' за отваряне на списъка със стари версии на документа.
+
diff --git a/inc/lang/bg/password.txt b/inc/lang/bg/password.txt
new file mode 100644
index 000000000..7a70ef1d8
--- /dev/null
+++ b/inc/lang/bg/password.txt
@@ -0,0 +1,9 @@
+Здравейте @FULLNAME@!
+
+Вашите потребителски данни за @TITLE@ на @DOKUWIKIURL@
+
+Потребител : @LOGIN@
+Парола : @PASSWORD@
+
+--
+Писмото е генерирано от DokuWiki на адрес @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/bg/preview.txt b/inc/lang/bg/preview.txt
new file mode 100644
index 000000000..41fde7380
--- /dev/null
+++ b/inc/lang/bg/preview.txt
@@ -0,0 +1,3 @@
+====== Преглед ======
+
+Ето как ще изглежда страницата. Текста все още **не е запазен**! \ No newline at end of file
diff --git a/inc/lang/bg/pwconfirm.txt b/inc/lang/bg/pwconfirm.txt
new file mode 100644
index 000000000..802153fd4
--- /dev/null
+++ b/inc/lang/bg/pwconfirm.txt
@@ -0,0 +1,13 @@
+Здравейте @FULLNAME@!
+
+Някой е поискал нова парола за потребител @TITLE@
+на @DOKUWIKIURL@
+
+Ако не сте поискали нова парола, тогава просто игнорирайте това писмо.
+
+За да потвърдите, че искането е наистина от вас, моля ползвайте следния линк:
+
+@CONFIRM@
+
+--
+Писмото е генерирано от DokuWiki на адрес @DOKUWIKIURL@
diff --git a/inc/lang/bg/read.txt b/inc/lang/bg/read.txt
new file mode 100644
index 000000000..861d47fc5
--- /dev/null
+++ b/inc/lang/bg/read.txt
@@ -0,0 +1,2 @@
+Страницата е само за четене. Може да разглеждате кода, но не и да го променяте. Обърнете се съм администратора, ако смятате, че това не е редно.
+
diff --git a/inc/lang/bg/recent.txt b/inc/lang/bg/recent.txt
new file mode 100644
index 000000000..c92029054
--- /dev/null
+++ b/inc/lang/bg/recent.txt
@@ -0,0 +1,4 @@
+====== Скорошни промени ======
+
+Следните страници са били променени наскоро.
+
diff --git a/inc/lang/bg/register.txt b/inc/lang/bg/register.txt
new file mode 100644
index 000000000..51fbb83fe
--- /dev/null
+++ b/inc/lang/bg/register.txt
@@ -0,0 +1,4 @@
+====== Регистриране като нов потребител ======
+
+Моля, попълнете всичките полета отдолу, за да бъде създаден нов профил. Уверете се, че въведеният **адрес на ел. поща е правилен**. Ако няма поле за парола, ще ви бъде изпратена такава на въведения адрес. Потребителското име трябва да бъде валидно [[doku>pagename|име на страница]].
+
diff --git a/inc/lang/bg/registermail.txt b/inc/lang/bg/registermail.txt
new file mode 100644
index 000000000..4b0828c7b
--- /dev/null
+++ b/inc/lang/bg/registermail.txt
@@ -0,0 +1,13 @@
+Регистриран е нов потребител. Ето детайлите:
+
+Потребител : @NEWUSER@
+Пълно име : @NEWNAME@
+E. поща : @NEWEMAIL@
+
+Дата : @DATE@
+Браузър : @BROWSER@
+IP адрес : @IPADDRESS@
+Име на хоста : @HOSTNAME@
+
+--
+Писмото е генерирано от DokuWiki на адрес @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/bg/resendpwd.txt b/inc/lang/bg/resendpwd.txt
new file mode 100644
index 000000000..38e2d1fe4
--- /dev/null
+++ b/inc/lang/bg/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Пращане на нова парола ======
+
+Моля, въведете потребителското си име във формата по-долу, ако желаете да получите нова парола. По ел. поща ще получите линк, с който да потвърдите.
diff --git a/inc/lang/bg/revisions.txt b/inc/lang/bg/revisions.txt
new file mode 100644
index 000000000..0e14662b7
--- /dev/null
+++ b/inc/lang/bg/revisions.txt
@@ -0,0 +1,4 @@
+====== Стари версии======
+
+Това са старите версии на документа. За да възстановите стара версия, изберете я долу, натиснете ''Редактиране'' и я запазете.
+
diff --git a/inc/lang/bg/searchpage.txt b/inc/lang/bg/searchpage.txt
new file mode 100644
index 000000000..48d47515a
--- /dev/null
+++ b/inc/lang/bg/searchpage.txt
@@ -0,0 +1,5 @@
+====== Търсене ======
+
+Резултата от търсенето ще намерите по-долу. Ако не намирате каквото сте търсили, може да създадете или редактирате страница, кръстена на вашата заявка, чрез съответния бутон.
+
+===== Резултати =====
diff --git a/inc/lang/bg/showrev.txt b/inc/lang/bg/showrev.txt
new file mode 100644
index 000000000..a3848f8bb
--- /dev/null
+++ b/inc/lang/bg/showrev.txt
@@ -0,0 +1,2 @@
+**Това е стара версия на документа!**
+----
diff --git a/inc/lang/bg/stopwords.txt b/inc/lang/bg/stopwords.txt
new file mode 100644
index 000000000..03fd13758
--- /dev/null
+++ b/inc/lang/bg/stopwords.txt
@@ -0,0 +1,29 @@
+# Това е списък с думи за игнориране при индексиране, с една дума на ред
+# Когато редактирате този файл, не забравяйте да използвате UNIX символ за нов ред
+# Не е нужно да включвате думи по-кратки от 3 символа - те биват игнорирани така или иначе
+# Списъкът се основава на думи от http://www.ranks.nl/stopwords/
+about
+are
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/bg/subscr_digest.txt b/inc/lang/bg/subscr_digest.txt
new file mode 100644
index 000000000..f0533daf4
--- /dev/null
+++ b/inc/lang/bg/subscr_digest.txt
@@ -0,0 +1,18 @@
+Здравейте!
+
+Страницата @PAGE@ в @TITLE@ wiki е променена.
+Промените са по-долу:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Стара версия: @OLDPAGE@
+Нова версия: @NEWPAGE@
+
+Ако желаете да прекратите уведомяването за страницата трябва да се впишете на адрес @DOKUWIKIURL@, да посетите
+@SUBSCRIBE@
+и да прекратите абонамента за промени по страницата или именното пространство.
+
+--
+Писмото е генерирано от DokuWiki на адрес @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/bg/subscr_form.txt b/inc/lang/bg/subscr_form.txt
new file mode 100644
index 000000000..e32a5ec26
--- /dev/null
+++ b/inc/lang/bg/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Диспечер на абонаменти ======
+
+Страницата ви позволява да управлявате текущите си абонаменти за страници и именни пространства. \ No newline at end of file
diff --git a/inc/lang/bg/subscr_list.txt b/inc/lang/bg/subscr_list.txt
new file mode 100644
index 000000000..e9e65bc39
--- /dev/null
+++ b/inc/lang/bg/subscr_list.txt
@@ -0,0 +1,15 @@
+Здравейте!
+
+Променени са страници от именното пространство @PAGE@ от @TITLE@ wiki.
+Ето променените страници:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Ако желаете да прекратите уведомяването за страницата трябва да се впишете на адрес @DOKUWIKIURL@, да посетите
+@SUBSCRIBE@
+и да прекратите абонамента за промени по страницата или именното пространство.
+
+--
+Писмото е генерирано от DokuWiki на адрес @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/bg/subscr_single.txt b/inc/lang/bg/subscr_single.txt
new file mode 100644
index 000000000..7b26f8e96
--- /dev/null
+++ b/inc/lang/bg/subscr_single.txt
@@ -0,0 +1,22 @@
+Здравейте!
+
+Страницата @PAGE@ в @TITLE@ wiki е променена.
+Промените са по-долу:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Дата : @DATE@
+Потребител : @USER@
+Обобщение: @SUMMARY@
+Стара версия: @OLDPAGE@
+Нова версия: @NEWPAGE@
+
+Ако желаете да прекратите уведомяването за страницата трябва да се впишете на адрес @DOKUWIKIURL@, да посетите
+@NEWPAGE@
+и да прекратите абонамента за промени по страницата или именното пространство.
+
+--
+Писмото е генерирано от DokuWiki на адрес
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/bg/updateprofile.txt b/inc/lang/bg/updateprofile.txt
new file mode 100644
index 000000000..6113f0d07
--- /dev/null
+++ b/inc/lang/bg/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Обновете профила си ======
+
+Трябва само да допълните полетата, които искате да промените. Потребителското не може да бъде променяно.
diff --git a/inc/lang/bg/uploadmail.txt b/inc/lang/bg/uploadmail.txt
new file mode 100644
index 000000000..ebd8d9112
--- /dev/null
+++ b/inc/lang/bg/uploadmail.txt
@@ -0,0 +1,13 @@
+Качен е файл на вашето DokuWiki. Ето детайлите
+
+Файл : @MEDIA@
+Дата : @DATE@
+Браузър : @BROWSER@
+IP адрес : @IPADDRESS@
+Име на хоста : @HOSTNAME@
+Размер : @SIZE@
+MIME тип : @MIME@
+Потребител : @USER@
+
+--
+Писмото е генерирано от DokuWiki на адрес @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ca-valencia/admin.txt b/inc/lang/ca-valencia/admin.txt
new file mode 100644
index 000000000..628948e86
--- /dev/null
+++ b/inc/lang/ca-valencia/admin.txt
@@ -0,0 +1,4 @@
+====== Administració ======
+
+Avall pot trobar una llista de tasques administratives disponibles en DokuWiki.
+
diff --git a/inc/lang/ca-valencia/adminplugins.txt b/inc/lang/ca-valencia/adminplugins.txt
new file mode 100644
index 000000000..6c5c4f90d
--- /dev/null
+++ b/inc/lang/ca-valencia/adminplugins.txt
@@ -0,0 +1 @@
+===== Plúgins adicionals ===== \ No newline at end of file
diff --git a/inc/lang/ca-valencia/backlinks.txt b/inc/lang/ca-valencia/backlinks.txt
new file mode 100644
index 000000000..06a1106f6
--- /dev/null
+++ b/inc/lang/ca-valencia/backlinks.txt
@@ -0,0 +1,3 @@
+====== Vínculs remitents ======
+
+Una llista de pàgines que pareixen vincular a la pàgina actual. \ No newline at end of file
diff --git a/inc/lang/ca-valencia/conflict.txt b/inc/lang/ca-valencia/conflict.txt
new file mode 100644
index 000000000..67319612d
--- /dev/null
+++ b/inc/lang/ca-valencia/conflict.txt
@@ -0,0 +1,6 @@
+====== Ya existix una versió més nova ======
+
+Existix una versió més nova del document que ha editat. Açò ha passat perque un atre usuari ha modificat el document mentres vosté estava editant-lo.
+
+Estudie be les diferències mostrades avall i decidixca quina versió vol guardar. Si pulsa ''Guardar'' es guardarà la versió que està editant. Pulse ''Cancelar'' per a conservar la versió modificada per l'atre usuari..
+
diff --git a/inc/lang/ca-valencia/denied.txt b/inc/lang/ca-valencia/denied.txt
new file mode 100644
index 000000000..39c45d946
--- /dev/null
+++ b/inc/lang/ca-valencia/denied.txt
@@ -0,0 +1,4 @@
+====== Permís denegat ======
+
+Disculpe, pero no té permís per a continuar. ¿Haurà oblidat iniciar sessió?
+
diff --git a/inc/lang/ca-valencia/diff.txt b/inc/lang/ca-valencia/diff.txt
new file mode 100644
index 000000000..2b5c60e1c
--- /dev/null
+++ b/inc/lang/ca-valencia/diff.txt
@@ -0,0 +1,4 @@
+====== Diferències ======
+
+Ací es mostren les diferències entre dos versions de la pàgina.
+
diff --git a/inc/lang/ca-valencia/draft.txt b/inc/lang/ca-valencia/draft.txt
new file mode 100644
index 000000000..e7e814a69
--- /dev/null
+++ b/inc/lang/ca-valencia/draft.txt
@@ -0,0 +1,6 @@
+====== Borrador trobat ======
+
+L'última edició d'esta pàgina no es completà correctament. DokuWiki guarda automàticament un borrador que ara pot recuperar per a continuar editant. Avall pot vore la data en que es guardà l'últim borrador.
+
+Per favor, decidixca si vol //recuperar// la sessió que pergué, //borrar// el borrador o //cancelar// esta edició.
+
diff --git a/inc/lang/ca-valencia/edit.txt b/inc/lang/ca-valencia/edit.txt
new file mode 100644
index 000000000..e1ca6bf23
--- /dev/null
+++ b/inc/lang/ca-valencia/edit.txt
@@ -0,0 +1,2 @@
+Edite la pàgina i pulse 'Guardar". Consulte la [[wiki:syntax|Sintaxis]] del Wiki. Per favor, edite la pàgina només **si pot millorar-la**. Si vol fer proves, deprenga a utilisar el Wiki en el [[playground:playground|espai de proves]].
+
diff --git a/inc/lang/ca-valencia/editrev.txt b/inc/lang/ca-valencia/editrev.txt
new file mode 100644
index 000000000..99188a0e9
--- /dev/null
+++ b/inc/lang/ca-valencia/editrev.txt
@@ -0,0 +1,2 @@
+**¡Ha carregat una versió antiga del document!** Si la guarda crearà una nova versió en el contingut d'esta.
+----
diff --git a/inc/lang/ca-valencia/index.txt b/inc/lang/ca-valencia/index.txt
new file mode 100644
index 000000000..5e57c1680
--- /dev/null
+++ b/inc/lang/ca-valencia/index.txt
@@ -0,0 +1,4 @@
+====== Índex ======
+
+Un índex de totes les pàgines disponibles ordenades per [[doku>namespaces|espais de noms]].
+
diff --git a/inc/lang/ca-valencia/install.html b/inc/lang/ca-valencia/install.html
new file mode 100644
index 000000000..eb77cd648
--- /dev/null
+++ b/inc/lang/ca-valencia/install.html
@@ -0,0 +1,11 @@
+<p>Esta pàgina l'ajudarà en la primera instalació i configuració de <a href="http://dokuwiki.org">Dokuwiki</a>. N'hi ha més informació de l'instalador disponible en la
+<a href="http://dokuwiki.org/installer">pàgina de documentació</a>.</p>
+
+<p>DokuWiki utilisa archius corrents per a l'almagasenament de les pàgines del wiki i atra informació associada ad estes pàgines (p. e. imàgens, índexs de busca, versions antigues, etc.). Per a que DokuWiki funcione correctament
+<strong>deu</strong> tindre accés d'escritura als directoris que contenen estos archius. Est instalador no pot ajustar els permissos del directori. Normalment haurà de fer-ho directament en una consola de del sistema o, si utilisa un hostage, per FTP o en el panel de control (p. e. cPanel).</p>
+
+<p>Est instalador configurarà <acronym title="access control list">ACL</acronym> en el seu DokuWiki, que al mateix temps permet l'accés de l'administrador i l'accés al menú d'administració de DokuWiki per a instalar plúgins, gestionar usuaris, gestionar els accessos a les pàgines del wiki i la modificació dels ajusts de configuració. No és necessari per a que DokuWiki funcione, pero farà més fàcil la seua administració.</p>
+
+<p>Els usuaris experimentats o en necessitats especials de configuració deuen utilisar estos vínculs per a informació referent a
+<a href="http://dokuwiki.org/install">instruccions d'instalació</a>
+i <a href="http://dokuwiki.org/config">ajusts de configuració</a>.</p>
diff --git a/inc/lang/ca-valencia/lang.php b/inc/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..6317197ed
--- /dev/null
+++ b/inc/lang/ca-valencia/lang.php
@@ -0,0 +1,231 @@
+<?php
+/**
+ * valencian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bernat Arlandis i Mañó <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Editar esta pàgina';
+$lang['btn_source'] = 'Mostrar font';
+$lang['btn_show'] = 'Mostrar pàgina';
+$lang['btn_create'] = 'Crear esta pàgina';
+$lang['btn_search'] = 'Buscar';
+$lang['btn_save'] = 'Guardar';
+$lang['btn_preview'] = 'Vista prèvia';
+$lang['btn_top'] = 'Tornar dalt';
+$lang['btn_newer'] = '<< més recents';
+$lang['btn_older'] = 'manco recents >>';
+$lang['btn_revs'] = 'Versions antigues';
+$lang['btn_recent'] = 'Canvis recents';
+$lang['btn_upload'] = 'Pujar';
+$lang['btn_cancel'] = 'Cancelar';
+$lang['btn_index'] = 'Índex';
+$lang['btn_secedit'] = 'Editar';
+$lang['btn_login'] = 'Iniciar sessió';
+$lang['btn_logout'] = 'Tancar sessió';
+$lang['btn_admin'] = 'Administrar';
+$lang['btn_update'] = 'Actualisar';
+$lang['btn_delete'] = 'Borrar';
+$lang['btn_back'] = 'Arrere';
+$lang['btn_backlink'] = 'Vínculs remitents';
+$lang['btn_backtomedia'] = 'Tornar a la selecció d\'archius de mijos';
+$lang['btn_subscribe'] = 'Subscriure\'s a la pàgina';
+$lang['btn_unsubscribe'] = 'Desubscriure\'s de la pàgina';
+$lang['btn_profile'] = 'Actualisar perfil';
+$lang['btn_reset'] = 'Reiniciar';
+$lang['btn_resendpwd'] = 'Enviar contrasenya nova';
+$lang['btn_draft'] = 'Editar borrador';
+$lang['btn_recover'] = 'Recuperar borrador';
+$lang['btn_draftdel'] = 'Borrar borrador';
+$lang['btn_revert'] = 'Recuperar';
+$lang['btn_register'] = 'Registrar-se';
+$lang['loggedinas'] = 'Sessió de';
+$lang['user'] = 'Nom d\'usuari';
+$lang['pass'] = 'Contrasenya';
+$lang['newpass'] = 'Contrasenya nova';
+$lang['oldpass'] = 'Confirmar la contrasenya actual';
+$lang['passchk'] = 'una atra volta';
+$lang['remember'] = 'Recorda\'m';
+$lang['fullname'] = 'Nom complet';
+$lang['email'] = 'Correu electrònic';
+$lang['profile'] = 'Perfil d\'usuari';
+$lang['badlogin'] = 'Disculpe, pero el nom d\'usuari o la contrasenya són incorrectes.';
+$lang['minoredit'] = 'Canvis menors';
+$lang['draftdate'] = 'Borrador gravat el';
+$lang['nosecedit'] = 'La pàgina ha canviat mentres tant, l\'informació de la secció no estava al dia, s\'ha carregat la pàgina sancera.';
+$lang['regmissing'] = 'Disculpe, pero deu omplir tots els camps.';
+$lang['reguexists'] = 'Disculpe, pero ya existix un usuari en este nom.';
+$lang['regsuccess'] = 'S\'ha creat l\'usuari i se li ha enviat la contrasenya per correu electrònic.';
+$lang['regsuccess2'] = 'S\'ha creat l\'usuari.';
+$lang['regmailfail'] = 'Pareix que ha hagut un erro enviant el correu en la contrasenya. ¡Per favor, contacte en l\'administrador!';
+$lang['regbadmail'] = 'La direcció de correu no pareix vàlida - contacte en l\'administrador si pensa que és deu a un erro nostre';
+$lang['regbadpass'] = 'Les dos contrasenyes que ha donat no són idèntiques, per favor, torne a intentar-ho.';
+$lang['regpwmail'] = 'La seua contrasenya de DokuWiki';
+$lang['reghere'] = '¿Encara no té un conte? Cree-se\'n un';
+$lang['profna'] = 'Este wiki no li permet modificar el perfil';
+$lang['profnochange'] = 'Sense canvis, no hi ha res que fer.';
+$lang['profnoempty'] = 'No es permet deixar el nom o la direcció de correu buits.';
+$lang['profchanged'] = 'Perfil de l\'usuari actualisat.';
+$lang['pwdforget'] = '¿Ha oblidat la contrasenya? Demane\'n una nova';
+$lang['resendna'] = 'Este wiki no permet reenviar la contrasenya.';
+$lang['resendpwd'] = 'Enviar contrasenya nova per a';
+$lang['resendpwdmissing'] = 'Disculpe, pero deu omplir tots els camps.';
+$lang['resendpwdnouser'] = 'Disculpe, pero no trobem ad est usuari en la base de senyes.';
+$lang['resendpwdbadauth'] = 'Disculpe, pero este còdic d\'autenticació no es vàlit. Verifique que haja utilisat el víncul de confirmació sancer.';
+$lang['resendpwdconfirm'] = 'Li hem enviat un víncul de confirmació al correu.';
+$lang['resendpwdsuccess'] = 'Se li ha enviat una nova contrasenya per correu electrònic.';
+$lang['license'] = 'Excepte quan s\'indique una atra cosa, el contingut d\'este wiki està llicenciat baix la següent llicència:';
+$lang['licenseok'] = 'Nota: a l\'editar esta pàgina accepta llicenciar el seu contingut baix la següent llicència:';
+$lang['searchmedia'] = 'Buscar nom d\'archiu:';
+$lang['searchmedia_in'] = 'Buscar en %s';
+$lang['txt_upload'] = 'Seleccione l\'archiu que vol pujar';
+$lang['txt_filename'] = 'Enviar com (opcional)';
+$lang['txt_overwrt'] = 'Sobreescriure archius existents';
+$lang['lockedby'] = 'Actualment bloquejat per';
+$lang['lockexpire'] = 'El bloqueig venç a les';
+$lang['js']['willexpire'] = 'El seu bloqueig per a editar esta pàgina vencerà en un minut.\nPer a evitar conflictes utilise el botó de vista prèvia i reiniciarà el contador.';
+$lang['js']['notsavedyet'] = "Els canvis no guardats es perdran.\n¿Segur que vol continuar?";
+$lang['rssfailed'] = 'Ha ocorregut un erro al solicitar este canal: ';
+$lang['nothingfound'] = 'No s\'ha trobat res.';
+$lang['mediaselect'] = 'Archius de mijos';
+$lang['fileupload'] = 'Enviar archius de mijos';
+$lang['uploadsucc'] = 'Enviament correcte';
+$lang['uploadfail'] = 'Enviament fallit. ¿Potser no tinga els permissos necessaris?';
+$lang['uploadwrong'] = 'Enviament denegat. ¡Esta extensió d\'archiu està prohibida!';
+$lang['uploadexist'] = 'L\'archiu ya existix. No s\'ha fet res.';
+$lang['uploadbadcontent'] = 'El contingut enviat no coincidix en l\'extensió de l\'archiu %s';
+$lang['uploadspam'] = 'L\'enviament ha segut bloquejat per la llista anti-spam.';
+$lang['uploadxss'] = 'L\'enviament ha segut bloquejat per ser possiblement perillós.';
+$lang['uploadsize'] = 'L\'archiu enviat és massa gran. (màx. %s)';
+$lang['deletesucc'] = 'S\'ha borrat l\'archiu "%s".';
+$lang['deletefail'] = 'No s\'ha pogut borrar "%s" - comprove els permissos.';
+$lang['mediainuse'] = 'L\'archiu "%s" no s\'ha borrat - encara s\'està utilisant.';
+$lang['namespaces'] = 'Espais de noms';
+$lang['mediafiles'] = 'Archius disponibles en';
+$lang['js']['searchmedia'] = 'Buscar archius';
+$lang['js']['keepopen'] = 'Mantindre la finestra oberta al seleccionar';
+$lang['js']['hidedetails'] = 'Ocultar detalls';
+$lang['js']['nosmblinks'] = 'Els vínculs a recursos compartits de Windows només funcionen en Microsoft Internet Explorer. No obstant, es poden copiar i apegar.';
+$lang['js']['linkwiz'] = 'Assistent de vínculs';
+$lang['js']['linkto'] = 'Vincular a:';
+$lang['js']['del_confirm'] = '¿Realment vol borrar el(s) ítem(s) seleccionat(s)?';
+$lang['mediausage'] = 'Utilise la següent sintaxis per a referenciar est archiu:';
+$lang['mediaview'] = 'Vore l\'archiu original';
+$lang['mediaroot'] = 'base';
+$lang['mediaupload'] = 'Enviar un archiu a l\'espai de noms actual. Per a crear sub-espais, afigga\'ls separats per dos punts davant del nom de l\'archiu que pose en "Enviar com".';
+$lang['mediaextchange'] = '¡Extensió de l\'archiu canviada de .%s a .%s!';
+$lang['reference'] = 'Referències per a';
+$lang['ref_inuse'] = 'No es pot borrar l\'archiu perque encara s\'utilisa en les següents pàgines:';
+$lang['ref_hidden'] = 'Algunes referències estan en pàgines que no té permissos per a vore';
+$lang['hits'] = 'Encerts';
+$lang['quickhits'] = 'Noms de pàgines coincidents';
+$lang['toc'] = 'Taula de continguts';
+$lang['current'] = 'Actual';
+$lang['yours'] = 'La seua versió';
+$lang['diff'] = 'Mostrar diferències en la versió actual';
+$lang['diff2'] = 'Mostrar diferències entre versions';
+$lang['line'] = 'Llínea';
+$lang['breadcrumb'] = 'Traça';
+$lang['youarehere'] = 'Vosté està ací';
+$lang['lastmod'] = 'Última modificació el';
+$lang['by'] = 'per';
+$lang['deleted'] = 'borrat';
+$lang['created'] = 'creat';
+$lang['restored'] = 'restaurada l\'última versió';
+$lang['external_edit'] = 'edició externa';
+$lang['summary'] = 'Editar sumari';
+$lang['noflash'] = 'Necessita el <a href="http://www.adobe.com/products/flashplayer/">plúgin d\'Adobe Flash</a> per a vore este contingut.';
+$lang['download'] = 'Descarregar un tros';
+$lang['mail_newpage'] = 'pàgina afegida:';
+$lang['mail_changed'] = 'pàgina canviada:';
+$lang['mail_new_user'] = 'Usuari nou:';
+$lang['mail_upload'] = 'archiu enviat:';
+$lang['qb_bold'] = 'Negreta';
+$lang['qb_italic'] = 'Itàlica';
+$lang['qb_underl'] = 'Subrallat';
+$lang['qb_code'] = 'Còdic';
+$lang['qb_strike'] = 'Tachat';
+$lang['qb_h1'] = 'Titular de nivell 1';
+$lang['qb_h2'] = 'Titular de nivell 2';
+$lang['qb_h3'] = 'Titular de nivell 3';
+$lang['qb_h4'] = 'Titular de nivell 4';
+$lang['qb_h5'] = 'Titular de nivell 5';
+$lang['qb_h'] = 'Titular';
+$lang['qb_hs'] = 'Triar titular';
+$lang['qb_hplus'] = 'Titular superior';
+$lang['qb_hminus'] = 'Titular inferior';
+$lang['qb_hequal'] = 'Titular al mateix nivell';
+$lang['qb_link'] = 'Víncul intern';
+$lang['qb_extlink'] = 'Víncul extern';
+$lang['qb_hr'] = 'Llínea horisontal';
+$lang['qb_ol'] = 'Llista numerada';
+$lang['qb_ul'] = 'Llista ';
+$lang['qb_media'] = 'Afegir imàgens i atres archius';
+$lang['qb_sig'] = 'Afegir firma';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Caràcters especials';
+$lang['upperns'] = 'anar a l\'espai de noms superior';
+$lang['admin_register'] = 'Afegir nou usuari';
+$lang['metaedit'] = 'Editar meta-senyes';
+$lang['metasaveerr'] = 'Erro escrivint meta-senyes';
+$lang['metasaveok'] = 'Meta-senyes guardades';
+$lang['img_backto'] = 'Tornar a';
+$lang['img_title'] = 'Títul';
+$lang['img_caption'] = 'Subtítul';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Nom de l\'archiu';
+$lang['img_fsize'] = 'Tamany';
+$lang['img_artist'] = 'Fotógraf';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Càmara';
+$lang['img_keywords'] = 'Paraules clau';
+$lang['subscribe_success'] = '%s afegit a la llista de subscripció per a %s';
+$lang['subscribe_error'] = 'Erro afegint a %s a la llista de subscripció per a %s';
+$lang['subscribe_noaddress'] = 'No hi ha cap direcció associada a la sessió, no es pot subscriure';
+$lang['unsubscribe_success'] = '%s borrat de la llista de subscripció per a %s';
+$lang['unsubscribe_error'] = 'Erro borrant a %s de la llista de subscripció per a %s';
+$lang['authmodfailed'] = 'Mala configuració de l\'autenticació d\'usuari. Per favor, informe a l\'administrador del Wiki.';
+$lang['authtempfail'] = 'L\'autenticació d\'usuaris està desactivada temporalment. Si la situació persistix, per favor, informe a l\'administrador del Wiki.';
+$lang['i_chooselang'] = 'Trie l\'idioma';
+$lang['i_installer'] = 'Instalador de DokuWiki';
+$lang['i_wikiname'] = 'Nom del Wiki';
+$lang['i_enableacl'] = 'Activar ACL (recomanat)';
+$lang['i_superuser'] = 'Super-usuari';
+$lang['i_problems'] = 'L\'instalador ha trobat els problemes mostrats més avall. No pot continuar fins que no els arregle.';
+$lang['i_modified'] = 'Per raons de seguritat, este procés només funcionarà en una instalació nova i verge de DokuWiki.
+Deuria tornar a extraure els archius del paquet que ha descarregat o consultar les
+<a href="http://dokuwiki.org/install">instruccions d\'instalació de Dokuwiki</a> completes';
+$lang['i_funcna'] = 'La funció de PHP <code>%s</code> no està disponible. ¿Pot ser que el seu proveïdor d\'hostage l\'haja desactivada per algun motiu?';
+$lang['i_phpver'] = 'La versió de PHP <code>%s</code> és menor que
+la <code>%s</code> que es necessita. Necessita actualisar PHP.';
+$lang['i_permfail'] = 'DokuWiki no pot escriure en <code>%s</code>. ¡Necessita arreglar els permissos d\'este directori!';
+$lang['i_confexists'] = '<code>%s</code> ya existix';
+$lang['i_writeerr'] = 'No es pot crear <code>%s</code>. Haurà de comprovar els permissos del directori/archiu i crear manualment l\'archiu.';
+$lang['i_badhash'] = 'dokuwiki.php substituït o modificat (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - valor illegal o buit';
+$lang['i_success'] = 'La configuració ha finalisat correctament. Ya pot borrar l\'archiu install.php. Passe al
+<a href="doku.php">nou DokuWiki</a>.';
+$lang['i_failure'] = 'Han aparegut alguns erros escrivint els archius de configuració. Deurà arreglar-los manualment abans de que
+puga utilisar el <a href="doku.php">nou DokuWiki</a>.';
+$lang['i_policy'] = 'Política inicial ACL';
+$lang['i_pol0'] = 'Wiki obert (llegir, escriure i enviar tots)';
+$lang['i_pol1'] = 'Wiki públic (llegir tots, escriure i enviar només usuaris registrats)';
+$lang['i_pol2'] = 'Wiki tancat (llegir, escriure i enviar només usuaris registrats)';
+$lang['i_retry'] = 'Reintentar';
+$lang['recent_global'] = 'Està veent els canvis dins de l\'espai de noms <b>%s</b>. També pot <a href="%s">vore els canvis recents en el wiki sancer</a>.';
+$lang['years'] = 'fa %d anys';
+$lang['months'] = 'fa %d mesos';
+$lang['weeks'] = 'fa %s semanes';
+$lang['days'] = 'fa %d dies';
+$lang['hours'] = 'fa %d hores';
+$lang['minutes'] = 'fa %d minuts';
+$lang['seconds'] = 'fa %d segons';
diff --git a/inc/lang/ca-valencia/locked.txt b/inc/lang/ca-valencia/locked.txt
new file mode 100644
index 000000000..bdb2bdf0e
--- /dev/null
+++ b/inc/lang/ca-valencia/locked.txt
@@ -0,0 +1,3 @@
+====== Pàgina bloquejada ======
+
+Esta pàgina està actualment bloquejada mentres l'edita un atre usuari. Ha d'esperar fins que l'usuari acabe d'editar la pàgina o vença el bloqueig.
diff --git a/inc/lang/ca-valencia/login.txt b/inc/lang/ca-valencia/login.txt
new file mode 100644
index 000000000..b550c6440
--- /dev/null
+++ b/inc/lang/ca-valencia/login.txt
@@ -0,0 +1,4 @@
+====== Inici de sessió ======
+
+¡Encara no ha iniciat sessió! Introduïxca les seues credencials d'autenticació per a iniciar-la. Necessita tindre les galletes del navegador activades.
+
diff --git a/inc/lang/ca-valencia/mailtext.txt b/inc/lang/ca-valencia/mailtext.txt
new file mode 100644
index 000000000..e8da6f8de
--- /dev/null
+++ b/inc/lang/ca-valencia/mailtext.txt
@@ -0,0 +1,17 @@
+S'ha afegit o modificat una pàgina en el seu DokuWiki. Les senyes són:
+
+Data: @DATE@
+Navegador: @BROWSER@
+Direcció IP: @IPADDRESS@
+Nom de la màquina: @HOSTNAME@
+Revisió anterior: @OLDPAGE@
+Nova revisió: @NEWPAGE@
+Resum: @SUMMARY@
+Usuari: @USER@
+
+@DIFF@
+
+
+--
+Este correu l'ha generat DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/ca-valencia/newpage.txt b/inc/lang/ca-valencia/newpage.txt
new file mode 100644
index 000000000..93b154425
--- /dev/null
+++ b/inc/lang/ca-valencia/newpage.txt
@@ -0,0 +1,3 @@
+====== Este tema encara no existix ======
+
+Ha seguit un víncul a una pàgina que encara no existix. Si té els permissos necessaris pot crear-la utilisant el botó ''Crear esta pàgina''.
diff --git a/inc/lang/ca-valencia/norev.txt b/inc/lang/ca-valencia/norev.txt
new file mode 100644
index 000000000..434e62dfa
--- /dev/null
+++ b/inc/lang/ca-valencia/norev.txt
@@ -0,0 +1,3 @@
+====== No existix la versió ======
+
+La versió especificada no existix. Utilise el botó ''Versions antigues'' per a vore una llista de versions antigues d'este document. \ No newline at end of file
diff --git a/inc/lang/ca-valencia/password.txt b/inc/lang/ca-valencia/password.txt
new file mode 100644
index 000000000..73e14e51b
--- /dev/null
+++ b/inc/lang/ca-valencia/password.txt
@@ -0,0 +1,10 @@
+¡Hola @FULLNAME@!
+
+Estes són les seues senyes d'usuari per a @TITLE@ en @DOKUWIKIURL@
+
+Usuari : @LOGIN@
+Contrasenya : @PASSWORD@
+
+--
+Este correu l'ha generat DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/ca-valencia/preview.txt b/inc/lang/ca-valencia/preview.txt
new file mode 100644
index 000000000..0997f5953
--- /dev/null
+++ b/inc/lang/ca-valencia/preview.txt
@@ -0,0 +1,4 @@
+====== Previsualisació ======
+
+Açò es una previsualisació per a vore cóm quedarà la pàgina. ¡Recorde que encara no està guardada!
+
diff --git a/inc/lang/ca-valencia/pwconfirm.txt b/inc/lang/ca-valencia/pwconfirm.txt
new file mode 100644
index 000000000..919c3d89d
--- /dev/null
+++ b/inc/lang/ca-valencia/pwconfirm.txt
@@ -0,0 +1,15 @@
+¡Hola @FULLNAME@!
+
+Algú ha solicitat una nova contrasenya per a entrar com a
+@TITLE en @DOKUWIKIURL@
+
+Si no ha segut vosté qui ha solicitat la nova contrasenya ignore este correu.
+
+Per a confirmar que la petició ha segut feta realment per vosté
+utilise el següent víncul.
+
+@CONFIRM@
+
+--
+Este correu l'ha generat DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/ca-valencia/read.txt b/inc/lang/ca-valencia/read.txt
new file mode 100644
index 000000000..80d96cd45
--- /dev/null
+++ b/inc/lang/ca-valencia/read.txt
@@ -0,0 +1,2 @@
+Esta pàgina és només de llectura. Pot vore el còdic font, pero no pot canviar-lo. Pregunte a l'administrador si creu que és un erro.
+
diff --git a/inc/lang/ca-valencia/recent.txt b/inc/lang/ca-valencia/recent.txt
new file mode 100644
index 000000000..ca1f5c5ed
--- /dev/null
+++ b/inc/lang/ca-valencia/recent.txt
@@ -0,0 +1,5 @@
+====== Canvis recents ======
+
+Les següents pàgines han canviat recentment.
+
+
diff --git a/inc/lang/ca-valencia/register.txt b/inc/lang/ca-valencia/register.txt
new file mode 100644
index 000000000..7515be6a9
--- /dev/null
+++ b/inc/lang/ca-valencia/register.txt
@@ -0,0 +1,5 @@
+====== Registrar-se com a usuari nou ======
+
+Escriga tota la informació que se li demana avall per a crear un nou conte en este wiki. Assegure's de donar una **direcció de correu electrònic vàlida** - si no se li demana una contrasenya ací se li enviarà a eixa direcció. El nom d'usuari deuria ser un
+[[doku>pagename|nom de pàgina]] vàlit.
+
diff --git a/inc/lang/ca-valencia/registermail.txt b/inc/lang/ca-valencia/registermail.txt
new file mode 100644
index 000000000..47b9318bd
--- /dev/null
+++ b/inc/lang/ca-valencia/registermail.txt
@@ -0,0 +1,14 @@
+S'ha registrat un usuari nou. Estes són les senyes:
+
+Nom d'usuari : @NEWUSER@
+Nom complet : @NEWNAME@
+Correu electrònic : @NEWEMAIL@
+
+Data : @DATE@
+Navegador : @BROWSER@
+Direcció IP : @IPADDRESS@
+Nom de la màquina : @HOSTNAME@
+
+--
+Este correu l'ha generat DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/ca-valencia/resendpwd.txt b/inc/lang/ca-valencia/resendpwd.txt
new file mode 100644
index 000000000..2feac0966
--- /dev/null
+++ b/inc/lang/ca-valencia/resendpwd.txt
@@ -0,0 +1,4 @@
+====== Enviar contrasenya nova ======
+
+Per favor, introduïxca el nom d'usuari en el formulari per a demanar una nova contrasenya per al seu conte en este wiki. Se li enviarà un víncul de confirmació a la direcció de correu en que estiga registrat.
+
diff --git a/inc/lang/ca-valencia/revisions.txt b/inc/lang/ca-valencia/revisions.txt
new file mode 100644
index 000000000..08e7e043c
--- /dev/null
+++ b/inc/lang/ca-valencia/revisions.txt
@@ -0,0 +1,4 @@
+====== Versions antigues ======
+
+Versions antigues del document actual. Per a recuperar una versió anterior de la pàgina, trie-la ací avall, pulse ''Editar esta pàgina'' i guarde-la.
+
diff --git a/inc/lang/ca-valencia/searchpage.txt b/inc/lang/ca-valencia/searchpage.txt
new file mode 100644
index 000000000..80f7e9119
--- /dev/null
+++ b/inc/lang/ca-valencia/searchpage.txt
@@ -0,0 +1,5 @@
+====== Buscar ======
+
+Pot vore els resultats de la busca ací avall. Si no ha trobat lo que buscava pot crear o editar una pàgina en el mateix nom que el text que ha buscat utilisant el botó corresponent.
+
+===== Resultats =====
diff --git a/inc/lang/ca-valencia/showrev.txt b/inc/lang/ca-valencia/showrev.txt
new file mode 100644
index 000000000..86f282292
--- /dev/null
+++ b/inc/lang/ca-valencia/showrev.txt
@@ -0,0 +1,2 @@
+**¡Açò és una versió antiga del document!**
+----
diff --git a/inc/lang/ca-valencia/stopwords.txt b/inc/lang/ca-valencia/stopwords.txt
new file mode 100644
index 000000000..1b4decbe5
--- /dev/null
+++ b/inc/lang/ca-valencia/stopwords.txt
@@ -0,0 +1,76 @@
+# 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
+ell
+ella
+nosatres
+nosatros
+mosatros
+vosatres
+vosatros
+ells
+els
+los
+dels
+les
+una
+uns
+unes
+seu
+seua
+seus
+seues
+meu
+meua
+meus
+meues
+teu
+teua
+teus
+teues
+nostre
+nostres
+vostre
+vostres
+nos
+vos
+#eix
+eixe
+eixa
+aquell
+aquella
+aquells
+aquelles
+#est
+este
+esta
+estos
+estes
+està
+això
+açò
+allò
+des
+soc
+eres
+som
+sou
+són
+fon
+per
+com
+cóm
+qui
+que
+qué
+quan
+quant
+quants
+quanta
+quantes
+mentres
+pero
+atre
+atra
+atres
+també
diff --git a/inc/lang/ca-valencia/updateprofile.txt b/inc/lang/ca-valencia/updateprofile.txt
new file mode 100644
index 000000000..9116fedf0
--- /dev/null
+++ b/inc/lang/ca-valencia/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Actualise el seu perfil ======
+
+Només deu completar els camps que vol canviar. No es pot canviar el nom d'usuari.
+
+
diff --git a/inc/lang/ca-valencia/uploadmail.txt b/inc/lang/ca-valencia/uploadmail.txt
new file mode 100644
index 000000000..c5a330274
--- /dev/null
+++ b/inc/lang/ca-valencia/uploadmail.txt
@@ -0,0 +1,14 @@
+S'ha enviat un archiu al seu DokuWiki. Les senyes:
+
+Archiu: @MEDIA@
+Data: @DATE@
+Navegador: @BROWSER@
+Direcció IP: @IPADDRESS@
+Nom de la màquina: @HOSTNAME@
+Tamany: @SIZE@
+Tipo MIME: @MIME@
+Usuari: @USER@
+
+--
+Este correu ha segut generat per DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ca/admin.txt b/inc/lang/ca/admin.txt
new file mode 100644
index 000000000..5c0a6d00a
--- /dev/null
+++ b/inc/lang/ca/admin.txt
@@ -0,0 +1,4 @@
+====== Administració ======
+
+Heus ací una llista de les tasques administratives disponibles en DokuWiki.
+
diff --git a/inc/lang/ca/adminplugins.txt b/inc/lang/ca/adminplugins.txt
new file mode 100644
index 000000000..9ea165c1f
--- /dev/null
+++ b/inc/lang/ca/adminplugins.txt
@@ -0,0 +1 @@
+===== Connectors addicionals ===== \ No newline at end of file
diff --git a/inc/lang/ca/backlinks.txt b/inc/lang/ca/backlinks.txt
new file mode 100644
index 000000000..e2ecaf4f9
--- /dev/null
+++ b/inc/lang/ca/backlinks.txt
@@ -0,0 +1,4 @@
+====== Enllaços ======
+
+Heus ací una llista de pàgines enllaçades amb la pàgina actual.
+
diff --git a/inc/lang/ca/conflict.txt b/inc/lang/ca/conflict.txt
new file mode 100644
index 000000000..53183f0b7
--- /dev/null
+++ b/inc/lang/ca/conflict.txt
@@ -0,0 +1,6 @@
+====== Hi ha una versió més recent ======
+
+Existeix una versió més recent del document que heu editat. Això passa quan un altre usuari canvia el document mentre l'estàveu editant.
+
+Examineu detingudament les diferències que es mostren més avall i després decidiu quina versió voleu mantenir. Si trieu ''desa'', es desarà la vostra versió. Si trieu ''cancel·la'' es mantindrà la versió actual.
+
diff --git a/inc/lang/ca/denied.txt b/inc/lang/ca/denied.txt
new file mode 100644
index 000000000..e6125e83b
--- /dev/null
+++ b/inc/lang/ca/denied.txt
@@ -0,0 +1,4 @@
+====== Permís denegat ======
+
+No teniu prou drets per continuar. Potser us heu descuidat d'entrar?
+
diff --git a/inc/lang/ca/diff.txt b/inc/lang/ca/diff.txt
new file mode 100644
index 000000000..83ca86782
--- /dev/null
+++ b/inc/lang/ca/diff.txt
@@ -0,0 +1,4 @@
+====== Diferències ======
+
+Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.
+
diff --git a/inc/lang/ca/draft.txt b/inc/lang/ca/draft.txt
new file mode 100644
index 000000000..68593c2fd
--- /dev/null
+++ b/inc/lang/ca/draft.txt
@@ -0,0 +1,5 @@
+====== S'ha trobat un esborrany ======
+
+La darrera sessió vostra d'edició d'aquesta pàgina no es va completar correctament. DokuWiki en va desar automàticament un esborrany mentre treballàveu, el qual podeu utilitzar ara per continuar l'edició. Més avall podeu veure la data i hora en què es va desar durant la vostra darrera sessió.
+
+Decidiu si voleu //recuperar// la vostra darrera sessió d'edició, //suprimir// l'esborrany que es va desar automàticament o //cancel·lar// el procés d'edició. \ No newline at end of file
diff --git a/inc/lang/ca/edit.txt b/inc/lang/ca/edit.txt
new file mode 100644
index 000000000..743b0ff55
--- /dev/null
+++ b/inc/lang/ca/edit.txt
@@ -0,0 +1,2 @@
+Editeu la pàgina i premeu ''Desa''. Per a més informació sobre la sintaxi Wiki vegeu [[wiki:syntax|sintaxi]]. Si us plau, editeu la pàgina només si podeu **millorar-la**. Si voleu fer proves, aprengueu a donar les primeres passes al [[playground:playground|pati]].
+
diff --git a/inc/lang/ca/editrev.txt b/inc/lang/ca/editrev.txt
new file mode 100644
index 000000000..b2f304cbb
--- /dev/null
+++ b/inc/lang/ca/editrev.txt
@@ -0,0 +1,2 @@
+**Heu penjat una revisió anterior del document.** Si la deseu, creareu una nova versió amb aquestes dades.
+----
diff --git a/inc/lang/ca/index.txt b/inc/lang/ca/index.txt
new file mode 100644
index 000000000..6ba71fd8f
--- /dev/null
+++ b/inc/lang/ca/index.txt
@@ -0,0 +1,4 @@
+====== Índex ======
+
+Heus ací un índex de totes les pàgines disponibles, ordenades per [[doku>namespaces|espais]].
+
diff --git a/inc/lang/ca/install.html b/inc/lang/ca/install.html
new file mode 100644
index 000000000..e7c8f0b57
--- /dev/null
+++ b/inc/lang/ca/install.html
@@ -0,0 +1,8 @@
+<p>Aquesta pàgina us ajuda a fer la primera instal·lació i la configuració de <a href="http://dokuwiki.org">Dokuwiki</a>. Hi ha més informació sobre aquest instal·lador en la seva <a href="http://dokuwiki.org/installer">pàgina de documentació</a>.</p>
+
+<p>DokuWiki utilitza fitxers normals per a emmagatzemar les pàgines wiki i la informació associada a aquestes pàgines (p. ex. imatges, índexs de cerca, revisions anteriors, etc.). Per tal de funcionar correctament DokuWiki <strong>necessita</strong> tenir accés d'escriptura als directoris que contenen aquests fitxers. Aquest instal·lador no pot configurar els permisos del directori. Normalment això cal fer-ho directament en la línia d'ordres o, si esteu utilitzant un hostatge, mitjançant FTP o el tauler de control del vostre hostatge (p. ex. cPanel).</p>
+
+<p>Aquest instal·lador configurarà el vostre DokuWiki per a <acronym title="access control list">ACL</acronym>, cosa que, al seu torn, permet l'accés de l'administrador al menú d'administració, on pot instal·lar connectors, gestionar usuaris, gestionar l'accés a les pàgines wiki i modificar els paràmetres de configuració. No és un requisit per al funcionament de DokuWiki, però el fa més fàcil d'administrar.</p>
+
+<p>Els usuaris experts o els que tinguin requeriments específics poden utilitzar els enllaços següents per a obtenir més detalls sobre <a href="http://dokuwiki.org/install">instruccions d'instal·lació</a>
+i <a href="http://dokuwiki.org/config">paràmetres de configuració</a>.</p> \ No newline at end of file
diff --git a/inc/lang/ca/lang.php b/inc/lang/ca/lang.php
new file mode 100644
index 000000000..81ef2c7fe
--- /dev/null
+++ b/inc/lang/ca/lang.php
@@ -0,0 +1,227 @@
+<?php
+/**
+ * catalan language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Edita aquesta pàgina';
+$lang['btn_source'] = 'Mostra codi font';
+$lang['btn_show'] = 'Mostra pàgina';
+$lang['btn_create'] = 'Crea aquesta pàgina';
+$lang['btn_search'] = 'Cerca';
+$lang['btn_save'] = 'Desa';
+$lang['btn_preview'] = 'Previsualitza';
+$lang['btn_top'] = 'Torna dalt';
+$lang['btn_newer'] = '<< més recent';
+$lang['btn_older'] = 'menys recent >>';
+$lang['btn_revs'] = 'Revisions anteriors';
+$lang['btn_recent'] = 'Canvis recents';
+$lang['btn_upload'] = 'Penja';
+$lang['btn_cancel'] = 'Cancel·la';
+$lang['btn_index'] = 'Índex';
+$lang['btn_secedit'] = 'Edita';
+$lang['btn_login'] = 'Entra';
+$lang['btn_logout'] = 'Surt';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Actualitza';
+$lang['btn_delete'] = 'Suprimeix';
+$lang['btn_back'] = 'Enrere';
+$lang['btn_backlink'] = 'Què hi enllaça';
+$lang['btn_backtomedia'] = 'Torna a la selecció de fitxers';
+$lang['btn_subscribe'] = 'Subscripció a canvis d\'aquesta pàgina';
+$lang['btn_unsubscribe'] = 'Cancel·la subscripció a pàgina';
+$lang['btn_profile'] = 'Actualització del perfil';
+$lang['btn_reset'] = 'Reinicia';
+$lang['btn_resendpwd'] = 'Envia nova contrasenya';
+$lang['btn_draft'] = 'Edita esborrany';
+$lang['btn_recover'] = 'Recupera esborrany';
+$lang['btn_draftdel'] = 'Suprimeix esborrany';
+$lang['btn_revert'] = 'Restaura';
+$lang['btn_register'] = 'Registra\'m';
+$lang['loggedinas'] = 'Heu entrat com';
+$lang['user'] = 'Nom d\'usuari';
+$lang['pass'] = 'Contrasenya';
+$lang['newpass'] = 'Nova contrasenya';
+$lang['oldpass'] = 'Confirmeu la contrasenya actual';
+$lang['passchk'] = 'una altra vegada';
+$lang['remember'] = 'Recorda\'m';
+$lang['fullname'] = 'Nom complet';
+$lang['email'] = 'Correu electrònic';
+$lang['profile'] = 'Perfil d\'usuari';
+$lang['badlogin'] = 'Nom d\'usuari o contrasenya incorrectes.';
+$lang['minoredit'] = 'Canvis menors';
+$lang['draftdate'] = 'L\'esborrany s\'ha desat automàticament';
+$lang['nosecedit'] = 'Mentrestant la pàgina ha estat modificada. La informació de seccions estava obsoleta i ha calgut carregar la pàgina sencera.';
+$lang['regmissing'] = 'Heu d\'omplir tots els camps.';
+$lang['reguexists'] = 'Ja existeix un altre usuari amb aquest nom.';
+$lang['regsuccess'] = 'S\'ha creat l\'usuari. La contrasenya s\'ha enviat per correu.';
+$lang['regsuccess2'] = 'S\'ha creat l\'usuari.';
+$lang['regmailfail'] = 'Sembla que un error ha impedit enviar la contrasenya per correu. Contacteu amb l\'administrador.';
+$lang['regbadmail'] = 'L\'adreça de correu que heu donat no sembla vàlida. Si creieu que això és un error, contacu amb l\'administrador.';
+$lang['regbadpass'] = 'Les dues contrasenyes no són iguals. Torneu a intentar-ho.';
+$lang['regpwmail'] = 'La vostra contrasenya per al Wiki';
+$lang['reghere'] = 'Si no teniu un compte, aquí en podeu obtenir un';
+$lang['profna'] = 'Aquest wiki no permet modificar el perfil';
+$lang['profnochange'] = 'No heu introduït cap canvi.';
+$lang['profnoempty'] = 'No es pot deixar en blanc el nom o l\'adreça de correu.';
+$lang['profchanged'] = 'El perfil d\'usuari s\'ha actualitzat correctament.';
+$lang['pwdforget'] = 'Heu oblidat la contrasenya? Podeu obtenir-ne una de nova.';
+$lang['resendna'] = 'Aquest wiki no permet tornar a enviar la contrasenya.';
+$lang['resendpwd'] = 'Enviament d\'una nova contrasenya per a';
+$lang['resendpwdmissing'] = 'Heu d\'emplenar tots els camps.';
+$lang['resendpwdnouser'] = 'No s\'ha pogut trobar aquest usuari a la base de dades.';
+$lang['resendpwdbadauth'] = 'Aquest codi d\'autenticació no és vàlid. Assegureu-vos d\'utilitzar l\'enllaç de confirmació complet.';
+$lang['resendpwdconfirm'] = 'Se us ha enviat per correu electrònic un enllaç de confirmació.';
+$lang['resendpwdsuccess'] = 'Se us ha enviat la nova contrasenya per correu electrònic.';
+$lang['license'] = 'Excepte on es digui una altra cosa, el contingut d\'aquest wiki està subjecte a la llicència següent:';
+$lang['licenseok'] = 'Nota. En editar aquesta pàgina esteu acceptant que el vostre contingut estigui subjecte a la llicència següent:';
+$lang['searchmedia'] = 'Cerca pel nom de fitxer';
+$lang['searchmedia_in'] = 'Cerca en: %s';
+$lang['txt_upload'] = 'Trieu el fitxer que voleu penjar';
+$lang['txt_filename'] = 'Introduïu el nom wiki (opcional)';
+$lang['txt_overwrt'] = 'Sobreescriu el fitxer actual';
+$lang['lockedby'] = 'Actualment blocat per:';
+$lang['lockexpire'] = 'Venciment del blocatge:';
+$lang['js']['willexpire'] = 'El blocatge per a editar aquesta pàgina venç d\'aquí a un minut.\nUtilitzeu la visualització prèvia per reiniciar el rellotge i evitar conflictes.';
+$lang['js']['notsavedyet'] = "Heu fet canvis que es perdran si no els deseu.\nVoleu continuar?";
+$lang['rssfailed'] = 'S\'ha produït un error en recollir aquesta alimentació: ';
+$lang['nothingfound'] = 'No s\'ha trobat res.';
+$lang['mediaselect'] = 'Selecció de fitxers';
+$lang['fileupload'] = 'Càrrega de fitxers';
+$lang['uploadsucc'] = 'S\'ha penjat el fitxer';
+$lang['uploadfail'] = 'No es pot penjar el fitxer. Potser no teniu prou permisos?';
+$lang['uploadwrong'] = 'No es pot penjar el fitxer. Aquesta extensió està prohibida.';
+$lang['uploadexist'] = 'El fitxer ja existeix. No s\'ha penjat.';
+$lang['uploadbadcontent'] = 'El contingut que heu penjat coincideix amb l\'extensió de fitxer %s.';
+$lang['uploadspam'] = 'La càrrega ha estat blocada per la llista negra de brossa.';
+$lang['uploadxss'] = 'La càrrega ha estat blocada perquè podria ser un contingut maligne.';
+$lang['uploadsize'] = 'El fitxer que voleu penjar és massa gran (màxim %s)';
+$lang['deletesucc'] = 'S\'ha suprimit el fitxer "%s".';
+$lang['deletefail'] = 'No s\'ha pogut suprimir el fitxer "%s". Comproveu els permisos.';
+$lang['mediainuse'] = 'No s\'ha pogut suprimir el fitxer "%s". Encara s\'està utilitzant.';
+$lang['namespaces'] = 'Espais';
+$lang['mediafiles'] = 'Fitxers disponibles en';
+$lang['js']['searchmedia'] = 'Cerca fitxers';
+$lang['js']['keepopen'] = 'Manté la finestra oberta';
+$lang['js']['hidedetails'] = 'Oculta detalls';
+$lang['js']['nosmblinks'] = 'Els enllaços amb recursos compartits de Windows només funcionen amb el Microsoft Internet Explorer.
+Si voleu podeu copiar i enganxar l\'enllaç.';
+$lang['js']['linkwiz'] = 'Auxiliar d\'enllaços';
+$lang['js']['linkto'] = 'Enllaça a:';
+$lang['js']['del_confirm'] = 'Suprimiu aquesta entrada?';
+$lang['mediausage'] = 'Utilitzeu la sintaxi següent per referir-vos a aquest enllaç:';
+$lang['mediaview'] = 'Mostra el fitxer original';
+$lang['mediaroot'] = 'arrel';
+$lang['mediaupload'] = 'Pengeu aquí un fitxer dins de l\'espai actual. Per a crear un nou subespai, poseu-ne el nom davant del nom de fitxer i separeu-los amb el signe de dos punts.';
+$lang['mediaextchange'] = 'S\'ha canviat l\'extensió del fitxer de .%s a .%s';
+$lang['reference'] = 'Referències per a';
+$lang['ref_inuse'] = 'El fitxer no es pot suprimir perquè l\'estan utilitzant les pàgines següents:';
+$lang['ref_hidden'] = 'Algunes referències apareixen en pàgines per a les quals no teniu permís de lectura';
+$lang['hits'] = 'Resultats';
+$lang['quickhits'] = 'Noms de pàgina coincidents';
+$lang['toc'] = 'Taula de continguts';
+$lang['current'] = 'actual';
+$lang['yours'] = 'La vostra versió';
+$lang['diff'] = 'Mostra diferències amb la versió actual';
+$lang['diff2'] = 'Mostra diferències entre les revisions seleccionades';
+$lang['line'] = 'Línia';
+$lang['breadcrumb'] = 'Camí';
+$lang['youarehere'] = 'Sou aquí';
+$lang['lastmod'] = 'Darrera modificació';
+$lang['by'] = 'per';
+$lang['deleted'] = 'suprimit';
+$lang['created'] = 'creat';
+$lang['restored'] = 's\'ha restaurat una versió anterior';
+$lang['external_edit'] = 'edició externa';
+$lang['summary'] = 'Resum d\'edició';
+$lang['noflash'] = 'Per a visualitzar aquest contingut necessiteu el <a href="http://www.adobe.com/products/flashplayer/">connector d\'Adobe Flash</a>.';
+$lang['download'] = 'Baixa el fragment';
+$lang['mail_newpage'] = 'pàgina afegida:';
+$lang['mail_changed'] = 'pàgina modificada:';
+$lang['mail_new_user'] = 'nou usuari:';
+$lang['mail_upload'] = 'fitxer penjat:';
+$lang['qb_bold'] = 'Negreta';
+$lang['qb_italic'] = 'Cursiva';
+$lang['qb_underl'] = 'Subratllat';
+$lang['qb_code'] = 'Codi';
+$lang['qb_strike'] = 'Text barrat';
+$lang['qb_h1'] = 'Encapçalament nivell 1';
+$lang['qb_h2'] = 'Encapçalament nivell 2';
+$lang['qb_h3'] = 'Encapçalament nivell 3';
+$lang['qb_h4'] = 'Encapçalament nivell 4';
+$lang['qb_h5'] = 'Encapçalament nivell 5';
+$lang['qb_h'] = 'Encapçalament';
+$lang['qb_hs'] = 'Selcciona l\'encapçalament';
+$lang['qb_hplus'] = 'Encapçalament més alt';
+$lang['qb_hminus'] = 'Encapçalament més baix';
+$lang['qb_hequal'] = 'Encapçalament del mateix nivell';
+$lang['qb_link'] = 'Enllaç intern';
+$lang['qb_extlink'] = 'Enllaç extern';
+$lang['qb_hr'] = 'Ratlla horitzontal';
+$lang['qb_ol'] = 'Element de llista numerada';
+$lang['qb_ul'] = 'Element de llista de pics';
+$lang['qb_media'] = 'Afegeix imatges o altres fitxers';
+$lang['qb_sig'] = 'Insereix signatura';
+$lang['qb_smileys'] = 'Emoticones';
+$lang['qb_chars'] = 'Caràcters especials';
+$lang['upperns'] = 'Salta a l\'espai superior';
+$lang['admin_register'] = 'Afegeix nou usuari';
+$lang['metaedit'] = 'Edita metadades';
+$lang['metasaveerr'] = 'No s\'han pogut escriure les metadades';
+$lang['metasaveok'] = 'S\'han desat les metadades';
+$lang['img_backto'] = 'Torna a';
+$lang['img_title'] = 'Títol';
+$lang['img_caption'] = 'Peu d\'imatge';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Nom de fitxer';
+$lang['img_fsize'] = 'Mida';
+$lang['img_artist'] = 'Fotògraf';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Càmera';
+$lang['img_keywords'] = 'Paraules clau';
+$lang['subscribe_success'] = 'S\'ha afegit %s a la llista de subscripcions de %s';
+$lang['subscribe_error'] = 'S\'ha produït un error en afegir %s a la llista de subscripcions de %s';
+$lang['subscribe_noaddress'] = 'No hi ha cap adreça de correu associada al vostre nom d\'usuari. No se us ha pogut afegir a la llista de subscripcions.';
+$lang['unsubscribe_success'] = '%s ha estat suprimit de la llista de subscripcions de %s';
+$lang['unsubscribe_error'] = 'S\'ha produït un error en suprimir %s de la llista de subscripcions de %s';
+$lang['authmodfailed'] = 'La configuració de l\'autenticació d\'usuaris és errònia. Informeu els administradors del wiki.';
+$lang['authtempfail'] = 'L\'autenticació d\'usuaris no està disponible temporalment. Si aquesta situació persisteix, si us plau informeu els administradors del wiki.';
+$lang['i_chooselang'] = 'Trieu l\'idioma';
+$lang['i_installer'] = 'Instal·lador de DokuWiki';
+$lang['i_wikiname'] = 'Nom del wiki';
+$lang['i_enableacl'] = 'Habilita ACL (recomanat)';
+$lang['i_superuser'] = 'Superusuari';
+$lang['i_problems'] = 'L\'instal·lador ha trobat alguns problemes, que s\'indiquen més avall. No podeu continuar fins que no els hàgiu solucionat.';
+$lang['i_modified'] = 'Per raons de seguretat aquesta seqüència només funciona amb una instal·lació nova i no modificada de Dokuwiki. Hauríeu de tornar a baixar el paquet i/o descomprimir-lo o consultar les <a href="http://dokuwiki.org/install">instruccions d\'instal·lació de Dokuwiki</a> completes';
+$lang['i_funcna'] = 'La funció PHP <code>%s</code> no està disponible. Potser el vostre proveïdor de serveis l\'ha inhabilitada per alguna raó';
+$lang['i_phpver'] = 'La vostra versió de PHP <code>%s</code> és inferior a la requerida <code>%s</code>. Necessiteu actualitzar la vostra instal·lació de PHP.';
+$lang['i_permfail'] = 'DokuWiki no pot escriure <code>%s</code>. Heu d\'arreglar els permisos d\'aquest directori';
+$lang['i_confexists'] = '<code>%s</code> ja existeix';
+$lang['i_writeerr'] = 'No es pot crear <code>%s</code>. Comproveu els permisos del directori i/o del fitxer i creeu el fitxer manualment.';
+$lang['i_badhash'] = 'dokuwiki.php no reconegut o modificat (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - valor il·legal o buit';
+$lang['i_success'] = 'La configuració s\'ha acabat amb èxit. Ara podeu suprimir el fitxer install.php. Aneu al vostre nou <a href="doku.php">DokuWiki</a>.';
+$lang['i_failure'] = 'S\'han produït alguns errors en escriure els fitxers de configuració. Potser caldrà que els arregleu manualment abans d\'utilitzar el vostre nou <a href="doku.php">DokuWiki</a>.';
+$lang['i_policy'] = 'Política ACL inicial';
+$lang['i_pol0'] = 'Wiki obert (tothom pot llegir, escriure i penjar fitxers)';
+$lang['i_pol1'] = 'Wiki públic (tothom pot llegir, els usuaris registrats poden escriure i penjar fitxers)';
+$lang['i_pol2'] = 'Wiki tancat (només els usuaris registrats poden llegir, escriure i penjar fitxers)';
+$lang['i_retry'] = 'Reintenta';
+$lang['recent_global'] = 'Esteu veient els canvis recents de l\'espai <strong>%s</strong>. També podeu veure els <a href="%s">canvis recents de tot el wiki</a>.';
+$lang['years'] = 'fa %d anys';
+$lang['months'] = 'fa %d mesos';
+$lang['weeks'] = 'fa %d setmanes';
+$lang['days'] = 'fa %d dies';
+$lang['hours'] = 'fa %d hores';
+$lang['minutes'] = 'fa %d minuts';
+$lang['seconds'] = 'fa %d segons';
diff --git a/inc/lang/ca/locked.txt b/inc/lang/ca/locked.txt
new file mode 100644
index 000000000..93487c268
--- /dev/null
+++ b/inc/lang/ca/locked.txt
@@ -0,0 +1,3 @@
+====== Pàgina blocada ======
+
+Aquesta pàgina actualment està blocada per a edició per un altre usuari. Haureu d'esperar fins que aquest usuari acabe d'editar-la o fins que venci el blocatge.
diff --git a/inc/lang/ca/login.txt b/inc/lang/ca/login.txt
new file mode 100644
index 000000000..37ca4d582
--- /dev/null
+++ b/inc/lang/ca/login.txt
@@ -0,0 +1,4 @@
+====== Entrada ======
+
+No heu entrat. Introduïu les vostres credencials d'autenticació en aquest formulari. A partir d'aquest moment heu de tenir les galetes habilitades en el vostre navegador.
+
diff --git a/inc/lang/ca/mailtext.txt b/inc/lang/ca/mailtext.txt
new file mode 100644
index 000000000..eda330954
--- /dev/null
+++ b/inc/lang/ca/mailtext.txt
@@ -0,0 +1,16 @@
+S'ha afegit o modificat una pàgina en el vostre wiki. Ací teniu més detalls:
+
+Data : @DATE@
+Navegador : @BROWSER@
+IP : @IPADDRESS@
+Rev. anterior : @OLDPAGE@
+Rev. actual : @NEWPAGE@
+Resum d'edició : @SUMMARY@
+Usuari : @USER@
+
+@DIFF@
+
+
+--
+Missatge generat per DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/ca/newpage.txt b/inc/lang/ca/newpage.txt
new file mode 100644
index 000000000..d0a2db92a
--- /dev/null
+++ b/inc/lang/ca/newpage.txt
@@ -0,0 +1,3 @@
+====== Aquest tema encara no existeix ======
+
+Heu seguit un enllaç a un tema que encara no existeix. Podeu crear-lo per mitjà del botó ''Crea aquesta pàgina''.
diff --git a/inc/lang/ca/norev.txt b/inc/lang/ca/norev.txt
new file mode 100644
index 000000000..b5089c5eb
--- /dev/null
+++ b/inc/lang/ca/norev.txt
@@ -0,0 +1,5 @@
+====== No existeix aquesta revisió ======
+
+
+La revisió especificada no existeix. Utilitzeu el botó ''Revisions anteriors'' per obtenir una llista de revisions d'aquest document.
+
diff --git a/inc/lang/ca/password.txt b/inc/lang/ca/password.txt
new file mode 100644
index 000000000..4735fda3f
--- /dev/null
+++ b/inc/lang/ca/password.txt
@@ -0,0 +1,10 @@
+Benvolgut/da @FULLNAME@,
+
+Aquestes són les teves dades per a entrar en @TITLE@ en l'adreça @DOKUWIKIURL@
+
+Usuari : @LOGIN@
+Contrasenya : @PASSWORD@
+
+--
+Missatge generat per DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/ca/preview.txt b/inc/lang/ca/preview.txt
new file mode 100644
index 000000000..fa2f98ca5
--- /dev/null
+++ b/inc/lang/ca/preview.txt
@@ -0,0 +1,4 @@
+====== Previsualització ======
+
+Heus ací una previsualització del vostre text. Recordeu que encara **no l'heu desat!**
+
diff --git a/inc/lang/ca/pwconfirm.txt b/inc/lang/ca/pwconfirm.txt
new file mode 100644
index 000000000..119c4292d
--- /dev/null
+++ b/inc/lang/ca/pwconfirm.txt
@@ -0,0 +1,15 @@
+@FULLNAME@,
+
+Algú ha sol·licitat una nova contrasenya per al vostre compte d'usuari en @TITLE@
+@DOKUWIKIURL@
+
+Si no heu fet aquesta sol·licitud, simplement no feu cas de la resta del missatge.
+
+Per confirmar que realment heu sol·licitat una nova contrasenya, utilitzeu
+l'enllaç següent:
+
+@CONFIRM@
+
+--
+Missatge generat per DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ca/read.txt b/inc/lang/ca/read.txt
new file mode 100644
index 000000000..e173ad2dc
--- /dev/null
+++ b/inc/lang/ca/read.txt
@@ -0,0 +1,2 @@
+Aquesta pàgina és només de lectura. Podeu veure'n el codi font, però no podeu canviar-la. Consulteu el vostre administrador si penseu que això és degut a algun error.
+
diff --git a/inc/lang/ca/recent.txt b/inc/lang/ca/recent.txt
new file mode 100644
index 000000000..cea2f5cff
--- /dev/null
+++ b/inc/lang/ca/recent.txt
@@ -0,0 +1,5 @@
+====== Canvis recents ======
+
+Les pàgines següents s'han modificat recentment.
+
+
diff --git a/inc/lang/ca/register.txt b/inc/lang/ca/register.txt
new file mode 100644
index 000000000..a91e6df31
--- /dev/null
+++ b/inc/lang/ca/register.txt
@@ -0,0 +1,4 @@
+====== Registre d'un usuari nou ======
+
+Empleneu tota la informació que se us demana per crear un compte nou en aquest wiki. Assegureu-vos que doneu una **adreça de correu vàlida**, on se us enviarà la vostra contrasenya. El nom d'usuari o usuària ha de ser vàlid com a [[doku>pagename|nom de pàgina]].
+
diff --git a/inc/lang/ca/registermail.txt b/inc/lang/ca/registermail.txt
new file mode 100644
index 000000000..84bf5f1a4
--- /dev/null
+++ b/inc/lang/ca/registermail.txt
@@ -0,0 +1,14 @@
+S'ha registrat un nou usuari. Heus ací els detalls:
+
+Nom d'usuari: @NEWUSER@
+Nom complet: @NEWNAME@
+E-mail: @NEWEMAIL@
+
+Data: @DATE@
+Navegador: @BROWSER@
+Adreça IP: @IPADDRESS@
+Ordinador: @HOSTNAME@
+
+--
+Missatge generat per DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ca/resendpwd.txt b/inc/lang/ca/resendpwd.txt
new file mode 100644
index 000000000..cd59f899d
--- /dev/null
+++ b/inc/lang/ca/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Nova contrasenya ======
+
+Per sol·licitar una nova contrasenya, introduïu el vostre nom d'usuari en el formulari següent. Se us enviarà un enllaç de confirmació a l'adreça de correu amb què us vau registrar. \ No newline at end of file
diff --git a/inc/lang/ca/revisions.txt b/inc/lang/ca/revisions.txt
new file mode 100644
index 000000000..5c044d8e6
--- /dev/null
+++ b/inc/lang/ca/revisions.txt
@@ -0,0 +1,4 @@
+====== Revisions anteriors ======
+
+Heus ací les revisions anteriors del document actual. Per restaurar una revisió anterior, seleccioneu-la de la llista, feu clic en ''Edita aquesta pàgina'' i deseu-la.
+
diff --git a/inc/lang/ca/searchpage.txt b/inc/lang/ca/searchpage.txt
new file mode 100644
index 000000000..bf69aef15
--- /dev/null
+++ b/inc/lang/ca/searchpage.txt
@@ -0,0 +1,5 @@
+====== Cerca ======
+
+Heus ací els resultats de la cerca. Si no trobeu allò que buscàveu, podeu crear una pàgina nova per mitjà del botó ''Edita aquesta pàgina''.
+
+===== Resultats ===== \ No newline at end of file
diff --git a/inc/lang/ca/showrev.txt b/inc/lang/ca/showrev.txt
new file mode 100644
index 000000000..b1411824f
--- /dev/null
+++ b/inc/lang/ca/showrev.txt
@@ -0,0 +1,2 @@
+**Aquesta és una revisió antiga del document**
+----
diff --git a/inc/lang/ca/stopwords.txt b/inc/lang/ca/stopwords.txt
new file mode 100644
index 000000000..03be425ed
--- /dev/null
+++ b/inc/lang/ca/stopwords.txt
@@ -0,0 +1,106 @@
+# Això és una llista de paraules que seran omeses per l'indexador, una paraula per línia
+# Utilitzeu finals de línia UNIX
+# No cal incloure paraules de menys de 3 caràcters: s'ometran igualment
+# Llista basada en http://www.ranks.nl/stopwords/
+abans
+algun
+alguna
+alguns
+algunes
+altre
+altra
+altres
+amb
+ambdós
+anar
+ans
+aquell
+aquella
+aquelles
+aquells
+aquí
+bastant
+cada
+com
+dalt
+des
+dins
+ell
+ella
+elles
+ells
+els
+ens
+entre
+era
+erem
+eren
+eres
+estan
+estat
+estava
+estem
+esteu
+estic
+està
+ets
+faig
+fan
+fas
+fem
+fer
+feu
+haver
+inclòs
+llarg
+llavors
+mentre
+meu
+mode
+molt
+molts
+nosaltres
+per
+per que
+perquè
+però
+podem
+poden
+poder
+podeu
+potser
+primer
+puc
+quan
+quant
+qui
+sabem
+saben
+saber
+sabeu
+sap
+saps
+sense
+ser
+seu
+seus
+sóc
+solament
+sols
+som
+sota
+també
+tene
+tenim
+tenir
+teniu
+teu
+tinc
+tot
+una
+uns
+unes
+uns
+vaig
+van
+vosaltres
diff --git a/inc/lang/ca/updateprofile.txt b/inc/lang/ca/updateprofile.txt
new file mode 100644
index 000000000..0ba022600
--- /dev/null
+++ b/inc/lang/ca/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Actualització del perfil d'usuari ======
+
+Només cal que completeu els camps que vulgueu canviar. El nom d'usuari no es pot canviar. \ No newline at end of file
diff --git a/inc/lang/ca/uploadmail.txt b/inc/lang/ca/uploadmail.txt
new file mode 100644
index 000000000..c282f1f37
--- /dev/null
+++ b/inc/lang/ca/uploadmail.txt
@@ -0,0 +1,14 @@
+S'ha penjat un fitxer al vostre DokuWiki. Heus ací els detalls:
+
+Fitxer: @MEDIA@
+Data: @DATE@
+Navegador: @BROWSER@
+Adreça IP: @IPADDRESS@
+Ordinador: @HOSTNAME@
+Mida: @SIZE@
+Tipus MIME: @MIME@
+Usuari: @USER@
+
+--
+Missatge generat per DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/cs/admin.txt b/inc/lang/cs/admin.txt
new file mode 100644
index 000000000..ccfbc4455
--- /dev/null
+++ b/inc/lang/cs/admin.txt
@@ -0,0 +1,3 @@
+====== Správa ======
+
+Níže je možno spravovat vaši DokuWiki.
diff --git a/inc/lang/cs/adminplugins.txt b/inc/lang/cs/adminplugins.txt
new file mode 100644
index 000000000..005f8f2df
--- /dev/null
+++ b/inc/lang/cs/adminplugins.txt
@@ -0,0 +1 @@
+===== Další pluginy ===== \ No newline at end of file
diff --git a/inc/lang/cs/backlinks.txt b/inc/lang/cs/backlinks.txt
new file mode 100644
index 000000000..59430eeae
--- /dev/null
+++ b/inc/lang/cs/backlinks.txt
@@ -0,0 +1,3 @@
+====== Zpětné odkazy ======
+
+Zde je seznam stránek, které pravděpodobně odkazují na aktuální stránku.
diff --git a/inc/lang/cs/conflict.txt b/inc/lang/cs/conflict.txt
new file mode 100644
index 000000000..941118db3
--- /dev/null
+++ b/inc/lang/cs/conflict.txt
@@ -0,0 +1,5 @@
+====== Existuje novější verze ======
+
+Existuje novější verze právě upravovaného dokumentu. To se stává, pokud někdo jiný změnil dokument, který právě upravujete.
+
+Prohlédněte si níže uvedené rozdíly, případně rozdíly z obou verzí ručně spojte dohromady a rozhodněte se, kterou verzi uchovat. Pokud zvolíte ''Uložit'', bude uložena vaše verze. Jinak stiskněte ''Storno'' pro uchování původní verze.
diff --git a/inc/lang/cs/denied.txt b/inc/lang/cs/denied.txt
new file mode 100644
index 000000000..00a8811de
--- /dev/null
+++ b/inc/lang/cs/denied.txt
@@ -0,0 +1,3 @@
+====== Nepovolená akce ======
+
+Promiňte, ale nemáte dostatečná oprávnění k této činnosti. Možná jste se zapomněli přihlásit?
diff --git a/inc/lang/cs/diff.txt b/inc/lang/cs/diff.txt
new file mode 100644
index 000000000..d49e56993
--- /dev/null
+++ b/inc/lang/cs/diff.txt
@@ -0,0 +1,4 @@
+====== Rozdíly ======
+
+Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
+
diff --git a/inc/lang/cs/draft.txt b/inc/lang/cs/draft.txt
new file mode 100644
index 000000000..ebdfb8d9d
--- /dev/null
+++ b/inc/lang/cs/draft.txt
@@ -0,0 +1,5 @@
+====== Nalezen koncept ======
+
+Vaše minulá editace této stránky nebyla korektně dokončena. DokuWiki během editace automaticky uložila koncept, který nyní můžete použít a pokračovat v editaci. Níže je vidět text uložený během minulé editace.
+
+Prosím rozhodněte se, jestli chcete automaticky uložený koncept //obnovit// a pokračovat v editaci, nebo jej chcete //vymazat//, nebo úplně //zrušit// celý proces editace.
diff --git a/inc/lang/cs/edit.txt b/inc/lang/cs/edit.txt
new file mode 100644
index 000000000..1a135aee3
--- /dev/null
+++ b/inc/lang/cs/edit.txt
@@ -0,0 +1 @@
+Upravte stránku a stiskněte ''Uložit''. Na stránce [[wiki:syntax]] se můžete dozvědět více o wiki syntaxi. Prosím upravujte stránky pouze, pokud je můžete **vylepšit**. V případě, že si chcete něco pouze vyzkoušet, použijte raději [[playground:playground|pískoviště]].
diff --git a/inc/lang/cs/editrev.txt b/inc/lang/cs/editrev.txt
new file mode 100644
index 000000000..44f0bc67d
--- /dev/null
+++ b/inc/lang/cs/editrev.txt
@@ -0,0 +1,2 @@
+**Máte načtenou starší verzi dokumentu!** Pokud ji uložíte, vytvoříte tím novou aktuální verzi.
+----
diff --git a/inc/lang/cs/index.txt b/inc/lang/cs/index.txt
new file mode 100644
index 000000000..d19626f6f
--- /dev/null
+++ b/inc/lang/cs/index.txt
@@ -0,0 +1,3 @@
+====== Index ======
+
+Zde je k dispozici index všech dostupných stránek seřazený podle [[doku>namespaces|jmenných prostorů]].
diff --git a/inc/lang/cs/install.html b/inc/lang/cs/install.html
new file mode 100644
index 000000000..726d7c31f
--- /dev/null
+++ b/inc/lang/cs/install.html
@@ -0,0 +1,23 @@
+<p>Tato stránka vám pomůže při první instalaci a konfiguraci
+<a href="http://dokuwiki.org">Dokuwiki</a>. Více
+informací o tomto instalátoru naleznete v jeho vlastní <a
+href="http://dokuwiki.org/installer">dokumentaci</a>.</p>
+
+<p>DokuWiki používá obyčejné soubory pro uložení wiki stránek a dalších informací
+spojených s nimi (např. obrázků, vyhledávacích indexů, starších verzí). Aby DokuWiki
+správně fungovala <strong>musí</strong> mít přístup k adresářům, kde jsou uloženy
+tyto soubory. Tento instalátor není schopen sám nastavit přístupová práva k souborům
+a adresářům. To se obyčejně dělá přímo v shellu nebo, používáte-li hosting, přes
+FTP nebo ovládací panel vašeho hostingu (např. cPanel).</p>
+
+<p>Tento instalátor nastaví <acronym title="access control list">ACL</acronym>
+(přístupová práva uživatelů) pro vaši DokuWiki, což umožní správci přihlásit
+se do administrační části DokuWiki a tam instalovat pluginy, spravovat uživatele,
+nastavovat přístup k wiki stránkám a měnit další nastavení wiki. Není to
+nutné, ale zpříjemní to správu DokuWiki.</p>
+
+<p>Zkušení uživatelé nebo uživatelé se speciálními požadavky by se
+měli podívat na následující stránky pro další informace ohledně
+<a href="http://dokuwiki.org/install">instalace</a> a
+<a href="http://dokuwiki.org/config">nastavení</a> DokuWiki.</p>
+
diff --git a/inc/lang/cs/lang.php b/inc/lang/cs/lang.php
new file mode 100644
index 000000000..badd57ac5
--- /dev/null
+++ b/inc/lang/cs/lang.php
@@ -0,0 +1,317 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author Tomas Valenta <t.valenta@sh.cvut.cz>
+ * @author Tomas Valenta <tomas@valenta.cz>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Upravit stránku';
+$lang['btn_source'] = 'Zdrojový kód stránky';
+$lang['btn_show'] = 'Zobrazit stránku';
+$lang['btn_create'] = 'Vytvořit stránku';
+$lang['btn_search'] = 'Hledat';
+$lang['btn_save'] = 'Uložit';
+$lang['btn_preview'] = 'Náhled';
+$lang['btn_top'] = 'Nahoru';
+$lang['btn_newer'] = '<< novější';
+$lang['btn_older'] = 'starší >>';
+$lang['btn_revs'] = 'Starší verze';
+$lang['btn_recent'] = 'Poslední úpravy';
+$lang['btn_upload'] = 'Načíst';
+$lang['btn_cancel'] = 'Storno';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit'] = 'Upravit';
+$lang['btn_login'] = 'Přihlásit se';
+$lang['btn_logout'] = 'Odhlásit se';
+$lang['btn_admin'] = 'Správa';
+$lang['btn_update'] = 'Aktualizovat';
+$lang['btn_delete'] = 'Vymazat';
+$lang['btn_back'] = 'Zpět';
+$lang['btn_backlink'] = 'Zpětné odkazy';
+$lang['btn_backtomedia'] = 'Zpět do Výběru dokumentu';
+$lang['btn_subscribe'] = 'Odebírat emailem změny stránky';
+$lang['btn_profile'] = 'Upravit profil';
+$lang['btn_reset'] = 'Reset';
+$lang['btn_resendpwd'] = 'Zaslat nové heslo';
+$lang['btn_draft'] = 'Upravit koncept';
+$lang['btn_recover'] = 'Obnovit koncept';
+$lang['btn_draftdel'] = 'Vymazat koncept';
+$lang['btn_revert'] = 'Vrátit zpět';
+$lang['btn_register'] = 'Registrovat';
+$lang['btn_apply'] = 'Použít';
+$lang['btn_media'] = 'Správa médií';
+$lang['loggedinas'] = 'Přihlášen(a) jako';
+$lang['user'] = 'Uživatelské jméno';
+$lang['pass'] = 'Heslo';
+$lang['newpass'] = 'Nové heslo';
+$lang['oldpass'] = 'Současné heslo';
+$lang['passchk'] = 'ještě jednou';
+$lang['remember'] = 'Přihlásit se nastálo';
+$lang['fullname'] = 'Celé jméno';
+$lang['email'] = 'E-mail';
+$lang['profile'] = 'Uživatelský profil';
+$lang['badlogin'] = 'Zadané uživatelské jméno a heslo není správně.';
+$lang['minoredit'] = 'Drobné změny';
+$lang['draftdate'] = 'Koncept automaticky uložen v';
+$lang['nosecedit'] = 'Stránka byla v mezičase změněna. Informace o sekci již nebylo platné, byla načtena celá stránka.';
+$lang['regmissing'] = 'Musíte vyplnit všechny údaje.';
+$lang['reguexists'] = 'Uživatel se stejným jménem už je zaregistrován.';
+$lang['regsuccess'] = 'Uživatelský účet byl vytvořen a heslo zasláno mailem.';
+$lang['regsuccess2'] = 'Uživatelský účet byl vytvořen.';
+$lang['regmailfail'] = 'Zdá se, že nastala chyba při posílání mailu s heslem. Zkuste kontaktovat správce.';
+$lang['regbadmail'] = 'Zadaná mailová adresa není platná. Pokud si myslíte, že to je špatně, zkuste kontaktovat správce.';
+$lang['regbadpass'] = 'Heslo nebylo zadáno dvakrát stejně, zkuste to prosím znovu.';
+$lang['regpwmail'] = 'Vaše heslo do systému DokuWiki';
+$lang['reghere'] = 'Nemáte uživatelský účet? Zřiďte si ho';
+$lang['profna'] = 'Tato wiki neumožňuje změnu profilu';
+$lang['profnochange'] = 'Žádné změny nebyly provedeny.';
+$lang['profnoempty'] = 'Nelze zadat prázdné jméno nebo mailová adresa.';
+$lang['profchanged'] = 'Uživatelský profil změněn.';
+$lang['pwdforget'] = 'Zapomněli jste heslo? Nechte si zaslat nové';
+$lang['resendna'] = 'Tato wiki neumožňuje zasílání nových hesel.';
+$lang['resendpwd'] = 'Odeslat nové heslo pro uživatele';
+$lang['resendpwdmissing'] = 'Musíte vyplnit všechny položky.';
+$lang['resendpwdnouser'] = 'Bohužel takový uživatel v systému není.';
+$lang['resendpwdbadauth'] = 'Autorizační kód není platný. Zadali jste opravdu celý odkaz na potvrzovací stránku?';
+$lang['resendpwdconfirm'] = 'Odkaz na potvrzovací stránku byl odeslán mailem.';
+$lang['resendpwdsuccess'] = 'Vaše nové heslo bylo odesláno emailem.';
+$lang['license'] = 'Kromě míst, kde je explicitně uvedeno jinak, je obsah této wiki licencován pod následující licencí:';
+$lang['licenseok'] = 'Poznámka: Tím, že editujete tuto stránku, souhlasíte, aby váš obsah byl licencován pod následující licencí:';
+$lang['searchmedia'] = 'Hledat jméno souboru:';
+$lang['searchmedia_in'] = 'Hledat v %s';
+$lang['txt_upload'] = 'Vyberte soubor jako přílohu';
+$lang['txt_filename'] = 'Wiki jméno (volitelné)';
+$lang['txt_overwrt'] = 'Přepsat existující soubor';
+$lang['lockedby'] = 'Právě zamknuto:';
+$lang['lockexpire'] = 'Zámek vyprší:';
+$lang['js']['willexpire'] = 'Váš zámek pro editaci za chvíli vyprší.\nAbyste předešli konfliktům, stiskněte tlačítko Náhled a zámek se prodlouží.';
+$lang['js']['notsavedyet'] = 'Jsou tu neuložené změny, které budou ztraceny.
+Chcete opravdu pokračovat?';
+$lang['js']['searchmedia'] = 'Hledat soubory';
+$lang['js']['keepopen'] = 'Po vybrání souboru nechat okno otevřené';
+$lang['js']['hidedetails'] = 'Skrýt detaily';
+$lang['js']['mediatitle'] = 'Nastavení odkazu';
+$lang['js']['mediadisplay'] = 'Typ odkazu';
+$lang['js']['mediaalign'] = 'Zarovnání';
+$lang['js']['mediasize'] = 'Velikost obrázku';
+$lang['js']['mediatarget'] = 'Cíl odkazu';
+$lang['js']['mediaclose'] = 'Zavřít';
+$lang['js']['mediainsert'] = 'Vložit';
+$lang['js']['mediadisplayimg'] = 'Ukázat obrázek';
+$lang['js']['mediadisplaylnk'] = 'Ukázat pouze odkaz';
+$lang['js']['mediasmall'] = 'Malá verze';
+$lang['js']['mediamedium'] = 'Střední verze';
+$lang['js']['medialarge'] = 'Velká verze';
+$lang['js']['mediaoriginal'] = 'Původní verze';
+$lang['js']['medialnk'] = 'Odkaz na stránku s detailem';
+$lang['js']['mediadirect'] = 'Přímý odkaz na originál';
+$lang['js']['medianolnk'] = 'Žádný odkaz';
+$lang['js']['medianolink'] = 'Neodkazovat na obrázek';
+$lang['js']['medialeft'] = 'Zarovnat obrázek doleva.';
+$lang['js']['mediaright'] = 'Zarovnat obrázek doprava.';
+$lang['js']['mediacenter'] = 'Zarovnat obrázek na střed.';
+$lang['js']['medianoalign'] = 'Nepoužívat zarovnání.';
+$lang['js']['nosmblinks'] = 'Odkazování na sdílené prostředky Windows funguje jen v Internet Exploreru.
+Přesto tento odkaz můžete zkopírovat a vložit jinde.';
+$lang['js']['linkwiz'] = 'Průvodce odkazy';
+$lang['js']['linkto'] = 'Odkaz na:';
+$lang['js']['del_confirm'] = 'Vymazat tuto položku?';
+$lang['js']['restore_confirm'] = 'Opravdu obnovit tuto verzi?';
+$lang['js']['media_diff'] = 'Prohlédnout rozdíly:';
+$lang['js']['media_diff_both'] = 'Vedle sebe';
+$lang['js']['media_diff_opacity'] = 'Zvýraznění';
+$lang['js']['media_diff_portions'] = 'Osvědčit';
+$lang['js']['media_select'] = 'Vybrat soubory...';
+$lang['js']['media_upload_btn'] = 'Nahrát';
+$lang['js']['media_done_btn'] = 'Hotovo';
+$lang['js']['media_drop'] = 'Sem přetáhněte soubory pro nahrátí';
+$lang['js']['media_cancel'] = 'odstranit';
+$lang['js']['media_overwrt'] = 'Přepsat existující soubory';
+$lang['rssfailed'] = 'Nastala chyba při vytváření tohoto RSS: ';
+$lang['nothingfound'] = 'Nic nenalezeno.';
+$lang['mediaselect'] = 'Výběr dokumentu';
+$lang['fileupload'] = 'Načtení dokumentu';
+$lang['uploadsucc'] = 'Přenos proběhl v pořádku';
+$lang['uploadfail'] = 'Chyba při načítání. Možná kvůli špatně nastaveným právům?';
+$lang['uploadwrong'] = 'Načtení souboru s takovouto příponou není dovoleno.';
+$lang['uploadexist'] = 'Soubor už existuje, necháme ho být.';
+$lang['uploadbadcontent'] = 'Obsah načteného dokumentu %s neodpovídá jeho příponě.';
+$lang['uploadspam'] = 'Načtený dokument byl odmítnut, je na spamovém blacklistu.';
+$lang['uploadxss'] = 'Načtený dokument byl odmítnut. Zdá se, že obsahuje škodlivé věci.';
+$lang['uploadsize'] = 'Nahraný soubor byl příliš velký (max. %s)';
+$lang['deletesucc'] = 'Soubor "%s" byl vymazán.';
+$lang['deletefail'] = 'Soubor "%s" nelze vymazat - zkontrolujte oprávnění.';
+$lang['mediainuse'] = 'Soubor "%s" nebyl vymazán - stále se používá.';
+$lang['namespaces'] = 'Jmenné prostory';
+$lang['mediafiles'] = 'Dostupné soubory';
+$lang['accessdenied'] = 'Nejste autorizován k přístupu na tuto stránku.';
+$lang['mediausage'] = 'K odkázání se na tento soubor použijte následující syntax:';
+$lang['mediaview'] = 'Zobrazit původní soubor';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Načíst soubor do aktuálního jmenného prostoru. K vytvoření nových jmenných prostorů, přidejte jejich názvy na začátek wiki jména (oddělte dvojtečkou).';
+$lang['mediaextchange'] = 'Přípona souboru byla změněna z .%s na .%s!';
+$lang['reference'] = 'Odkazy na';
+$lang['ref_inuse'] = 'Soubor nelze vymazat, jelikož ho využívají následující stránky:';
+$lang['ref_hidden'] = 'Některé odkazy jsou na stránkách, kam nemáte právo přístupu';
+$lang['hits'] = '- počet výskytů';
+$lang['quickhits'] = 'Odpovídající stránky';
+$lang['toc'] = 'Obsah';
+$lang['current'] = 'aktuální';
+$lang['yours'] = 'Vaše verze';
+$lang['diff'] = 'Zobrazit rozdíly vůči aktuální verzi';
+$lang['diff2'] = 'Zobrazit rozdíly mezi vybranými verzemi';
+$lang['difflink'] = 'Odkaz na výstup diff';
+$lang['diff_type'] = 'Zobrazit rozdíly:';
+$lang['diff_inline'] = 'Vložené';
+$lang['diff_side'] = 'Přidané';
+$lang['line'] = 'Řádek';
+$lang['breadcrumb'] = 'Historie';
+$lang['youarehere'] = 'Umístění';
+$lang['lastmod'] = 'Poslední úprava';
+$lang['by'] = 'autor:';
+$lang['deleted'] = 'odstraněno';
+$lang['created'] = 'vytvořeno';
+$lang['restored'] = 'stará verze byla obnovena';
+$lang['external_edit'] = 'upraveno mimo DokuWiki';
+$lang['summary'] = 'Komentář k úpravám';
+$lang['noflash'] = 'Pro přehrání obsahu potřebujete <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>.';
+$lang['download'] = 'Stáhnout snippet';
+$lang['mail_newpage'] = 'nová stránka:';
+$lang['mail_changed'] = 'změna stránky:';
+$lang['mail_subscribe_list'] = 'stránky změněné ve jmenném prostoru:';
+$lang['mail_new_user'] = 'nový uživatel:';
+$lang['mail_upload'] = 'načtený dokument:';
+$lang['changes_type'] = 'Prohlednou změny ';
+$lang['pages_changes'] = 'stránek';
+$lang['media_changes'] = 'souborů médií';
+$lang['both_changes'] = 'stránek i médií';
+$lang['qb_bold'] = 'Tučně';
+$lang['qb_italic'] = 'Kurzíva';
+$lang['qb_underl'] = 'Podtržení';
+$lang['qb_code'] = 'Neformátovat (zdrojový kód)';
+$lang['qb_strike'] = 'Přeškrtnutý text';
+$lang['qb_h1'] = 'Nadpis 1. úrovně';
+$lang['qb_h2'] = 'Nadpis 2. úrovně';
+$lang['qb_h3'] = 'Nadpis 3. úrovně';
+$lang['qb_h4'] = 'Nadpis 4. úrovně';
+$lang['qb_h5'] = 'Nadpis 5. úrovně';
+$lang['qb_h'] = 'Nadpis';
+$lang['qb_hs'] = 'Vybrat nadpis';
+$lang['qb_hplus'] = 'Nadpis vyšší úrovně';
+$lang['qb_hminus'] = 'Nadpis nižší úrovně';
+$lang['qb_hequal'] = 'Nadpis stejné úrovně';
+$lang['qb_link'] = 'Interní odkaz';
+$lang['qb_extlink'] = 'Externí odkaz';
+$lang['qb_hr'] = 'Vodorovná čára';
+$lang['qb_ol'] = 'Číslovaný seznam';
+$lang['qb_ul'] = 'Nečíslovaný seznam';
+$lang['qb_media'] = 'Vložit obrázky nebo jiné soubory';
+$lang['qb_sig'] = 'Vložit podpis';
+$lang['qb_smileys'] = 'Emotikony';
+$lang['qb_chars'] = 'Speciální znaky';
+$lang['upperns'] = 'skočit do nadřazeného jmenného prostoru';
+$lang['admin_register'] = 'Přidat nového uživatele';
+$lang['metaedit'] = 'Upravit Metadata';
+$lang['metasaveerr'] = 'Chyba při zápisu metadat';
+$lang['metasaveok'] = 'Metadata uložena';
+$lang['img_backto'] = 'Zpět na';
+$lang['img_title'] = 'Titulek';
+$lang['img_caption'] = 'Popis';
+$lang['img_date'] = 'Datum';
+$lang['img_fname'] = 'Jméno souboru';
+$lang['img_fsize'] = 'Velikost';
+$lang['img_artist'] = 'Autor fotografie';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Formát';
+$lang['img_camera'] = 'Typ fotoaparátu';
+$lang['img_keywords'] = 'Klíčová slova';
+$lang['img_width'] = 'Šířka';
+$lang['img_height'] = 'Výška';
+$lang['img_manager'] = 'Zobrazit ve správě médií';
+$lang['subscr_subscribe_success'] = '%s byl přihlášen do seznamu odběratelů %s';
+$lang['subscr_subscribe_error'] = 'Došlo k chybě při přihlašování %s do seznamu odběratelů %s';
+$lang['subscr_subscribe_noaddress'] = 'K Vašemu loginu neexistuje žádná adresa, nemohl jste být přihlášen do seznamu odběratelů.';
+$lang['subscr_unsubscribe_success'] = '%s byl odhlášen ze seznamu odběratelů %s';
+$lang['subscr_unsubscribe_error'] = 'Došlo k chybě při odhlašování %s ze seznamu odběratelů %s';
+$lang['subscr_already_subscribed'] = '%s již je přihlášen do seznamu odběratelů %s';
+$lang['subscr_not_subscribed'] = '%s není přihlášen do seznamu odběratelů %s';
+$lang['subscr_m_not_subscribed'] = 'V současné době neodebíráte změny na aktuální stránce nebo ve jmenném prostoru.';
+$lang['subscr_m_new_header'] = 'Přihlásit k odebírání změn emailem';
+$lang['subscr_m_current_header'] = 'Aktuální odběratelé změn';
+$lang['subscr_m_unsubscribe'] = 'Odhlásit z odběru změn emailem';
+$lang['subscr_m_subscribe'] = 'Přihlásit se k odběru změn emailem';
+$lang['subscr_m_receive'] = 'Přejete si dostávat';
+$lang['subscr_style_every'] = 'email pro každou změnu';
+$lang['subscr_style_digest'] = 'souhrnný email změn pro každou stránku (každé %.2f dny/dní)';
+$lang['subscr_style_list'] = 'seznam změněných stránek od posledního emailu (každé %.2f dny/dní)';
+$lang['authmodfailed'] = 'Autentizace uživatelů je špatně nastavena. Informujte prosím správce této wiki.';
+$lang['authtempfail'] = 'Autentizace uživatelů je dočasně nedostupná. Pokud tento problém přetrvává, informujte prosím správce této wiki.';
+$lang['i_chooselang'] = 'Vyberte si jazyk';
+$lang['i_installer'] = 'Instalace DokuWiki';
+$lang['i_wikiname'] = 'Název wiki';
+$lang['i_enableacl'] = 'Zapnout ACL (doporučeno)';
+$lang['i_superuser'] = 'Správce';
+$lang['i_problems'] = 'Instalátor narazil na níže popsané problémy. Nelze pokračovat v instalaci, dokud je neopravíte.';
+$lang['i_modified'] = 'Instalátor bude z bezpečnostních důvodů pracovat pouze s čistou a ještě neupravenou instalací DokuWiki. Buď znovu rozbalte soubory z instalačního balíčku, nebo zkuste prostudovat <a href="http://dokuwiki.org/install">instrukce pro instalaci DokuWiki</a>.';
+$lang['i_funcna'] = 'PHP funkce <code>%s</code> není dostupná. Váš webhosting ji možná z nějakého důvodu vypnul.';
+$lang['i_phpver'] = 'Verze vaší instalace PHP <code>%s</code> je nižší než požadovaná <code>%s</code>. Budete muset aktualizovat svou instalaci PHP.';
+$lang['i_permfail'] = 'DokuWiki nemůže zapisovat do <code>%s</code>. Budete muset opravit práva k tomuto adresáři.';
+$lang['i_confexists'] = '<code>%s</code> již existuje';
+$lang['i_writeerr'] = 'Nelze vytvořit <code>%s</code>. Budete muset zkontrolovat práva k souborům či adresářům a vytvořit tento soubor ručně.';
+$lang['i_badhash'] = 'soubor dokuwiki.php (hash=<code>%s</code>) nebyl rozpoznán nebo byl upraven';
+$lang['i_badval'] = '<code>%s</code> - neplatná nebo prázdná hodnota';
+$lang['i_success'] = 'Konfigurace byla úspěšně dokončena. Nyní můžete smazat soubor install.php. Pokračujte do <a href="doku.php">své nové DokuWiki</a>.';
+$lang['i_failure'] = 'Vyskytly se nějaké chyby při zápisu do konfiguračních souborů. Budete je nejspíš muset upravit ručně před použitím <a href="doku.php">své nové DokuWiki</a>.';
+$lang['i_policy'] = 'Úvodní politika ACL';
+$lang['i_pol0'] = 'Otevřená wiki (čtení, zápis a upload pro všechny)';
+$lang['i_pol1'] = 'Veřejná wiki (čtení pro všechny, zápis a upload pro registrované uživatele)';
+$lang['i_pol2'] = 'Uzavřená wiki (čtení, zápis a upload pouze pro registrované uživatele)';
+$lang['i_retry'] = 'Zkusit znovu';
+$lang['i_license'] = 'Vyberte prosím licenci obsahu:';
+$lang['recent_global'] = 'Právě si prohlížíte změny ve jmenném prostoru <b>%s</b>. Také si můžete <a href="%s">zobrazit změny v celé wiki</a>.';
+$lang['years'] = 'před %d roky';
+$lang['months'] = 'před %d měsíci';
+$lang['weeks'] = 'před %d týdny';
+$lang['days'] = 'před %d dny';
+$lang['hours'] = 'před %d hodinami';
+$lang['minutes'] = 'před %d minutami';
+$lang['seconds'] = 'před %d sekundami';
+$lang['wordblock'] = 'Vaše změny nebyly uloženy, protože obsahují blokovaný text(spam).';
+$lang['media_uploadtab'] = 'Nahrát';
+$lang['media_searchtab'] = 'Hledat';
+$lang['media_file'] = 'Soubor';
+$lang['media_viewtab'] = 'Zobrazit';
+$lang['media_edittab'] = 'Upravit';
+$lang['media_historytab'] = 'Historie';
+$lang['media_list_thumbs'] = 'Zmenšeniny';
+$lang['media_list_rows'] = 'Řádky';
+$lang['media_sort_name'] = 'Jméno';
+$lang['media_sort_date'] = 'Datum';
+$lang['media_namespaces'] = 'Vyber jmenný prostor';
+$lang['media_files'] = 'Soubory v %s';
+$lang['media_upload'] = 'Upload do %s';
+$lang['media_search'] = 'Hledat v %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s na %s';
+$lang['media_edit'] = 'Upravit %s';
+$lang['media_history'] = 'Historie %s';
+$lang['media_meta_edited'] = 'metadata upravena';
+$lang['media_perm_read'] = 'Bohužel, nemáte práva číst soubory.';
+$lang['media_perm_upload'] = 'Bohužel, nemáte práva nahrávat soubory.';
+$lang['media_update'] = 'Nahrát novou verzi';
+$lang['media_restore'] = 'Obnovit tuto verzi';
+$lang['plugin_install_err'] = 'Plugin je špatně nainstalován. Přejmenujte adresář pluginu \'%s\' na \'%s\'.';
diff --git a/inc/lang/cs/locked.txt b/inc/lang/cs/locked.txt
new file mode 100644
index 000000000..23fd943a1
--- /dev/null
+++ b/inc/lang/cs/locked.txt
@@ -0,0 +1,3 @@
+====== Stránka je zamknutá ======
+
+Tato stránka je právě zamknutá pro úpravy jiným uživatelem. Musíte počkat, než onen uživatel dokončí své úpravy nebo než tento zámek vyprší.
diff --git a/inc/lang/cs/login.txt b/inc/lang/cs/login.txt
new file mode 100644
index 000000000..a44ae599a
--- /dev/null
+++ b/inc/lang/cs/login.txt
@@ -0,0 +1,3 @@
+====== Přihlášení ======
+
+Momentálně nejste přihlášen(a)! Prosím vložte své identifikační údaje níže. Pro přihlášení musíte mít zapnuté cookies.
diff --git a/inc/lang/cs/mailtext.txt b/inc/lang/cs/mailtext.txt
new file mode 100644
index 000000000..f235a299b
--- /dev/null
+++ b/inc/lang/cs/mailtext.txt
@@ -0,0 +1,17 @@
+Stránka ve vaší DokuWiki byla změněna. Zde jsou podrobnosti:
+
+Datum : @DATE@
+Prohlížeč : @BROWSER@
+IP adresa : @IPADDRESS@
+Hostitel : @HOSTNAME@
+Stará verze : @OLDPAGE@
+Nová verze : @NEWPAGE@
+Komentář : @SUMMARY@
+Uživatel : @USER@
+
+@DIFF@
+
+
+--
+Tento email byl automaticky vygenerován systémem DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/cs/newpage.txt b/inc/lang/cs/newpage.txt
new file mode 100644
index 000000000..091250af7
--- /dev/null
+++ b/inc/lang/cs/newpage.txt
@@ -0,0 +1,3 @@
+====== Stránka s tímto názvem ještě neexistuje ======
+
+Odkaz vás zavedl na stránku, která ještě neexistuje. Můžete ji vytvořit stisknutím tlačítka ''Vytvořit stránku''.
diff --git a/inc/lang/cs/norev.txt b/inc/lang/cs/norev.txt
new file mode 100644
index 000000000..f601f5899
--- /dev/null
+++ b/inc/lang/cs/norev.txt
@@ -0,0 +1,3 @@
+====== Taková verze neexistuje ======
+
+Zadaná verze neexistuje. Stiskněte tlačítko ''Starší verze'' pro seznam starších verzí tohoto dokumentu.
diff --git a/inc/lang/cs/password.txt b/inc/lang/cs/password.txt
new file mode 100644
index 000000000..18f21f1b1
--- /dev/null
+++ b/inc/lang/cs/password.txt
@@ -0,0 +1,11 @@
+Dobrý den,
+
+Zde jsou přihlašovací informace pro wiki @TITLE@ (@DOKUWIKIURL@)
+
+Jméno : @FULLNAME@
+Uživatelské jméno : @LOGIN@
+Heslo : @PASSWORD@
+
+--
+Tento email byl automaticky vygenerován systémem DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/cs/preview.txt b/inc/lang/cs/preview.txt
new file mode 100644
index 000000000..079eda4e7
--- /dev/null
+++ b/inc/lang/cs/preview.txt
@@ -0,0 +1,3 @@
+====== Náhled ======
+
+Zde je náhled, jak bude dokument vypadat. Pozor: Soubor zatím **není uložen**!
diff --git a/inc/lang/cs/pwconfirm.txt b/inc/lang/cs/pwconfirm.txt
new file mode 100644
index 000000000..aa37b3b84
--- /dev/null
+++ b/inc/lang/cs/pwconfirm.txt
@@ -0,0 +1,13 @@
+Dobrý den,
+
+Někdo požádal o nové heslo k vašemu uživatelskému účtu na wiki @TITLE@ (@DOKUWIKIURL@)
+
+Pokud jste o nové heslo nežádali, ignorujte prosím tento email.
+
+Pro potvrzení, že jste tento požadavek poslali opravdu vy, prosím otevřete následující odkaz.
+
+@CONFIRM@
+
+--
+Tento email byl automaticky vygenerován systémem DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/cs/read.txt b/inc/lang/cs/read.txt
new file mode 100644
index 000000000..d5b2d73cb
--- /dev/null
+++ b/inc/lang/cs/read.txt
@@ -0,0 +1 @@
+Tato stránka je pouze pro čtení. Můžete si pouze prohlédnout zdrojový kód, ale ne ho měnit. Zeptejte se správce, pokud si myslíte, že něco není v pořádku.
diff --git a/inc/lang/cs/recent.txt b/inc/lang/cs/recent.txt
new file mode 100644
index 000000000..e4ca5e9bc
--- /dev/null
+++ b/inc/lang/cs/recent.txt
@@ -0,0 +1,3 @@
+====== Poslední úpravy ======
+
+Následující stránky byly nedávno změněny.
diff --git a/inc/lang/cs/register.txt b/inc/lang/cs/register.txt
new file mode 100644
index 000000000..b0d6bb1ff
--- /dev/null
+++ b/inc/lang/cs/register.txt
@@ -0,0 +1,3 @@
+====== Zaregistrujte se jako nový uživatel ======
+
+Abyste získali uživatelský účet, vyplňte prosím všechny informace v následujícím formuláři. Zadejte **platnou** mailovou adresu, na níž bude zasláno heslo. Uživatelské jméno musí být v platném [[doku>pagename|formátu]] (který je stejný jako formát názvu stránky).
diff --git a/inc/lang/cs/registermail.txt b/inc/lang/cs/registermail.txt
new file mode 100644
index 000000000..7f5e4feb1
--- /dev/null
+++ b/inc/lang/cs/registermail.txt
@@ -0,0 +1,14 @@
+Zaregistroval se nový uživatel. Zde jsou detaily:
+
+Uživatelské jméno : @NEWUSER@
+Celé jméno : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Datum : @DATE@
+Prohlížeč : @BROWSER@
+IP adresa : @IPADDRESS@
+Hostitel : @HOSTNAME
+
+--
+Tento email byl automaticky vygenerován systémem DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/cs/resendpwd.txt b/inc/lang/cs/resendpwd.txt
new file mode 100644
index 000000000..1d2aa0d97
--- /dev/null
+++ b/inc/lang/cs/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Zaslat nové heslo ======
+
+Abyste získali nové heslo k vašemu učtu v této wiki, vyplňte všechny níže uvedené informace . Vaše nové heslo bude zasláno na emailovou adresu, kterou jste zadali při registraci. Uživatelské jméno by mělo být stejné jako vaše uživatelské jméno, s nímž se přihlašujete do této wiki.
diff --git a/inc/lang/cs/revisions.txt b/inc/lang/cs/revisions.txt
new file mode 100644
index 000000000..e3744b76f
--- /dev/null
+++ b/inc/lang/cs/revisions.txt
@@ -0,0 +1,3 @@
+====== Starší verze ======
+
+Zde jsou starší verze daného dokumentu. Pro návrat ke starší verzi si ji zvolte ze seznamu níže, stiskněte tlačítko ''Upravit stránku'' a uložte ji.
diff --git a/inc/lang/cs/searchpage.txt b/inc/lang/cs/searchpage.txt
new file mode 100644
index 000000000..ac045e100
--- /dev/null
+++ b/inc/lang/cs/searchpage.txt
@@ -0,0 +1,5 @@
+====== Vyhledávání ======
+
+Výsledky hledání můžete vidět níže. Pokud jste nenašli, co hledáte, zkuste požadovanou stránku sami vytvořit stisknutím tlačítka ''Vytvořit stránku''.
+
+===== Výsledky =====
diff --git a/inc/lang/cs/showrev.txt b/inc/lang/cs/showrev.txt
new file mode 100644
index 000000000..48be467b2
--- /dev/null
+++ b/inc/lang/cs/showrev.txt
@@ -0,0 +1,3 @@
+**Toto je starší verze dokumentu!**
+----
+
diff --git a/inc/lang/cs/stopwords.txt b/inc/lang/cs/stopwords.txt
new file mode 100644
index 000000000..26d874143
--- /dev/null
+++ b/inc/lang/cs/stopwords.txt
@@ -0,0 +1,944 @@
+# Stopwords for Czech - generated from ispell-cs (license: GNU GPL)
+aby
+ako
+akorát
+ale
+and
+ani
+ano
+apod
+asi
+atd
+během
+bez
+beze
+blízko
+bohudík
+bohužel
+bokem
+buď
+bude
+budem
+budeme
+budeš
+budete
+budiž
+budou
+budu
+bůhvíco
+bůhvíčí
+bůhvíjak
+bůhvíjaký
+bůhvíkam
+bůhvíkde
+bůhvíkdo
+bůhvíkdy
+bůhvíkolik
+bůhvíkterý
+bůhvínač
+bůhvíproč
+bych
+bychom
+byl
+byla
+byli
+bylo
+byly
+bysme
+být
+cca
+cokoli
+cokoliv
+copak
+cosi
+což
+cože
+častěji
+často
+čeho
+čehokoli
+čehokoliv
+čehosi
+čehož
+čem
+čemkoli
+čemkoliv
+čemsi
+čemu
+čemukoli
+čemukoliv
+čemusi
+čemuž
+čemž
+čertvíco
+čertvíčí
+čertvíjak
+čertvíjaký
+čertvíkam
+čertvíkde
+čertvíkdo
+čertvíkdy
+čertvíkolik
+čertvíkterý
+čertvínač
+čertvíproč
+číhokoli
+číhosi
+číchkoli
+číchsi
+číkoli
+čím
+čímakoli
+čímasi
+čímikoli
+čímisi
+čímkoli
+čímkoliv
+čímpak
+čímsi
+čímukoli
+čímusi
+čímž
+čísi
+dál
+dále
+daleko
+další
+dám
+dle
+dnem
+dnes
+dneska
+dobrá
+dobré
+dobrý
+dobře
+docela
+dokonce
+doposavad
+doposud
+doprostřed
+dosavad
+dospod
+dospodu
+dost
+dosti
+dosud
+dovnitř
+eště
+formou
+ho
+hodinou
+hodně
+horší
+hůř
+hůře
+chceš
+chci
+chtěl
+jacíkoli
+jacíkoliv
+jacípak
+jacísi
+jak
+jakákoli
+jakákoliv
+jakápak
+jakási
+jaké
+jakéhokoli
+jakéhokoliv
+jakéhopak
+jakéhosi
+jakékoli
+jakékoliv
+jakémkoli
+jakémkoliv
+jakémpak
+jakémsi
+jakémukoli
+jakémukoliv
+jakémupak
+jakémusi
+jaképak
+jakési
+jakmile
+jako
+jakou
+jakoukoli
+jakoukoliv
+jakoupak
+jakousi
+jakož
+jakpak
+jaký
+jakýchkoli
+jakýchkoliv
+jakýchpak
+jakýchsi
+jakýkoli
+jakýkoliv
+jakýmakoli
+jakýmakoliv
+jakýmapak
+jakýmasi
+jakýmikoli
+jakýmikoliv
+jakýmipak
+jakýmisi
+jakýmkoli
+jakýmkoliv
+jakýmpak
+jakýmsi
+jakýpak
+jakýsi
+jakže
+jasné
+jasně
+jde
+je
+jediná
+jediné
+jediný
+jeho
+jehož
+jej
+její
+jejíhož
+jejich
+jejichž
+jejíchž
+jejímaž
+jejímiž
+jejímuž
+jejímž
+jejíž
+jejž
+jelikož
+jemu
+jemuž
+jen
+jenom
+jenž
+jenže
+jestli
+ještě
+jež
+ježto
+ji
+jí
+jich
+jichž
+jim
+jím
+jimi
+jimiž
+jimž
+jímž
+jiná
+jinak
+jiné
+jinou
+jiný
+jiných
+jiným
+jisté
+jistě
+již
+jíž
+jménem
+jsem
+jseš
+jsi
+jsme
+jsou
+jste
+kam
+každý
+kde
+kdeco
+kdečí
+kdejaký
+kdekdo
+kdekterý
+kdepak
+kdesi
+kdo
+kdokoli
+kdokoliv
+kdopak
+kdosi
+kdovíjak
+kdovíkde
+kdovíkdo
+kdož
+kdy
+kdysi
+když
+kohokoli
+kohokoliv
+kohopak
+kohosi
+kohož
+kol
+kolem
+kolik
+kolikže
+kolkolem
+komkoli
+komkoliv
+kompak
+komsi
+komu
+komukoli
+komukoliv
+komupak
+komusi
+komuž
+komž
+koncem
+konče
+končí
+končíc
+konec
+kontra
+kromě
+která
+kterákoli
+kterákoliv
+kterási
+kterážto
+které
+kteréhokoli
+kteréhokoliv
+kteréhosi
+kteréhož
+kterékoli
+kterékoliv
+kterém
+kterémkoli
+kterémkoliv
+kterémsi
+kterémukoli
+kterémukoliv
+kterémusi
+kterémuž
+kterémžto
+kterési
+kteréžto
+kterou
+kteroukoli
+kteroukoliv
+kterousi
+kteroužto
+který
+kterýchkoli
+kterýchkoliv
+kterýchsi
+kterýchžto
+kterýkoli
+kterýkoliv
+kterým
+kterýmakoli
+kterýmakoliv
+kterýmasi
+kterýmikoli
+kterýmikoliv
+kterýmisi
+kterýmiž
+kterýmkoli
+kterýmkoliv
+kterýmsi
+kterýmžto
+kterýsi
+kterýžto
+kteří
+kteřísi
+kteřížto
+ktříkoli
+ktříkoliv
+kupodivu
+kupříkladu
+kvůli
+kýmkoli
+kýmkoliv
+kýmpak
+kýmsi
+kýmž
+lecco
+leccos
+lecčems
+lecjak
+lecjaký
+leckam
+leckams
+leckde
+leckdo
+leckdy
+leckterý
+ledaco
+ledacos
+ledačí
+ledajak
+ledajaký
+ledakdo
+ledakterý
+ledaskam
+ledaskde
+ledaskdo
+ledaskdy
+lépe
+lepší
+líp
+má
+mají
+málo
+máloco
+málokdo
+málokterý
+mám
+máme
+máš
+máte
+max
+mé
+mě
+mého
+měl
+měla
+mělo
+mém
+mému
+mezi
+mi
+mí
+mimo
+min
+míň
+místo
+mít
+mne
+mně
+mnoho
+mnou
+moc
+mohl
+mohla
+mohou
+mohu
+moje
+moji
+mojí
+mou
+možná
+mu
+můj
+musel
+muset
+musí
+musím
+musíš
+musíte
+může
+můžeš
+můžete
+můžu
+my
+mých
+mým
+mými
+nač
+načež
+načpak
+nad
+nade
+nám
+námi
+namísto
+naň
+naprosto
+naproti
+např
+napříč
+nás
+náš
+naši
+navíc
+navrch
+navrchu
+navzdory
+ně
+nebo
+nebude
+nebyl
+nebyli
+nebyly
+něco
+něčí
+nedaleko
+nehledíc
+něho
+něhož
+nechceš
+nechci
+nechť
+nechtěl
+něj
+nějak
+nějaká
+nějaké
+nějakého
+nějakou
+nějaký
+nejasné
+nejasný
+nejčastěji
+nejde
+nejen
+nejhůř
+nejhůře
+nejlépe
+nejnižší
+nejsem
+nejsou
+nejvyšší
+nějž
+někam
+někde
+někdo
+někdy
+několik
+nekončí
+některý
+nelze
+něm
+nemá
+nemají
+nemálo
+nemám
+nemáme
+nemáš
+nemáte
+nemít
+nemohl
+nemohla
+nemohou
+nemohu
+němu
+nemusel
+nemuset
+nemusí
+nemusím
+nemusíš
+němuž
+nemůže
+nemůžeš
+nemůžete
+nemůžu
+němž
+není
+nepřesná
+nepřesné
+nepřesně
+nepřesný
+nepřímo
+netřeba
+netuším
+netýká
+neví
+nevím
+nevíš
+nevlastní
+nevyjímaje
+nevyjímajíc
+než
+něž
+ni
+ní
+nic
+ničeho
+ničem
+ničemu
+ničí
+ničím
+nie
+nieje
+nich
+nichž
+nijaký
+nikdo
+nikto
+nim
+ním
+nimi
+nimiž
+nimž
+nímž
+nízká
+niž
+níž
+nižádný
+níže
+nižší
+nový
+nutně
+oba
+obě
+oběma
+obou
+oč
+očpak
+ode
+odspoda
+odspodu
+ohledně
+okamžikem
+okolo
+on
+oň
+ona
+onen
+oni
+ono
+ony
+opravdu
+oproti
+ostatní
+osum
+pak
+poblíž
+počátkem
+počínaje
+počínajíc
+pod
+pode
+podél
+podle
+podobně
+pokud
+poměrně
+pomocí
+ponad
+pořád
+poslední
+posléze
+posud
+potom
+pražádný
+pro
+proč
+pročpak
+proň
+prostě
+proti
+proto
+protože
+před
+přede
+předem
+přes
+přese
+přesná
+přesné
+přesně
+přesný
+při
+přičemž
+přímo
+případná
+případné
+případně
+případný
+přitom
+půlí
+raději
+rokem
+sám
+sama
+samá
+samé
+samého
+samém
+samému
+sami
+samo
+samou
+samozřejmě
+samozřejmý
+samu
+samy
+samý
+samých
+samým
+samými
+se
+sebe
+sebou
+sem
+ses
+si
+sice
+sis
+skoro
+skrz
+skrze
+snad
+sobě
+som
+sotva
+sotvaco
+sotvakdo
+spíš
+spíše
+spodem
+spolu
+stačí
+stejně
+stranou
+středem
+svá
+své
+svého
+svém
+svému
+sví
+svoje
+svoji
+svojí
+svou
+svrchu
+svůj
+svých
+svým
+svými
+špatná
+špatné
+špatně
+špatný
+tací
+tady
+tahle
+tak
+taká
+také
+takhle
+takováto
+takové
+takovéhoto
+takovémto
+takovémuto
+takovéto
+takovíto
+takovouto
+takový
+takovýchto
+takovýma
+takovýmato
+takovýmito
+takovýmto
+takovýto
+takto
+taky
+taký
+takže
+tam
+tamten
+tatáž
+tato
+táž
+tě
+tebe
+tebou
+teď
+teda
+tedy
+téhle
+téhož
+těchhle
+těchto
+těchže
+těm
+téma
+těmahle
+těmhle
+těmihle
+těmito
+těmto
+těmu
+témuž
+témž
+témže
+ten
+tenhle
+tenhleten
+tento
+tentýž
+této
+téže
+ti
+tihle
+tím
+tímhle
+tímtéž
+tímto
+titíž
+tito
+tíž
+tobě
+tohle
+toho
+tohohle
+tohoto
+tom
+tomhle
+tomtéž
+tomto
+tomu
+tomuhle
+tomuto
+totéž
+toto
+touhle
+toutéž
+touto
+touž
+touže
+trochu
+trošku
+třeba
+tuhle
+tutéž
+tuto
+tvá
+tvé
+tvého
+tvém
+tvému
+tví
+tvoje
+tvoji
+tvojí
+tvou
+tvůj
+tvých
+tvým
+tvými
+ty
+tyhle
+týchž
+týká
+týmiž
+týmž
+tys
+tytéž
+tyto
+týž
+úderem
+uplná
+uplné
+úplně
+úplný
+uprostřed
+určitě
+uvnitř
+úvodem
+vám
+vámi
+vás
+váš
+vaše
+vaši
+včetně
+vedle
+velmi
+veprostřed
+versus
+vespod
+vespodu
+veškerý
+vevnitř
+víc
+více
+vím
+vinou
+víš
+viz
+vlastně
+vlivem
+vně
+vnitřka
+vnitřkem
+vnitřku
+von
+vrchem
+však
+vše
+všecek
+všecka
+všecko
+všecky
+všeho
+všech
+všechen
+všechna
+všechno
+všechnu
+všechny
+všelico
+všelicos
+všeličehos
+všeličems
+všeličemus
+všeličí
+všeličíms
+všelijaký
+všelikdo
+všeliký
+všeliskdo
+všem
+všemi
+všemu
+vši
+vší
+všicci
+všichni
+vším
+vůbec
+vůči
+vy
+vyjma
+vysoká
+výše
+vyšší
+vzdor
+vzhledem
+vždy
+za
+zač
+začátkem
+začpak
+zaň
+zásluhou
+zatím
+závěrem
+zboku
+zcela
+zčásti
+zda
+zdaleka
+zde
+zespoda
+zespodu
+zevnitř
+zeza
+znovu
+zpět
+zpod
+zponad
+zpoza
+zprostřed
+zřídkaco
+zřídkakdo
+zvnitřka
+zvnitřku
+žádný
diff --git a/inc/lang/cs/subscr_digest.txt b/inc/lang/cs/subscr_digest.txt
new file mode 100644
index 000000000..57b7240c5
--- /dev/null
+++ b/inc/lang/cs/subscr_digest.txt
@@ -0,0 +1,22 @@
+Dobrý den!
+
+Byla změněna stránka @PAGE@ ve wiki @TITLE@.
+Zde jsou změny:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Stará revize: @OLDPAGE@
+Nová revize: @NEWPAGE@
+
+Pro odhlášení z odebírání změn na této webové stránce
+se prosím příhlašte do wiki na adrese
+@DOKUWIKIURL@,pak navštivte
+@SUBSCRIBE@
+a odhlaště se z odebírání změn na stránce či
+ve jmenném prostoru.
+
+--
+Tento email byl automaticky vygenerován systémem DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/cs/subscr_form.txt b/inc/lang/cs/subscr_form.txt
new file mode 100644
index 000000000..d051b646f
--- /dev/null
+++ b/inc/lang/cs/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Správa odběratelů změn ======
+
+Tato stránka Vám umožňuje spravovat uživatele přihlášené k odběru změn aktuální stránky nebo jmenného prostoru. \ No newline at end of file
diff --git a/inc/lang/cs/subscr_list.txt b/inc/lang/cs/subscr_list.txt
new file mode 100644
index 000000000..82683c57f
--- /dev/null
+++ b/inc/lang/cs/subscr_list.txt
@@ -0,0 +1,19 @@
+Dobrý den!
+
+Byly změněny stránky ve jmenném prostoru @PAGE@ wiki @TITLE@.
+Zde jsou:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Pro odhlášení z odebírání změn
+se prosím příhlašte do wiki na adrese
+@DOKUWIKIURL@,pak navštivte
+@SUBSCRIBE@
+a odhlaště se z odebírání změn na stránce či
+ve jmenném prostoru.
+
+--
+Tento email byl automaticky vygenerován systémem DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/cs/subscr_single.txt b/inc/lang/cs/subscr_single.txt
new file mode 100644
index 000000000..c0089c1b7
--- /dev/null
+++ b/inc/lang/cs/subscr_single.txt
@@ -0,0 +1,25 @@
+Dobrý den!
+
+Byla změněna stránka @PAGE@ ve wiki @TITLE@.
+Zde jsou změny:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Datum: @DATE@
+Uživatel: @USER@
+Souhrn editace: @SUMMARY@
+Stará revize: @OLDPAGE@
+Nová revize: @NEWPAGE@
+
+Pro odhlášení z odebírání změn na této webové stránce
+se prosím příhlašte do wiki na adrese
+@DOKUWIKIURL@,pak navštivte
+@SUBSCRIBE@
+a odhlaště se z odebírání změn na stránce či
+ve jmenném prostoru.
+
+--
+Tento email byl automaticky vygenerován systémem DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/cs/updateprofile.txt b/inc/lang/cs/updateprofile.txt
new file mode 100644
index 000000000..d5eadc66c
--- /dev/null
+++ b/inc/lang/cs/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Upravit profil vašeho učtu ======
+
+Vyplňte pouze pole, která chcete změnit. Nemůžete ale změnit své uživatelské jméno.
+
+
diff --git a/inc/lang/cs/uploadmail.txt b/inc/lang/cs/uploadmail.txt
new file mode 100644
index 000000000..b19b0bf7e
--- /dev/null
+++ b/inc/lang/cs/uploadmail.txt
@@ -0,0 +1,14 @@
+Do vaší DokuWiki byl nahrán nový dokument. Tady jsou detaily:
+
+Soubor : @MEDIA@
+Datum : @DATE@
+Prohlážeč : @BROWSER@
+IP adresa : @IPADDRESS@
+Hostitel : @HOSTNAME@
+Velikost : @SIZE@
+MIME typ : @MIME@
+Uživatel : @USER@
+
+--
+Tento email byl automaticky vygenerován systémem DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/da/admin.txt b/inc/lang/da/admin.txt
new file mode 100644
index 000000000..3ac4a70df
--- /dev/null
+++ b/inc/lang/da/admin.txt
@@ -0,0 +1,4 @@
+====== Administration ======
+
+Nedenfor kan du finde en række administrative værktøjer.
+
diff --git a/inc/lang/da/adminplugins.txt b/inc/lang/da/adminplugins.txt
new file mode 100644
index 000000000..2a3d687f1
--- /dev/null
+++ b/inc/lang/da/adminplugins.txt
@@ -0,0 +1 @@
+===== Yderligere udvidelser ===== \ No newline at end of file
diff --git a/inc/lang/da/backlinks.txt b/inc/lang/da/backlinks.txt
new file mode 100644
index 000000000..6dfa3cc43
--- /dev/null
+++ b/inc/lang/da/backlinks.txt
@@ -0,0 +1,4 @@
+====== Henvisninger bagud ======
+
+Dette er en liste over alle de dokumenter der henviser tilbage til det nuværende dokument.
+
diff --git a/inc/lang/da/conflict.txt b/inc/lang/da/conflict.txt
new file mode 100644
index 000000000..fc38cee63
--- /dev/null
+++ b/inc/lang/da/conflict.txt
@@ -0,0 +1,5 @@
+====== Der eksisterer en nyere udgave af dokumentet ======
+
+Der eksisterer en nyere udgave af dette dokument. Det sker når flere brugere ændrer i dokumentet på samme tid.
+
+Gennemgå de viste forskelle grundigt, og beslut hvilken udgave der skal bevares. Hvis du vælger ''Gem'', bliver din udgave af dokumentet gemt. Vælger du ''Fortryd'' beholder du den nuværende udgave.
diff --git a/inc/lang/da/denied.txt b/inc/lang/da/denied.txt
new file mode 100644
index 000000000..a4fa8b88f
--- /dev/null
+++ b/inc/lang/da/denied.txt
@@ -0,0 +1,3 @@
+====== Adgang nægtet! ======
+
+Du har ikke rettigheder til at fortsætte. Måske er du ikke logget ind.
diff --git a/inc/lang/da/diff.txt b/inc/lang/da/diff.txt
new file mode 100644
index 000000000..f77224f2f
--- /dev/null
+++ b/inc/lang/da/diff.txt
@@ -0,0 +1,4 @@
+====== Forskelle ======
+
+Dette viser forskellene mellem den valgte og den nuværende udgave af dokumentet. Gul er linjer der findes i den gamle udgave, og grøn er linjer der findes i den nuværende.
+
diff --git a/inc/lang/da/draft.txt b/inc/lang/da/draft.txt
new file mode 100644
index 000000000..69c780140
--- /dev/null
+++ b/inc/lang/da/draft.txt
@@ -0,0 +1,6 @@
+====== Kladdefil fundet ======
+
+Din sidste redigeringssession på denne side blev ikke afsluttet korrekt. DokuWiki har automatisk gemt en kladde mens du arbejdede, som du kan benytte til at fortsætte redigeringen. Forneden kan du se de data der blev gemt fra din sidste session.
+
+Vælg venligst, om du vil //gendanne// din tabte redigering, //slette// den gemte kladde eller //afbryde// redigeringen.
+
diff --git a/inc/lang/da/edit.txt b/inc/lang/da/edit.txt
new file mode 100644
index 000000000..0a9ea39dc
--- /dev/null
+++ b/inc/lang/da/edit.txt
@@ -0,0 +1,2 @@
+Rediger dette dokument og tryk på knappen **''[Gem]''**. Se [[wiki:syntax|Formaterings tips]] for Wiki syntaks. Ret venligst kun dette dokument hvis du kan **forbedre** det. Brug venligst [[playground:playground|sandkassen]] til at teste før du retter i et rigtigt dokument. Husk også at bruge **''[Forhåndsvisning]''** før du gemmer dokumentet.
+
diff --git a/inc/lang/da/editrev.txt b/inc/lang/da/editrev.txt
new file mode 100644
index 000000000..438363e5d
--- /dev/null
+++ b/inc/lang/da/editrev.txt
@@ -0,0 +1,2 @@
+**Du har hentet en gammel udgave af dette dokument!** Hvis du gemmer dokumentet vil du overskrive den nuværende med den gamle udgave.
+----
diff --git a/inc/lang/da/index.txt b/inc/lang/da/index.txt
new file mode 100644
index 000000000..74afb9831
--- /dev/null
+++ b/inc/lang/da/index.txt
@@ -0,0 +1,3 @@
+====== Indeks ======
+
+Dette er en oversigt over alle tilgængelige dokumenter, sorteret efter [[doku>namespaces|navnerum]].
diff --git a/inc/lang/da/install.html b/inc/lang/da/install.html
new file mode 100644
index 000000000..5c53c5546
--- /dev/null
+++ b/inc/lang/da/install.html
@@ -0,0 +1,24 @@
+<p>Denne side hjælper til første-gangs installation og konfiguration af
+<a href="http://dokuwiki.org">Dokuwiki</a>. Mere information om denne
+installer er tilgængelig på dens egen
+<a href="http://dokuwiki.org/installer">dokumentations side</a>.</p>
+
+<p>DokuWiki bruger almindelige filer til at gemme wiki sider og anden
+information relaterende til disse sider (f.eks. billeder, søge indeks, gamle
+udgaver, osv). For at fungerer optimalt <strong>skal</strong> DokuWiki have
+skrive adgang til mapperne der holder disse filer. Denne installer er ikke
+istand til at opsætte mappe tilladelser. Det skal normalt udføres direkte i en
+kommando shell eller hvis du bruger hosting, gennem FTP eller dit hostings
+kontrol panel (f.eks. cPanel).</p>
+
+<p>Denne installer vil opsætte din DokuWiki konfiguration for
+<acronym title="access control list">ACL</acronym>, hvilket tillader
+administrator login og adgang til DokuWiki's adminstrative menu til
+installation af udvidelser, håndtering af brugere, håndtering af adgang til wiki
+sider og ændring af konfigurations indstillinger. Det er ikke et krav for at
+DokuWiki kan fungere, men det vil gøre DokuWiki lettere at administre.</p>
+
+<p>Erfarne brugere og brugere med specielle opsætningskrav burde bruge disse
+henvisninger for detaljer vedrørende
+<a href="http://dokuwiki.org/install">installations instruktioner</a>
+og <a href="http://dokuwiki.org/config">konfigurations indstillinger</a>.</p>
diff --git a/inc/lang/da/lang.php b/inc/lang/da/lang.php
new file mode 100644
index 000000000..e8a4e3fe9
--- /dev/null
+++ b/inc/lang/da/lang.php
@@ -0,0 +1,273 @@
+<?php
+/**
+ * danish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author koeppe <koeppe@kazur.dk>
+ * @author Jon Bendtsen <bendtsen@diku.dk>
+ * @author Lars Næsbye Christensen <larsnaesbye@stud.ku.dk>
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Rediger denne side';
+$lang['btn_source'] = 'Vis kildekode';
+$lang['btn_show'] = 'Vis side';
+$lang['btn_create'] = 'Opret denne side';
+$lang['btn_search'] = 'Søg';
+$lang['btn_save'] = 'Gem';
+$lang['btn_preview'] = 'Forhåndsvisning';
+$lang['btn_top'] = 'Tilbage til toppen';
+$lang['btn_newer'] = '<< forrige side';
+$lang['btn_older'] = 'næste side >>';
+$lang['btn_revs'] = 'Gamle udgaver';
+$lang['btn_recent'] = 'Nye ændringer';
+$lang['btn_upload'] = 'Overfør';
+$lang['btn_cancel'] = 'Fortryd';
+$lang['btn_index'] = 'Indeks';
+$lang['btn_secedit'] = 'Redigér';
+$lang['btn_login'] = 'Log ind';
+$lang['btn_logout'] = 'Log ud';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Opdatér';
+$lang['btn_delete'] = 'Slet';
+$lang['btn_back'] = 'Tilbage';
+$lang['btn_backlink'] = 'Henvisninger bagud';
+$lang['btn_backtomedia'] = 'Tilbage til valg af mediefil';
+$lang['btn_subscribe'] = 'Abonnér på ændringer';
+$lang['btn_profile'] = 'Opdatér profil';
+$lang['btn_reset'] = 'Nulstil';
+$lang['btn_resendpwd'] = 'Send ny adgangskode';
+$lang['btn_draft'] = 'Redigér kladde';
+$lang['btn_recover'] = 'Gendan kladde';
+$lang['btn_draftdel'] = 'Slet kladde';
+$lang['btn_revert'] = 'Reetablér';
+$lang['btn_register'] = 'Registrér';
+$lang['loggedinas'] = 'Logget ind som';
+$lang['user'] = 'Brugernavn';
+$lang['pass'] = 'Adgangskode';
+$lang['newpass'] = 'Ny adgangskode';
+$lang['oldpass'] = 'Bekræft gammel adgangskode';
+$lang['passchk'] = 'Gentag ny adgangskode';
+$lang['remember'] = 'Automatisk log ind';
+$lang['fullname'] = 'Fulde navn';
+$lang['email'] = 'E-mail';
+$lang['profile'] = 'Brugerprofil';
+$lang['badlogin'] = 'Brugernavn eller adgangskode var forkert.';
+$lang['minoredit'] = 'Mindre ændringer';
+$lang['draftdate'] = 'Kladde automatisk gemt d.';
+$lang['nosecedit'] = 'Siden blev ændret i mellemtiden, sektions information var for gammel, hentede hele siden i stedet.';
+$lang['regmissing'] = 'Du skal udfylde alle felter.';
+$lang['reguexists'] = 'Dette brugernavn er allerede i brug.';
+$lang['regsuccess'] = 'Du er nu oprettet som bruger. Dit adgangskode bliver sendt til dig i en e-mail.';
+$lang['regsuccess2'] = 'Du er nu oprettet som bruger.';
+$lang['regmailfail'] = 'Dit adgangskode blev ikke sendt. Kontakt venligst administratoren.';
+$lang['regbadmail'] = 'E-mail-adressen er ugyldig. Kontakt venligst administratoren, hvis du mener dette er en fejl.';
+$lang['regbadpass'] = 'De to adgangskoder er ikke ens, vær venlig at prøve igen.';
+$lang['regpwmail'] = 'Dit DokuWiki password';
+$lang['reghere'] = 'Opret en DokuWiki-konto her';
+$lang['profna'] = 'Denne wiki understøtter ikke ændring af profiler';
+$lang['profnochange'] = 'Ingen ændringer, intet modificeret.';
+$lang['profnoempty'] = 'Tomt navn eller e-mail adresse er ikke tilladt.';
+$lang['profchanged'] = 'Brugerprofil opdateret korrekt.';
+$lang['pwdforget'] = 'Har du glemt dit adgangskode? Få et nyt';
+$lang['resendna'] = 'Denne wiki understøtter ikke udsendelse af nyt adgangskode.';
+$lang['resendpwd'] = 'Send nyt adgangskode for';
+$lang['resendpwdmissing'] = 'Du skal udfylde alle felter.';
+$lang['resendpwdnouser'] = 'Vi kan ikke finde denne bruger i vores database.';
+$lang['resendpwdbadauth'] = 'Beklager, denne autoriseringskode er ikke gyldig. Kontroller venligst at du benyttede det fulde link til bekræftelse.';
+$lang['resendpwdconfirm'] = 'Et henvisning med bekræftelse er blevet sendt med email.';
+$lang['resendpwdsuccess'] = 'Dit nye adgangskode er blevet sendt med e-mail.';
+$lang['license'] = 'Med mindre andet angivet, vil indhold på denne wiki blive frigjort under følgende licens:';
+$lang['licenseok'] = 'Note: ved at ændre denne side, acceptere du at dit indhold bliver frigivet under følgende licens:';
+$lang['searchmedia'] = 'Søg filnavn';
+$lang['searchmedia_in'] = 'Søg i %s';
+$lang['txt_upload'] = 'Vælg den fil der skal overføres';
+$lang['txt_filename'] = 'Indtast wikinavn (valgfrit)';
+$lang['txt_overwrt'] = 'Overskriv eksisterende fil';
+$lang['lockedby'] = 'Midlertidig låst af';
+$lang['lockexpire'] = 'Lås udløber kl.';
+$lang['js']['willexpire'] = 'Din lås på dette dokument udløber om et minut.\nTryk på Forhåndsvisning-knappen for at undgå konflikter.';
+$lang['js']['notsavedyet'] = 'Ugemte ændringer vil blive mistet
+Fortsæt alligevel?';
+$lang['js']['searchmedia'] = 'Søg efter filer';
+$lang['js']['keepopen'] = 'Hold vindue åbent ved valg';
+$lang['js']['hidedetails'] = 'Skjul detaljer';
+$lang['js']['mediatitle'] = 'Link indstillinger';
+$lang['js']['mediadisplay'] = 'Link type';
+$lang['js']['mediaalign'] = 'Juster';
+$lang['js']['mediasize'] = 'Billede størrelse';
+$lang['js']['mediatarget'] = 'Link mål';
+$lang['js']['mediaclose'] = 'Luk';
+$lang['js']['mediainsert'] = 'Indsæt';
+$lang['js']['mediadisplayimg'] = 'Vis billedet';
+$lang['js']['mediadisplaylnk'] = 'Vis kun linket';
+$lang['js']['mediasmall'] = 'Lille version';
+$lang['js']['mediamedium'] = 'Medium version';
+$lang['js']['medialarge'] = 'Stor version';
+$lang['js']['mediaoriginal'] = 'Original version';
+$lang['js']['medialnk'] = 'Link til detajle side';
+$lang['js']['mediadirect'] = 'Direkte link til originalen';
+$lang['js']['medianolnk'] = 'Intet link';
+$lang['js']['medianolink'] = 'Link ikke billedet';
+$lang['js']['medialeft'] = 'Juster billedet til venstre';
+$lang['js']['mediaright'] = 'Juster billedet til højre';
+$lang['js']['mediacenter'] = 'Centreret';
+$lang['js']['medianoalign'] = 'Brug ingen justering';
+$lang['js']['nosmblinks'] = 'Henvisninger til Windows shares virker kun i Microsoft Internet Explorer.
+Du kan stadig kopiere og indsætte linket.';
+$lang['js']['linkwiz'] = 'guiden til henvisninger';
+$lang['js']['linkto'] = 'Henvise til:';
+$lang['js']['del_confirm'] = 'Slet valgte post(er)?';
+$lang['rssfailed'] = 'Der opstod en fejl ved indhentning af: ';
+$lang['nothingfound'] = 'Søgningen gav intet resultat.';
+$lang['mediaselect'] = 'Vælg mediefil';
+$lang['fileupload'] = 'Overføre mediefil';
+$lang['uploadsucc'] = 'Overførelse var en succes';
+$lang['uploadfail'] = 'Overførelse fejlede. Der er muligvis problemer med rettighederne.';
+$lang['uploadwrong'] = 'Overførelse afvist. Filtypen er ikke tilladt.';
+$lang['uploadexist'] = 'Filen eksisterer allerede.';
+$lang['uploadbadcontent'] = 'Overføret indhold tilsvaret ikke til %s fil-endelsen.';
+$lang['uploadspam'] = 'Overførelsen blev blokeret af spam sortlisten.';
+$lang['uploadxss'] = 'Overførelsen blev blokeret på grund af mulig skadeligt indhold.';
+$lang['uploadsize'] = 'Den overføret fil var for stor (max. %s)';
+$lang['deletesucc'] = 'Filen "%s" er blevet slettet.';
+$lang['deletefail'] = '"%s" kunne ikke slettes - check rettighederne.';
+$lang['mediainuse'] = 'Filen "%s" er ikke slettet - den er stadig i brug.';
+$lang['namespaces'] = 'Navnerum';
+$lang['mediafiles'] = 'Tilgængelige filer i';
+$lang['accessdenied'] = 'Du har ikke tilladelse til at se denne side';
+$lang['mediausage'] = 'Brug den følgende syntaks til at henvise til denne fil:';
+$lang['mediaview'] = 'Vis oprindelig fil';
+$lang['mediaroot'] = 'rod';
+$lang['mediaupload'] = 'Overføre en fil til det nuværende navnerum her. For at oprette under-navnerum, tilføj dem til "Overføre som" filnavnet, adskilt af kolontegn.';
+$lang['mediaextchange'] = 'Filudvidelse ændret fra .%s til .%s!';
+$lang['reference'] = 'Henvisning til';
+$lang['ref_inuse'] = 'Filen kan ikke slettes, da den stadig er i brug på følgende sider:';
+$lang['ref_hidden'] = 'Nogle henvisninger er i dokumenter du ikke har læserettigheder til';
+$lang['hits'] = 'Besøg';
+$lang['quickhits'] = 'Tilsvarende dokumentnavne';
+$lang['toc'] = 'Indholdsfortegnelse';
+$lang['current'] = 'nuværende';
+$lang['yours'] = 'Din version';
+$lang['diff'] = 'Vis forskelle i forhold til den nuværende udgave';
+$lang['diff2'] = 'Vis forskelle i forhold til de valgte revisioner';
+$lang['difflink'] = 'Link til denne sammenlinings vising';
+$lang['line'] = 'Linje';
+$lang['breadcrumb'] = 'Sti';
+$lang['youarehere'] = 'Du er her';
+$lang['lastmod'] = 'Sidst ændret';
+$lang['by'] = 'af';
+$lang['deleted'] = 'slettet';
+$lang['created'] = 'oprettet';
+$lang['restored'] = 'gammel udgave reetableret';
+$lang['external_edit'] = 'ekstern redigering';
+$lang['summary'] = 'Redigerings resumé';
+$lang['noflash'] = 'Den <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> er nødvendig til at vise denne indehold.';
+$lang['download'] = 'Hente kodestykke';
+$lang['mail_newpage'] = 'dokument tilføjet:';
+$lang['mail_changed'] = 'dokument ændret:';
+$lang['mail_subscribe_list'] = 'sider ændret i navnerum';
+$lang['mail_new_user'] = 'Ny bruger';
+$lang['mail_upload'] = 'fil overføret:';
+$lang['qb_bold'] = 'Fed';
+$lang['qb_italic'] = 'Kursiv';
+$lang['qb_underl'] = 'Understregning';
+$lang['qb_code'] = 'Skrivemaskine tekst';
+$lang['qb_strike'] = 'Gennemstregning';
+$lang['qb_h1'] = 'Niveau 1 overskrift';
+$lang['qb_h2'] = 'Niveau 2 overskrift';
+$lang['qb_h3'] = 'Niveau 3 overskrift';
+$lang['qb_h4'] = 'Niveau 4 overskrift';
+$lang['qb_h5'] = 'Niveau 5 overskrift';
+$lang['qb_h'] = 'Overskrift';
+$lang['qb_hs'] = 'Vælg overskriften';
+$lang['qb_hplus'] = 'Højere overskriftsniveau';
+$lang['qb_hminus'] = 'Lavere overskriftsniveau';
+$lang['qb_hequal'] = 'Samme overskriftsniveau';
+$lang['qb_link'] = 'Intern henvisning';
+$lang['qb_extlink'] = 'Ekstern henvisning';
+$lang['qb_hr'] = 'Vandret linje';
+$lang['qb_ol'] = 'Nummereret liste';
+$lang['qb_ul'] = 'Unummereret liste';
+$lang['qb_media'] = 'Tilføj billeder og andre filer';
+$lang['qb_sig'] = 'Indsæt signatur';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Specialtegn';
+$lang['upperns'] = 'Gå til overordnet navnerum';
+$lang['admin_register'] = 'Tilføj ny bruger';
+$lang['metaedit'] = 'Rediger metadata';
+$lang['metasaveerr'] = 'Skrivning af metadata fejlede';
+$lang['metasaveok'] = 'Metadata gemt';
+$lang['img_backto'] = 'Tilbage til';
+$lang['img_title'] = 'Titel';
+$lang['img_caption'] = 'Billedtekst';
+$lang['img_date'] = 'Dato';
+$lang['img_fname'] = 'Filnavn';
+$lang['img_fsize'] = 'Størrelse';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Ophavsret';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Emneord';
+$lang['subscr_subscribe_success'] = 'Tilføjede %s til abonnement listen for %s';
+$lang['subscr_subscribe_error'] = 'Fejl ved tilføjelse af %s til abonnement listen for %s';
+$lang['subscr_subscribe_noaddress'] = 'Der er ikke nogen addresse forbundet til din bruger, så du kan ikke blive tilføjet til abonnement listen';
+$lang['subscr_unsubscribe_success'] = 'Fjernede %s fra abonnement listen for %s';
+$lang['subscr_unsubscribe_error'] = 'Fejl ved fjernelse af %s fra abonnement listen for %s';
+$lang['subscr_already_subscribed'] = '%s har allerede et abonnement for listen %s';
+$lang['subscr_not_subscribed'] = '%s har ikke et abonnement for listen %s';
+$lang['subscr_m_not_subscribed'] = 'Du har ikke et abonnement til denne side eller navnerum';
+$lang['subscr_m_new_header'] = 'Tilføj abonnement';
+$lang['subscr_m_current_header'] = 'Nuværende abonnementer';
+$lang['subscr_m_unsubscribe'] = 'Fjern abonnement';
+$lang['subscr_m_subscribe'] = 'Abonér';
+$lang['subscr_m_receive'] = 'Modtag';
+$lang['subscr_style_every'] = 'email på hver ændring';
+$lang['subscr_style_list'] = 'list af ændrede sider siden sidste email (hver %.2f dage)';
+$lang['authmodfailed'] = 'Fejl i brugervalideringens konfiguration. Kontakt venligst wikiens administrator.';
+$lang['authtempfail'] = 'Brugervalidering er midlertidigt ude af drift. Hvis dette er vedvarende, kontakt venligst wikiens administrator.';
+$lang['i_chooselang'] = 'Vælg dit sprog';
+$lang['i_installer'] = 'DokuWiki Installer';
+$lang['i_wikiname'] = 'Wiki Navn';
+$lang['i_enableacl'] = 'Brug ACL (foreslået)';
+$lang['i_superuser'] = 'Superbruger';
+$lang['i_problems'] = 'Installeren fandt nogle problemer, vist nedenunder. Du kan ikke fortsætte før du har rettet dem.';
+$lang['i_modified'] = 'Af sikkerheds hensyn vil dette script kun virke på en ny og umodificeret Dokuwiki installation.
+Du burde enten gen-udpakke filerne fra den hentede pakke eller tjekke den fuldstændige
+<a href="http://dokuwiki.org/install">DokuWiki installations instruktioner</a>';
+$lang['i_funcna'] = 'PHP funtionen <code>%s</code> er ikke tilgængelig. Måske har din udbyder slået det fra af en eller anden grund?';
+$lang['i_phpver'] = 'Din PHP version <code>%s</code> er mindre en den nødvendige <code>%s</code>. Du er nød til at opgradere din PHP installation.';
+$lang['i_permfail'] = 'DokuWiki kan ikke skrive til <code>%s</code>. Du er nød til at rette tilladelses indstillingerne for denne mappe!';
+$lang['i_confexists'] = '<code>%s</code> eksisterer allerede';
+$lang['i_writeerr'] = 'Kunne ikke oprette <code>%s</code>. Du bliver nød til at tjekke mappe/fil- tilladelserne og oprette filen manuelt.';
+$lang['i_badhash'] = 'uigenkendelig eller modificeret dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - ulovlig eller tom værdi';
+$lang['i_success'] = 'Konfigurationen fulførtedes med success. Du kan nu slette install.php filen. Fortsætte til <a href="doku.php">din nye DokuWiki</a>.';
+$lang['i_failure'] = 'Nogle fejl forekom mens konfigurations filerne skulle skrives. Du er mulighvis nød til at fixe dem manuelt før du kan bruge <a href="doku.php">din nye DokuWiki</a>.';
+$lang['i_policy'] = 'Begyndende ACL politik';
+$lang['i_pol0'] = 'Åben Wiki (alle kan læse, skrive og uploade)';
+$lang['i_pol1'] = 'Offentlig Wiki (alle kan læse, kun registrerede brugere kan skrive og overføre)';
+$lang['i_pol2'] = 'Lukket Wiki (kun for registerede brugere kan læse, skrive og overføre)';
+$lang['i_retry'] = 'Forsøg igen';
+$lang['i_license'] = 'Vælg venligst licensen du vil tilføje dit indhold under:';
+$lang['recent_global'] = 'Du ser lige nu ændringerne i <b>%s</b> navnerummet. Du kan også <a href="%s">se de sidste ændringer for hele wiki siden </a>';
+$lang['years'] = '%d år siden';
+$lang['months'] = '%d måned siden';
+$lang['weeks'] = '%d uge siden';
+$lang['days'] = '%d dage siden';
+$lang['hours'] = '%d timer siden';
+$lang['minutes'] = '%d minutter siden';
+$lang['seconds'] = '%d sekunder siden';
+$lang['wordblock'] = 'Din ændring blev ikke gemt da den indeholder blokeret tekst (spam).';
diff --git a/inc/lang/da/locked.txt b/inc/lang/da/locked.txt
new file mode 100644
index 000000000..74b677d51
--- /dev/null
+++ b/inc/lang/da/locked.txt
@@ -0,0 +1,3 @@
+====== Låst Dokument ======
+
+Dette dokument er midlertidigt låst af en anden bruger. Vent venligst til brugeren er færdig med at redigere dokumentet, eller låsen udløber.
diff --git a/inc/lang/da/login.txt b/inc/lang/da/login.txt
new file mode 100644
index 000000000..039bb0a7a
--- /dev/null
+++ b/inc/lang/da/login.txt
@@ -0,0 +1,3 @@
+====== Login ======
+
+Du er ikke logget ind! Indtast brugernavn og adgangskode. Din browser skal have tilladt cookies for at du kan logge ind.
diff --git a/inc/lang/da/mailtext.txt b/inc/lang/da/mailtext.txt
new file mode 100644
index 000000000..948a265fb
--- /dev/null
+++ b/inc/lang/da/mailtext.txt
@@ -0,0 +1,17 @@
+Et dokument i din DokuWiki blev ændret eller tilføjet. Her er detajlerne:
+
+Dato : @DATE@
+Browser : @BROWSER@
+IP-adresse : @IPADDRESS@
+Hostnavn : @HOSTNAME@
+Gammel udgave : @OLDPAGE@
+Ny udgave : @NEWPAGE@
+Redigerings resumé : @SUMMARY@
+Bruger : @USER@
+
+@DIFF@
+
+
+--
+Denne e-mail blev genereret af DokuWiki på:
+@DOKUWIKIURL@
diff --git a/inc/lang/da/newpage.txt b/inc/lang/da/newpage.txt
new file mode 100644
index 000000000..1d602c02c
--- /dev/null
+++ b/inc/lang/da/newpage.txt
@@ -0,0 +1,3 @@
+====== Dette dokument eksisterer ikke (endnu) ======
+
+Du har fulgt en henvisning til et dokument der ikke eksisterer (endnu). Du kan oprette dokumentet ved at trykke på knappen **''[Opret dette dokument]''**.
diff --git a/inc/lang/da/norev.txt b/inc/lang/da/norev.txt
new file mode 100644
index 000000000..aa6896237
--- /dev/null
+++ b/inc/lang/da/norev.txt
@@ -0,0 +1,4 @@
+====== Den valgte udgave findes ikke ======
+
+Den valgte udgave af dokumentet findes ikke! Tryk på knappen **''[Gamle udgaver]''** for at se en liste af gamle udgaver af dette dokument.
+
diff --git a/inc/lang/da/password.txt b/inc/lang/da/password.txt
new file mode 100644
index 000000000..051564cb6
--- /dev/null
+++ b/inc/lang/da/password.txt
@@ -0,0 +1,11 @@
+Hej @FULLNAME@!
+
+Her er dine brugeroplysninger @TITLE@ at @DOKUWIKIURL@
+
+Brugernavn : @LOGIN@
+Adgangskode : @PASSWORD@
+
+--
+Denne e-mail blev genereret af DokuWiki på
+@DOKUWIKIURL@
+ \ No newline at end of file
diff --git a/inc/lang/da/preview.txt b/inc/lang/da/preview.txt
new file mode 100644
index 000000000..23e65e89d
--- /dev/null
+++ b/inc/lang/da/preview.txt
@@ -0,0 +1,4 @@
+====== Forhåndsvisning ======
+
+Dette er en forhåndsvisning af hvordan dokumentet vil se ud. Husk: Det er //**IKKE**// gemt endnu! Hvis det ser godt ud, så tryk på knappen **''[Gem]''**
+
diff --git a/inc/lang/da/pwconfirm.txt b/inc/lang/da/pwconfirm.txt
new file mode 100644
index 000000000..3df556e68
--- /dev/null
+++ b/inc/lang/da/pwconfirm.txt
@@ -0,0 +1,14 @@
+Hej @FULLNAME@!
+
+Nogen har bedt om et nyt password til dit @TITLE@
+login på @DOKUWIKIURL@
+
+Hvis du ikke bad om dette, så ignorer venligst denne email.
+
+For at bekræfte at det var dig der bad om dette, benyt venligst det følgende henvisning.
+
+@CONFIRM@
+
+--
+Denne e-mail blev genereret af DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/da/read.txt b/inc/lang/da/read.txt
new file mode 100644
index 000000000..49f65831b
--- /dev/null
+++ b/inc/lang/da/read.txt
@@ -0,0 +1,2 @@
+Dette dokument kan kun læses. Du kan se kildekoden, men ikke gemme ændringer i det. Hvis du mener at dette er en fejl, så skriv det venligst på [[wiki:fejl-oversigt]].
+
diff --git a/inc/lang/da/recent.txt b/inc/lang/da/recent.txt
new file mode 100644
index 000000000..c44fa368e
--- /dev/null
+++ b/inc/lang/da/recent.txt
@@ -0,0 +1,5 @@
+====== Nye ændringer ======
+
+Følgende dokumenter er blevet ændret for nylig.
+
+
diff --git a/inc/lang/da/register.txt b/inc/lang/da/register.txt
new file mode 100644
index 000000000..4ff2ed1eb
--- /dev/null
+++ b/inc/lang/da/register.txt
@@ -0,0 +1,4 @@
+====== Opret en wiki-konto ======
+
+Udfyld nedenstånde skema for at oprette en konto i denne wiki. Sørg for at bruge en **gyldig e-mail-adresse** - dit adgangskode bliver sendt til dig. Dit brugernavn skal være et gyldigt [[doku>pagename|dokumentnavn]].
+
diff --git a/inc/lang/da/registermail.txt b/inc/lang/da/registermail.txt
new file mode 100644
index 000000000..d431f7591
--- /dev/null
+++ b/inc/lang/da/registermail.txt
@@ -0,0 +1,14 @@
+En ny bruger har registreret. Her er detaljerne:
+
+Brugernavn : @NEWUSER@
+Navn : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Dato : @DATE@
+Browser : @BROWSER@
+IP-adresse : @IPADDRESS@
+Værtsnavn : @HOSTNAME@
+
+--
+Denne mail blev genereret af DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/da/resendpwd.txt b/inc/lang/da/resendpwd.txt
new file mode 100644
index 000000000..e96861ed2
--- /dev/null
+++ b/inc/lang/da/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Send nyt password ======
+
+Udfyld alle nedenstående felter for at få tilsendt et nyt password til denne wiki. Dit nye password vil blive sendt til den opgivne e-mail-adresse. Brugernavnet bør være dit wiki brugernavn.
diff --git a/inc/lang/da/revisions.txt b/inc/lang/da/revisions.txt
new file mode 100644
index 000000000..08f6f2073
--- /dev/null
+++ b/inc/lang/da/revisions.txt
@@ -0,0 +1,3 @@
+====== Gamle udgaver ======
+
+Her er de gamle udgaver af dette dokument. Du kan vende tilbage til en tidligere udgave af dokumentet ved at vælge det nedenfor, trykke på knappen **''[Rediger dette dokument]''**, og til sidst gemme dokumentet.
diff --git a/inc/lang/da/searchpage.txt b/inc/lang/da/searchpage.txt
new file mode 100644
index 000000000..eca1b589c
--- /dev/null
+++ b/inc/lang/da/searchpage.txt
@@ -0,0 +1,5 @@
+====== Søgning ======
+
+Du kan se resultaterne af din søgning nedenunder. Hvis resultaterne ikke indeholder det du søgte efter kan du oprette et nyt dokument med samme navn som søgningen ved at trykke på knappen **''[Opret dette dokument]''**.
+
+===== Søgeresultater =====
diff --git a/inc/lang/da/showrev.txt b/inc/lang/da/showrev.txt
new file mode 100644
index 000000000..3d4890397
--- /dev/null
+++ b/inc/lang/da/showrev.txt
@@ -0,0 +1,2 @@
+**Dette er en gammel udgave af dokumentet!**
+----
diff --git a/inc/lang/da/stopwords.txt b/inc/lang/da/stopwords.txt
new file mode 100644
index 000000000..0fb926720
--- /dev/null
+++ b/inc/lang/da/stopwords.txt
@@ -0,0 +1,87 @@
+# 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/
+alle
+andet
+andre
+begge
+den
+denne
+der
+deres
+det
+dette
+dig
+din
+dog
+eller
+end
+ene
+eneste
+enhver
+fem
+fire
+flere
+fleste
+for
+fordi
+forrige
+fra
+før
+god
+han
+hans
+har
+hendes
+her
+hun
+hvad
+hvem
+hver
+hvilken
+hvis
+hvor
+hvordan
+hvorfor
+hvornår
+ikke
+ind
+ingen
+intet
+jeg
+jeres
+kan
+kom
+kommer
+lav
+lidt
+lille
+man
+mand
+mange
+med
+meget
+men
+mens
+mere
+mig
+ned
+nogen
+noget
+nyt
+nær
+næste
+næsten
+otte
+over
+seks
+ses
+som
+stor
+store
+syv
+til
+tre
+var
+www \ No newline at end of file
diff --git a/inc/lang/da/subscr_form.txt b/inc/lang/da/subscr_form.txt
new file mode 100644
index 000000000..9de6565b1
--- /dev/null
+++ b/inc/lang/da/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Abonnementadministration ======
+
+Denne side gør det muligt for dig at administrere dine abonnementer for den nuværende side eller navnerum. \ No newline at end of file
diff --git a/inc/lang/da/subscr_single.txt b/inc/lang/da/subscr_single.txt
new file mode 100644
index 000000000..64b14588c
--- /dev/null
+++ b/inc/lang/da/subscr_single.txt
@@ -0,0 +1,23 @@
+Hej!
+
+Siden @PAGE@ i wikien @TITLE@ er blevet ændret.
+Her er ændringerne:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Dato : @DATE@
+Bruger : @USER@
+Summering: @SUMMARY@
+Gammel Revision: @OLDPAGE@
+Ny Revision: @NEWPAGE@
+
+For at slå side notifikationer fra, skal du logge ind på
+@DOKUWIKIURL@ og besøge
+@NEWPAGE@
+og slå abonnoment for side / navnerum ændringer fra.
+
+--
+Denne email blev generet af DokuWiki på
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/da/updateprofile.txt b/inc/lang/da/updateprofile.txt
new file mode 100644
index 000000000..2c6ce3f16
--- /dev/null
+++ b/inc/lang/da/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Opdater din kontos profil ======
+
+Du behøver kun at udfylde de felter du ønsker at ændre. Du kan ikke ændre dit brugernavn.
diff --git a/inc/lang/da/uploadmail.txt b/inc/lang/da/uploadmail.txt
new file mode 100644
index 000000000..316463fee
--- /dev/null
+++ b/inc/lang/da/uploadmail.txt
@@ -0,0 +1,14 @@
+En fil blev overføret til din DokuWiki. Her er detaljerne:
+
+Fil : @MEDIA@
+Dato : @DATE@
+Browser : @BROWSER@
+IP-adresse : @IPADDRESS@
+Værtsnavn : @HOSTNAME@
+Størrelse : @SIZE@
+MIME Type : @MIME@
+Bruger : @USER@
+
+--
+Denne e-mail blev genereret af DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/de-informal/admin.txt b/inc/lang/de-informal/admin.txt
new file mode 100644
index 000000000..c52f343ea
--- /dev/null
+++ b/inc/lang/de-informal/admin.txt
@@ -0,0 +1,4 @@
+====== Administration ======
+
+Folgende administrative Aufgaben stehen in DokuWiki zur Verfügung.
+
diff --git a/inc/lang/de-informal/adminplugins.txt b/inc/lang/de-informal/adminplugins.txt
new file mode 100644
index 000000000..a0ae21faf
--- /dev/null
+++ b/inc/lang/de-informal/adminplugins.txt
@@ -0,0 +1 @@
+===== Zusätzliche Plugins ===== \ No newline at end of file
diff --git a/inc/lang/de-informal/backlinks.txt b/inc/lang/de-informal/backlinks.txt
new file mode 100644
index 000000000..aae4c5582
--- /dev/null
+++ b/inc/lang/de-informal/backlinks.txt
@@ -0,0 +1,5 @@
+====== Backlinks ======
+
+Dies ist eine Liste der Seiten, die zurück zur momentanen Seite linken.
+
+
diff --git a/inc/lang/de-informal/conflict.txt b/inc/lang/de-informal/conflict.txt
new file mode 100644
index 000000000..eec345061
--- /dev/null
+++ b/inc/lang/de-informal/conflict.txt
@@ -0,0 +1,6 @@
+====== Eine neuere Version existiert ======
+
+Eine neuere Version des aktuell in Bearbeitung befindlichen Dokuments existiert. Das heißt, jemand hat gleichzeitig an der selben Seite gearbeitet und zuerst gespeichert.
+
+Die unten aufgeführten Unterschiede können bei der Entscheidung helfen, welchem Dokument Vorrang gewährt wird. Wähle **''[Speichern]''** zum Sichern deiner Version oder **''[Abbrechen]''**, um deine Version zu verwerfen und die zuerst gespeicherte Seite zu behalten.
+
diff --git a/inc/lang/de-informal/denied.txt b/inc/lang/de-informal/denied.txt
new file mode 100644
index 000000000..0bc0e59a8
--- /dev/null
+++ b/inc/lang/de-informal/denied.txt
@@ -0,0 +1,4 @@
+====== Zugang verweigert ======
+
+Du hast nicht die erforderliche Berechtigung, um diese Aktion durchzuführen. Eventuell bist du nicht am Wiki angemeldet?
+
diff --git a/inc/lang/de-informal/diff.txt b/inc/lang/de-informal/diff.txt
new file mode 100644
index 000000000..82fbbc252
--- /dev/null
+++ b/inc/lang/de-informal/diff.txt
@@ -0,0 +1,5 @@
+====== Unterschiede ======
+
+Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
+
+
diff --git a/inc/lang/de-informal/draft.txt b/inc/lang/de-informal/draft.txt
new file mode 100644
index 000000000..e56dbe083
--- /dev/null
+++ b/inc/lang/de-informal/draft.txt
@@ -0,0 +1,6 @@
+====== Entwurf gefunden ======
+
+Deine letzte Bearbeitungssitzung wurde nicht ordnungsgemäß abgeschlossen. DokuWiki hat während deiner Arbeit automatisch einen Zwischenentwurf gespeichert, den du jetzt nutzen kannst, um deine Arbeit fortzusetzen. Unten siehst du die Daten, die bei deiner letzten Sitzung gespeichert wurden.
+
+Bitte entscheide dich, ob du den Entwurf //wiederherstellen// oder //löschen// willst oder ob du die Bearbeitung abbrechen möchtest.
+
diff --git a/inc/lang/de-informal/edit.txt b/inc/lang/de-informal/edit.txt
new file mode 100644
index 000000000..28a764124
--- /dev/null
+++ b/inc/lang/de-informal/edit.txt
@@ -0,0 +1,4 @@
+Bitte bearbeite dieses Dokument nur, wenn du es **verbessern** kannst.
+
+Nach dem Bearbeiten den **''[Speichern]''**-Knopf drücken. Siehe [[wiki:syntax]] zur Wiki-Syntax. Zum Testen bitte erst im [[playground:playground|Spielplatz]] üben.
+
diff --git a/inc/lang/de-informal/editrev.txt b/inc/lang/de-informal/editrev.txt
new file mode 100644
index 000000000..6c1f642cc
--- /dev/null
+++ b/inc/lang/de-informal/editrev.txt
@@ -0,0 +1,2 @@
+**Eine ältere Version des Dokuments wurde geladen!** Beim Speichern wird eine neue Version des Dokuments mit diesem Inhalt erstellt.
+---- \ No newline at end of file
diff --git a/inc/lang/de-informal/index.txt b/inc/lang/de-informal/index.txt
new file mode 100644
index 000000000..fa8dc4663
--- /dev/null
+++ b/inc/lang/de-informal/index.txt
@@ -0,0 +1,4 @@
+====== Übersicht ======
+
+Dies ist eine Übersicht über alle vorhandenen Seiten und [[doku>namespaces|Namensräume]].
+
diff --git a/inc/lang/de-informal/install.html b/inc/lang/de-informal/install.html
new file mode 100644
index 000000000..dd91c7a78
--- /dev/null
+++ b/inc/lang/de-informal/install.html
@@ -0,0 +1,27 @@
+<p>Diese Seite hilft dir bei der Erst-Installation und Konfiguration von
+<a href="http://dokuwiki.org">Dokuwiki</a>. Zusätzliche Informationen zu
+diesem Installationsskript findest du auf der entsprechenden
+<a href="http://dokuwiki.org/installer">Hilfe-Seite</a> (en).</p>
+
+<p>DokuWiki verwendet normale Dateien für das Speichern von Wikiseiten und
+anderen Informationen (Bilder, Suchindizes, alte Versionen, usw.).
+Um DokuWiki betreiben zu können, <strong>muss</strong> Schreibzugriff auf die
+Verzeichnisse bestehen, in denen DokuWiki diese Dateien ablegt. Dieses
+Installationsprogramm kann diese Rechte nicht für dich setzen. Du musst dies
+manuell auf einer Kommando-Shell oder, falls du DokuWiki bei einem Fremdanbieter
+hostest, über FTP oder ein entsprechendes Werkzeug (z.B. cPanel) durchführen.</p>
+
+<p>Dieses Skript hilft dir beim ersten Einrichten des Zugangsschutzes
+(<acronym title="access control list">ACL</acronym>) von DokuWiki, welcher eine
+Administratoranmeldung und damit Zugang zum Administrationsmenü ermöglicht.
+Dort kannst du dann weitere Tätigkeiten wie das Installieren von Plugins, das
+Verwalten von Nutzern und das Ändern von Konfigurationseinstellungen durchführen.
+Das Nutzen der Zugangskontrolle ist nicht zwingend erforderlich, es erleichtert aber
+die Administration von DokuWiki.</p>
+
+<p>Erfahrene Anwender oder Nutzer mit speziellen Konfigurationsbedürfnissen sollten
+die folgenden Links nutzen, um sich über
+<a href="http://dokuwiki.org/install">Installation</a>
+und <a href="http://dokuwiki.org/config">Konfiguration</a> zu
+informieren.</p>
+
diff --git a/inc/lang/de-informal/lang.php b/inc/lang/de-informal/lang.php
new file mode 100644
index 000000000..eca04bbc4
--- /dev/null
+++ b/inc/lang/de-informal/lang.php
@@ -0,0 +1,323 @@
+<?php
+/**
+ * german language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Christof <gagi@fin.de>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <mailinglist@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Diese Seite bearbeiten';
+$lang['btn_source'] = 'Zeige Quelltext';
+$lang['btn_show'] = 'Seite anzeigen';
+$lang['btn_create'] = 'Seite anlegen';
+$lang['btn_search'] = 'Suche';
+$lang['btn_save'] = 'Speichern';
+$lang['btn_preview'] = 'Vorschau';
+$lang['btn_top'] = 'Nach oben';
+$lang['btn_newer'] = '<< jüngere Änderungen';
+$lang['btn_older'] = 'ältere Änderungen >>';
+$lang['btn_revs'] = 'Ältere Versionen';
+$lang['btn_recent'] = 'Letzte Änderungen';
+$lang['btn_upload'] = 'Hochladen';
+$lang['btn_cancel'] = 'Abbrechen';
+$lang['btn_index'] = 'Übersicht';
+$lang['btn_secedit'] = 'Bearbeiten';
+$lang['btn_login'] = 'Anmelden';
+$lang['btn_logout'] = 'Abmelden';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Updaten';
+$lang['btn_delete'] = 'Löschen';
+$lang['btn_back'] = 'Zurück';
+$lang['btn_backlink'] = 'Links hierher';
+$lang['btn_backtomedia'] = 'Zurück zur Dateiauswahl';
+$lang['btn_subscribe'] = 'Aboverwaltung';
+$lang['btn_profile'] = 'Benutzerprofil';
+$lang['btn_reset'] = 'Zurücksetzen';
+$lang['btn_resendpwd'] = 'Sende neues Passwort';
+$lang['btn_draft'] = 'Entwurf bearbeiten';
+$lang['btn_recover'] = 'Entwurf wiederherstellen';
+$lang['btn_draftdel'] = 'Entwurf löschen';
+$lang['btn_revert'] = 'Wiederherstellen';
+$lang['btn_register'] = 'Registrieren';
+$lang['btn_apply'] = 'Übernehmen';
+$lang['btn_media'] = 'Medien-Manager';
+$lang['loggedinas'] = 'Angemeldet als';
+$lang['user'] = 'Benutzername';
+$lang['pass'] = 'Passwort';
+$lang['newpass'] = 'Neues Passwort';
+$lang['oldpass'] = 'Bestätigen (Altes Passwort)';
+$lang['passchk'] = 'und nochmal';
+$lang['remember'] = 'Angemeldet bleiben';
+$lang['fullname'] = 'Voller Name';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'Benutzerprofil';
+$lang['badlogin'] = 'Nutzername oder Passwort sind falsch.';
+$lang['minoredit'] = 'Kleine Änderung';
+$lang['draftdate'] = 'Entwurf gespeichert am';
+$lang['nosecedit'] = 'Diese Seite wurde in der Zwischenzeit geändert, da das Sektionsinfo veraltet ist. Die ganze Seite wird stattdessen geladen.';
+$lang['regmissing'] = 'Alle Felder müssen ausgefüllt werden';
+$lang['reguexists'] = 'Der Nutzername existiert leider schon.';
+$lang['regsuccess'] = 'Der neue Nutzer wurde angelegt und das Passwort per E-Mail versandt.';
+$lang['regsuccess2'] = 'Der neue Nutzer wurde angelegt.';
+$lang['regmailfail'] = 'Offenbar ist ein Fehler beim Versenden der Passwortmail aufgetreten. Bitte wende dich an den Wiki-Admin.';
+$lang['regbadmail'] = 'Die angegebene Mail-Adresse scheint ungültig zu sein. Falls dies ein Fehler ist, wende dich bitte an den Wiki-Admin.';
+$lang['regbadpass'] = 'Die beiden eingegeben Passwörter stimmen nicht überein. Bitte versuche es noch einmal.';
+$lang['regpwmail'] = 'Ihr DokuWiki Passwort';
+$lang['reghere'] = 'Du hast noch keinen Zugang? Hier registrieren';
+$lang['profna'] = 'Änderung des Benutzerprofils in diesem Wiki nicht möglich.';
+$lang['profnochange'] = 'Keine Änderungen, nichts zu tun.';
+$lang['profnoempty'] = 'Es muss ein Name oder eine E-Mail Adresse angegeben werden.';
+$lang['profchanged'] = 'Benutzerprofil erfolgreich geändert.';
+$lang['pwdforget'] = 'Passwort vergessen? Fordere ein neues an';
+$lang['resendna'] = 'Passwörter versenden ist in diesem Wiki nicht möglich.';
+$lang['resendpwd'] = 'Neues Passwort senden für';
+$lang['resendpwdmissing'] = 'Es tut mir Leid, aber du musst alle Felder ausfüllen.';
+$lang['resendpwdnouser'] = 'Es tut mir Leid, aber der Benutzer existiert nicht in unserer Datenbank.';
+$lang['resendpwdbadauth'] = 'Es tut mir Leid, aber dieser Authentifizierungscode ist ungültig. Stelle sicher, dass du den kompletten Bestätigungslink verwendet haben.';
+$lang['resendpwdconfirm'] = 'Ein Bestätigungslink wurde per E-Mail versandt.';
+$lang['resendpwdsuccess'] = 'Dein neues Passwort wurde per E-Mail versandt.';
+$lang['license'] = 'Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht:';
+$lang['licenseok'] = 'Hinweis: Durch das Bearbeiten dieser Seite gibst du dein Einverständnis, dass dein Inhalt unter der folgenden Lizenz veröffentlicht wird:';
+$lang['searchmedia'] = 'Suche nach Datei:';
+$lang['searchmedia_in'] = 'Suche in %s';
+$lang['txt_upload'] = 'Datei zum Hochladen auswählen';
+$lang['txt_filename'] = 'Hochladen als (optional)';
+$lang['txt_overwrt'] = 'Bestehende Datei überschreiben';
+$lang['lockedby'] = 'Momentan gesperrt von';
+$lang['lockexpire'] = 'Sperre läuft ab am';
+$lang['js']['willexpire'] = 'Die Sperre zur Bearbeitung dieser Seite läuft in einer Minute ab.\nUm Bearbeitungskonflikte zu vermeiden, solltest du sie durch einen Klick auf den Vorschau-Knopf verlängern.';
+$lang['js']['notsavedyet'] = 'Nicht gespeicherte Änderungen gehen verloren!';
+$lang['js']['searchmedia'] = 'Suche nach Dateien';
+$lang['js']['keepopen'] = 'Fenster nach Auswahl nicht schließen';
+$lang['js']['hidedetails'] = 'Details ausblenden';
+$lang['js']['mediatitle'] = 'Link-Eigenschaften';
+$lang['js']['mediadisplay'] = 'Linktyp';
+$lang['js']['mediaalign'] = 'Ausrichtung';
+$lang['js']['mediasize'] = 'Bildgröße';
+$lang['js']['mediatarget'] = 'Linkziel';
+$lang['js']['mediaclose'] = 'Schließen';
+$lang['js']['mediainsert'] = 'Einfügen';
+$lang['js']['mediadisplayimg'] = 'Bild anzeigen.';
+$lang['js']['mediadisplaylnk'] = 'Nur den Link anzeigen.';
+$lang['js']['mediasmall'] = 'Kleine Version';
+$lang['js']['mediamedium'] = 'Mittelgroße Version';
+$lang['js']['medialarge'] = 'Große Version';
+$lang['js']['mediaoriginal'] = 'Original Version';
+$lang['js']['medialnk'] = 'Link zu der Detailseite';
+$lang['js']['mediadirect'] = 'Direkter Link zum Original';
+$lang['js']['medianolnk'] = 'Kein link';
+$lang['js']['medianolink'] = 'Keine Verlinkung des Bildes';
+$lang['js']['medialeft'] = 'Bild nach links ausrichten.';
+$lang['js']['mediaright'] = 'Bild nach rechts ausrichten.';
+$lang['js']['mediacenter'] = 'Bild in der Mitte ausrichten';
+$lang['js']['medianoalign'] = 'Keine Ausrichtung des Bildes.';
+$lang['js']['nosmblinks'] = 'Das Verlinken von Windows-Freigaben funktioniert nur im Microsoft Internet-Explorer.\nDer Link kann jedoch durch Kopieren und Einfügen verwendet werden.';
+$lang['js']['linkwiz'] = 'Link-Assistent';
+$lang['js']['linkto'] = 'Link zu:';
+$lang['js']['del_confirm'] = 'Die ausgewählten Dateien wirklich löschen?';
+$lang['js']['restore_confirm'] = 'Wirkliich diese Version wieder herstellen?';
+$lang['js']['media_diff'] = 'Unterschiede anzeigen:';
+$lang['js']['media_diff_both'] = 'Seite für Seite';
+$lang['js']['media_diff_opacity'] = 'Überblenden';
+$lang['js']['media_diff_portions'] = 'Übergang';
+$lang['js']['media_select'] = 'Dateien auswählen…';
+$lang['js']['media_upload_btn'] = 'Hochladen';
+$lang['js']['media_done_btn'] = 'Fertig';
+$lang['js']['media_drop'] = 'Dateien hier draufziehen um sie hochzuladen';
+$lang['js']['media_cancel'] = 'Entfernen';
+$lang['js']['media_overwrt'] = 'Existierende Dateien überschreiben';
+$lang['rssfailed'] = 'Es ist ein Fehler beim Laden des Feeds aufgetreten: ';
+$lang['nothingfound'] = 'Nichts gefunden.';
+$lang['mediaselect'] = 'Dateiauswahl';
+$lang['fileupload'] = 'Datei hochladen';
+$lang['uploadsucc'] = 'Datei wurde erfolgreich hochgeladen';
+$lang['uploadfail'] = 'Hochladen fehlgeschlagen. Keine Berechtigung?';
+$lang['uploadwrong'] = 'Hochladen verweigert. Diese Dateiendung ist nicht erlaubt.';
+$lang['uploadexist'] = 'Datei existiert bereits. Keine Änderungen vorgenommen.';
+$lang['uploadbadcontent'] = 'Die hochgeladenen Daten stimmen nicht mit der Dateiendung %s überein.';
+$lang['uploadspam'] = 'Hochladen verweigert: Treffer auf der Spamliste.';
+$lang['uploadxss'] = 'Hochladen verweigert: Daten scheinen Schadcode zu enthalten.';
+$lang['uploadsize'] = 'Die hochgeladene Datei war zu groß. (max. %s)';
+$lang['deletesucc'] = 'Die Datei "%s" wurde gelöscht.';
+$lang['deletefail'] = '"%s" konnte nicht gelöscht werden. Keine Berechtigung?.';
+$lang['mediainuse'] = 'Die Datei "%s" wurde nicht gelöscht. Sie wird noch verwendet.';
+$lang['namespaces'] = 'Namensräume';
+$lang['mediafiles'] = 'Vorhandene Dateien in';
+$lang['accessdenied'] = 'Du hast keinen Zugriff auf diese Seite';
+$lang['mediausage'] = 'Syntax zum Verwenden dieser Datei:';
+$lang['mediaview'] = 'Originaldatei öffnen';
+$lang['mediaroot'] = 'Wurzel';
+$lang['mediaupload'] = 'Lade hier eine Datei in den momentanen Namensraum hoch. Um Unterordner zu erstellen, stelle diese dem Dateinamen durch Doppelpunkt getrennt voran, nachdem Du die Datei ausgewählt hast.';
+$lang['mediaextchange'] = 'Dateiendung vom .%s nach .%s geändert!';
+$lang['reference'] = 'Verwendung von';
+$lang['ref_inuse'] = 'Diese Datei kann nicht gelöscht werden, da sie noch von folgenden Seiten benutzt wird:';
+$lang['ref_hidden'] = 'Einige Verweise sind auf Seiten, für die du keine Leseberechtigung hast.';
+$lang['hits'] = 'Treffer';
+$lang['quickhits'] = 'Passende Seitennamen';
+$lang['toc'] = 'Inhaltsverzeichnis';
+$lang['current'] = 'aktuell';
+$lang['yours'] = 'Deine Version';
+$lang['diff'] = 'Zeige Unterschiede zu aktueller Version';
+$lang['diff2'] = 'Zeige Unterschiede der ausgewählten Versionen';
+$lang['difflink'] = 'Link zu der Versionshistorie';
+$lang['diff_type'] = 'Unterschiede anzeigen:';
+$lang['diff_inline'] = 'Inline';
+$lang['diff_side'] = 'Side by Side';
+$lang['line'] = 'Zeile';
+$lang['breadcrumb'] = 'Zuletzt angesehen';
+$lang['youarehere'] = 'Du befindest dich hier';
+$lang['lastmod'] = 'Zuletzt geändert';
+$lang['by'] = 'von';
+$lang['deleted'] = 'gelöscht';
+$lang['created'] = 'angelegt';
+$lang['restored'] = 'alte Version wiederhergestellt';
+$lang['external_edit'] = 'Externe Bearbeitung';
+$lang['summary'] = 'Zusammenfassung';
+$lang['noflash'] = 'Das <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> wird benötigt, um diesen Inhalt anzuzeigen.';
+$lang['download'] = 'Download-Teil';
+$lang['mail_newpage'] = 'Neue Seite:';
+$lang['mail_changed'] = 'Seite geändert:';
+$lang['mail_subscribe_list'] = 'Seite hat sich im Namespace geändert:';
+$lang['mail_new_user'] = 'Neuer Benutzer:';
+$lang['mail_upload'] = 'Datei hochgeladen:';
+$lang['changes_type'] = 'Änderungen anzeigen von';
+$lang['pages_changes'] = 'Seiten';
+$lang['media_changes'] = 'Mediendateien';
+$lang['both_changes'] = 'Beides, Seiten- und Mediendateien';
+$lang['qb_bold'] = 'Fetter Text';
+$lang['qb_italic'] = 'Kursiver Text';
+$lang['qb_underl'] = 'Unterstrichener Text';
+$lang['qb_code'] = 'Code Text';
+$lang['qb_strike'] = 'Durchgestrichener Text';
+$lang['qb_h1'] = 'Level 1 Überschrift';
+$lang['qb_h2'] = 'Level 2 Überschrift';
+$lang['qb_h3'] = 'Level 3 Überschrift';
+$lang['qb_h4'] = 'Level 4 Überschrift';
+$lang['qb_h5'] = 'Level 5 Überschrift';
+$lang['qb_h'] = 'Überschrift';
+$lang['qb_hs'] = 'Wähle eine Überschrift';
+$lang['qb_hplus'] = 'Überschrift eine Ebene höher';
+$lang['qb_hminus'] = 'Überschrift eine Ebene runter';
+$lang['qb_hequal'] = 'Überschrift auf selber Ebene';
+$lang['qb_link'] = 'Interner Link';
+$lang['qb_extlink'] = 'Externer Link';
+$lang['qb_hr'] = 'Horizontale Linie';
+$lang['qb_ol'] = 'Nummerierter Listenpunkt';
+$lang['qb_ul'] = 'Listenpunkt';
+$lang['qb_media'] = 'Bilder und andere Dateien hinzufügen';
+$lang['qb_sig'] = 'Unterschrift einfügen';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Sonderzeichen';
+$lang['upperns'] = 'Gehe zum übergeordneten Namensraum';
+$lang['admin_register'] = 'Neuen Benutzer anmelden';
+$lang['metaedit'] = 'Metadaten bearbeiten';
+$lang['metasaveerr'] = 'Die Metadaten konnten nicht gesichert werden';
+$lang['metasaveok'] = 'Metadaten gesichert';
+$lang['img_backto'] = 'Zurück zu';
+$lang['img_title'] = 'Titel';
+$lang['img_caption'] = 'Bildunterschrift';
+$lang['img_date'] = 'Datum';
+$lang['img_fname'] = 'Dateiname';
+$lang['img_fsize'] = 'Größe';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Schlagwörter';
+$lang['img_width'] = 'Breite';
+$lang['img_height'] = 'Höhe';
+$lang['img_manager'] = 'Im Medien-Manager anzeigen';
+$lang['subscr_subscribe_success'] = 'Die Seite %s wurde zur Abonnementenliste von %s hinzugefügt';
+$lang['subscr_subscribe_error'] = 'Fehler beim Hinzufügen von %s zur Abonnementenliste von %s';
+$lang['subscr_subscribe_noaddress'] = 'In deinem Account ist keine E-Mail-Adresse hinterlegt. Dadurch kann die Seite nicht abonniert werden';
+$lang['subscr_unsubscribe_success'] = 'Die Seite %s wurde von der Abonnementenliste von %s entfernt';
+$lang['subscr_unsubscribe_error'] = 'Fehler beim Entfernen von %s von der Abonnementenliste von %s';
+$lang['subscr_already_subscribed'] = '%s ist bereits auf der Abonnementenliste von %s';
+$lang['subscr_not_subscribed'] = '%s ist nicht auf der Abonnementenliste von %s';
+$lang['subscr_m_not_subscribed'] = 'Du hast kein Abonnement von dieser Seite oder dem Namensraum.';
+$lang['subscr_m_new_header'] = 'Abonnementen hinzufügen';
+$lang['subscr_m_current_header'] = 'Aktive Abonnements';
+$lang['subscr_m_unsubscribe'] = 'Abbestellen';
+$lang['subscr_m_subscribe'] = 'Abonnieren';
+$lang['subscr_m_receive'] = 'Erhalten';
+$lang['subscr_style_every'] = 'E-Mail bei jeder Änderung';
+$lang['subscr_style_digest'] = 'E-Mail mit zusammengefasster Übersicht der Seitenänderungen (alle %.2f Tage)';
+$lang['subscr_style_list'] = 'Auflistung aller geänderten Seiten seit der letzten E-Mail (alle %.2f Tage)';
+$lang['authmodfailed'] = 'Benutzerüberprüfung nicht möglich. Bitte wende dich an den Admin.';
+$lang['authtempfail'] = 'Benutzerüberprüfung momentan nicht möglich. Falls das Problem andauert, wende dich an den Admin.';
+$lang['i_chooselang'] = 'Wähle deine Sprache';
+$lang['i_installer'] = 'DokuWiki-Installation';
+$lang['i_wikiname'] = 'Wiki-Name';
+$lang['i_enableacl'] = 'Zugangskontrolle (ACL) aktivieren (empfohlen)';
+$lang['i_superuser'] = 'Benutzername des Administrators';
+$lang['i_problems'] = 'Das Installationsprogramm hat unten aufgeführte Probleme festgestellt, die zunächst behoben werden müssen, bevor du mit der Installation fortfahren kannst.';
+$lang['i_modified'] = 'Aus Sicherheitsgründen arbeitet dieses Script nur mit einer neuen, unmodifizierten DokuWiki-Installation. Du solltest entweder alle Dateien noch einmal frisch installieren oder die <a href="http://dokuwiki.org/install">Dokuwiki-Installationsanleitung</a> konsultieren.';
+$lang['i_funcna'] = 'Die PHP-Funktion <code>%s</code> ist nicht verfügbar. Unter Umständen wurde sie von deinem Hoster deaktiviert?';
+$lang['i_phpver'] = 'Deine PHP-Version <code>%s</code> ist niedriger als die benötigte Version <code>%s</code>. Bitte aktualisiere deine PHP-Installation.';
+$lang['i_permfail'] = '<code>%s</code> ist nicht durch DokuWiki beschreibbar. Du musst die Berechtigungen dieses Ordners ändern!';
+$lang['i_confexists'] = '<code>%s</code> existiert bereits';
+$lang['i_writeerr'] = '<code>%s</code> konnte nicht erzeugt werden. Du solltest die Verzeichnis-/Datei-Rechte überprüfen und die Datei manuell anlegen.';
+$lang['i_badhash'] = 'Unbekannte oder modifizierte dokuwiki.php (Hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - unerlaubter oder leerer Wert';
+$lang['i_success'] = 'Die Konfiguration wurde erfolgreich abgeschlossen. Du kannst jetzt die install.php löschen. Dein <a href="doku.php">neues DokuWiki</a> ist jetzt für dich bereit.';
+$lang['i_failure'] = 'Es sind Fehler beim Schreiben der Konfigurationsdateien aufgetreten. Du musst diese vermutlich von Hand beheben, bevor du dein <a href="doku.php">neues DokuWiki</a> nutzen kannst.';
+$lang['i_policy'] = 'Anfangseinstellung für Zugangskontrolle (ACL)';
+$lang['i_pol0'] = 'Offenes Wiki (lesen, schreiben, hochladen für alle)';
+$lang['i_pol1'] = 'Öffentliches Wiki (lesen für alle, schreiben und hochladen für registrierte Nutzer)';
+$lang['i_pol2'] = 'Geschlossenes Wiki (lesen, schreiben, hochladen nur für registrierte Nutzer)';
+$lang['i_retry'] = 'Wiederholen';
+$lang['i_license'] = 'Bitte wähle die Lizenz aus unter der die Wiki-Inhalte veröffentlicht werden sollen:';
+$lang['recent_global'] = 'Im Moment siehst du die Änderungen im Namensraum <b>%s</b>. Du kannst auch <a href="%s">die Änderungen im gesamten Wiki sehen</a>.';
+$lang['years'] = 'vor %d Jahren';
+$lang['months'] = 'vor %d Monaten';
+$lang['weeks'] = 'vor %d Wochen';
+$lang['days'] = 'vor %d Tagen';
+$lang['hours'] = 'vor %d Stunden';
+$lang['minutes'] = 'vor %d Minuten';
+$lang['seconds'] = 'vor %d Sekunden';
+$lang['wordblock'] = 'Deine Bearbeitung wurde nicht gespeichert, da sie gesperrten Text enthielt (Spam).';
+$lang['media_uploadtab'] = 'Hochladen';
+$lang['media_searchtab'] = 'Suchen';
+$lang['media_file'] = 'Datei';
+$lang['media_viewtab'] = 'Anzeigen';
+$lang['media_edittab'] = 'Bearbeiten';
+$lang['media_historytab'] = 'Verlauf';
+$lang['media_list_thumbs'] = 'Medien anzeigen als Miniaturansicht';
+$lang['media_list_rows'] = 'Medien anzeigen als Listenansicht';
+$lang['media_sort_name'] = 'Sortieren nach Name';
+$lang['media_sort_date'] = 'Sortieren nach Datum';
+$lang['media_namespaces'] = 'Namensraum wählen';
+$lang['media_files'] = 'Medien im Namensraum <strong>%s</strong>.';
+$lang['media_upload'] = 'In den <strong>%s</strong> Namensraum hochladen.';
+$lang['media_search'] = 'Im Namensraum <strong>%s</strong> suchen.';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s in %s';
+$lang['media_edit'] = '%s bearbeiten';
+$lang['media_history'] = 'Versionen von %s';
+$lang['media_meta_edited'] = 'Meta-Informationen bearbeitet';
+$lang['media_perm_read'] = 'Du besitzt nicht die notwendigen Berechtigungen um die Datei anzuzeigen.';
+$lang['media_perm_upload'] = 'Du besitzt nicht die notwendigen Berechtigungen um Dateien hochzuladen.';
+$lang['media_update'] = 'Neue Version hochladen';
+$lang['media_restore'] = 'Diese Version wiederherstellen';
+$lang['plugin_install_err'] = 'Plugin nicht korrekt installiert. Plugin-Verzeichnis von \'%s\' nach \'%s\' umbenennen.';
diff --git a/inc/lang/de-informal/locked.txt b/inc/lang/de-informal/locked.txt
new file mode 100644
index 000000000..4430fc6dd
--- /dev/null
+++ b/inc/lang/de-informal/locked.txt
@@ -0,0 +1,4 @@
+====== Seite gesperrt ======
+
+Diese Seite ist momentan von einem anderen Nutzer gesperrt. Warte, bis dieser mit dem Bearbeiten fertig ist oder die Sperre abläuft.
+
diff --git a/inc/lang/de-informal/login.txt b/inc/lang/de-informal/login.txt
new file mode 100644
index 000000000..5c99c48f1
--- /dev/null
+++ b/inc/lang/de-informal/login.txt
@@ -0,0 +1,4 @@
+====== Anmelden ======
+
+Gib deinen Benutzernamen und dein Passwort in das Formular unten ein, um dich anzumelden. Bitte beachte, dass dafür "Cookies" in den Sicherheitseinstellungen deines Browsers erlaubt sein müssen.
+
diff --git a/inc/lang/de-informal/mailtext.txt b/inc/lang/de-informal/mailtext.txt
new file mode 100644
index 000000000..508c080f7
--- /dev/null
+++ b/inc/lang/de-informal/mailtext.txt
@@ -0,0 +1,18 @@
+Eine Seite in deinem Wiki wurde geändert oder neu angelegt. Hier sind die Details:
+
+Datum : @DATE@
+Browser : @BROWSER@
+IP-Adresse : @IPADDRESS@
+Hostname : @HOSTNAME@
+Alte Version : @OLDPAGE@
+Neue Version : @NEWPAGE@
+Zusammenfassung: @SUMMARY@
+Benutzer : @USER@
+
+@DIFF@
+
+
+--
+Diese Mail wurde vom DokuWiki auf
+@DOKUWIKIURL@
+erzeugt.
diff --git a/inc/lang/de-informal/newpage.txt b/inc/lang/de-informal/newpage.txt
new file mode 100644
index 000000000..5e261cc89
--- /dev/null
+++ b/inc/lang/de-informal/newpage.txt
@@ -0,0 +1,5 @@
+====== Dieses Thema existiert noch nicht ======
+
+Du bist einem Link zu einer Seite gefolgt, die noch nicht existiert. Du kannst die Seite mit dem Knopf **''[Seite anlegen]''** selbst anlegen und mit Inhalt füllen.
+
+
diff --git a/inc/lang/de-informal/norev.txt b/inc/lang/de-informal/norev.txt
new file mode 100644
index 000000000..c6243313d
--- /dev/null
+++ b/inc/lang/de-informal/norev.txt
@@ -0,0 +1,4 @@
+====== Version existiert nicht ======
+
+Die angegebene Version des Dokuments wurde nicht gefunden. Benutze den **''[Ältere Versionen]''** Knopf, um eine Liste aller verfügbaren Versionen dieses Dokuments zu erhalten.
+
diff --git a/inc/lang/de-informal/password.txt b/inc/lang/de-informal/password.txt
new file mode 100644
index 000000000..8ce252966
--- /dev/null
+++ b/inc/lang/de-informal/password.txt
@@ -0,0 +1,11 @@
+Hallo @FULLNAME@!
+
+Hier sind deine Nutzerdaten für @TITLE@ auf @DOKUWIKIURL@
+
+Benutzername: @LOGIN@
+Passwort : @PASSWORD@
+
+--
+Diese Mail wurde vom DokuWiki auf
+@DOKUWIKIURL@
+erzeugt. \ No newline at end of file
diff --git a/inc/lang/de-informal/preview.txt b/inc/lang/de-informal/preview.txt
new file mode 100644
index 000000000..d3a578f69
--- /dev/null
+++ b/inc/lang/de-informal/preview.txt
@@ -0,0 +1,5 @@
+====== Vorschau ======
+
+So wird dein Text später aussehen. Achtung: Der Text wurde noch **nicht gespeichert**!
+
+
diff --git a/inc/lang/de-informal/pwconfirm.txt b/inc/lang/de-informal/pwconfirm.txt
new file mode 100644
index 000000000..9029bf195
--- /dev/null
+++ b/inc/lang/de-informal/pwconfirm.txt
@@ -0,0 +1,17 @@
+Hallo @FULLNAME@!
+
+Jemand hat ein neues Passwort für deinen @TITLE@
+Login auf @DOKUWIKIURL@ angefordert.
+
+Wenn du diese Änderung nicht angefordert hast, ignoriere diese
+E-Mail einfach.
+
+Um die Anforderung zu bestätigen, folge bitte dem unten angegebenen
+Bestätigungslink.
+
+@CONFIRM@
+
+--
+Diese Mail wurde vom DokuWiki auf
+@DOKUWIKIURL@
+erzeugt.
diff --git a/inc/lang/de-informal/read.txt b/inc/lang/de-informal/read.txt
new file mode 100644
index 000000000..1c5422a29
--- /dev/null
+++ b/inc/lang/de-informal/read.txt
@@ -0,0 +1,2 @@
+Diese Seite ist nicht editierbar. Du kannst den Quelltext sehen, jedoch nicht verändern. Kontaktiere den Administrator, wenn du glaubst, dass hier ein Fehler vorliegt.
+
diff --git a/inc/lang/de-informal/recent.txt b/inc/lang/de-informal/recent.txt
new file mode 100644
index 000000000..c05bbae12
--- /dev/null
+++ b/inc/lang/de-informal/recent.txt
@@ -0,0 +1,5 @@
+====== Letzte Änderungen ======
+
+Die folgenden Seiten wurden zuletzt geändert.
+
+
diff --git a/inc/lang/de-informal/register.txt b/inc/lang/de-informal/register.txt
new file mode 100644
index 000000000..8fe4718dc
--- /dev/null
+++ b/inc/lang/de-informal/register.txt
@@ -0,0 +1,4 @@
+====== Als neuer Nutzer registrieren ======
+
+Bitte fülle alle Felder aus, um einen neuen Nutzer-Account in diesem Wiki anzulegen. Stelle sicher, dass eine **gültige E-Mail-Adresse** angegeben wird - das Passwort wird an diese Adresse gesendet. Der Nutzername sollte aus einem Wort ohne Umlaute, Leer- oder Sonderzeichen bestehen.
+
diff --git a/inc/lang/de-informal/registermail.txt b/inc/lang/de-informal/registermail.txt
new file mode 100644
index 000000000..ed37a9505
--- /dev/null
+++ b/inc/lang/de-informal/registermail.txt
@@ -0,0 +1,14 @@
+Ein neuer Benutzer hat sich registriert. Hier sind die Details:
+
+Benutzername : @NEWUSER@
+Voller Name : @NEWNAME@
+E-Mail : @NEWEMAIL@
+
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
diff --git a/inc/lang/de-informal/resendpwd.txt b/inc/lang/de-informal/resendpwd.txt
new file mode 100644
index 000000000..a0a714218
--- /dev/null
+++ b/inc/lang/de-informal/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Neues Passwort anfordern ======
+
+Fülle alle Felder unten aus, um ein neues Passwort für deinen Zugang zu erhalten. Das neue Passwort wird an deine gespeicherte E-Mail-Adresse geschickt. Der Benutzername muss deinem Wiki-Benutzernamen entsprechen.
diff --git a/inc/lang/de-informal/revisions.txt b/inc/lang/de-informal/revisions.txt
new file mode 100644
index 000000000..b69169a4e
--- /dev/null
+++ b/inc/lang/de-informal/revisions.txt
@@ -0,0 +1,4 @@
+====== Ältere Versionen ======
+
+Dies sind ältere Versionen der gewählten Seite. Um zu einer älteren Version zurückzukehren, wähle die entsprechende Version aus, klicke auf **''[Diese Seite bearbeiten]''** und speichere sie erneut ab.
+
diff --git a/inc/lang/de-informal/searchpage.txt b/inc/lang/de-informal/searchpage.txt
new file mode 100644
index 000000000..72c57b765
--- /dev/null
+++ b/inc/lang/de-informal/searchpage.txt
@@ -0,0 +1,7 @@
+====== Suche ======
+
+Unten sind die Ergebnisse deiner Suche gelistet. Falls der gesuchte Begriff nicht gefunden wurde, kannst du direkt eine neue Seite für den Suchbegriff anlegen, indem du auf den Knopf **''[Seite anlegen]''** drückst.
+
+===== Ergebnisse =====
+
+
diff --git a/inc/lang/de-informal/showrev.txt b/inc/lang/de-informal/showrev.txt
new file mode 100644
index 000000000..65f53c9c1
--- /dev/null
+++ b/inc/lang/de-informal/showrev.txt
@@ -0,0 +1,2 @@
+**Dies ist eine alte Version des Dokuments!**
+----
diff --git a/inc/lang/de-informal/stopwords.txt b/inc/lang/de-informal/stopwords.txt
new file mode 100644
index 000000000..443b17723
--- /dev/null
+++ b/inc/lang/de-informal/stopwords.txt
@@ -0,0 +1,125 @@
+# 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/
+aber
+als
+auch
+auf
+aus
+bei
+bin
+bis
+bist
+dadurch
+daher
+darum
+das
+daß
+dass
+dein
+deine
+dem
+den
+der
+des
+dessen
+deshalb
+die
+dies
+dieser
+dieses
+doch
+dort
+durch
+ein
+eine
+einem
+einen
+einer
+eines
+euer
+eure
+für
+hatte
+hatten
+hattest
+hattet
+hier
+hinter
+ich
+ihr
+ihre
+in
+im
+ist
+jede
+jedem
+jeden
+jeder
+jedes
+jener
+jenes
+jetzt
+kann
+kannst
+können
+könnt
+machen
+mein
+meine
+mit
+muß
+mußt
+musst
+müssen
+müßt
+nach
+nachdem
+nein
+nicht
+nun
+oder
+seid
+sein
+seine
+sich
+sie
+sind
+soll
+sollen
+sollst
+sollt
+sonst
+soweit
+sowie
+und
+unser
+unsere
+unter
+vom
+von
+vor
+um
+wann
+warum
+was
+weiter
+weitere
+wenn
+wer
+werde
+werden
+werdet
+weshalb
+wie
+wieder
+wieso
+wir
+wird
+wirst
+woher
+wohin
+zum
+zur
+über
diff --git a/inc/lang/de-informal/subscr_digest.txt b/inc/lang/de-informal/subscr_digest.txt
new file mode 100644
index 000000000..f8cab210f
--- /dev/null
+++ b/inc/lang/de-informal/subscr_digest.txt
@@ -0,0 +1,21 @@
+Hallo!
+
+Die Seite @PAGE@ im @TITLE@ Wiki wurde bearbeitet.
+Üersicht der Änderungen:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Alte Revision: @OLDPAGE@
+Neue Revision: @NEWPAGE@
+
+Um das Abonnement für diese Seite aufzulösen, melde dich im Wiki an
+@DOKUWIKIURL@, besuchen dann
+@SUBSCRIBE@
+und klicke auf den Link 'Aboverwaltung'.
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
+
diff --git a/inc/lang/de-informal/subscr_form.txt b/inc/lang/de-informal/subscr_form.txt
new file mode 100644
index 000000000..7bf74f2cf
--- /dev/null
+++ b/inc/lang/de-informal/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Abonnementverwaltung ======
+
+Hier kannst du deine Abonnements für die aktuelle Seite oder den aktuellen [[doku>Namespaces|Namespace]] verwalten.
diff --git a/inc/lang/de-informal/subscr_list.txt b/inc/lang/de-informal/subscr_list.txt
new file mode 100644
index 000000000..5f99cf9dd
--- /dev/null
+++ b/inc/lang/de-informal/subscr_list.txt
@@ -0,0 +1,17 @@
+Hallo!
+
+Die Seiten im Namensraum @PAGE@ im @TITLE@ wurden geändert.
+Nachfolgenden findest du die geänderten Seiten:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Um die Benachrichtigungen zu deaktivieren, melde dich am Wiki unter
+@DOKUWIKIURL@ an, gehe zur Seite
+@SUBSCRIBE@
+und deaktiviere das Abonnement für die Seite und/oder den Namensraum.
+
+--
+Diese E-Mail wurde erzeugt vom DokuWiki unter
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/de-informal/subscr_single.txt b/inc/lang/de-informal/subscr_single.txt
new file mode 100644
index 000000000..3c557bc17
--- /dev/null
+++ b/inc/lang/de-informal/subscr_single.txt
@@ -0,0 +1,24 @@
+Hallo!
+
+Die Seite @PAGE@ im @TITLE@ Wiki wurde bearbeitet.
+Übersicht der Änderungen:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Datum: @DATE@
+Benutzer: @USER@
+Zusammenfassung: @SUMMARY@
+Alte Revision: @OLDPAGE@
+Neue Revision: @NEWPAGE@
+
+Um das Abonnement für diese Seite aufzulösen, melde dich im Wiki an
+@DOKUWIKIURL@, besuche dann
+@NEWPAGE@
+und klicke auf den Link 'Aboverwaltung'.
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
+
diff --git a/inc/lang/de-informal/updateprofile.txt b/inc/lang/de-informal/updateprofile.txt
new file mode 100644
index 000000000..66c2e8293
--- /dev/null
+++ b/inc/lang/de-informal/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Benutzerprofil ändern ======
+
+Nur die Felder, die du änderst, werden aktualisiert. Alle anderen bleiben, wie sie sind. Deinen Benutzernamen kannst du jedoch nicht ändern.
+
+
diff --git a/inc/lang/de-informal/uploadmail.txt b/inc/lang/de-informal/uploadmail.txt
new file mode 100644
index 000000000..69f11400f
--- /dev/null
+++ b/inc/lang/de-informal/uploadmail.txt
@@ -0,0 +1,16 @@
+Eine Datei wurde in deinem Wiki hochgeladen. Hier sind die Details:
+
+Datei : @MEDIA@
+Alte Version: @OLD@
+Datum : @DATE@
+Browser : @BROWSER@
+IP-Adresse : @IPADDRESS@
+Hostname : @HOSTNAME@
+Größe : @SIZE@
+MIME-Typ : @MIME@
+Benutzer : @USER@
+
+--
+Diese Mail wurde vom DokuWiki auf
+@DOKUWIKIURL@
+erzeugt.
diff --git a/inc/lang/de/admin.txt b/inc/lang/de/admin.txt
new file mode 100644
index 000000000..c52f343ea
--- /dev/null
+++ b/inc/lang/de/admin.txt
@@ -0,0 +1,4 @@
+====== Administration ======
+
+Folgende administrative Aufgaben stehen in DokuWiki zur Verfügung.
+
diff --git a/inc/lang/de/adminplugins.txt b/inc/lang/de/adminplugins.txt
new file mode 100644
index 000000000..d3bfd0910
--- /dev/null
+++ b/inc/lang/de/adminplugins.txt
@@ -0,0 +1 @@
+===== Weitere Plugins ===== \ No newline at end of file
diff --git a/inc/lang/de/backlinks.txt b/inc/lang/de/backlinks.txt
new file mode 100644
index 000000000..b797b0003
--- /dev/null
+++ b/inc/lang/de/backlinks.txt
@@ -0,0 +1,5 @@
+====== Links hierher ======
+
+Dies ist eine Liste der Seiten, die zurück zur momentanen Seite linken.
+
+
diff --git a/inc/lang/de/conflict.txt b/inc/lang/de/conflict.txt
new file mode 100644
index 000000000..d24e5b198
--- /dev/null
+++ b/inc/lang/de/conflict.txt
@@ -0,0 +1,6 @@
+====== Eine neuere Version existiert ======
+
+Eine neuere Version des aktuell in Bearbeitung befindlichen Dokuments existiert. Das heißt, jemand hat parallel an der selben Seite gearbeitet und zuerst gespeichert.
+
+Die unten aufgeführten Unterschiede können bei der Entscheidung helfen, welchem Dokument Vorrang gewährt wird. Wählen Sie **''[Speichern]''** zum Sichern Ihrer Version oder **''[Abbrechen]''**, um Ihre Version zu verwerfen und die zuerst gespeicherte Seite zu behalten.
+
diff --git a/inc/lang/de/denied.txt b/inc/lang/de/denied.txt
new file mode 100644
index 000000000..8efa81f1b
--- /dev/null
+++ b/inc/lang/de/denied.txt
@@ -0,0 +1,4 @@
+====== Zugang verweigert ======
+
+Sie haben nicht die erforderliche Berechtigung, um diese Aktion durchzuführen. Eventuell sind Sie nicht am Wiki angemeldet?
+
diff --git a/inc/lang/de/diff.txt b/inc/lang/de/diff.txt
new file mode 100644
index 000000000..82fbbc252
--- /dev/null
+++ b/inc/lang/de/diff.txt
@@ -0,0 +1,5 @@
+====== Unterschiede ======
+
+Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
+
+
diff --git a/inc/lang/de/draft.txt b/inc/lang/de/draft.txt
new file mode 100644
index 000000000..77a55b165
--- /dev/null
+++ b/inc/lang/de/draft.txt
@@ -0,0 +1,6 @@
+====== Entwurf gefunden ======
+
+Ihre letzte Bearbeitungssitzung wurde nicht ordnungsgemäß abgeschlossen. DokuWiki hat während Ihrer Arbeit automatisch einen Zwischenentwurf gespeichert, den Sie jetzt nutzen können, um Ihre Arbeit fortzusetzen. Unten sehen Sie die Daten, die bei Ihrer letzten Sitzung gespeichert wurden.
+
+Bitte entscheiden Sie, ob Sie den Entwurf //wiederherstellen// oder //löschen// wollen oder ob Sie die Bearbeitung abbrechen möchten.
+
diff --git a/inc/lang/de/edit.txt b/inc/lang/de/edit.txt
new file mode 100644
index 000000000..15e02c61a
--- /dev/null
+++ b/inc/lang/de/edit.txt
@@ -0,0 +1,4 @@
+Bitte nur editieren, falls das Dokument **verbessert** werden kann.
+
+Nach dem Bearbeiten den **''[Speichern]''**-Knopf drücken. Siehe [[wiki:syntax]] zur Wiki-Syntax. Zum Testen bitte erst im [[playground:playground|Spielplatz]] üben.
+
diff --git a/inc/lang/de/editrev.txt b/inc/lang/de/editrev.txt
new file mode 100644
index 000000000..6c1f642cc
--- /dev/null
+++ b/inc/lang/de/editrev.txt
@@ -0,0 +1,2 @@
+**Eine ältere Version des Dokuments wurde geladen!** Beim Speichern wird eine neue Version des Dokuments mit diesem Inhalt erstellt.
+---- \ No newline at end of file
diff --git a/inc/lang/de/index.txt b/inc/lang/de/index.txt
new file mode 100644
index 000000000..fa8dc4663
--- /dev/null
+++ b/inc/lang/de/index.txt
@@ -0,0 +1,4 @@
+====== Übersicht ======
+
+Dies ist eine Übersicht über alle vorhandenen Seiten und [[doku>namespaces|Namensräume]].
+
diff --git a/inc/lang/de/install.html b/inc/lang/de/install.html
new file mode 100644
index 000000000..15fd1c36b
--- /dev/null
+++ b/inc/lang/de/install.html
@@ -0,0 +1,27 @@
+<p>Diese Seite hilft Ihnen bei der Erst-Installation und Konfiguration von
+<a href="http://dokuwiki.org">Dokuwiki</a>. Zusätzliche Informationen zu
+diesem Installationsskript finden Sie auf der entsprechenden
+<a href="http://dokuwiki.org/installer">Hilfe Seite</a> (en).</p>
+
+<p>DokuWiki verwendet normale Dateien für das Speichern von Wikiseiten und
+anderen Informationen (Bilder, Suchindizes, alte Versionen, usw.).
+Um DokuWiki betreiben zu können, <strong>muss</strong> Schreibzugriff auf die
+Verzeichnisse bestehen, in denen DokuWiki diese Dateien ablegt. Dieses
+Installationsprogramm kann diese Rechte nicht für Sie setzen. Sie müssen dies
+manuell auf einer Kommando-Shell oder, falls Sie DokuWiki bei einem Fremdanbieter
+hosten, über FTP oder ein entsprechendes Werkzeug (z.B. cPanel) durchführen.</p>
+
+<p>Dieses Skript hilft Ihnen beim ersten Einrichten des Zugangsschutzes
+(<acronym title="access control list">ACL</acronym>) von DokuWiki, welcher eine
+Administratoranmeldung und damit Zugang zum Administrationsmenu ermöglicht.
+Dort können Sie dann weitere Tätigkeiten wie das Installieren von Plugins, das
+Verwalten von Nutzern und das Ändern von Konfigurationseinstellungen durchführen.
+Das Nutzen der Zugangskontrolle ist nicht zwingend erforderlich, es erleichtert aber
+die Administration von DokuWiki.</p>
+
+<p>Erfahrene Anwender oder Nutzer mit speziellen Konfigurationsbedürfnissen sollten
+die folgenden Links nutzen, um sich über
+<a href="http://dokuwiki.org/install">Installation</a>
+und <a href="http://dokuwiki.org/config">Konfiguration</a> zu
+informieren.</p>
+
diff --git a/inc/lang/de/lang.php b/inc/lang/de/lang.php
new file mode 100644
index 000000000..f36c9949c
--- /dev/null
+++ b/inc/lang/de/lang.php
@@ -0,0 +1,330 @@
+<?php
+/**
+ * german language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Christof <gagi@fin.de>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Matthias Schulte <mailinglist@lupo49.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Diese Seite bearbeiten';
+$lang['btn_source'] = 'Zeige Quelltext';
+$lang['btn_show'] = 'Seite anzeigen';
+$lang['btn_create'] = 'Seite anlegen';
+$lang['btn_search'] = 'Suche';
+$lang['btn_save'] = 'Speichern';
+$lang['btn_preview'] = 'Vorschau';
+$lang['btn_top'] = 'Nach oben';
+$lang['btn_newer'] = '<< jüngere Änderungen';
+$lang['btn_older'] = 'ältere Änderungen >>';
+$lang['btn_revs'] = 'Ältere Versionen';
+$lang['btn_recent'] = 'Letzte Änderungen';
+$lang['btn_upload'] = 'Hochladen';
+$lang['btn_cancel'] = 'Abbrechen';
+$lang['btn_index'] = 'Übersicht';
+$lang['btn_secedit'] = 'Bearbeiten';
+$lang['btn_login'] = 'Anmelden';
+$lang['btn_logout'] = 'Abmelden';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Updaten';
+$lang['btn_delete'] = 'Löschen';
+$lang['btn_back'] = 'Zurück';
+$lang['btn_backlink'] = 'Links hierher';
+$lang['btn_backtomedia'] = 'Zurück zur Dateiauswahl';
+$lang['btn_subscribe'] = 'Aboverwaltung';
+$lang['btn_profile'] = 'Benutzerprofil';
+$lang['btn_reset'] = 'Zurücksetzen';
+$lang['btn_resendpwd'] = 'Sende neues Passwort';
+$lang['btn_draft'] = 'Entwurf bearbeiten';
+$lang['btn_recover'] = 'Entwurf wiederherstellen';
+$lang['btn_draftdel'] = 'Entwurf löschen';
+$lang['btn_revert'] = 'Wiederherstellen';
+$lang['btn_register'] = 'Registrieren';
+$lang['btn_apply'] = 'Übernehmen';
+$lang['btn_media'] = 'Medien-Manager';
+$lang['loggedinas'] = 'Angemeldet als';
+$lang['user'] = 'Benutzername';
+$lang['pass'] = 'Passwort';
+$lang['newpass'] = 'Neues Passwort';
+$lang['oldpass'] = 'Bestätigen (Altes Passwort)';
+$lang['passchk'] = 'und nochmal';
+$lang['remember'] = 'Angemeldet bleiben';
+$lang['fullname'] = 'Voller Name';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'Benutzerprofil';
+$lang['badlogin'] = 'Nutzername oder Passwort sind falsch.';
+$lang['minoredit'] = 'kleine Änderung';
+$lang['draftdate'] = 'Entwurf gespeichert am';
+$lang['nosecedit'] = 'Diese Seite wurde in der Zwischenzeit geändert, Sektionsinfo ist veraltet, lade stattdessen volle Seite.';
+$lang['regmissing'] = 'Alle Felder müssen ausgefüllt werden.';
+$lang['reguexists'] = 'Der Nutzername existiert leider schon.';
+$lang['regsuccess'] = 'Der neue Nutzer wurde angelegt und das Passwort per E-Mail versandt.';
+$lang['regsuccess2'] = 'Der neue Nutzer wurde angelegt.';
+$lang['regmailfail'] = 'Offenbar ist ein Fehler beim Versenden der Passwort-E-Mail aufgetreten. Bitte wenden Sie sich an den Wiki-Admin.';
+$lang['regbadmail'] = 'Die angegebene E-Mail-Adresse scheint ungültig zu sein. Falls dies ein Fehler ist, wenden Sie sich bitte an den Wiki-Admin.';
+$lang['regbadpass'] = 'Die beiden eingegeben Passwörter stimmen nicht überein. Bitte versuchen Sie es noch einmal.';
+$lang['regpwmail'] = 'Ihr DokuWiki Passwort';
+$lang['reghere'] = 'Sie haben noch keinen Zugang? Hier registrieren';
+$lang['profna'] = 'Änderung des Benutzerprofils in diesem Wiki nicht möglich.';
+$lang['profnochange'] = 'Keine Änderungen, nichts zu tun.';
+$lang['profnoempty'] = 'Es muss ein Name und eine E-Mail-Adresse angegeben werden.';
+$lang['profchanged'] = 'Benutzerprofil erfolgreich geändert.';
+$lang['pwdforget'] = 'Passwort vergessen? Fordere ein neues an';
+$lang['resendna'] = 'Passwörter versenden ist in diesem Wiki nicht möglich.';
+$lang['resendpwd'] = 'Neues Passwort senden für';
+$lang['resendpwdmissing'] = 'Es tut mir Leid, aber Sie müssen alle Felder ausfüllen.';
+$lang['resendpwdnouser'] = 'Es tut mir Leid, aber der Benutzer existiert nicht in unserer Datenbank.';
+$lang['resendpwdbadauth'] = 'Es tut mir Leid, aber dieser Authentifizierungscode ist ungültig. Stellen Sie sicher, dass Sie den kompletten Bestätigungslink verwendet haben.';
+$lang['resendpwdconfirm'] = 'Ein Bestätigungslink wurde per E-Mail versandt.';
+$lang['resendpwdsuccess'] = 'Ihr neues Passwort wurde per E-Mail versandt.';
+$lang['license'] = 'Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht:';
+$lang['licenseok'] = 'Hinweis: Durch das Bearbeiten dieser Seite geben Sie Ihr Einverständnis, dass Ihr Inhalt unter der folgenden Lizenz veröffentlicht wird:';
+$lang['searchmedia'] = 'Suche Dateinamen:';
+$lang['searchmedia_in'] = 'Suche in %s';
+$lang['txt_upload'] = 'Datei zum Hochladen auswählen';
+$lang['txt_filename'] = 'Hochladen als (optional)';
+$lang['txt_overwrt'] = 'Bestehende Datei überschreiben';
+$lang['lockedby'] = 'Momentan gesperrt von';
+$lang['lockexpire'] = 'Sperre läuft ab am';
+$lang['js']['willexpire'] = 'Die Sperre zur Bearbeitung dieser Seite läuft in einer Minute ab.\nUm Bearbeitungskonflikte zu vermeiden, sollten Sie sie durch einen Klick auf den Vorschau-Knopf verlängern.';
+$lang['js']['notsavedyet'] = 'Nicht gespeicherte Änderungen gehen verloren!';
+$lang['js']['searchmedia'] = 'Suche Dateien';
+$lang['js']['keepopen'] = 'Fenster nach Auswahl nicht schließen';
+$lang['js']['hidedetails'] = 'Details ausblenden';
+$lang['js']['mediatitle'] = 'Linkeinstellungen';
+$lang['js']['mediadisplay'] = 'Linktyp';
+$lang['js']['mediaalign'] = 'Anordnung';
+$lang['js']['mediasize'] = 'Bildgröße';
+$lang['js']['mediatarget'] = 'Linkziel';
+$lang['js']['mediaclose'] = 'Schließen';
+$lang['js']['mediainsert'] = 'Einfügen';
+$lang['js']['mediadisplayimg'] = 'Bild anzeigen.';
+$lang['js']['mediadisplaylnk'] = 'Nur den Link anzeigen.';
+$lang['js']['mediasmall'] = 'Kleine Version';
+$lang['js']['mediamedium'] = 'Mittlere Version';
+$lang['js']['medialarge'] = 'Große Version';
+$lang['js']['mediaoriginal'] = 'Originalversion';
+$lang['js']['medialnk'] = 'Link zur Detailseite';
+$lang['js']['mediadirect'] = 'Direktlink zum Original';
+$lang['js']['medianolnk'] = 'Kein Link';
+$lang['js']['medianolink'] = 'Bild nicht verlinken';
+$lang['js']['medialeft'] = 'Das Bild links anordnen.';
+$lang['js']['mediaright'] = 'Das Bild rechts anordnen.';
+$lang['js']['mediacenter'] = 'Das Bild in der Mitte anordnen.';
+$lang['js']['medianoalign'] = 'Keine Anordnung benutzen.';
+$lang['js']['nosmblinks'] = 'Das Verlinken von Windows-Freigaben funktioniert nur im Microsoft Internet Explorer.\nDer Link kann jedoch durch Kopieren und Einfügen verwendet werden.';
+$lang['js']['linkwiz'] = 'Link-Assistent';
+$lang['js']['linkto'] = 'Link nach:';
+$lang['js']['del_confirm'] = 'Eintrag wirklich löschen?';
+$lang['js']['restore_confirm'] = 'Really restore this version?';
+$lang['js']['media_diff'] = 'Unterschiede anzeigen:';
+$lang['js']['media_diff_both'] = 'Side by Side';
+$lang['js']['media_diff_opacity'] = 'Überblenden';
+$lang['js']['media_diff_portions'] = 'Übergang';
+$lang['js']['media_select'] = 'Dateien auswählen…';
+$lang['js']['media_upload_btn'] = 'Hochladen';
+$lang['js']['media_done_btn'] = 'Fertig';
+$lang['js']['media_drop'] = 'Dateien hier draufziehen um sie hochzuladen';
+$lang['js']['media_cancel'] = 'Entfernen';
+$lang['js']['media_overwrt'] = 'Existierende Dateien überschreiben';
+$lang['rssfailed'] = 'Es ist ein Fehler beim Laden des Feeds aufgetreten: ';
+$lang['nothingfound'] = 'Nichts gefunden.';
+$lang['mediaselect'] = 'Dateiauswahl';
+$lang['fileupload'] = 'Datei hochladen';
+$lang['uploadsucc'] = 'Datei wurde erfolgreich hochgeladen';
+$lang['uploadfail'] = 'Hochladen fehlgeschlagen. Keine Berechtigung?';
+$lang['uploadwrong'] = 'Hochladen verweigert. Diese Dateiendung ist nicht erlaubt.';
+$lang['uploadexist'] = 'Datei existiert bereits. Keine Änderungen vorgenommen.';
+$lang['uploadbadcontent'] = 'Die hochgeladenen Daten stimmen nicht mit der Dateiendung %s überein.';
+$lang['uploadspam'] = 'Hochladen verweigert: Treffer auf der Spamliste.';
+$lang['uploadxss'] = 'Hochladen verweigert: Daten scheinen Schadcode zu enthalten.';
+$lang['uploadsize'] = 'Die hochgeladene Datei war zu groß. (max. %s)';
+$lang['deletesucc'] = 'Die Datei "%s" wurde gelöscht.';
+$lang['deletefail'] = '"%s" konnte nicht gelöscht werden - prüfen Sie die Berechtigungen.';
+$lang['mediainuse'] = 'Die Datei "%s" wurde nicht gelöscht - sie wird noch verwendet.';
+$lang['namespaces'] = 'Namensräume';
+$lang['mediafiles'] = 'Vorhandene Dateien in';
+$lang['accessdenied'] = 'Es ist Ihnen nicht gestattet, diese Seite zu sehen.';
+$lang['mediausage'] = 'Syntax zum Verwenden dieser Datei:';
+$lang['mediaview'] = 'Originaldatei öffnen';
+$lang['mediaroot'] = 'Wurzel';
+$lang['mediaupload'] = 'Laden Sie hier eine Datei in den momentanen Namensraum hoch. Um Unterordner zu erstellen, stellen Sie diese dem Dateinamen durch Doppelpunkt getrennt voran, nachdem Sie die Datei ausgewählt haben.';
+$lang['mediaextchange'] = 'Dateiendung vom .%s nach .%s geändert!';
+$lang['reference'] = 'Verwendung von';
+$lang['ref_inuse'] = 'Diese Datei kann nicht gelöscht werden, da sie noch von folgenden Seiten benutzt wird:';
+$lang['ref_hidden'] = 'Einige Verweise sind auf Seiten, für die Sie keine Leseberechtigung haben.';
+$lang['hits'] = 'Treffer';
+$lang['quickhits'] = 'Passende Seitennamen';
+$lang['toc'] = 'Inhaltsverzeichnis';
+$lang['current'] = 'aktuell';
+$lang['yours'] = 'Ihre Version';
+$lang['diff'] = 'Zeige Unterschiede zu aktueller Version';
+$lang['diff2'] = 'Zeige Unterschiede der ausgewählten Versionen';
+$lang['difflink'] = 'Link zu dieser Vergleichsansicht';
+$lang['diff_type'] = 'Unterschiede anzeigen:';
+$lang['diff_inline'] = 'Inline';
+$lang['diff_side'] = 'Side by Side';
+$lang['line'] = 'Zeile';
+$lang['breadcrumb'] = 'Zuletzt angesehen';
+$lang['youarehere'] = 'Sie befinden sich hier';
+$lang['lastmod'] = 'Zuletzt geändert';
+$lang['by'] = 'von';
+$lang['deleted'] = 'gelöscht';
+$lang['created'] = 'angelegt';
+$lang['restored'] = 'alte Version wieder hergestellt';
+$lang['external_edit'] = 'Externe Bearbeitung';
+$lang['summary'] = 'Zusammenfassung';
+$lang['noflash'] = 'Das <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> wird benötigt, um diesen Inhalt anzuzeigen.';
+$lang['download'] = 'Schnipsel herunterladen';
+$lang['tools'] = 'Werkzeuge';
+$lang['user_tools'] = 'Benutzer-Werkzeuge';
+$lang['site_tools'] = 'Webseiten-Werkzeuge';
+$lang['page_tools'] = 'Seiten-Werkzeuge';
+$lang['skip_to_content'] = 'zum Inhalt springen';
+$lang['mail_newpage'] = 'Neue Seite:';
+$lang['mail_changed'] = 'Seite geändert:';
+$lang['mail_subscribe_list'] = 'Geänderte Seiten im Namensraum:';
+$lang['mail_new_user'] = 'Neuer Benutzer:';
+$lang['mail_upload'] = 'Datei hochgeladen:';
+$lang['changes_type'] = 'Änderungen anzeigen von';
+$lang['pages_changes'] = 'Seiten';
+$lang['media_changes'] = 'Mediendateien';
+$lang['both_changes'] = 'Beides, Seiten- und Mediendateien';
+$lang['qb_bold'] = 'Fetter Text';
+$lang['qb_italic'] = 'Kursiver Text';
+$lang['qb_underl'] = 'Unterstrichener Text';
+$lang['qb_code'] = 'Code Text';
+$lang['qb_strike'] = 'Durchgestrichener Text';
+$lang['qb_h1'] = 'Level 1 Überschrift';
+$lang['qb_h2'] = 'Level 2 Überschrift';
+$lang['qb_h3'] = 'Level 3 Überschrift';
+$lang['qb_h4'] = 'Level 4 Überschrift';
+$lang['qb_h5'] = 'Level 5 Überschrift';
+$lang['qb_h'] = 'Überschrift';
+$lang['qb_hs'] = 'Wähle die Überschrift';
+$lang['qb_hplus'] = 'Obere Überschrift';
+$lang['qb_hminus'] = 'Untere Überschrift';
+$lang['qb_hequal'] = 'Gleichzeilige Überschrift';
+$lang['qb_link'] = 'Interner Link';
+$lang['qb_extlink'] = 'Externer Link';
+$lang['qb_hr'] = 'Horizontale Linie';
+$lang['qb_ol'] = 'Nummerierter Listenpunkt';
+$lang['qb_ul'] = 'Listenpunkt';
+$lang['qb_media'] = 'Bilder und andere Dateien hinzufügen';
+$lang['qb_sig'] = 'Unterschrift einfügen';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Sonderzeichen';
+$lang['upperns'] = 'zum übergeordneten Namensraum springen';
+$lang['admin_register'] = 'Neuen Benutzer anmelden';
+$lang['metaedit'] = 'Metadaten bearbeiten';
+$lang['metasaveerr'] = 'Die Metadaten konnten nicht gesichert werden';
+$lang['metasaveok'] = 'Metadaten gesichert';
+$lang['img_backto'] = 'Zurück zu';
+$lang['img_title'] = 'Titel';
+$lang['img_caption'] = 'Bildunterschrift';
+$lang['img_date'] = 'Datum';
+$lang['img_fname'] = 'Dateiname';
+$lang['img_fsize'] = 'Größe';
+$lang['img_artist'] = 'FotografIn';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Schlagwörter';
+$lang['img_width'] = 'Breite';
+$lang['img_height'] = 'Höhe';
+$lang['img_manager'] = 'Im Medien-Manager anzeigen';
+$lang['subscr_subscribe_success'] = '%s hat nun Änderungen der Seite %s abonniert';
+$lang['subscr_subscribe_error'] = '%s kann die Änderungen der Seite %s nicht abonnieren';
+$lang['subscr_subscribe_noaddress'] = 'Weil Ihre E-Mail-Adresse fehlt, können Sie das Thema nicht abonnieren';
+$lang['subscr_unsubscribe_success'] = 'Das Abonnement von %s für die Seite %s wurde aufgelöst';
+$lang['subscr_unsubscribe_error'] = 'Das Abonnement von %s für die Seite %s konnte nicht aufgelöst werden';
+$lang['subscr_already_subscribed'] = '%s hat %s bereits abonniert';
+$lang['subscr_not_subscribed'] = '%s hat %s nicht abonniert';
+$lang['subscr_m_not_subscribed'] = 'Sie haben die aktuelle Seite und ihre Namensräume nicht abonniert.';
+$lang['subscr_m_new_header'] = 'Abonnement hinzufügen';
+$lang['subscr_m_current_header'] = 'Aktuelle Abonnements';
+$lang['subscr_m_unsubscribe'] = 'Löschen';
+$lang['subscr_m_subscribe'] = 'Abonnieren';
+$lang['subscr_m_receive'] = 'Benachrichtigung';
+$lang['subscr_style_every'] = 'E-Mail bei jeder Bearbeitung';
+$lang['subscr_style_digest'] = 'Zusammenfassung der Änderungen für jede veränderte Seite (Alle %.2f Tage)';
+$lang['subscr_style_list'] = 'Liste der geänderten Seiten (Alle %.2f Tage)';
+$lang['authmodfailed'] = 'Benutzerüberprüfung nicht möglich. Bitte wenden Sie sich an den Systembetreuer.';
+$lang['authtempfail'] = 'Benutzerüberprüfung momentan nicht möglich. Falls das Problem andauert, wenden Sie sich an den Systembetreuer.';
+$lang['i_chooselang'] = 'Wählen Sie Ihre Sprache';
+$lang['i_installer'] = 'DokuWiki Installation';
+$lang['i_wikiname'] = 'Wiki-Name';
+$lang['i_enableacl'] = 'Zugangskontrolle (ACL) aktivieren (empfohlen)';
+$lang['i_superuser'] = 'Administrator Benutzername';
+$lang['i_problems'] = 'Das Installationsprogramm hat unten aufgeführte Probleme festgestellt, die zunächst behoben werden müssen bevor Sie mit der Installation fortfahren können.';
+$lang['i_modified'] = 'Aus Sicherheitsgründen arbeitet dieses Script nur mit einer neuen, unmodifizierten DokuWiki Installation. Sie sollten entweder alle Dateien noch einmal frisch installieren oder die <a href="http://dokuwiki.org/install">Dokuwiki-Installationsanleitung</a> konsultieren.';
+$lang['i_funcna'] = 'Die PHP-Funktion <code>%s</code> ist nicht verfügbar. Unter Umständen wurde sie von Ihrem Hoster deaktiviert?';
+$lang['i_phpver'] = 'Ihre PHP-Version <code>%s</code> ist niedriger als die benötigte Version <code>%s</code>. Bitte aktualisieren Sie Ihre PHP-Installation.';
+$lang['i_permfail'] = '<code>%s</code> ist nicht durch DokuWiki beschreibbar. Sie müssen die Berechtigungen dieses Ordners ändern!';
+$lang['i_confexists'] = '<code>%s</code> existiert bereits';
+$lang['i_writeerr'] = '<code>%s</code> konnte nicht erzeugt werden. Sie sollten die Verzeichnis-/Datei-Rechte überprüfen und die Datei manuell anlegen.';
+$lang['i_badhash'] = 'Unbekannte oder modifizierte dokuwiki.php (Hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - unerlaubter oder leerer Wert';
+$lang['i_success'] = 'Die Konfiguration wurde erfolgreich abgeschlossen. Sie können jetzt die install.php löschen. Ihr <a href="doku.php">neues DokuWiki</a> ist jetzt für Sie bereit.';
+$lang['i_failure'] = 'Es sind Fehler beim Schreiben der Konfigurationsdateien aufgetreten. Sie müssen diese vermutlich von Hand beheben, bevor Sie Ihr <a href="doku.php">neues DokuWiki</a> nutzen können.';
+$lang['i_policy'] = 'Anfangseinstellung für Zugangskontrolle (ACL)';
+$lang['i_pol0'] = 'Offenes Wiki (lesen, schreiben, hochladen für alle)';
+$lang['i_pol1'] = 'Öffentliches Wiki (lesen für alle, schreiben und hochladen für registrierte Nutzer)';
+$lang['i_pol2'] = 'Geschlossenes Wiki (lesen, schreiben, hochladen nur für registrierte Nutzer)';
+$lang['i_retry'] = 'Wiederholen';
+$lang['i_license'] = 'Bitte wählen Sie die Lizenz, unter die Sie Ihre Inhalte stellen möchten:';
+$lang['recent_global'] = 'Im Moment sehen Sie die Änderungen im Namensraum <b>%s</b>. Sie können auch <a href="%s">die Änderungen im gesamten Wiki sehen</a>.';
+$lang['years'] = 'vor %d Jahren';
+$lang['months'] = 'vor %d Monaten';
+$lang['weeks'] = 'vor %d Wochen';
+$lang['days'] = 'vor %d Tagen';
+$lang['hours'] = 'vor %d Stunden';
+$lang['minutes'] = 'vor %d Minuten';
+$lang['seconds'] = 'vor %d Sekunden';
+$lang['wordblock'] = 'Ihre Bearbeitung wurde nicht gespeichert, da sie gesperrten Text enthielt (Spam).';
+$lang['media_uploadtab'] = 'Hochladen';
+$lang['media_searchtab'] = 'Suchen';
+$lang['media_file'] = 'Datei';
+$lang['media_viewtab'] = 'Anzeigen';
+$lang['media_edittab'] = 'Bearbeiten';
+$lang['media_historytab'] = 'Verlauf';
+$lang['media_list_thumbs'] = 'Vorschaubilder';
+$lang['media_list_rows'] = 'Reihen';
+$lang['media_sort_name'] = 'nach Name';
+$lang['media_sort_date'] = 'nach Datum';
+$lang['media_namespaces'] = 'Namensraum wählen';
+$lang['media_files'] = 'Dateien in %s';
+$lang['media_upload'] = 'In den <strong>%s</strong> Namespace hochladen.';
+$lang['media_search'] = 'Im Namespace <strong>%s</strong> suchen.';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s in %s';
+$lang['media_edit'] = '%s bearbeiten';
+$lang['media_history'] = 'Versionsverlauf von %s.';
+$lang['media_meta_edited'] = 'Meta-Informationen bearbeitet';
+$lang['media_perm_read'] = 'Sie besitzen nicht die notwendigen Berechtigungen um die Datei anzuzeigen.';
+$lang['media_perm_upload'] = 'Sie besitzen nicht die notwendigen Berechtigungen um Dateien hochzuladen.';
+$lang['media_update'] = 'Neue Version hochladen';
+$lang['media_restore'] = 'Diese Version wiederherstellen';
+$lang['plugin_install_err'] = 'Plugin nicht korrekt installiert. Plugin-Verzeichnis von \'%s\' nach \'%s\' umbenennen.';
diff --git a/inc/lang/de/locked.txt b/inc/lang/de/locked.txt
new file mode 100644
index 000000000..6656beece
--- /dev/null
+++ b/inc/lang/de/locked.txt
@@ -0,0 +1,4 @@
+====== Seite gesperrt ======
+
+Diese Seite ist momentan von einem anderen Nutzer gesperrt. Warten Sie, bis dieser mit dem Bearbeiten fertig ist oder die Sperre abläuft.
+
diff --git a/inc/lang/de/login.txt b/inc/lang/de/login.txt
new file mode 100644
index 000000000..6698da614
--- /dev/null
+++ b/inc/lang/de/login.txt
@@ -0,0 +1,4 @@
+====== Anmelden ======
+
+Geben Sie Ihren Benutzernamen und Ihr Passwort in das Formular unten ein, um sich anzumelden. Bitte beachten Sie, dass dafür "Cookies" in den Sicherheitseinstellungen Ihres Browsers erlaubt sein müssen.
+
diff --git a/inc/lang/de/mailtext.txt b/inc/lang/de/mailtext.txt
new file mode 100644
index 000000000..fee88d4d8
--- /dev/null
+++ b/inc/lang/de/mailtext.txt
@@ -0,0 +1,17 @@
+Eine Seite in Ihrem Wiki wurde geändert oder neu angelegt. Hier sind die Details:
+
+Datum : @DATE@
+Browser : @BROWSER@
+IP-Adresse : @IPADDRESS@
+Hostname : @HOSTNAME@
+Alte Version : @OLDPAGE@
+Neue Version : @NEWPAGE@
+Zusammenfassung: @SUMMARY@
+Benutzer : @USER@
+
+@DIFF@
+
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
diff --git a/inc/lang/de/newpage.txt b/inc/lang/de/newpage.txt
new file mode 100644
index 000000000..7871c67de
--- /dev/null
+++ b/inc/lang/de/newpage.txt
@@ -0,0 +1,5 @@
+====== Dieses Thema existiert noch nicht ======
+
+Sie sind einem Link zu einer Seite gefolgt, die noch nicht existiert. Sie können die Seite mit dem Knopf **"[Seite anlegen]"** selbst anlegen und mit Inhalt füllen.
+
+
diff --git a/inc/lang/de/norev.txt b/inc/lang/de/norev.txt
new file mode 100644
index 000000000..8a9c6927b
--- /dev/null
+++ b/inc/lang/de/norev.txt
@@ -0,0 +1,4 @@
+====== Version existiert nicht ======
+
+Die angegebene Version des Dokuments wurde nicht gefunden. Benutzen Sie den **''[Ältere Versionen]''** Knopf, um eine Liste aller verfügbaren Versionen dieses Dokuments zu erhalten.
+
diff --git a/inc/lang/de/password.txt b/inc/lang/de/password.txt
new file mode 100644
index 000000000..dd10b43e2
--- /dev/null
+++ b/inc/lang/de/password.txt
@@ -0,0 +1,10 @@
+Hallo @FULLNAME@!
+
+Hier sind Ihre Nutzerdaten für @TITLE@ auf @DOKUWIKIURL@
+
+Benutzername: @LOGIN@
+Passwort : @PASSWORD@
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
diff --git a/inc/lang/de/preview.txt b/inc/lang/de/preview.txt
new file mode 100644
index 000000000..b07ae5091
--- /dev/null
+++ b/inc/lang/de/preview.txt
@@ -0,0 +1,5 @@
+====== Vorschau ======
+
+So wird Ihr Text später aussehen. Achtung: Der Text wurde noch **nicht gespeichert**!
+
+
diff --git a/inc/lang/de/pwconfirm.txt b/inc/lang/de/pwconfirm.txt
new file mode 100644
index 000000000..3aa81bf77
--- /dev/null
+++ b/inc/lang/de/pwconfirm.txt
@@ -0,0 +1,16 @@
+Hallo @FULLNAME@!
+
+Jemand hat ein neues Passwort für Ihren @TITLE@
+login auf @DOKUWIKIURL@ angefordert.
+
+Wenn Sie diese Änderung nicht angefordert haben, ignorieren Sie diese
+E-Mail einfach.
+
+Um die Anforderung zu bestätigen, folgen Sie bitte dem unten angegebenen
+Bestätigungslink.
+
+@CONFIRM@
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
diff --git a/inc/lang/de/read.txt b/inc/lang/de/read.txt
new file mode 100644
index 000000000..bc011d0ee
--- /dev/null
+++ b/inc/lang/de/read.txt
@@ -0,0 +1,2 @@
+Diese Seite ist nicht editierbar. Sie können den Quelltext sehen, jedoch nicht verändern. Kontaktieren Sie den Administrator, wenn Sie glauben, dass hier ein Fehler vorliegt.
+
diff --git a/inc/lang/de/recent.txt b/inc/lang/de/recent.txt
new file mode 100644
index 000000000..c05bbae12
--- /dev/null
+++ b/inc/lang/de/recent.txt
@@ -0,0 +1,5 @@
+====== Letzte Änderungen ======
+
+Die folgenden Seiten wurden zuletzt geändert.
+
+
diff --git a/inc/lang/de/register.txt b/inc/lang/de/register.txt
new file mode 100644
index 000000000..83684f500
--- /dev/null
+++ b/inc/lang/de/register.txt
@@ -0,0 +1,4 @@
+====== Als neuer Nutzer registrieren ======
+
+Bitte füllen Sie alle Felder aus, um einen neuen Nutzer-Account in diesem Wiki anzulegen. Stellen Sie sicher, dass eine **gültige E-Mail-Adresse** angegeben wird - das Passwort wird an diese Adresse gesendet. Der Nutzername sollte aus einem Wort ohne Umlaute, Leer- oder Sonderzeichen bestehen.
+
diff --git a/inc/lang/de/registermail.txt b/inc/lang/de/registermail.txt
new file mode 100644
index 000000000..ed37a9505
--- /dev/null
+++ b/inc/lang/de/registermail.txt
@@ -0,0 +1,14 @@
+Ein neuer Benutzer hat sich registriert. Hier sind die Details:
+
+Benutzername : @NEWUSER@
+Voller Name : @NEWNAME@
+E-Mail : @NEWEMAIL@
+
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
diff --git a/inc/lang/de/resendpwd.txt b/inc/lang/de/resendpwd.txt
new file mode 100644
index 000000000..a63fd5d55
--- /dev/null
+++ b/inc/lang/de/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Neues Passwort anfordern ======
+
+Füllen Sie alle Felder unten aus, um ein neues Passwort für Ihren Zugang zu erhalten. Das neue Passwort wird an Ihre gespeicherte E-Mail-Adresse geschickt. Der Benutzername muss Ihrem Wiki-Benutzernamen entsprechen.
diff --git a/inc/lang/de/revisions.txt b/inc/lang/de/revisions.txt
new file mode 100644
index 000000000..843c3f9f4
--- /dev/null
+++ b/inc/lang/de/revisions.txt
@@ -0,0 +1,4 @@
+====== Ältere Versionen ======
+
+Dies sind ältere Versionen der gewählten Seite. Um zu einer älteren Version zurückzukehren, wählen Sie die entsprechende Version aus, klicken auf **''[Diese Seite bearbeiten]''** und speichern Sie diese erneut ab.
+
diff --git a/inc/lang/de/searchpage.txt b/inc/lang/de/searchpage.txt
new file mode 100644
index 000000000..56104551b
--- /dev/null
+++ b/inc/lang/de/searchpage.txt
@@ -0,0 +1,7 @@
+====== Suche ======
+
+Unten sind die Ergebnisse Ihrer Suche gelistet. Falls der gesuchte Begriff nicht gefunden wurde, können Sie direkt eine neue Seite für den Suchbegriff anlegen, indem Sie auf den **''[Seite anlegen]''** Knopf drücken.
+
+===== Ergebnisse =====
+
+
diff --git a/inc/lang/de/showrev.txt b/inc/lang/de/showrev.txt
new file mode 100644
index 000000000..65f53c9c1
--- /dev/null
+++ b/inc/lang/de/showrev.txt
@@ -0,0 +1,2 @@
+**Dies ist eine alte Version des Dokuments!**
+----
diff --git a/inc/lang/de/stopwords.txt b/inc/lang/de/stopwords.txt
new file mode 100644
index 000000000..0487a940a
--- /dev/null
+++ b/inc/lang/de/stopwords.txt
@@ -0,0 +1,125 @@
+# Die Wörter dieser Liste werden bei der Indexierung ignoriert. Jedes Wort steht in einer neuen Zeile.
+# Beachten Sie beim Bearbeiten der Datei darauf, dass Sie UNIX-Zeilenumbrüche verwenden (einfacher Zeilenumbruch).
+# Wörter, die kürzer als 3 Buchstaben sind, brauchen Sie nicht in die Liste mit aufnehmen. Diese werden automatisch ignoriert.
+# Diese Liste basiert auf der folgenden: http://www.ranks.nl/stopwords/
+aber
+als
+auch
+auf
+aus
+bei
+bin
+bis
+bist
+dadurch
+daher
+darum
+das
+daß
+dass
+dein
+deine
+dem
+den
+der
+des
+dessen
+deshalb
+die
+dies
+dieser
+dieses
+doch
+dort
+durch
+ein
+eine
+einem
+einen
+einer
+eines
+euer
+eure
+für
+hatte
+hatten
+hattest
+hattet
+hier
+hinter
+ich
+ihr
+ihre
+in
+im
+ist
+jede
+jedem
+jeden
+jeder
+jedes
+jener
+jenes
+jetzt
+kann
+kannst
+können
+könnt
+machen
+mein
+meine
+mit
+muß
+mußt
+musst
+müssen
+müßt
+nach
+nachdem
+nein
+nicht
+nun
+oder
+seid
+sein
+seine
+sich
+sie
+sind
+soll
+sollen
+sollst
+sollt
+sonst
+soweit
+sowie
+und
+unser
+unsere
+unter
+vom
+von
+vor
+um
+wann
+warum
+was
+weiter
+weitere
+wenn
+wer
+werde
+werden
+werdet
+weshalb
+wie
+wieder
+wieso
+wir
+wird
+wirst
+woher
+wohin
+zum
+zur
+über
diff --git a/inc/lang/de/subscr_digest.txt b/inc/lang/de/subscr_digest.txt
new file mode 100644
index 000000000..7cc79bba2
--- /dev/null
+++ b/inc/lang/de/subscr_digest.txt
@@ -0,0 +1,21 @@
+Hallo!
+
+Die Seite @PAGE@ im @TITLE@ Wiki wurde bearbeitet.
+Übersicht der Änderungen:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Alte Revision: @OLDPAGE@
+Neue Revision: @NEWPAGE@
+
+Um das Abonnement für diese Seite aufzulösen, melden Sie sich im Wiki an
+@DOKUWIKIURL@, besuchen dann
+@SUBSCRIBE@
+und klicken auf den Link 'Aboverwaltung'.
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
+
diff --git a/inc/lang/de/subscr_form.txt b/inc/lang/de/subscr_form.txt
new file mode 100644
index 000000000..4ba6afb09
--- /dev/null
+++ b/inc/lang/de/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Abonnementverwaltung ======
+
+Hier können Sie Ihre Abonnements für die aktuelle Seite oder den aktuellen [[doku>Namespaces|Namespace]] verwalten.
diff --git a/inc/lang/de/subscr_list.txt b/inc/lang/de/subscr_list.txt
new file mode 100644
index 000000000..98ec4c2ab
--- /dev/null
+++ b/inc/lang/de/subscr_list.txt
@@ -0,0 +1,18 @@
+Hallo!
+
+Seite im Namensraum @PAGE@ im @TITLE@ Wiki wurden bearbeitet.
+Das sind die geänderten Seiten:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Um das Abonnement für diese Seite aufzulösen, melde Sie sich im Wiki an
+@DOKUWIKIURL@, besuchen dann
+@SUBSCRIBE@
+und klicken auf die Taste 'Änderungen abbestellen'.
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
+
diff --git a/inc/lang/de/subscr_single.txt b/inc/lang/de/subscr_single.txt
new file mode 100644
index 000000000..f3e1cd393
--- /dev/null
+++ b/inc/lang/de/subscr_single.txt
@@ -0,0 +1,24 @@
+Hallo!
+
+Die Seite @PAGE@ im @TITLE@ Wiki wurde bearbeitet.
+Übersicht der Änderungen:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Datum: @DATE@
+Benutzer: @USER@
+Zusammenfassung: @SUMMARY@
+Alte Revision: @OLDPAGE@
+Neue Revision: @NEWPAGE@
+
+Um das Abonnement für diese Seite aufzulösen, melden Sie sich im Wiki an
+@DOKUWIKIURL@, besuchen dann
+@NEWPAGE@
+und klicken auf die Taste 'Aboverwaltung'.
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
+
diff --git a/inc/lang/de/updateprofile.txt b/inc/lang/de/updateprofile.txt
new file mode 100644
index 000000000..f19dd13f6
--- /dev/null
+++ b/inc/lang/de/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Benutzerprofil ändern ======
+
+Nur die Felder, die Sie ändern, werden aktualisiert. Alle anderen bleiben, wie sie sind. Ihren Benutzernamen können Sie jedoch nicht ändern.
+
+
diff --git a/inc/lang/de/uploadmail.txt b/inc/lang/de/uploadmail.txt
new file mode 100644
index 000000000..977e7561c
--- /dev/null
+++ b/inc/lang/de/uploadmail.txt
@@ -0,0 +1,15 @@
+Eine Datei wurde in Ihrem Wiki hochgeladen. Hier sind die Details:
+
+Datei : @MEDIA@
+Alte Version: @OLD@
+Datum : @DATE@
+Browser : @BROWSER@
+IP-Adresse : @IPADDRESS@
+Hostname : @HOSTNAME@
+Größe : @SIZE@
+MIME-Typ : @MIME@
+Benutzer : @USER@
+
+--
+Diese Mail kommt vom DokuWiki auf
+@DOKUWIKIURL@
diff --git a/inc/lang/el/admin.txt b/inc/lang/el/admin.txt
new file mode 100644
index 000000000..729004b05
--- /dev/null
+++ b/inc/lang/el/admin.txt
@@ -0,0 +1,3 @@
+====== Διαχείριση ======
+
+Παρακάτω μπορείτε να βρείτε μια λίστα με τις λειτουργίες διαχείρισης στο DokuWiki
diff --git a/inc/lang/el/adminplugins.txt b/inc/lang/el/adminplugins.txt
new file mode 100644
index 000000000..ef1a2853b
--- /dev/null
+++ b/inc/lang/el/adminplugins.txt
@@ -0,0 +1 @@
+===== Πρόσθετα ===== \ No newline at end of file
diff --git a/inc/lang/el/backlinks.txt b/inc/lang/el/backlinks.txt
new file mode 100644
index 000000000..572f85791
--- /dev/null
+++ b/inc/lang/el/backlinks.txt
@@ -0,0 +1,3 @@
+====== Σύνδεσμοι προς την τρέχουσα σελίδα ======
+
+Οι παρακάτω σελίδες περιέχουν συνδέσμους προς την τρέχουσα σελίδα. \ No newline at end of file
diff --git a/inc/lang/el/conflict.txt b/inc/lang/el/conflict.txt
new file mode 100644
index 000000000..a2065c0f3
--- /dev/null
+++ b/inc/lang/el/conflict.txt
@@ -0,0 +1,8 @@
+====== Υπάρχει μία νεώτερη έκδοση αυτής της σελίδας ======
+
+Υπάρχει μία νεώτερη έκδοση της σελίδας που τρoποποιήσατε.
+Αυτό συμβαίνει εάν κάποιος άλλος χρήστης τροποποίησε την ίδια σελίδα ενώ την επεξεργαζόσασταν και εσείς.
+
+Ελέγξτε προσεκτικά τις διαφορές που παρουσιάζονται παρακάτω και έπειτα αποφασίστε ποια έκδοση θα κρατήσετε.
+Εάν επιλέξετε ''Αποθήκευση'', η δική σας έκδοση θα αποθηκευτεί.
+Εάν επιλέξετε ''Ακύρωση'', η νεώτερη έκδοση θα διατηρηθεί ως τρέχουσα.
diff --git a/inc/lang/el/denied.txt b/inc/lang/el/denied.txt
new file mode 100644
index 000000000..36d7ae103
--- /dev/null
+++ b/inc/lang/el/denied.txt
@@ -0,0 +1,5 @@
+====== Μη επιτρεπτή ενέργεια ======
+
+Συγγνώμη, αλλά δεν έχετε επαρκή δικαιώματα για την συγκεκριμένη ενέργεια.
+
+Μήπως παραλείψατε να συνδεθείτε;
diff --git a/inc/lang/el/diff.txt b/inc/lang/el/diff.txt
new file mode 100644
index 000000000..dde065b43
--- /dev/null
+++ b/inc/lang/el/diff.txt
@@ -0,0 +1,3 @@
+====== Σύγκριση εκδόσεων ======
+
+Εδώ βλέπετε τις διαφορές μεταξύ της επιλεγμένης έκδοσης και της τρέχουσας έκδοσης της σελίδας.
diff --git a/inc/lang/el/draft.txt b/inc/lang/el/draft.txt
new file mode 100644
index 000000000..5ca7b8dfa
--- /dev/null
+++ b/inc/lang/el/draft.txt
@@ -0,0 +1,9 @@
+====== Βρέθηκε μία αυτόματα αποθηκευμένη σελίδα ======
+
+Η τελευταία τροποποίηση αυτής της σελίδας δεν ολοκληρώθηκε επιτυχώς.
+Η εφαρμογή αποθήκευσε αυτόματα μία εκδοχή της σελίδας την ώρα που την επεξεργαζόσασταν και μπορείτε να την χρησιμοποιήσετε για να συνεχίσετε την εργασία σας.
+Παρακάτω φαίνεται αυτή η πιο πρόσφατη αυτόματα αποθηκευμένη σελίδα.
+
+Μπορείτε να //επαναφέρετε// αυτή την αυτόματα αποθηκευμένη σελίδα ως τρέχουσα, να την //διαγράψετε// ή να //ακυρώσετε// τη διαδικασία τροποποίησης της τρέχουσας σελίδας.
+
+
diff --git a/inc/lang/el/edit.txt b/inc/lang/el/edit.txt
new file mode 100644
index 000000000..8d9559fcc
--- /dev/null
+++ b/inc/lang/el/edit.txt
@@ -0,0 +1,3 @@
+Τροποποιήστε την σελίδα **μόνο** εάν μπορείτε να την **βελτιώσετε**.
+Για να κάνετε δοκιμές με ασφάλεια ή να εξοικειωθείτε με το περιβάλλον χρησιμοποιήστε το [[:playground:playground|playground]].
+Αφού τροποποιήστε την σελίδα επιλέξτε ''Αποθήκευση''. Δείτε τις [[:wiki:syntax|οδηγίες]] για την σωστή σύνταξη.
diff --git a/inc/lang/el/editrev.txt b/inc/lang/el/editrev.txt
new file mode 100644
index 000000000..ac6bc5a3d
--- /dev/null
+++ b/inc/lang/el/editrev.txt
@@ -0,0 +1,2 @@
+**Φορτώσατε μια παλαιότερη έκδοση της σελίδας!** Εάν την αποθηκεύσετε, θα αντικαταστήσει την τρέχουσα έκδοση.
+---- \ No newline at end of file
diff --git a/inc/lang/el/index.txt b/inc/lang/el/index.txt
new file mode 100644
index 000000000..e2da3a85e
--- /dev/null
+++ b/inc/lang/el/index.txt
@@ -0,0 +1,3 @@
+====== Κατάλογος ======
+
+Εδώ βλέπετε τον κατάλογο όλων των διαθέσιμων σελίδων, ταξινομημένες κατά [[doku>namespaces|φακέλους]].
diff --git a/inc/lang/el/install.html b/inc/lang/el/install.html
new file mode 100644
index 000000000..9487de7c7
--- /dev/null
+++ b/inc/lang/el/install.html
@@ -0,0 +1,26 @@
+<p>Αυτή η σελίδα περιέχει πληροφορίες που βοηθούν στην αρχική εγκατάσταση και
+ρύθμιση της εφαρμογής <a href="http://www.dokuwiki.org/el:dokuwiki">Dokuwiki</a>.
+Περισσότερες πληροφορίες υπάρχουν στη <a href="http://www.dokuwiki.org/el:installer">
+σελίδα τεκμηρίωσης</a> του οδηγού εγκατάστασης.</p>
+
+<p>Η εφαρμογή DokuWiki χρησιμοποιεί απλά αρχεία για να αποθηκεύει τις σελίδες
+wiki καθώς και πληροφορίες που σχετίζονται με αυτές (π.χ. εικόνες, καταλόγους
+αναζήτησης, παλαιότερες εκδόσεις σελίδων, κλπ). Για να λειτουργεί σωστά η εφαρμογή
+DokuWiki <strong>πρέπει</strong> να έχει δικαιώματα εγγραφής στους φακέλους που
+φιλοξενούν αυτά τα αρχεία. Ο οδηγός εγκατάστασης δεν έχει την δυνατότητα να
+παραχωρήσει αυτά τα δικαιώματα εγγραφής στους σχετικούς φακέλους. Ο κανονικός
+τρόπος για να γίνει αυτό είναι είτε απευθείας σε περιβάλλον γραμμής εντολών ή,
+εάν δεν έχετε τέτοια πρόσβαση, μέσω FTP ή του πίνακα ελέγχου του περιβάλλοντος
+φιλοξενίας (π.χ. cPanel).</p>
+
+<p>Ο οδηγός εγκατάστασης θα ρυθμίσει την εφαρμογή DokuWiki ώστε να χρησιμοποιεί
+<acronym title="access control list">ACL</acronym>, με τρόπο ώστε ο διαχειριστής
+να έχει δυνατότητα εισόδου και πρόσβαση στο μενού διαχείρισης της εφαρμογής για
+εγκατάσταση επεκτάσεων, διαχείριση χρηστών, διαχείριση δικαιωμάτων πρόσβασης στις
+διάφορες σελίδες και αλλαγή των ρυθμίσεων. Αυτό δεν είναι απαραίτητο για να
+λειτουργήσει η εφαρμογή, αλλά κάνει την διαχείρισή της ευκολότερη.</p>
+
+<p>Οι έμπειροι χρήστες και οι χρήστες με ειδικές απαιτήσεις μπορούν να επισκεφθούν
+τις σελίδες που περιέχουν λεπτομερείς <a href="http://dokuwiki.org/install">
+οδηγίες εγκατάστασης</a> και <a href="http://dokuwiki.org/config">πληροφορίες
+για τις ρυθμίσεις</a>.</p> \ No newline at end of file
diff --git a/inc/lang/el/lang.php b/inc/lang/el/lang.php
new file mode 100644
index 000000000..34a7d36e8
--- /dev/null
+++ b/inc/lang/el/lang.php
@@ -0,0 +1,311 @@
+<?php
+/**
+ * Greek language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Επεξεργασία σελίδας';
+$lang['btn_source'] = 'Προβολή κώδικα σελίδας';
+$lang['btn_show'] = 'Προβολή σελίδας';
+$lang['btn_create'] = 'Δημιουργία σελίδας';
+$lang['btn_search'] = 'Αναζήτηση';
+$lang['btn_save'] = 'Αποθήκευση';
+$lang['btn_preview'] = 'Προεπισκόπηση';
+$lang['btn_top'] = 'Επιστροφή στην κορυφή της σελίδας';
+$lang['btn_newer'] = '<< πρόσφατες';
+$lang['btn_older'] = 'παλαιότερες >>';
+$lang['btn_revs'] = 'Παλαιότερες εκδόσεις σελίδας';
+$lang['btn_recent'] = 'Πρόσφατες αλλαγές';
+$lang['btn_upload'] = 'Φόρτωση';
+$lang['btn_cancel'] = 'Ακύρωση';
+$lang['btn_index'] = 'Κατάλογος';
+$lang['btn_secedit'] = 'Επεξεργασία';
+$lang['btn_login'] = 'Σύνδεση χρήστη';
+$lang['btn_logout'] = 'Αποσύνδεση χρήστη';
+$lang['btn_admin'] = 'Διαχείριση';
+$lang['btn_update'] = 'Ενημέρωση';
+$lang['btn_delete'] = 'Σβήσιμο';
+$lang['btn_back'] = 'Πίσω';
+$lang['btn_backlink'] = 'Σύνδεσμοι προς αυτή τη σελίδα';
+$lang['btn_backtomedia'] = 'Επιστροφή στην επιλογή αρχείων';
+$lang['btn_subscribe'] = 'Εγγραφή σε λήψη ενημερώσεων σελίδας';
+$lang['btn_profile'] = 'Επεξεργασία προφίλ';
+$lang['btn_reset'] = 'Ακύρωση';
+$lang['btn_resendpwd'] = 'Αποστολή νέου κωδικού';
+$lang['btn_draft'] = 'Επεξεργασία αυτόματα αποθηκευμένης σελίδας';
+$lang['btn_recover'] = 'Επαναφορά αυτόματα αποθηκευμένης σελίδας';
+$lang['btn_draftdel'] = 'Διαγραφή αυτόματα αποθηκευμένης σελίδας';
+$lang['btn_revert'] = 'Αποκατάσταση';
+$lang['btn_register'] = 'Εγγραφή';
+$lang['btn_apply'] = 'Εφαρμογή';
+$lang['btn_media'] = 'Διαχειριστής πολυμέσων';
+$lang['loggedinas'] = 'Συνδεδεμένος ως';
+$lang['user'] = 'Όνομα χρήστη';
+$lang['pass'] = 'Κωδικός';
+$lang['newpass'] = 'Νέος κωδικός';
+$lang['oldpass'] = 'Επιβεβαίωση τρέχοντος κωδικού';
+$lang['passchk'] = 'ακόμη μια φορά';
+$lang['remember'] = 'Απομνημόνευση στοιχείων λογαριασμού';
+$lang['fullname'] = 'Ονοματεπώνυμο';
+$lang['email'] = 'e-mail';
+$lang['profile'] = 'Προφίλ χρήστη';
+$lang['badlogin'] = 'Συγνώμη, το όνομα χρήστη ή ο κωδικός ήταν λανθασμένο.';
+$lang['minoredit'] = 'Ασήμαντες αλλαγές';
+$lang['draftdate'] = 'Αυτόματη αποθήκευση πρόχειρης σελίδας στις';
+$lang['nosecedit'] = 'Η σελίδα τροποποιήθηκε στο μεταξύ και τα στοιχεία της ενότητας δεν ήταν συγχρονισμένα, οπότε φορτώθηκε η πλήρης σελίδα. ';
+$lang['regmissing'] = 'Πρέπει να συμπληρώσετε όλα τα πεδία.';
+$lang['reguexists'] = 'Αυτός ο λογαριασμός υπάρχει ήδη.';
+$lang['regsuccess'] = 'Ο λογαριασμός δημιουργήθηκε και ο κωδικός εστάλει με e-mail.';
+$lang['regsuccess2'] = 'Ο λογαριασμός δημιουργήθηκε.';
+$lang['regmailfail'] = 'Φαίνεται να υπάρχει πρόβλημα με την αποστολή του κωδικού μέσω e-mail. Παρακαλούμε επικοινωνήστε μαζί μας!';
+$lang['regbadmail'] = 'Η διεύθυνση e-mail δεν είναι έγκυρη - εάν πιστεύετε ότι αυτό είναι λάθος, επικοινωνήστε μαζί μας';
+$lang['regbadpass'] = 'Οι δύο κωδικοί δεν είναι ίδιοι, προσπαθήστε ξανά.';
+$lang['regpwmail'] = 'Ο κωδικός σας';
+$lang['reghere'] = 'Δεν έχετε λογαριασμό ακόμη? Δημιουργήστε έναν';
+$lang['profna'] = 'Αυτό το wiki δεν υποστηρίζει την επεξεργασία προφίλ.';
+$lang['profnochange'] = 'Καμία αλλαγή.';
+$lang['profnoempty'] = 'Δεν επιτρέπεται κενό όνομα χρήστη η κενή διεύθυνση email.';
+$lang['profchanged'] = 'Το προφίλ χρήστη τροποποιήθηκε επιτυχώς.';
+$lang['pwdforget'] = 'Ξεχάσατε το κωδικό σας; Αποκτήστε νέο.';
+$lang['resendna'] = 'Αυτό το wiki δεν υποστηρίζει την εκ\' νέου αποστολή κωδικών.';
+$lang['resendpwd'] = 'Αποστολή νέων κωδικών για τον χρήστη';
+$lang['resendpwdmissing'] = 'Πρέπει να συμπληρώσετε όλα τα πεδία.';
+$lang['resendpwdnouser'] = 'Αυτός ο χρήστης δεν υπάρχει στα αρχεία μας.';
+$lang['resendpwdbadauth'] = 'Αυτός ο κωδικός ενεργοποίησης δεν είναι έγκυρος.';
+$lang['resendpwdconfirm'] = 'Ο σύνδεσμος προς την σελίδα ενεργοποίησης εστάλει με e-mail.';
+$lang['resendpwdsuccess'] = 'Ο νέος σας κωδικός εστάλη με e-mail.';
+$lang['license'] = 'Εκτός εάν αναφέρεται διαφορετικά, το περιεχόμενο σε αυτο το wiki διέπεται από την ακόλουθη άδεια:';
+$lang['licenseok'] = 'Σημείωση: Τροποποιώντας αυτή την σελίδα αποδέχεστε την διάθεση του υλικού σας σύμφωνα με την ακόλουθη άδεια:';
+$lang['searchmedia'] = 'Αναζήτηση αρχείου:';
+$lang['searchmedia_in'] = 'Αναζήτηση σε %s';
+$lang['txt_upload'] = 'Επιλέξτε αρχείο για φόρτωση';
+$lang['txt_filename'] = 'Επιλέξτε νέο όνομα αρχείου (προαιρετικό)';
+$lang['txt_overwrt'] = 'Αντικατάσταση υπάρχοντος αρχείου';
+$lang['lockedby'] = 'Προσωρινά κλειδωμένο από';
+$lang['lockexpire'] = 'Το κλείδωμα λήγει στις';
+$lang['js']['willexpire'] = 'Το κλείδωμά σας για την επεξεργασία αυτής της σελίδας θα λήξει σε ένα λεπτό.\n Για να το ανανεώσετε χρησιμοποιήστε την Προεπισκόπηση.';
+$lang['js']['notsavedyet'] = 'Οι μη αποθηκευμένες αλλαγές θα χαθούν.
+Θέλετε να συνεχίσετε;';
+$lang['js']['searchmedia'] = 'Αναζήτηση για αρχεία';
+$lang['js']['keepopen'] = 'Το παράθυρο να μην κλείνει';
+$lang['js']['hidedetails'] = 'Απόκρυψη λεπτομερειών';
+$lang['js']['mediatitle'] = 'Ρυθμίσεις συνδέσμων';
+$lang['js']['mediadisplay'] = 'Τύπος συνδέσμου';
+$lang['js']['mediaalign'] = 'Στοίχηση';
+$lang['js']['mediasize'] = 'Μέγεθος εικόνας';
+$lang['js']['mediatarget'] = 'Προορισμός συνδέσμου';
+$lang['js']['mediaclose'] = 'Κλείσιμο';
+$lang['js']['mediainsert'] = 'Εισαγωγή';
+$lang['js']['mediadisplayimg'] = 'Προβολή εικόνας.';
+$lang['js']['mediadisplaylnk'] = 'Προβολή μόνο του συνδέσμου.';
+$lang['js']['mediasmall'] = 'Μικρό μέγεθος';
+$lang['js']['mediamedium'] = 'Μεσαίο μέγεθος';
+$lang['js']['medialarge'] = 'Μεγάλο μέγεθος';
+$lang['js']['mediaoriginal'] = 'Αρχικό μέγεθος';
+$lang['js']['medialnk'] = 'Σύνδεσμος στην σελίδα λεπτομερειών';
+$lang['js']['mediadirect'] = 'Απευθείας σύνδεσμος στο αυθεντικό';
+$lang['js']['medianolnk'] = 'Χωρίς σύνδεσμο';
+$lang['js']['medianolink'] = 'Να μην γίνει σύνδεσμος η εικόνα';
+$lang['js']['medialeft'] = 'Αριστερή στοίχιση εικόνας.';
+$lang['js']['mediaright'] = 'Δεξιά στοίχιση εικόνας.';
+$lang['js']['mediacenter'] = 'Κέντρική στοίχιση εικόνας.';
+$lang['js']['medianoalign'] = 'Χωρίς στοίχηση.';
+$lang['js']['nosmblinks'] = 'Οι σύνδεσμοι προς Windows shares δουλεύουν μόνο στον Microsoft Internet Explorer.
+Μπορείτε πάντα να κάνετε αντιγραφή και επικόλληση του συνδέσμου.';
+$lang['js']['linkwiz'] = 'Αυτόματος Οδηγός Συνδέσμων';
+$lang['js']['linkto'] = 'Σύνδεση σε:';
+$lang['js']['del_confirm'] = 'Να διαγραφεί;';
+$lang['js']['restore_confirm'] = 'Θέλετε την επαναφορά σε αυτή την έκδοση;';
+$lang['js']['media_diff'] = 'Εμφάνιση διαφορών:';
+$lang['js']['media_diff_both'] = 'Δίπλα δίπλα';
+$lang['js']['media_diff_opacity'] = 'Επικάλυψη';
+$lang['js']['media_diff_portions'] = 'Κύλιση';
+$lang['js']['media_select'] = 'Επιλογή αρχείων...';
+$lang['js']['media_upload_btn'] = 'Φόρτωση';
+$lang['js']['media_done_btn'] = 'Ολοκλήρωση';
+$lang['js']['media_drop'] = 'Ρίξτε αρχεία εδώ για να τα φορτώσετε';
+$lang['js']['media_cancel'] = 'αφαίρεση';
+$lang['js']['media_overwrt'] = 'Αντικατάσταση υπάρχοντων αρχείων';
+$lang['rssfailed'] = 'Παρουσιάστηκε κάποιο σφάλμα κατά την ανάγνωση αυτού του feed: ';
+$lang['nothingfound'] = 'Δεν βρέθηκαν σχετικά αποτελέσματα.';
+$lang['mediaselect'] = 'Επιλογή Αρχείων';
+$lang['fileupload'] = 'Φόρτωση αρχείου';
+$lang['uploadsucc'] = 'Επιτυχής φόρτωση';
+$lang['uploadfail'] = 'Η μεταφόρτωση απέτυχε. Πιθανόν αυτό να οφείλεται στις ρυθμίσεις πρόσβασης του αρχείου.';
+$lang['uploadwrong'] = 'Η μεταφόρτωση δεν έγινε δεκτή. Δεν επιτρέπονται αρχεία αυτού του τύπου!';
+$lang['uploadexist'] = 'Το αρχείο ήδη υπάρχει. Δεν έγινε καμία αλλαγή.';
+$lang['uploadbadcontent'] = 'Το περιεχόμενο του αρχείου δεν ταιριάζει με την επέκτασή του.';
+$lang['uploadspam'] = 'Η μεταφόρτωση ακυρώθηκε από το φίλτρο spam.';
+$lang['uploadxss'] = 'Η μεταφόρτωση ακυρώθηκε λόγω πιθανού επικίνδυνου περιεχομένου.';
+$lang['uploadsize'] = 'Το αρχείο ήταν πολύ μεγάλο. (μέγιστο %s)';
+$lang['deletesucc'] = 'Το αρχείο "%s" διαγράφηκε.';
+$lang['deletefail'] = 'Το αρχείο "%s" δεν διαγράφηκε. Πιθανόν αυτό να οφείλεται στις ρυθμίσεις πρόσβασης του αρχείου.';
+$lang['mediainuse'] = 'Το αρχείο "%s" δεν διαγράφηκε - είναι ακόμα σε χρήση.';
+$lang['namespaces'] = 'Φάκελοι';
+$lang['mediafiles'] = 'Διαθέσιμα αρχεία σε';
+$lang['accessdenied'] = 'Δεν σας επιτρέπεται να δείτε αυτήν την σελίδα.';
+$lang['mediausage'] = 'Χρησιμοποιήστε την ακόλουθη σύνταξη για να παραθέσετε αυτό το αρχείο:';
+$lang['mediaview'] = 'Κανονική προβολή αρχείου';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Φορτώστε ένα αρχείο στον τρέχοντα φάκελο. Για δημιουργία υπο-φακέλων, προσθέστε τους πριν από το όνομα του αρχείου, στο πεδίο "Αποθήκευση ως", χρησιμοποιώντας άνω-κάτω τελείες ως διαχωριστικά.';
+$lang['mediaextchange'] = 'Η επέκταση του αρχείου τροποποιήθηκε από .%s σε .%s!';
+$lang['reference'] = 'Αναφορές προς';
+$lang['ref_inuse'] = 'Το αρχείο δεν μπορεί να διαγραφεί, επειδή είναι ακόμη σε χρήση από τις ακόλουθες σελίδες:';
+$lang['ref_hidden'] = 'Μερικές αναφορές βρίσκονται σε σελίδες που δεν έχετε δικαίωμα να διαβάσετε';
+$lang['hits'] = 'Αναφορές';
+$lang['quickhits'] = 'Σχετικές σελίδες';
+$lang['toc'] = 'Πίνακας Περιεχομένων';
+$lang['current'] = 'τρέχουσα';
+$lang['yours'] = 'Η έκδοσή σας';
+$lang['diff'] = 'Προβολή διαφορών με την τρέχουσα έκδοση';
+$lang['diff2'] = 'Προβολή διαφορών μεταξύ των επιλεγμένων εκδόσεων';
+$lang['difflink'] = 'Σύνδεσμος σε αυτή την προβολή διαφορών.';
+$lang['diff_type'] = 'Προβολή διαφορών:';
+$lang['diff_inline'] = 'Σε σειρά';
+$lang['diff_side'] = 'Δίπλα-δίπλα';
+$lang['line'] = 'Γραμμή';
+$lang['breadcrumb'] = 'Ιστορικό';
+$lang['youarehere'] = 'Είστε εδώ';
+$lang['lastmod'] = 'Τελευταία τροποποίηση';
+$lang['by'] = 'από';
+$lang['deleted'] = 'διαγράφηκε';
+$lang['created'] = 'δημιουργήθηκε';
+$lang['restored'] = 'παλαιότερη έκδοση επαναφέρθηκε';
+$lang['external_edit'] = 'εξωτερική τροποποίηση';
+$lang['summary'] = 'Επεξεργασία σύνοψης';
+$lang['noflash'] = 'Το <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> απαιτείται για την προβολή αυτού του στοιχείου.';
+$lang['download'] = 'Λήψη Κώδικα';
+$lang['mail_newpage'] = 'σελίδα προστέθηκε:';
+$lang['mail_changed'] = 'σελίδα τροποποιήθηκε:';
+$lang['mail_subscribe_list'] = 'σελίδες που άλλαξαν στον φάκελο:';
+$lang['mail_new_user'] = 'νέος χρήστης:';
+$lang['mail_upload'] = 'αρχείο φορτώθηκε:';
+$lang['changes_type'] = 'Εμφάνιση αλλαγών του';
+$lang['pages_changes'] = 'Σελίδες';
+$lang['media_changes'] = 'Αρχεία πολυμέσων';
+$lang['both_changes'] = 'Σελίδες και αρχεία πολυμέσων';
+$lang['qb_bold'] = 'Έντονο Κείμενο';
+$lang['qb_italic'] = 'Πλάγιο Κείμενο';
+$lang['qb_underl'] = 'Υπογραμμισμένο Κείμενο';
+$lang['qb_code'] = 'Κείμενο κώδικα';
+$lang['qb_strike'] = 'Διαγραμμισμένο Κείμενο';
+$lang['qb_h1'] = 'Κεφαλίδα 1ου Επιπέδου';
+$lang['qb_h2'] = 'Κεφαλίδα 2ου Επιπέδου';
+$lang['qb_h3'] = 'Κεφαλίδα 3ου Επιπέδου';
+$lang['qb_h4'] = 'Κεφαλίδα 4ου Επιπέδου';
+$lang['qb_h5'] = 'Κεφαλίδα 5ου Επιπέδου';
+$lang['qb_h'] = 'Κεφαλίδα';
+$lang['qb_hs'] = 'Επιλογή Κεφαλίδας';
+$lang['qb_hplus'] = 'Μεγαλύτερη Κεφαλίδα';
+$lang['qb_hminus'] = 'Μικρότερη Κεφαλίδα';
+$lang['qb_hequal'] = 'Κεφαλίδα ίδιο μεγέθους';
+$lang['qb_link'] = 'Εσωτερικός Σύνδεσμος';
+$lang['qb_extlink'] = 'Εξωτερικός Σύνδεσμος';
+$lang['qb_hr'] = 'Διαχωριστική Γραμμή';
+$lang['qb_ol'] = 'Αριθμημένη Λίστα';
+$lang['qb_ul'] = 'Λίστα';
+$lang['qb_media'] = 'Προσθήκη Αρχείων';
+$lang['qb_sig'] = 'Προσθήκη Υπογραφής';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Ειδικοί Χαρακτήρες';
+$lang['upperns'] = 'πήγαινε στον μητρικό φάκελο';
+$lang['admin_register'] = 'Προσθήκη νέου χρήστη';
+$lang['metaedit'] = 'Τροποποίηση metadata';
+$lang['metasaveerr'] = 'Η αποθήκευση των metadata απέτυχε';
+$lang['metasaveok'] = 'Επιτυχής αποθήκευση metadata';
+$lang['img_backto'] = 'Επιστροφή σε';
+$lang['img_title'] = 'Τίτλος';
+$lang['img_caption'] = 'Λεζάντα';
+$lang['img_date'] = 'Ημερομηνία';
+$lang['img_fname'] = 'Όνομα αρχείου';
+$lang['img_fsize'] = 'Μέγεθος';
+$lang['img_artist'] = 'Καλλιτέχνης';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Camera';
+$lang['img_keywords'] = 'Λέξεις-κλειδιά';
+$lang['img_width'] = 'Πλάτος';
+$lang['img_height'] = 'Ύψος';
+$lang['img_manager'] = 'Εμφάνιση στον διαχειριστή πολυμέσων';
+$lang['subscr_subscribe_success'] = 'Ο/η %s προστέθηκε στην λίστα ειδοποιήσεων για το %s';
+$lang['subscr_subscribe_error'] = 'Σφάλμα κατά την προσθήκη του/της %s στην λίστα ειδοποιήσεων για το %s';
+$lang['subscr_subscribe_noaddress'] = 'Δεν υπάρχει διεύθυνση ταχυδρομείου συσχετισμένη με το όνομα χρήστη σας. Κατά συνέπεια δεν μπορείτε να προστεθείτε στην λίστα ειδοποιήσεων';
+$lang['subscr_unsubscribe_success'] = 'Ο/η %s, απομακρύνθηκε από την λίστα ειδοποιήσεων για το %s';
+$lang['subscr_unsubscribe_error'] = 'Σφάλμα κατά την απομάκρυνση του/της %s στην λίστα ειδοποιήσεων για το %s';
+$lang['subscr_already_subscribed'] = 'Ο/η %s είναι ήδη στην λίστα ειδοποίησης για το %s';
+$lang['subscr_not_subscribed'] = 'Ο/η %s δεν είναι στην λίστα ειδοποίησης για το %s';
+$lang['subscr_m_not_subscribed'] = 'Αυτήν την στιγμή, δεν είσαστε εγεγγραμμένος/η στην λίστα ειδοποίησης της τρέχουσας σελίδας ή φακέλου.';
+$lang['subscr_m_new_header'] = 'Προσθήκη στην λίστα ειδοποίησης';
+$lang['subscr_m_current_header'] = 'Τρέχουσες εγγραφές ειδοποιήσεων';
+$lang['subscr_m_unsubscribe'] = 'Διαγραφή';
+$lang['subscr_m_subscribe'] = 'Εγγραφή';
+$lang['subscr_m_receive'] = 'Λήψη';
+$lang['subscr_style_every'] = 'email σε κάθε αλλαγή';
+$lang['subscr_style_digest'] = 'συνοπτικό email αλλαγών της σελίδας (κάθε %.2f μέρες)';
+$lang['subscr_style_list'] = 'λίστα σελίδων με αλλαγές μετά από το τελευταίο email (κάθε %.2f μέρες)';
+$lang['authmodfailed'] = 'Κακή ρύθμιση λίστας χρηστών. Παρακαλούμε ενημερώστε τον διαχειριστή του wiki.';
+$lang['authtempfail'] = 'Η συνδεση χρηστών είναι απενεργοποιημένη αυτή την στιγμή. Αν αυτό διαρκέσει για πολύ, παρακαλούμε ενημερώστε τον διαχειριστή του wiki.';
+$lang['i_chooselang'] = 'Επιλογή γλώσσας';
+$lang['i_installer'] = 'Οδηγός εγκατάστασης DokuWiki';
+$lang['i_wikiname'] = 'Ονομασία wiki';
+$lang['i_enableacl'] = 'Ενεργοποίηση Λίστας Δικαιωμάτων Πρόσβασης - ACL (συνίσταται)';
+$lang['i_superuser'] = 'Διαχειριστής';
+$lang['i_problems'] = 'Ο οδηγός εγκατάστασης συνάντησε τα προβλήματα που αναφέρονται παρακάτω. Η εγκατάσταση δεν θα ολοκληρωθεί επιτυχώς μέχρι να επιλυθούν αυτά τα προβλήματα.';
+$lang['i_modified'] = 'Για λόγους ασφαλείας, ο οδηγός εγκατάστασης λειτουργεί μόνο με νέες και μη τροποποιημένες εγκαταστάσεις Dokuwiki.
+Πρέπει είτε να κάνετε νέα εγκατάσταση, χρησιμοποιώντας το αρχικό πακέτο εγκατάστασης, ή να συμβουλευτείτε τις <a href="http://dokuwiki.org/el:install">οδηγίες εγκατάστασης της εφαρμογής</a>.';
+$lang['i_funcna'] = 'Η λειτουργία <code>%s</code> της PHP δεν είναι διαθέσιμη. Πιθανόν να είναι απενεργοποιημένη στις ρυθμίσεις έναρξης της PHP';
+$lang['i_phpver'] = 'Η έκδοση <code>%s</code> της PHP που έχετε είναι παλαιότερη της απαιτούμενης <code>%s</code>. Πρέπει να αναβαθμίσετε την PHP.';
+$lang['i_permfail'] = 'Ο φάκελος <code>%s</code> δεν είναι εγγράψιμος από την εφαρμογή DokuWiki. Πρέπει να διορθώσετε τα δικαιώματα πρόσβασης αυτού του φακέλου!';
+$lang['i_confexists'] = '<code>%s</code> υπάρχει ήδη';
+$lang['i_writeerr'] = 'Δεν είναι δυνατή η δημιουργία του <code>%s</code>. Πρέπει να διορθώσετε τα δικαιώματα πρόσβασης αυτού του φακέλου/αρχείου και να δημιουργήσετε το αρχείο χειροκίνητα!';
+$lang['i_badhash'] = 'Μη αναγνωρίσιμο ή τροποποιημένο αρχείο dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - λάθος ή ανύπαρκτη τιμή';
+$lang['i_success'] = 'Η εγκατάσταση ολοκληρώθηκε επιτυχώς. Μπορείτε πλέον να διαγράψετε το αρχείο install.php. Συνεχίστε στο <a href="doku.php">νέο σας DokuWiki</a>.';
+$lang['i_failure'] = 'Εμφανίστηκαν κάποια προβλήματα στη διαδικασία ανανέωσης των αρχείων ρυθμίσεων. Πιθανόν να χρειάζεται να τα τροποποιήσετε χειροκίνητα ώστε να μπορείτε να χρησιμοποιήσετε το <a href="doku.php">νέο σας DokuWiki</a>.';
+$lang['i_policy'] = 'Αρχική πολιτική Λίστας Δικαιωμάτων Πρόσβασης - ACL';
+$lang['i_pol0'] = 'Ανοιχτό Wiki (όλοι μπορούν να διαβάσουν ή να δημιουργήσουν/τροποποιήσουν σελίδες και να μεταφορτώσουν αρχεία)';
+$lang['i_pol1'] = 'Δημόσιο Wiki (όλοι μπορούν να διαβάσουν σελίδες αλλά μόνο οι εγγεγραμμένοι χρήστες μπορούν να δημιουργήσουν/τροποποιήσουν σελίδες και να μεταφορτώσουν αρχεία)';
+$lang['i_pol2'] = 'Κλειστό Wiki (μόνο οι εγγεγραμμένοι χρήστες μπορούν να διαβάσουν ή να δημιουργήσουν/τροποποιήσουν σελίδες και να μεταφορτώσουν αρχεία)';
+$lang['i_retry'] = 'Νέα προσπάθεια';
+$lang['i_license'] = 'Παρακαλώ επιλέξτε την άδεια που θα χρησιμοποιήσετε για την διάθεση του περιεχομένου σας:';
+$lang['recent_global'] = 'Βλέπετε τις αλλαγές εντός του φακέλου <b>%s</b>. Μπορείτε επίσης να <a href="%s">δείτε τις πρόσφατες αλλαγές σε όλο το wiki</a>.';
+$lang['years'] = 'πριν %d χρόνια';
+$lang['months'] = 'πριν %d μήνες';
+$lang['weeks'] = 'πριν %d εβδομάδες';
+$lang['days'] = 'πριν %d ημέρες';
+$lang['hours'] = 'πριν %d ώρες';
+$lang['minutes'] = 'πριν %d λεπτά';
+$lang['seconds'] = 'πριν %d δευτερόλεπτα';
+$lang['wordblock'] = 'Η αλλαγή σας δεν αποθηκεύτηκε γιατί περιείχε spam.';
+$lang['media_uploadtab'] = 'Φόρτωση';
+$lang['media_searchtab'] = 'Αναζήτηση';
+$lang['media_viewtab'] = 'Εμφάνιση';
+$lang['media_edittab'] = 'Επεξεργασία';
+$lang['media_historytab'] = 'Ιστορικό';
+$lang['media_thumbsview'] = 'Προεπισκόπιση';
+$lang['media_listview'] = 'Λίστα';
+$lang['media_sort'] = 'Ταξινόμιση';
+$lang['media_sort_name'] = 'ανά όνομα';
+$lang['media_sort_date'] = 'ανά ημερομηνία';
+$lang['media_upload'] = 'Φόρτωση στο <strong>%s</strong> φάκελο.';
+$lang['media_search'] = 'Αναζήτηση στο <strong>%s</strong> φάκελο.';
+$lang['media_edit'] = 'Επεξεργασία';
+$lang['media_history'] = 'Αυτές είναι οι παλαιότερες αναθεωρήσεις του αρχείου.';
+$lang['media_meta_edited'] = 'τα μεταδεδομένα επεξεργάστηκαν';
+$lang['media_perm_read'] = 'Συγνώμη, δεν έχετε επαρκή διακαιώματα για να διαβάσετε αυτά τα αρχεία.';
+$lang['media_perm_upload'] = 'Συγνώμη, δεν έχετε επαρκή διακαιώματα για να φορτώσετε αυτά τα αρχεία.';
+$lang['media_update'] = 'Φόρτωση νέας έκδοσης';
+$lang['media_restore'] = 'Επαναφορά αυτή της έκδοσης';
+$lang['plugin_install_err'] = 'Η επέκταση δεν εγκαταστήθηκε σωστά. Μετονομασία φακέλου επεκτάσεων από \'%s\' σε \'%s\'.';
diff --git a/inc/lang/el/locked.txt b/inc/lang/el/locked.txt
new file mode 100644
index 000000000..425c334f1
--- /dev/null
+++ b/inc/lang/el/locked.txt
@@ -0,0 +1,5 @@
+====== Κλειδωμένη σελίδα ======
+
+Αυτή η σελίδα είναι προς το παρόν δεσμευμένη για τροποποίηση από άλλον χρήστη.
+Θα πρέπει να περιμένετε μέχρι ο συγκεκριμένος χρήστης να σταματήσει να την επεξεργάζεται ή να εκπνεύσει το χρονικό όριο για το σχετικό κλείδωμα.
+
diff --git a/inc/lang/el/login.txt b/inc/lang/el/login.txt
new file mode 100644
index 000000000..3021a19ea
--- /dev/null
+++ b/inc/lang/el/login.txt
@@ -0,0 +1,5 @@
+====== Σύνδεση χρήστη ======
+
+Αυτή την στιγμή δεν έχετε συνδεθεί ως χρήστης!
+Για να συνδεθείτε, εισάγετε τα στοιχεία σας στην παρακάτω φόρμα.
+Πρέπει να έχετε ενεργοποιήσει τα cookies στο πρόγραμμα περιήγηση σας.
diff --git a/inc/lang/el/mailtext.txt b/inc/lang/el/mailtext.txt
new file mode 100644
index 000000000..a5059ca4d
--- /dev/null
+++ b/inc/lang/el/mailtext.txt
@@ -0,0 +1,17 @@
+Μία σελίδα προστέθηκε ή τροποποιήθηκε στο DokuWiki σας.
+Αυτά είναι τα αντίστοιχα στοιχεία:
+
+Ημερομηνία : @DATE@
+Φυλλομετρητής : @BROWSER@
+IP-Διεύθυνση : @IPADDRESS@
+Όνομα υπολογιστή: @HOSTNAME@
+Παλιά έκδοση : @OLDPAGE@
+Νέα έκδοση : @NEWPAGE@
+Σύνοψη : @SUMMARY@
+Χρήστης : @USER@
+
+@DIFF@
+
+--
+Αυτό το e-mail δημιουργήθηκε αυτόματα από την εφαρμογή DokuWiki στην διεύθυνση
+@DOKUWIKIURL@
diff --git a/inc/lang/el/newpage.txt b/inc/lang/el/newpage.txt
new file mode 100644
index 000000000..3349ad90e
--- /dev/null
+++ b/inc/lang/el/newpage.txt
@@ -0,0 +1,4 @@
+====== Αυτή η σελίδα δεν υπάρχει ακόμη ======
+
+Η σελίδα που ζητάτε δεν υπάρχει ακόμη.
+Aν όμως έχετε επαρκή δικαιώματα, μπορείτε να την δημιουργήσετε επιλέγοντας ''Δημιουργία σελίδας''.
diff --git a/inc/lang/el/norev.txt b/inc/lang/el/norev.txt
new file mode 100644
index 000000000..2b13290ff
--- /dev/null
+++ b/inc/lang/el/norev.txt
@@ -0,0 +1,5 @@
+====== Αυτή η έκδοση δεν υπάρχει ======
+
+Η έκδοση που αναζητήσατε δεν υπάρχει.
+Μπορείτε να δείτε λίστα με τις παλαιότερες εκδόσεις της τρέχουσας σελίδας πατώντας ''Παλαιότερες εκδόσεις σελίδας''.
+
diff --git a/inc/lang/el/password.txt b/inc/lang/el/password.txt
new file mode 100644
index 000000000..d27fbb3c3
--- /dev/null
+++ b/inc/lang/el/password.txt
@@ -0,0 +1,10 @@
+@FULLNAME@!, γειά σας.
+
+Αυτά είναι τα στοιχεία εισόδου για το @TITLE@ στο @DOKUWIKIURL@
+
+Όνομα : @LOGIN@
+Συνθηματικό : @PASSWORD@
+
+--
+Αυτό το e-mail δημιουργήθηκε αυτόματα από την εφαρμογή DokuWiki στην διεύθυνση
+@DOKUWIKIURL@
diff --git a/inc/lang/el/preview.txt b/inc/lang/el/preview.txt
new file mode 100644
index 000000000..aef65c974
--- /dev/null
+++ b/inc/lang/el/preview.txt
@@ -0,0 +1,5 @@
+====== Προεπισκόπηση ======
+
+Αυτή είναι μια προεπισκόπηση του πως θα δείχνει η σελίδα.
+Υπενθύμιση: Οι αλλαγές σας **δεν έχουν αποθηκευθεί** ακόμη!
+
diff --git a/inc/lang/el/pwconfirm.txt b/inc/lang/el/pwconfirm.txt
new file mode 100644
index 000000000..a9e58be7d
--- /dev/null
+++ b/inc/lang/el/pwconfirm.txt
@@ -0,0 +1,14 @@
+Γεια σας @FULLNAME@!
+
+Κάποιος ζήτησε τη δημιουργία νέου συνθηματικού για τον λογαριασμό @TITLE@
+που διατηρείτε στο @DOKUWIKIURL@
+
+Αν δεν ζητήσατε εσείς την δημιουργία νέου συνθηματικού απλά αγνοήστε αυτό το e-mail.
+
+Αν όντως εσείς ζητήσατε την δημιουργία νέου συνθηματικού, ακολουθήστε τον παρακάτω σύνδεσμο για να το επιβεβαιώσετε.
+
+@CONFIRM@
+
+--
+Αυτό το e-mail δημιουργήθηκε αυτόματα από την εφαρμογή DokuWiki στην διεύθυνση
+@DOKUWIKIURL@
diff --git a/inc/lang/el/read.txt b/inc/lang/el/read.txt
new file mode 100644
index 000000000..a620ab559
--- /dev/null
+++ b/inc/lang/el/read.txt
@@ -0,0 +1,2 @@
+Μπορείτε να διαβάσετε αυτή την σελίδα αλλά δεν μπορείτε να την τροποποιήσετε.
+Αν πιστεύετε ότι αυτό δεν είναι σωστό, απευθυνθείτε στον διαχειριστή της εφαρμογής.
diff --git a/inc/lang/el/recent.txt b/inc/lang/el/recent.txt
new file mode 100644
index 000000000..78c74a655
--- /dev/null
+++ b/inc/lang/el/recent.txt
@@ -0,0 +1,3 @@
+====== Πρόσφατες αλλαγές ======
+
+Οι παρακάτω σελίδες τροποποιήθηκαν πρόσφατα:
diff --git a/inc/lang/el/register.txt b/inc/lang/el/register.txt
new file mode 100644
index 000000000..6a4e963e4
--- /dev/null
+++ b/inc/lang/el/register.txt
@@ -0,0 +1,5 @@
+====== Εγγραφή νέου χρήστη ======
+
+Συμπληρώστε όλα τα παρακάτω πεδία για να δημιουργήσετε ένα νέο λογαριασμό σε αυτό το wiki.
+Πρέπει να δώσετε μια **υπαρκτή e-mail διεύθυνση** - ο κωδικός σας θα σας αποσταλεί σε αυτήν.
+Το όνομα χρήστη θα πρέπει να πληρεί τις ίδιες απαιτήσεις ονόματος που ισχύουν και για τους [[doku>el:pagename|φακέλους]].
diff --git a/inc/lang/el/registermail.txt b/inc/lang/el/registermail.txt
new file mode 100644
index 000000000..0b3e0b78b
--- /dev/null
+++ b/inc/lang/el/registermail.txt
@@ -0,0 +1,14 @@
+Ένας νέος χρήστης εγγράφηκε. Ορίστε οι λεπτομέρειες:
+
+Χρήστης : @NEWUSER@
+Όνομα : @NEWNAME@
+e-mail : @NEWEMAIL@
+
+Ημερομηνία : @DATE@
+Φυλλομετρητής : @BROWSER@
+IP-Διεύθυνση : @IPADDRESS@
+Όνομα υπολογιστή: @HOSTNAME@
+
+--
+Αυτό το e-mail δημιουργήθηκε αυτόματα από την εφαρμογή DokuWiki στην διεύθυνση
+@DOKUWIKIURL@
diff --git a/inc/lang/el/resendpwd.txt b/inc/lang/el/resendpwd.txt
new file mode 100644
index 000000000..6b4f3bbca
--- /dev/null
+++ b/inc/lang/el/resendpwd.txt
@@ -0,0 +1,6 @@
+====== Αποστολή νέου κωδικού ======
+
+Συμπληρώστε όλα τα παρακάτω πεδία για να λάβετε ένα νέο κωδικό για τον λογαριασμό σας σε αυτό το wiki.
+Ο νέος κωδικός σας θα σταλεί στην e-mail διεύθυνση που έχετε ήδη δηλώσει.
+Το όνομα πρέπει να είναι αυτό που ισχύει για τον λογαριασμό σας σε αυτό το wiki.
+
diff --git a/inc/lang/el/revisions.txt b/inc/lang/el/revisions.txt
new file mode 100644
index 000000000..955fa1703
--- /dev/null
+++ b/inc/lang/el/revisions.txt
@@ -0,0 +1,8 @@
+====== Παλαιότερες εκδόσεις σελίδας ======
+
+Οι παρακάτω είναι παλαιότερες εκδόσεις της τρέχουσας σελίδας.
+Εάν θέλετε να αντικαταστήσετε την τρέχουσα σελίδα με κάποια από τις παλαιότερες εκδόσεις της κάντε τα παρακάτω:
+ * επιλέξτε την σχετική έκδοση
+ * επιλέξτε ''Τροποποίηση σελίδας''
+ * κάνετε τυχόν αλλαγές
+ * αποθηκεύστε την
diff --git a/inc/lang/el/searchpage.txt b/inc/lang/el/searchpage.txt
new file mode 100644
index 000000000..b52162b60
--- /dev/null
+++ b/inc/lang/el/searchpage.txt
@@ -0,0 +1,4 @@
+====== Αναζήτηση ======
+
+Τα αποτελέσματα της αναζήτησής σας:
+
diff --git a/inc/lang/el/showrev.txt b/inc/lang/el/showrev.txt
new file mode 100644
index 000000000..a6ba3f99e
--- /dev/null
+++ b/inc/lang/el/showrev.txt
@@ -0,0 +1,2 @@
+**Βλέπετε μια παλαιότερη έκδοση της σελίδας!**
+----
diff --git a/inc/lang/el/stopwords.txt b/inc/lang/el/stopwords.txt
new file mode 100644
index 000000000..01d5103b3
--- /dev/null
+++ b/inc/lang/el/stopwords.txt
@@ -0,0 +1,103 @@
+# 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 provided by Fotis Lazarinis based on his research found at: http://lazarinf.teimes.gr/papers/J8.pdf
+και
+ήταν
+το
+ενός
+να
+πολύ
+του
+όμως
+κατά
+της
+αυτή
+με
+όταν
+που
+μέσα
+την
+οποίο
+από
+πως
+για
+έτσι
+τα
+στους
+είναι
+μέσω
+των
+όλα
+σε
+καθώς
+ο
+αυτά
+οι
+προς
+στο
+ένας
+θα
+πριν
+τη
+μου
+στην
+όχι
+τον
+χωρίς
+τους
+επίσης
+δεν
+μεταξύ
+τις
+μέχρι
+ένα
+έναν
+μια
+μιας
+ότι
+αφού
+ακόμα
+στη
+όπου
+στα
+είχε
+μας
+δηλαδή
+αλλά
+τρόπος
+στον
+όσο
+στις
+ακόμη
+αυτό
+τόσο
+όπως
+έχουμε
+αν
+ώστε
+μπορεί
+αυτές
+μετά
+γιατί
+σας
+πάνω
+δύο
+τότε
+τι
+τώρα
+ως
+κάτι
+κάθε
+άλλο
+πρέπει
+μην
+πιο
+εδώ
+οποία
+είτε
+μόνο
+μη
+ενώ \ No newline at end of file
diff --git a/inc/lang/el/subscr_digest.txt b/inc/lang/el/subscr_digest.txt
new file mode 100644
index 000000000..7dd0345d7
--- /dev/null
+++ b/inc/lang/el/subscr_digest.txt
@@ -0,0 +1,20 @@
+Χαίρετε!
+
+Η σελίδα @PAGE@ στο @TITLE@ άλλαξε.
+Ορίστε οι αλλαγές:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Παλιά έκδοση: @OLDPAGE@
+Νέα έκδοση: @NEWPAGE@
+
+Για να σταματήσουν αυτές οι ειδοποιήσεις συνδεθείτε
+στο wiki στην διεύθυνση @DOKUWIKIURL@
+και στην συνέχεια επισκεφθείτε το @SUBSCRIBE@
+και διαγραφείτε από τις ειδοποιήσεις της σελίδας ή του φακέλου.
+
+--
+Αυτό το μήνυμα παράχθηκε απο το DokuWiki στην
+διεύθυνση @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/el/subscr_form.txt b/inc/lang/el/subscr_form.txt
new file mode 100644
index 000000000..c21a29a9a
--- /dev/null
+++ b/inc/lang/el/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Διαχείριση Εγγραφών σε Ειδοποιήσεις ======
+
+Εδώ μπορείτε να διαχειριστείτε τις εγγραφές σας στις ειδοποιήσεις για αλλαγές στην τρέχουσα σελίδα και φάκελο. \ No newline at end of file
diff --git a/inc/lang/el/subscr_list.txt b/inc/lang/el/subscr_list.txt
new file mode 100644
index 000000000..97b8dc47d
--- /dev/null
+++ b/inc/lang/el/subscr_list.txt
@@ -0,0 +1,20 @@
+Χαίρετε!
+
+Η σελίδα @PAGE@ στο @TITLE@ άλλαξε.
+
+Κάποιες σελίδες στον φάκελο @PAGE@ του wiki
+@TITLE@ έχουν αλλάξει.
+Ορίστε οι αλλαγμένες σελίδες:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Για να σταματήσουν αυτές οι ειδοποιήσεις συνδεθείτε στο wiki
+στην διεύθυνση @DOKUWIKIURL@
+και στην συνέχεια επισκεφθείτε το @SUBSCRIBE@
+και διαγραφείτε από τις ειδοποιήσεις της σελίδας ή του φακέλου.
+
+--
+Αυτό το μήνυμα παράχθηκε απο το DokuWiki στην
+διεύθυνση @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/el/subscr_single.txt b/inc/lang/el/subscr_single.txt
new file mode 100644
index 000000000..610af49a2
--- /dev/null
+++ b/inc/lang/el/subscr_single.txt
@@ -0,0 +1,22 @@
+Χαίρετε!
+
+Η σελίδα @PAGE@ στο @TITLE@ άλλαξε.
+Ορίστε οι αλλαγές:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+Ημερομηνία : @DATE@
+Χρήστης : @USER@
+Περίληψη αλλαγών: @SUMMARY@
+Παλιά έκδοση: @OLDPAGE@
+Νέα έκδοση: @NEWPAGE@
+
+Για να σταματήσουν αυτές οι ειδοποιήσεις συνδεθείτε στο wiki
+στην διεύθυνση @DOKUWIKIURL@
+και στην συνέχεια επισκεφθείτε το @SUBSCRIBE@
+και διαγραφείτε από τις ειδοποιήσεις της σελίδας ή του φακέλου.
+
+--
+Αυτό το μήνυμα παράχθηκε απο το DokuWiki στην
+διεύθυνση @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/el/updateprofile.txt b/inc/lang/el/updateprofile.txt
new file mode 100644
index 000000000..56f176d37
--- /dev/null
+++ b/inc/lang/el/updateprofile.txt
@@ -0,0 +1,4 @@
+====== Τροποποίηση προφίλ ======
+
+Τροποποιήστε **μόνο** τα πεδία που θέλετε να αλλάξετε.
+Δεν μπορείτε να αλλάξετε το πεδίο ''Όνομα''.
diff --git a/inc/lang/el/uploadmail.txt b/inc/lang/el/uploadmail.txt
new file mode 100644
index 000000000..52d2f1f53
--- /dev/null
+++ b/inc/lang/el/uploadmail.txt
@@ -0,0 +1,15 @@
+Ένα αρχείο φορτώθηκε στο DokuWiki σας.
+Αυτά είναι τα αντίστοιχα στοιχεία:
+
+Αρχείο : @MEDIA@
+Ημερομηνία : @DATE@
+Φυλλομετρητής : @BROWSER@
+IP-Διεύθυνση : @IPADDRESS@
+Όνομα υπολογιστή: @HOSTNAME@
+Μέγεθος : @SIZE@
+MIME Type : @MIME@
+Χρήστης : @USER@
+
+--
+Αυτό το e-mail δημιουργήθηκε αυτόματα από την εφαρμογή DokuWiki στην διεύθυνση
+@DOKUWIKIURL@
diff --git a/inc/lang/en/admin.txt b/inc/lang/en/admin.txt
new file mode 100644
index 000000000..cfd21b217
--- /dev/null
+++ b/inc/lang/en/admin.txt
@@ -0,0 +1,4 @@
+====== Administration ======
+
+Below you can find a list of administrative tasks available in DokuWiki.
+
diff --git a/inc/lang/en/adminplugins.txt b/inc/lang/en/adminplugins.txt
new file mode 100644
index 000000000..3ec46cf4e
--- /dev/null
+++ b/inc/lang/en/adminplugins.txt
@@ -0,0 +1,2 @@
+===== Additional Plugins =====
+
diff --git a/inc/lang/en/backlinks.txt b/inc/lang/en/backlinks.txt
new file mode 100644
index 000000000..5b40b84ea
--- /dev/null
+++ b/inc/lang/en/backlinks.txt
@@ -0,0 +1,4 @@
+====== Backlinks ======
+
+This is a list of pages that seem to link back to the current page.
+
diff --git a/inc/lang/en/conflict.txt b/inc/lang/en/conflict.txt
new file mode 100644
index 000000000..624f17b21
--- /dev/null
+++ b/inc/lang/en/conflict.txt
@@ -0,0 +1,6 @@
+====== 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/inc/lang/en/denied.txt b/inc/lang/en/denied.txt
new file mode 100644
index 000000000..3ac72820c
--- /dev/null
+++ b/inc/lang/en/denied.txt
@@ -0,0 +1,4 @@
+====== Permission Denied ======
+
+Sorry, you don't have enough rights to continue. Perhaps you forgot to login?
+
diff --git a/inc/lang/en/diff.txt b/inc/lang/en/diff.txt
new file mode 100644
index 000000000..934534d42
--- /dev/null
+++ b/inc/lang/en/diff.txt
@@ -0,0 +1,4 @@
+====== Differences ======
+
+This shows you the differences between two versions of the page.
+
diff --git a/inc/lang/en/draft.txt b/inc/lang/en/draft.txt
new file mode 100644
index 000000000..e84d34a5b
--- /dev/null
+++ b/inc/lang/en/draft.txt
@@ -0,0 +1,6 @@
+====== 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/inc/lang/en/edit.txt b/inc/lang/en/edit.txt
new file mode 100644
index 000000000..48c9c296d
--- /dev/null
+++ b/inc/lang/en/edit.txt
@@ -0,0 +1,2 @@
+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/inc/lang/en/editrev.txt b/inc/lang/en/editrev.txt
new file mode 100644
index 000000000..638216b07
--- /dev/null
+++ b/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/inc/lang/en/index.txt b/inc/lang/en/index.txt
new file mode 100644
index 000000000..152911bbb
--- /dev/null
+++ b/inc/lang/en/index.txt
@@ -0,0 +1,4 @@
+====== Sitemap ======
+
+This is a sitemap over all available pages ordered by [[doku>namespaces|namespaces]].
+
diff --git a/inc/lang/en/install.html b/inc/lang/en/install.html
new file mode 100644
index 000000000..0f94839a6
--- /dev/null
+++ b/inc/lang/en/install.html
@@ -0,0 +1,24 @@
+<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
+<acronym title="access control list">ACL</acronym>, 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/inc/lang/en/lang.php b/inc/lang/en/lang.php
new file mode 100644
index 000000000..24974ea5e
--- /dev/null
+++ b/inc/lang/en/lang.php
@@ -0,0 +1,349 @@
+<?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'] = 'Login';
+$lang['btn_logout'] = 'Logout';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Update';
+$lang['btn_delete'] = 'Delete';
+$lang['btn_back'] = 'Back';
+$lang['btn_backlink'] = "Backlinks";
+$lang['btn_backtomedia'] = 'Back to Mediafile Selection';
+$lang['btn_subscribe'] = 'Manage Subscriptions';
+$lang['btn_profile'] = 'Update Profile';
+$lang['btn_reset'] = 'Reset';
+$lang['btn_resendpwd'] = 'Send 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['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['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['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['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['pwdforget'] = 'Forgotten your password? Get a new one';
+$lang['resendna'] = 'This wiki does not support password resending.';
+$lang['resendpwd'] = 'Send 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['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['fileupload'] = 'Media File Upload';
+$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['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';
+$lang['external_edit'] = 'external edit';
+$lang['summary'] = 'Edit summary';
+$lang['noflash'] = 'The <a href="http://www.adobe.com/products/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['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'] = 'Code 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';
+$lang['qb_sig'] = 'Insert Signature';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Special Chars';
+
+$lang['upperns'] = 'jump to parent namespace';
+
+$lang['admin_register'] = 'Add new user';
+
+$lang['metaedit'] = 'Edit Metadata';
+$lang['metasaveerr'] = 'Writing metadata failed';
+$lang['metasaveok'] = 'Metadata saved';
+$lang['img_backto'] = 'Back to';
+$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['img_manager'] = 'View in media manager';
+
+$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['authmodfailed'] = 'Bad user authentication configuration. Please inform your Wiki Admin.';
+$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="http://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_phpver'] = 'Your PHP version <code>%s</code> is lower than the needed <code>%s</code>. You need to upgrade your PHP install.';
+$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">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">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_retry'] = 'Retry';
+$lang['i_license'] = 'Please choose the license you want to put your content under:';
+
+$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['plugin_install_err'] = "Plugin installed incorrectly. Rename plugin directory '%s' to '%s'.";
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/lang/en/locked.txt b/inc/lang/en/locked.txt
new file mode 100644
index 000000000..af6347a96
--- /dev/null
+++ b/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/inc/lang/en/login.txt b/inc/lang/en/login.txt
new file mode 100644
index 000000000..2004ea198
--- /dev/null
+++ b/inc/lang/en/login.txt
@@ -0,0 +1,4 @@
+====== 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/inc/lang/en/mailtext.txt b/inc/lang/en/mailtext.txt
new file mode 100644
index 000000000..44a3f6553
--- /dev/null
+++ b/inc/lang/en/mailtext.txt
@@ -0,0 +1,17 @@
+A page in your DokuWiki was added or changed. Here are the details:
+
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+Old Revision: @OLDPAGE@
+New Revision: @NEWPAGE@
+Edit Summary: @SUMMARY@
+User : @USER@
+
+@DIFF@
+
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/en/newpage.txt b/inc/lang/en/newpage.txt
new file mode 100644
index 000000000..848d4df09
--- /dev/null
+++ b/inc/lang/en/newpage.txt
@@ -0,0 +1,4 @@
+====== 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 using the ''Create this page'' button.
+
diff --git a/inc/lang/en/norev.txt b/inc/lang/en/norev.txt
new file mode 100644
index 000000000..0b21bf3f0
--- /dev/null
+++ b/inc/lang/en/norev.txt
@@ -0,0 +1,4 @@
+====== No such revision ======
+
+The specified revision doesn't exist. Use the ''Old revisions'' button for a list of old revisions of this document.
+
diff --git a/inc/lang/en/password.txt b/inc/lang/en/password.txt
new file mode 100644
index 000000000..6d5cbe678
--- /dev/null
+++ b/inc/lang/en/password.txt
@@ -0,0 +1,10 @@
+Hi @FULLNAME@!
+
+Here is your userdata for @TITLE@ at @DOKUWIKIURL@
+
+Login : @LOGIN@
+Password : @PASSWORD@
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/en/preview.txt b/inc/lang/en/preview.txt
new file mode 100644
index 000000000..16c96c5d7
--- /dev/null
+++ b/inc/lang/en/preview.txt
@@ -0,0 +1,4 @@
+====== Preview ======
+
+This is a preview of how your text will look like. Remember: It is **not saved** yet!
+
diff --git a/inc/lang/en/pwconfirm.txt b/inc/lang/en/pwconfirm.txt
new file mode 100644
index 000000000..a342ff95a
--- /dev/null
+++ b/inc/lang/en/pwconfirm.txt
@@ -0,0 +1,15 @@
+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@
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/en/read.txt b/inc/lang/en/read.txt
new file mode 100644
index 000000000..9f56d81ad
--- /dev/null
+++ b/inc/lang/en/read.txt
@@ -0,0 +1,2 @@
+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/inc/lang/en/recent.txt b/inc/lang/en/recent.txt
new file mode 100644
index 000000000..3f7b58c46
--- /dev/null
+++ b/inc/lang/en/recent.txt
@@ -0,0 +1,5 @@
+====== Recent Changes ======
+
+The following pages were changed recently.
+
+
diff --git a/inc/lang/en/register.txt b/inc/lang/en/register.txt
new file mode 100644
index 000000000..db68d4f2f
--- /dev/null
+++ b/inc/lang/en/register.txt
@@ -0,0 +1,4 @@
+====== 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/inc/lang/en/registermail.txt b/inc/lang/en/registermail.txt
new file mode 100644
index 000000000..f02015767
--- /dev/null
+++ b/inc/lang/en/registermail.txt
@@ -0,0 +1,14 @@
+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@
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/en/resendpwd.txt b/inc/lang/en/resendpwd.txt
new file mode 100644
index 000000000..98c8c756b
--- /dev/null
+++ b/inc/lang/en/resendpwd.txt
@@ -0,0 +1,4 @@
+====== 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/inc/lang/en/revisions.txt b/inc/lang/en/revisions.txt
new file mode 100644
index 000000000..dd5f35b8e
--- /dev/null
+++ b/inc/lang/en/revisions.txt
@@ -0,0 +1,4 @@
+====== 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/inc/lang/en/searchpage.txt b/inc/lang/en/searchpage.txt
new file mode 100644
index 000000000..e357d6cdd
--- /dev/null
+++ b/inc/lang/en/searchpage.txt
@@ -0,0 +1,5 @@
+====== Search ======
+
+You can find the results of your search below. If you didn't find what you were looking for, you can create or edit the page named after your query with the appropriate button.
+
+===== Results =====
diff --git a/inc/lang/en/showrev.txt b/inc/lang/en/showrev.txt
new file mode 100644
index 000000000..3608de36b
--- /dev/null
+++ b/inc/lang/en/showrev.txt
@@ -0,0 +1,2 @@
+**This is an old revision of the document!**
+----
diff --git a/inc/lang/en/stopwords.txt b/inc/lang/en/stopwords.txt
new file mode 100644
index 000000000..afc301659
--- /dev/null
+++ b/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/inc/lang/en/subscr_digest.txt b/inc/lang/en/subscr_digest.txt
new file mode 100644
index 000000000..fac8564bd
--- /dev/null
+++ b/inc/lang/en/subscr_digest.txt
@@ -0,0 +1,20 @@
+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.
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/en/subscr_form.txt b/inc/lang/en/subscr_form.txt
new file mode 100644
index 000000000..d606508c6
--- /dev/null
+++ b/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/inc/lang/en/subscr_list.txt b/inc/lang/en/subscr_list.txt
new file mode 100644
index 000000000..efe27d866
--- /dev/null
+++ b/inc/lang/en/subscr_list.txt
@@ -0,0 +1,17 @@
+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.
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/en/subscr_single.txt b/inc/lang/en/subscr_single.txt
new file mode 100644
index 000000000..f2abe6d77
--- /dev/null
+++ b/inc/lang/en/subscr_single.txt
@@ -0,0 +1,23 @@
+Hello!
+
+The page @PAGE@ in the @TITLE@ wiki changed.
+Here are the changes:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Date : @DATE@
+User : @USER@
+Edit Summary: @SUMMARY@
+Old Revision: @OLDPAGE@
+New Revision: @NEWPAGE@
+
+To cancel the page notifications, log into the wiki at
+@DOKUWIKIURL@ then visit
+@NEWPAGE@
+and unsubscribe page and/or namespace changes.
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/en/updateprofile.txt b/inc/lang/en/updateprofile.txt
new file mode 100644
index 000000000..b929fee83
--- /dev/null
+++ b/inc/lang/en/updateprofile.txt
@@ -0,0 +1,5 @@
+====== 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/inc/lang/en/uploadmail.txt b/inc/lang/en/uploadmail.txt
new file mode 100644
index 000000000..16bb6989c
--- /dev/null
+++ b/inc/lang/en/uploadmail.txt
@@ -0,0 +1,15 @@
+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@
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/eo/admin.txt b/inc/lang/eo/admin.txt
new file mode 100644
index 000000000..2ede2763c
--- /dev/null
+++ b/inc/lang/eo/admin.txt
@@ -0,0 +1,3 @@
+====== Administro ======
+
+Sube vi povas trovi liston de administraj taskoj disponeblaj en DokuWiki.
diff --git a/inc/lang/eo/adminplugins.txt b/inc/lang/eo/adminplugins.txt
new file mode 100644
index 000000000..769a8c538
--- /dev/null
+++ b/inc/lang/eo/adminplugins.txt
@@ -0,0 +1 @@
+===== Eksteraj kromaĵoj ===== \ No newline at end of file
diff --git a/inc/lang/eo/backlinks.txt b/inc/lang/eo/backlinks.txt
new file mode 100644
index 000000000..cd0cca9c6
--- /dev/null
+++ b/inc/lang/eo/backlinks.txt
@@ -0,0 +1,3 @@
+====== Retroligiloj ======
+
+Ĉi tiu listo montras paĝojn, kiuj referencas al la aktuala paĝo. \ No newline at end of file
diff --git a/inc/lang/eo/conflict.txt b/inc/lang/eo/conflict.txt
new file mode 100644
index 000000000..603af39e1
--- /dev/null
+++ b/inc/lang/eo/conflict.txt
@@ -0,0 +1,5 @@
+====== Pli nova versio ekzistas ======
+
+Ekzistas pli nova versio de la dokumento. Tio okazas kiam iu alia uzanto ŝanĝigis enhavon de la dokumento dum vi redaktis ĝin.
+
+Atente esploru distingojn kaj decidu kiun version vi tenigos. Se vi premos '&quot;Konservi'&quot;, do via versio estos konservita. Presonte butonon '&quot;Rezigni&quot; vi tenos la kurantan version.
diff --git a/inc/lang/eo/denied.txt b/inc/lang/eo/denied.txt
new file mode 100644
index 000000000..b35fe0412
--- /dev/null
+++ b/inc/lang/eo/denied.txt
@@ -0,0 +1,4 @@
+====== Aliro malpermesita ======
+
+Vi ne havas sufiĉe da rajtoj por rigardi ĉi tiujn paĝojn. Eble vi forgesis identiĝi.
+
diff --git a/inc/lang/eo/diff.txt b/inc/lang/eo/diff.txt
new file mode 100644
index 000000000..ac5474ef1
--- /dev/null
+++ b/inc/lang/eo/diff.txt
@@ -0,0 +1,4 @@
+====== Diferencoj ======
+
+Ĉi tie vi povas ekvidi diferencojn inter la aktuala versio kaj la elektita revizio de la paĝo.
+
diff --git a/inc/lang/eo/draft.txt b/inc/lang/eo/draft.txt
new file mode 100644
index 000000000..fa43ecb74
--- /dev/null
+++ b/inc/lang/eo/draft.txt
@@ -0,0 +1,5 @@
+====== Skiza dosiero estis trovata ======
+
+Via lasta sekcio de redakto en tiu ĉi paĝo ne estis korekte kompletita. DokuWiki aŭtomate konservis skizon dum vi laboris, kiun vi nun povas uzi por daŭrigi vian redaktadon. Sube vi povas vidi la datenaron, kiu estis konservata el via lasta sekcio.
+
+Bonvolu decidi ĉu vi volas //restarigi// vian perditan redakton, //forigi// la aŭtomate konservitan skizon aŭ //rezigni// pri la redakta procezo.
diff --git a/inc/lang/eo/edit.txt b/inc/lang/eo/edit.txt
new file mode 100644
index 000000000..9239c7fe6
--- /dev/null
+++ b/inc/lang/eo/edit.txt
@@ -0,0 +1 @@
+Redaktu paĝon kaj poste premu butonon titolitan '&quot;Konservi'&quot;. Bonvolu tralegi la [[vikio:sintakso|vikian sintakson]] por kompreni kiel vi povas krei paĝojn. Bonvolu redakti nur se vi planas **plibonigi** la enhavon de la paĝo. Se vi volas nur testi ion, do bonvolu uzi specialan paĝon: [[vikio:ludejo|ludejo]].
diff --git a/inc/lang/eo/editrev.txt b/inc/lang/eo/editrev.txt
new file mode 100644
index 000000000..4bab50b93
--- /dev/null
+++ b/inc/lang/eo/editrev.txt
@@ -0,0 +1,2 @@
+**Vi laboras kun malnova revizio de la dokumento!** Se vi konservos ĝin, tiel kreiĝos nova kuranta versio kun la sama enhavo.
+----
diff --git a/inc/lang/eo/index.txt b/inc/lang/eo/index.txt
new file mode 100644
index 000000000..4ef720cb2
--- /dev/null
+++ b/inc/lang/eo/index.txt
@@ -0,0 +1,3 @@
+====== Enhavo ======
+
+Tio ĉi estas indekso pri ĉiuj disponeblaj paĝoj ordigitaj laŭ [[doku&gt;namespaces|nomspacoj]]. \ No newline at end of file
diff --git a/inc/lang/eo/install.html b/inc/lang/eo/install.html
new file mode 100644
index 000000000..9f43ae82e
--- /dev/null
+++ b/inc/lang/eo/install.html
@@ -0,0 +1,9 @@
+&lt;p&gt;Tiu ĉi paĝo helpas en la unua instalo kaj agordado de &lt;a href=&quot;http://dokuwiki.org&quot;&gt;DokuWiki&lt;/a&gt;. Pli da informo pri tiu instalilo estas disponebla en ĝia propra &lt;a href=&quot;http://dokuwiki.org/installer&quot;&gt;dokumentada paĝo&lt;/a&gt;.&lt;/p&gt;
+
+&lt;p&gt;DokuWiki uzas ordinarajn dosierojn por konservi vikiajn paĝojn kaj aliajn informojn asociitaj al tiuj paĝoj (ekz. bildoj, serĉindeksoj, malnovaj revizioj, ktp). Por bone funkcii, DokuWiki &lt;strong&gt;devas&lt;/strong&gt; havi registran rajton sur la subdosierujoj, kiuj entenas tiujn dosierojn. Tiu ĉi instalilo ne kapablas difini permes-atributojn de dosierujoj. Ordinare, tio devas esti senpere farita de iu komando en konzolo aŭ, se vi abonas retprovizanton, per FTP aŭ kontrola panelo de tiu retprovidanto (ekz. cPanel).</p>
+
+&lt;p&gt;Tiu ĉi instalilo difinos vian DokuWiki-an agordadon por &lt;acronym title=&quot;alir-kontrola listo&quot;&gt;ACL&lt;/acronym&gt;, kiu ebligas al administranto identiĝi kaj aliri taŭgan interfacon por instali kromaĵojn, administri uzantojn kaj alireblon al vikipaĝoj, kaj difini agordojn ĝeneralajn.
+Ĝi ne estas nepra por ke DokuWiki funkciu, tamen ĝi multe faciligos administradon.&lt;/p&gt;
+
+&lt;p&gt;Spertuloj aŭ uzantoj kiuj bezonas specialajn agordrimedojn devus uzi tiujn ligilojn por havi pli detalojn pri &lt;a href=&quot;http://dokuwiki.org/install&quot;&gt;instaladaj instrukcioj&lt;/a&gt;
+kaj &lt;a href=&quot;http://dokuwiki.org/config&quot;&gt;agordadaj difinoj&lt;/a&gt;.&lt;/p&gt; \ No newline at end of file
diff --git a/inc/lang/eo/lang.php b/inc/lang/eo/lang.php
new file mode 100644
index 000000000..c8148c772
--- /dev/null
+++ b/inc/lang/eo/lang.php
@@ -0,0 +1,316 @@
+<?php
+/**
+ * Esperanta dosiero
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Antono Vasiljev <esperanto.minsk ĈE tut.by>
+ * @author Felipe Castro <fefcas@yahoo.com.br>
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Redakti la paĝon';
+$lang['btn_source'] = 'Montri fontan tekston';
+$lang['btn_show'] = 'Montri paĝon';
+$lang['btn_create'] = 'Krei paĝon';
+$lang['btn_search'] = 'Serĉi';
+$lang['btn_save'] = 'Konservi';
+$lang['btn_preview'] = 'Antaŭrigardi';
+$lang['btn_top'] = 'Supren';
+$lang['btn_newer'] = '<< pli freŝe';
+$lang['btn_older'] = 'malpli freŝe >>';
+$lang['btn_revs'] = 'Malnovaj revizioj';
+$lang['btn_recent'] = 'Freŝaj ŝanĝoj';
+$lang['btn_upload'] = 'Alŝuti';
+$lang['btn_cancel'] = 'Rezigni';
+$lang['btn_index'] = 'Indekso';
+$lang['btn_secedit'] = 'Redakti';
+$lang['btn_login'] = 'Ensaluti';
+$lang['btn_logout'] = 'Elsaluti';
+$lang['btn_admin'] = 'Administri';
+$lang['btn_update'] = 'Ĝisdatigi';
+$lang['btn_delete'] = 'Forigi';
+$lang['btn_back'] = 'Retroiri';
+$lang['btn_backlink'] = 'Retroligoj';
+$lang['btn_backtomedia'] = 'Retroiri al elekto de dosiero';
+$lang['btn_subscribe'] = 'Aliĝi al paĝaj modifoj';
+$lang['btn_profile'] = 'Ĝisdatigi profilon';
+$lang['btn_reset'] = 'Rekomenci';
+$lang['btn_resendpwd'] = 'Sendi novan pasvorton';
+$lang['btn_draft'] = 'Redakti skizon';
+$lang['btn_recover'] = 'Restarigi skizon';
+$lang['btn_draftdel'] = 'Forigi skizon';
+$lang['btn_revert'] = 'Restarigi';
+$lang['btn_register'] = 'Registriĝi';
+$lang['btn_apply'] = 'Apliki';
+$lang['btn_media'] = 'Medio-administrilo';
+$lang['loggedinas'] = 'Ensalutinta kiel';
+$lang['user'] = 'Uzant-nomo';
+$lang['pass'] = 'Pasvorto';
+$lang['newpass'] = 'Nova pasvorto';
+$lang['oldpass'] = 'Konfirmu la nunan pasvorton';
+$lang['passchk'] = 'plian fojon';
+$lang['remember'] = 'Rememoru min';
+$lang['fullname'] = 'Kompleta nomo';
+$lang['email'] = 'Retpoŝto';
+$lang['profile'] = 'Uzanto-profilo';
+$lang['badlogin'] = 'Pardonu, uzant-nomo aŭ pasvorto estis erara.';
+$lang['minoredit'] = 'Etaj modifoj';
+$lang['draftdate'] = 'Lasta konservo de la skizo:';
+$lang['nosecedit'] = 'La paĝo ŝanĝiĝis intertempe, sekcio-informo estis malĝisdata, tial la tuta paĝo estas reŝargita.';
+$lang['regmissing'] = 'Pardonu, vi devas plenigi ĉiujn kampojn.';
+$lang['reguexists'] = 'Pardonu, ĉi tiu uzanto-nomo jam ekzistas.';
+$lang['regsuccess'] = 'La uzanto estas kreita kaj la pasvorto estis elsendita per retpoŝto.';
+$lang['regsuccess2'] = 'La uzanto estas kreita.';
+$lang['regmailfail'] = 'Ŝajne okazis eraro dum elsendo de la pasvorto. Bonvolu informi administranton pri tio!';
+$lang['regbadmail'] = 'Entajpita retpoŝta adreso ne ŝajnas valida. Se vi pensas, ke tio estas eraro, kontaktu la administranton.';
+$lang['regbadpass'] = 'La du pasvortoj ne samas, bonvolu provi refoje.';
+$lang['regpwmail'] = 'Via DokuWiki-pasvorto';
+$lang['reghere'] = 'Se vi ne havas konton, vi povas akiri ĝin';
+$lang['profna'] = 'Tiu ĉi vikio ne ebligas modifon en la profiloj.';
+$lang['profnochange'] = 'Neniu ŝanĝo, nenio farinda.';
+$lang['profnoempty'] = 'Malplena nomo aŭ retadreso ne estas permesataj.';
+$lang['profchanged'] = 'La profilo de la uzanto estas sukcese ĝisdatigita.';
+$lang['pwdforget'] = 'Ĉu vi forgesis vian pasvorton? Prenu novan';
+$lang['resendna'] = 'Tiu ĉi vikio ne ebligas resendon de la pasvortoj.';
+$lang['resendpwd'] = 'Sendi novan pasvorton al';
+$lang['resendpwdmissing'] = 'Pardonu, vi devas plenigi ĉiujn kampojn.';
+$lang['resendpwdnouser'] = 'Pardonu, ni ne trovas tiun uzanton en nia datenbazo.';
+$lang['resendpwdbadauth'] = 'Pardonu, tiu aŭtentiga kodo ne validas. Certiĝu, ke vi uzis la kompletan konfirmigan ligilon.';
+$lang['resendpwdconfirm'] = 'Konfirmiga ligilo estas sendita per retpoŝto.';
+$lang['resendpwdsuccess'] = 'Via nova pasvorto estas sendita per retpoŝto.';
+$lang['license'] = 'Krom kie rekte indikite, enhavo de tiu ĉi vikio estas publikigita laŭ la jena permesilo:';
+$lang['licenseok'] = 'Rimarku: redaktante tiun ĉi paĝon vi konsentas publikigi vian enhavon laŭ la jena permesilo:';
+$lang['searchmedia'] = 'Serĉi dosiernomon:';
+$lang['searchmedia_in'] = 'Serĉi en %s';
+$lang['txt_upload'] = 'Elektu dosieron por alŝuto';
+$lang['txt_filename'] = 'Alŝuti kiel (laŭvole)';
+$lang['txt_overwrt'] = 'Anstataŭigi ekzistantan dosieron';
+$lang['lockedby'] = 'Nune ŝlosita de';
+$lang['lockexpire'] = 'Ŝlosado ĉesos en';
+$lang['js']['willexpire'] = 'Vi povos redakti ĉi tiun paĝon post unu minuto.\nSe vi volas nuligi tempkontrolon de la ŝlosado, do premu butonon "Antaŭrigardi".';
+$lang['js']['notsavedyet'] = 'Ne konservitaj modifoj perdiĝos.
+Ĉu vi certe volas daŭrigi la procezon?';
+$lang['js']['searchmedia'] = 'Serĉi dosierojn';
+$lang['js']['keepopen'] = 'Tenu la fenestron malfermata dum elekto';
+$lang['js']['hidedetails'] = 'Kaŝi detalojn';
+$lang['js']['mediatitle'] = 'Ligilaj agordoj';
+$lang['js']['mediadisplay'] = 'Ligila tipo';
+$lang['js']['mediaalign'] = 'Poziciigo';
+$lang['js']['mediasize'] = 'Bildgrandeco';
+$lang['js']['mediatarget'] = 'Ligila celo';
+$lang['js']['mediaclose'] = 'Fermi';
+$lang['js']['mediainsert'] = 'Enmeti';
+$lang['js']['mediadisplayimg'] = 'Montri la bildon.';
+$lang['js']['mediadisplaylnk'] = 'Montri nur la ligilon.';
+$lang['js']['mediasmall'] = 'Malgranda versio';
+$lang['js']['mediamedium'] = 'Meza versio';
+$lang['js']['medialarge'] = 'Granda versio';
+$lang['js']['mediaoriginal'] = 'Origina versio';
+$lang['js']['medialnk'] = 'Ligilo al detala paĝo';
+$lang['js']['mediadirect'] = 'Rekta ligilo al la origino';
+$lang['js']['medianolnk'] = 'Neniu ligilo';
+$lang['js']['medianolink'] = 'Ne ligi la bildon';
+$lang['js']['medialeft'] = 'Meti la bildon maldekstren.';
+$lang['js']['mediaright'] = 'Meti la bildon dekstren.';
+$lang['js']['mediacenter'] = 'Meti la bildon mezen.';
+$lang['js']['medianoalign'] = 'Ne uzi poziciigon.';
+$lang['js']['nosmblinks'] = 'Tio ĉi nur funkcias en la Vindozaĉa "Microsoft Internet Explorer".\nVi ankoraŭ povas kopii kaj almeti la ligilon.';
+$lang['js']['linkwiz'] = 'Ligil-Asistanto';
+$lang['js']['linkto'] = 'Ligilo al:';
+$lang['js']['del_confirm'] = 'Ĉu vere forigi elektitajn ero(j)n?';
+$lang['js']['restore_confirm'] = 'Ĉu vere restarigi ĉi tiun version?';
+$lang['js']['media_diff'] = 'Rigardu la diferencojn:';
+$lang['js']['media_diff_both'] = 'Flankon apud flanko';
+$lang['js']['media_diff_opacity'] = 'Unu super la alia';
+$lang['js']['media_diff_portions'] = 'Ŝovilo';
+$lang['js']['media_select'] = 'Elektu dosierojn...';
+$lang['js']['media_upload_btn'] = 'Alŝuto';
+$lang['js']['media_done_btn'] = 'Finita';
+$lang['js']['media_drop'] = 'Demetu ĉi-tien por alŝuti';
+$lang['js']['media_cancel'] = 'forigi';
+$lang['js']['media_overwrt'] = 'Anstataûi ekzistantajn dosierojn';
+$lang['rssfailed'] = 'Okazis eraro dum ricevado de la novaĵ-fluo: ';
+$lang['nothingfound'] = 'Ankoraŭ nenio troviĝas tie ĉi.';
+$lang['mediaselect'] = 'Elekto de aŭdvidaĵa dosiero';
+$lang['fileupload'] = 'Alŝuto de aŭdvidaĵa dosiero';
+$lang['uploadsucc'] = 'Alŝuto estis sukcesa';
+$lang['uploadfail'] = 'Alŝuto estis malsukcesa. Eble ĉu estas problemoj pro permes-atributoj?';
+$lang['uploadwrong'] = 'Rifuzita alŝuto. Tiu ĉi dosiersufikso estas malpermesata!';
+$lang['uploadexist'] = 'La dosiero jam ekzistas. Nenio estas farita.';
+$lang['uploadbadcontent'] = 'La alŝutita enhavo ne kongruas al la sufikso %s.';
+$lang['uploadspam'] = 'La alŝutaĵo estis blokita de kontraŭspama vortlisto.';
+$lang['uploadxss'] = 'La alŝutajo estis blokita pro ebla malica enhavo.';
+$lang['uploadsize'] = 'La alŝutita dosiero estis tro granda. (maks. %s)';
+$lang['deletesucc'] = 'La dosiero "%s" estas forigita.';
+$lang['deletefail'] = '"%s" ne povis esti forigita - kontrolu permes-atributojn.';
+$lang['mediainuse'] = 'La dosiero "%s" ne estis forigita - ĝi ankoraŭ estas uzata.';
+$lang['namespaces'] = 'Nomspacoj';
+$lang['mediafiles'] = 'Disponeblaj dosieroj';
+$lang['accessdenied'] = 'Vi ne rajtas vidi tiun paĝon.';
+$lang['mediausage'] = 'Uzu la jenan sintakson por referenci tiun ĉi dosieron:';
+$lang['mediaview'] = 'Rigardi originalan dosieron';
+$lang['mediaroot'] = 'ĉefo (root)';
+$lang['mediaupload'] = 'Alŝutu dosieron al la kuranta nomspaco tien ĉi. Por krei subnomspacojn, antaŭmetu ilin al via "Alŝuti kiel" dosiernomo, apartigante per dupunktoj (:).';
+$lang['mediaextchange'] = 'La dosiersufikso ŝanĝis de .%s al .%s!';
+$lang['reference'] = 'Referencoj por';
+$lang['ref_inuse'] = 'La dosiero ne povas esti forigita, ĉar ĝi ankoraŭ estas uzata de la jenaj paĝoj:';
+$lang['ref_hidden'] = 'Kelkaj referencoj estas en paĝoj, kiujn vi ne rajtas legi';
+$lang['hits'] = 'Trafoj';
+$lang['quickhits'] = 'Trafoj trovitaj en paĝnomoj';
+$lang['toc'] = 'Enhavtabelo';
+$lang['current'] = 'aktuala';
+$lang['yours'] = 'Via versio';
+$lang['diff'] = 'Montri diferencojn el la aktuala versio';
+$lang['diff2'] = 'Montri diferencojn inter la elektitaj revizioj';
+$lang['difflink'] = 'Ligilo al kompara rigardo';
+$lang['diff_type'] = 'Rigardi malsamojn:';
+$lang['diff_inline'] = 'Samlinie';
+$lang['diff_side'] = 'Apude';
+$lang['line'] = 'Linio';
+$lang['breadcrumb'] = 'Paŝoj';
+$lang['youarehere'] = 'Vi estas ĉi tie';
+$lang['lastmod'] = 'Lastaj ŝanĝoj';
+$lang['by'] = 'de';
+$lang['deleted'] = 'forigita';
+$lang['created'] = 'kreita';
+$lang['restored'] = 'malnova revizio restarigita';
+$lang['external_edit'] = 'ekstera redakto';
+$lang['summary'] = 'Bulteno de ŝanĝoj';
+$lang['noflash'] = 'La <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> estas bezonata por montrigi tiun ĉi enhavon.';
+$lang['download'] = 'Elŝuti eltiraĵon';
+$lang['mail_newpage'] = 'paĝo aldonita:';
+$lang['mail_changed'] = 'paĝo modifita:';
+$lang['mail_subscribe_list'] = 'ŝanĝitaj paĝoj en nomspaco:';
+$lang['mail_new_user'] = 'Nova uzanto:';
+$lang['mail_upload'] = 'dosiero alŝutita:';
+$lang['changes_type'] = 'Rigardi ŝanĝojn de';
+$lang['pages_changes'] = 'Paĝoj';
+$lang['media_changes'] = 'Mediaj dosieroj';
+$lang['both_changes'] = 'Ambaû - paĝojn kaj mediajn dosierojn';
+$lang['qb_bold'] = 'Dika teksto';
+$lang['qb_italic'] = 'Dekliva teksto';
+$lang['qb_underl'] = 'Substrekita teksto';
+$lang['qb_code'] = 'Koduma teksto';
+$lang['qb_strike'] = 'Trastrekita teksto';
+$lang['qb_h1'] = 'Titolo de 1-a nivelo';
+$lang['qb_h2'] = 'Titolo de 2-a nivelo';
+$lang['qb_h3'] = 'Titolo de 3-a nivelo';
+$lang['qb_h4'] = 'Titolo de 4-a nivelo';
+$lang['qb_h5'] = 'Titolo de 5-a nivelo';
+$lang['qb_h'] = 'Ĉeftitolo';
+$lang['qb_hs'] = 'Elektu ĉeftitolon';
+$lang['qb_hplus'] = 'Altnivela titolo';
+$lang['qb_hminus'] = 'Subnivela titolo';
+$lang['qb_hequal'] = 'Samnivela titolo';
+$lang['qb_link'] = 'Interna ligilo';
+$lang['qb_extlink'] = 'Ekstera ligilo';
+$lang['qb_hr'] = 'Horizontala streko';
+$lang['qb_ol'] = 'Elemento de numerita listo';
+$lang['qb_ul'] = 'Elemento de ne numerita listo';
+$lang['qb_media'] = 'Aldoni bildojn kaj aliajn dosierojn';
+$lang['qb_sig'] = 'Inkluzivi subskribon';
+$lang['qb_smileys'] = 'Ridetuloj';
+$lang['qb_chars'] = 'Specialaj signaĵoj';
+$lang['upperns'] = 'saltu al la parenca nomspaco';
+$lang['admin_register'] = 'Aldoni novan uzanton';
+$lang['metaedit'] = 'Redakti metadatenaron';
+$lang['metasaveerr'] = 'La konservo de metadatenaro malsukcesis';
+$lang['metasaveok'] = 'La metadatenaro estis konservita';
+$lang['img_backto'] = 'Retroiri al';
+$lang['img_title'] = 'Titolo';
+$lang['img_caption'] = 'Priskribo';
+$lang['img_date'] = 'Dato';
+$lang['img_fname'] = 'Dosiernomo';
+$lang['img_fsize'] = 'Grandeco';
+$lang['img_artist'] = 'Fotisto';
+$lang['img_copyr'] = 'Kopirajtoj';
+$lang['img_format'] = 'Formato';
+$lang['img_camera'] = 'Kamerao';
+$lang['img_keywords'] = 'Ŝlosilvortoj';
+$lang['img_width'] = 'Larĝeco';
+$lang['img_height'] = 'Alteco';
+$lang['img_manager'] = 'Rigardi en media-administrilo';
+$lang['subscr_subscribe_success'] = 'Aldonis %s al la abonlisto por %s';
+$lang['subscr_subscribe_error'] = 'Eraro dum aldono de %s al la abonlisto por %s';
+$lang['subscr_subscribe_noaddress'] = 'Ne estas adreso ligita al via ensaluto, ne eblas aldoni vin al la abonlisto';
+$lang['subscr_unsubscribe_success'] = 'Forigis %s de la abonlisto por %s';
+$lang['subscr_unsubscribe_error'] = 'Eraro dum forigo de %s de la abonlisto por %s';
+$lang['subscr_already_subscribed'] = '%s jam estas abonanta al %s';
+$lang['subscr_not_subscribed'] = '%s ne abonas al %s';
+$lang['subscr_m_not_subscribed'] = 'Momente vi ne abonas la aktualan paĝon aŭ nomspacon.';
+$lang['subscr_m_new_header'] = 'Aldoni abonon';
+$lang['subscr_m_current_header'] = 'Momentaj abonoj';
+$lang['subscr_m_unsubscribe'] = 'Malaboni';
+$lang['subscr_m_subscribe'] = 'Aboni';
+$lang['subscr_m_receive'] = 'Ricevi';
+$lang['subscr_style_every'] = 'retpoŝtaĵo pro ĉiu ŝanĝo';
+$lang['subscr_style_digest'] = 'resuma retpoŝtaĵo de ŝanĝoj por ĉiu paĝo (je %.2f tagoj)';
+$lang['subscr_style_list'] = 'listo de ŝanĝitaj paĝoj ekde la lasta retpoŝtaĵo (je %.2f tagoj)';
+$lang['authmodfailed'] = 'Malbona agordo por identigi la uzanton. Bonvolu informi la administranton de la vikio.';
+$lang['authtempfail'] = 'La identigo de via uzantonomo estas intertempe maldisponebla. Se tiu ĉi situacio daŭros, bonvolu informi la adminstranton de la vikio.';
+$lang['i_chooselang'] = 'Elektu vian lingvon';
+$lang['i_installer'] = 'Instalilo de DokuWiki';
+$lang['i_wikiname'] = 'Nomo de la vikio';
+$lang['i_enableacl'] = 'Ebligi "ACL" (alirkontrolo, rekomendinde)';
+$lang['i_superuser'] = 'Superuzanto';
+$lang['i_problems'] = 'La instalilo trovis kelkajn problemojn, indikitaj sube. Vi ne povas pluiri ĝis ili estos iel korektitaj.';
+$lang['i_modified'] = 'Pro sekureco tiu ĉi instalilo nur funkcias por nova kaj nemodifita DokuWiki-pakaĵo.
+Vi devas aŭ redemeti la dosierojn el la elŝutita pakaĵo aŭ plibone informiĝi pri la instalada procezo.';
+$lang['i_funcna'] = 'La PHP-a funkcio <code>%s</code> ne estas uzebla. Eble via retprovizanto ial malpermesis tion?';
+$lang['i_phpver'] = 'La versio de la PHP <code>%s</code> estas pli malnova ol la bezonata <code>%s</code>. Vi bezonas ĝisdatigi la PHP-an instalon.';
+$lang['i_permfail'] = '<code>%s</code> ne estas skribebla por DokuWiki. Vi devas redifini la permes-atributojn de tiu ĉi dosierujo!';
+$lang['i_confexists'] = '<code>%s</code> jam ekzistas';
+$lang['i_writeerr'] = 'Ne eblas krei "<code>%s</code>". Vi bezonas kontroli la permesojn de la dosier(uj)oj kaj mem krej la dosieron.';
+$lang['i_badhash'] = 'dokuwiki.php ne estas rekonebla aŭ ĝi estas modifita (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - malvalida aŭ malplena valoro';
+$lang['i_success'] = 'La agordado estas sukcese kompletita. Vi povas forigi la dosieron nun. Pluiru al <a href="doku.php">via nova DokuWiki</a>.';
+$lang['i_failure'] = 'Kelkaj eraroj okazis dum la konservo de la agordaj dosieroj. Vi devas senpere korekti ilin antaŭ ol vi povos uzi <a href="doku.php">vian novan DokuWiki-on</a>. ';
+$lang['i_policy'] = 'Komenca ACL-a agordo';
+$lang['i_pol0'] = 'Malferma Vikio (legi, skribi, alŝuti povas ĉiuj)';
+$lang['i_pol1'] = 'Publika Vikio (legi povas ĉiuj, skribi kaj alŝuti povas registritaj uzantoj)';
+$lang['i_pol2'] = 'Ferma Vikio (legi, skribi, alŝuti nur povas registritaj uzantoj)';
+$lang['i_retry'] = 'Reprovi';
+$lang['i_license'] = 'Bonvolu elekti la permesilon, sub kiun vi volas meti vian enhavon:';
+$lang['recent_global'] = 'Vi nun rigardas la ŝanĝojn ene de la nomspaco <b>%s</b>. Vi povas ankaŭ <a href="%s">vidi la freŝajn ŝanĝojn de la tuta vikio</a>.';
+$lang['years'] = 'antaŭ %d jaroj';
+$lang['months'] = 'antaŭ %d monatoj';
+$lang['weeks'] = 'antaŭ %d semajnoj';
+$lang['days'] = 'antaŭ %d tagoj';
+$lang['hours'] = 'antaŭ %d horoj';
+$lang['minutes'] = 'antaŭ %d minutoj';
+$lang['seconds'] = 'antaŭ %d sekundoj';
+$lang['wordblock'] = 'Via ŝanĝo ne estis savita, ĉar ĝi enhavas blokitan tekston (spamon).';
+$lang['media_uploadtab'] = 'Alŝuto';
+$lang['media_searchtab'] = 'Serĉo';
+$lang['media_file'] = 'Dosiero';
+$lang['media_viewtab'] = 'Rigardi';
+$lang['media_edittab'] = 'Modifi';
+$lang['media_historytab'] = 'Historio';
+$lang['media_list_thumbs'] = 'Bildeto';
+$lang['media_list_rows'] = 'Kolumnoj';
+$lang['media_sort_name'] = 'per nomo';
+$lang['media_sort_date'] = 'per dato';
+$lang['media_namespaces'] = 'Elektu nomspacon';
+$lang['media_files'] = 'Dosieroj en %s';
+$lang['media_upload'] = 'Alŝuti al la nomspaco <strong>%s</strong>.';
+$lang['media_search'] = 'Serĉi en la nomspaco <strong>%s</strong>.';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s ĉe %s';
+$lang['media_edit'] = 'Modifi %s';
+$lang['media_history'] = 'Protokolo de %s';
+$lang['media_meta_edited'] = 'metadatumoj ŝanĝitaj';
+$lang['media_perm_read'] = 'Bedaûrinde viaj rajtoj ne sufiĉas por legi dosierojn.';
+$lang['media_perm_upload'] = 'Bedaûrinde viaj rajtoj ne sufiĉas por alŝuti dosierojn.';
+$lang['media_update'] = 'Alŝuti novan version';
+$lang['media_restore'] = 'Restarigi ĉi tiun version';
+$lang['plugin_install_err'] = 'Kromaĵo instalita malĝuste. Renomu la kromaĵan dosierujon \'%s\' al \'%s\'.';
diff --git a/inc/lang/eo/locked.txt b/inc/lang/eo/locked.txt
new file mode 100644
index 000000000..68963da75
--- /dev/null
+++ b/inc/lang/eo/locked.txt
@@ -0,0 +1,3 @@
+====== La paĝo estas ŝlosita ======
+
+Tiu ĉi paĝo nun estas blokita pro redaktado de iu alia uzanto. Bonvole atendu ke ŝi/li finu redakti aŭ ke la ŝlosada tempolimo finiĝu.
diff --git a/inc/lang/eo/login.txt b/inc/lang/eo/login.txt
new file mode 100644
index 000000000..2b9b34340
--- /dev/null
+++ b/inc/lang/eo/login.txt
@@ -0,0 +1,3 @@
+====== Enirejo ======
+
+Vi ankoraŭ ne identiĝis! Entajpu necesajn informojn sube por identiĝi. Kuketoj (cookies) devas esti ŝaltitaj. \ No newline at end of file
diff --git a/inc/lang/eo/mailtext.txt b/inc/lang/eo/mailtext.txt
new file mode 100644
index 000000000..b2cb3b49d
--- /dev/null
+++ b/inc/lang/eo/mailtext.txt
@@ -0,0 +1,16 @@
+Paĝo en via DokuVikio estis ŝanĝita aŭ aldonita. Jen detaloj:
+
+Dato: @DATE@
+Foliumilo: @BROWSER@
+IP-adreso: @IPADDRESS@
+RetNodo: @HOSTNAME@
+Antaŭa revizio: @OLDPAGE@
+Nova revizio: @NEWPAGE@
+Bulteno de ŝanĝoj: @SUMMARY@
+Uzulo: @USER@
+
+@DIFF@
+
+--
+Tiu ĉi mesaĝo estis kreita de DokuWiki, kiu lokiĝas tie:
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/eo/newpage.txt b/inc/lang/eo/newpage.txt
new file mode 100644
index 000000000..486f61f5a
--- /dev/null
+++ b/inc/lang/eo/newpage.txt
@@ -0,0 +1,4 @@
+====== Ĉi tiu paĝo ankoraŭ ne ekzistas ======
+
+Vi sekvis ligilon, kiu kondukas al artikolo ankoraŭ ne ekzistanta. Se vi rajtas, tiel vi povas krei tiun ĉi paĝon ekpremante la butonon &quot;Krei paĝon&quot;.
+
diff --git a/inc/lang/eo/norev.txt b/inc/lang/eo/norev.txt
new file mode 100644
index 000000000..dc44d194b
--- /dev/null
+++ b/inc/lang/eo/norev.txt
@@ -0,0 +1,3 @@
+====== Tiu revizio ne ekzistas ======
+
+La elektita revizio ne ekzistas. Premu butonon &quot;Malnovaj revizioj&quot; por vidi liston de malnovaj revizioj de la dokumento. \ No newline at end of file
diff --git a/inc/lang/eo/password.txt b/inc/lang/eo/password.txt
new file mode 100644
index 000000000..ef744059e
--- /dev/null
+++ b/inc/lang/eo/password.txt
@@ -0,0 +1,10 @@
+Saluton @FULLNAME@!
+
+Jen via uzantodatenoj por @TITLE@ ĉe @DOKUWIKIURL@
+
+Ensalutnomo: @LOGIN@
+Pasvorto: @PASSWORD@
+
+--
+Tiu ĉi mesaĝo estis kreita de DokuWiki ĉe
+@DOKUWIKIURL@
diff --git a/inc/lang/eo/preview.txt b/inc/lang/eo/preview.txt
new file mode 100644
index 000000000..ac2e75d00
--- /dev/null
+++ b/inc/lang/eo/preview.txt
@@ -0,0 +1,3 @@
+====== Antaŭrigardo ======
+
+Tiu ĉi estas antaŭrigardo de redaktita teksto. Memoru: ĝi ankoraŭ **ne estas konservita**! \ No newline at end of file
diff --git a/inc/lang/eo/pwconfirm.txt b/inc/lang/eo/pwconfirm.txt
new file mode 100644
index 000000000..f227752b1
--- /dev/null
+++ b/inc/lang/eo/pwconfirm.txt
@@ -0,0 +1,14 @@
+Saluton @FULLNAME@!
+
+Iu petis novan pasvorton por via @TITLE@
+ensalutnomo ĉe @DOKUWIKIURL@
+
+Se ne estas vi, kiu petis tion, do preterlasu tiun ĉi mesaĝon.
+
+Por konfirmi, ke la peto estis vere via, bonvolu musklaki la jenan ligilon.
+
+@CONFIRM@
+
+--
+Tiu ĉi mesaĝo estis kreita de DokuWiki ĉe
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/eo/read.txt b/inc/lang/eo/read.txt
new file mode 100644
index 000000000..734eb1654
--- /dev/null
+++ b/inc/lang/eo/read.txt
@@ -0,0 +1,2 @@
+Tiu ĉi paĝo estas disponigata nur por legado (vi ne povas redakti ĝin). Sciigu administranton, se vi opinias ke tio estas ne ĝusta malpermeso.
+
diff --git a/inc/lang/eo/recent.txt b/inc/lang/eo/recent.txt
new file mode 100644
index 000000000..ffd9936e2
--- /dev/null
+++ b/inc/lang/eo/recent.txt
@@ -0,0 +1,3 @@
+====== Freŝaj Ŝanĝoj ======
+
+La jenaj paĝoj estis ŝanĝitaj antaŭ nelonga tempo. \ No newline at end of file
diff --git a/inc/lang/eo/register.txt b/inc/lang/eo/register.txt
new file mode 100644
index 000000000..57d5ca1f4
--- /dev/null
+++ b/inc/lang/eo/register.txt
@@ -0,0 +1,4 @@
+====== Registriĝi ======
+
+Entajpu necesajn informojn por enregistriĝi. Certiĝu ke via retpoŝta adreso estas vera ĉar ni sendos al ĝi vian pasvorton.
+
diff --git a/inc/lang/eo/registermail.txt b/inc/lang/eo/registermail.txt
new file mode 100644
index 000000000..8b9ea8501
--- /dev/null
+++ b/inc/lang/eo/registermail.txt
@@ -0,0 +1,14 @@
+Nova uzanto estis registrata. Jen la detaloj:
+
+Uzantonomo: @NEWUSER@
+Kompleta nomo: @NEWNAME@
+Retadreso: @NEWEMAIL@
+
+Dato: @DATE@
+Foliumilo: @BROWSER@
+IP-Adreso: @IPADDRESS@
+Provizanto: @HOSTNAME@
+
+--
+Tiu ĉi mesaĝo estis kreita de DokuWiki ĉe
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/eo/resendpwd.txt b/inc/lang/eo/resendpwd.txt
new file mode 100644
index 000000000..57b4b0408
--- /dev/null
+++ b/inc/lang/eo/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Sendi novan pasvorton ======
+
+Bonvolu meti vian uzantonomon en la suban formularon petante novan pasvorton por via aliĝo en tiu ĉi vikio. Konfirma ligilo estos sendata al via registrita retadreso.
diff --git a/inc/lang/eo/revisions.txt b/inc/lang/eo/revisions.txt
new file mode 100644
index 000000000..4f37bb125
--- /dev/null
+++ b/inc/lang/eo/revisions.txt
@@ -0,0 +1,3 @@
+====== Malnovaj revizioj ======
+
+Sube estas listo de malnovaj revizioj de la dokumento. Elektu revizion se vi volas rigardi ĝin aŭ anstataŭigi kurantan paĝon per ĝi. \ No newline at end of file
diff --git a/inc/lang/eo/searchpage.txt b/inc/lang/eo/searchpage.txt
new file mode 100644
index 000000000..a940c503d
--- /dev/null
+++ b/inc/lang/eo/searchpage.txt
@@ -0,0 +1,5 @@
+====== Serĉo ======
+
+Sube estas rezultoj de serĉo en la retejo.\\ Se vi ne trovis tion, kion vi serĉis, vi povas krei novan paĝon kun necesa nomo per la koresponda butono.
+
+===== Rezultoj =====
diff --git a/inc/lang/eo/showrev.txt b/inc/lang/eo/showrev.txt
new file mode 100644
index 000000000..e3a8a1747
--- /dev/null
+++ b/inc/lang/eo/showrev.txt
@@ -0,0 +1,2 @@
+**Tiu estas malnova revizio de la dokumento**. Klaku sur titolo por ricevi kurantan version.
+----
diff --git a/inc/lang/eo/stopwords.txt b/inc/lang/eo/stopwords.txt
new file mode 100644
index 000000000..38757ae04
--- /dev/null
+++ b/inc/lang/eo/stopwords.txt
@@ -0,0 +1,20 @@
+# Jen listo de vortoj, kiujn la indeksilo ignoras, unu vorton po linio
+# Kiam vi modifas la dosieron, estu certa ke vi uzas UNIX-stilajn linifinaĵojn (unuopa novlinio)
+# Ne enmetu vortojn malpli longajn ol 3 literoj - tiuj ĉiukaze estas ignorataj
+pri
+estas
+kaj
+mia
+via
+ili
+ilia
+kun
+por
+kiel
+tiu
+estis
+kio
+kiam
+kie
+kiu
+www \ No newline at end of file
diff --git a/inc/lang/eo/subscr_digest.txt b/inc/lang/eo/subscr_digest.txt
new file mode 100644
index 000000000..d6bc69887
--- /dev/null
+++ b/inc/lang/eo/subscr_digest.txt
@@ -0,0 +1,20 @@
+Saluton!
+
+La paĝo @PAGE@ en la vikio @TITLE@ ŝanĝiĝis.
+Jen sekvas la ŝanĝoj:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Malnova versio: @OLDPAGE@
+Nova versio: @NEWPAGE@
+
+Por nuligi la paĝinformojn, ensalutu la vikion ĉe
+@DOKUWIKIURL@, poste iru al
+@SUBSCRIBE@
+kaj malabonu la paĝajn kaj/aŭ nomspacajn ŝanĝojn.
+
+--
+Tiu retpoŝtaĵo kreiĝis de DokuWiki ĉe
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/eo/subscr_form.txt b/inc/lang/eo/subscr_form.txt
new file mode 100644
index 000000000..259b21045
--- /dev/null
+++ b/inc/lang/eo/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Abona administrado ======
+
+Tiu paĝo lasas vin administri viajn abonojn por la aktualaj paĝo kaj nomspaco. \ No newline at end of file
diff --git a/inc/lang/eo/subscr_list.txt b/inc/lang/eo/subscr_list.txt
new file mode 100644
index 000000000..175e3f3d2
--- /dev/null
+++ b/inc/lang/eo/subscr_list.txt
@@ -0,0 +1,17 @@
+Saluton!
+
+Paĝoj en la nomspaco @PAGE@ en la vikio @TITLE@ ŝanĝiĝis.
+Jen sekvas la ŝanĝitaj paĝoj:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Por nuligi la paĝinformojn, ensalutu la vikion ĉe
+@DOKUWIKIURL@, poste iru al
+@SUBSCRIBE@
+kaj malabonu la paĝajn kaj/aŭ nomspacajn ŝanĝojn.
+
+--
+Tiu retpoŝtaĵo kreiĝis de DokuWiki ĉe
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/eo/subscr_single.txt b/inc/lang/eo/subscr_single.txt
new file mode 100644
index 000000000..d51c5ca15
--- /dev/null
+++ b/inc/lang/eo/subscr_single.txt
@@ -0,0 +1,23 @@
+Saluton!
+
+La paĝo @PAGE@ en la vikio @TITLE@ ŝanĝiĝis.
+Jen sekvas la ŝanĝoj:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Dato: @DATE@
+Uzanto: @USER@
+Modifa resumo: @SUMMARY@
+Malnova versio: @OLDPAGE@
+Nova versio: @NEWPAGE@
+
+Por nuligi la paĝinformojn, ensalutu la vikion ĉe
+@DOKUWIKIURL@, poste iru al
+@NEWPAGE@
+kaj malabonu la paĝajn kaj/aŭ nomspacajn ŝanĝojn.
+
+--
+Tiu retpoŝtaĵo kreiĝis de DokuWiki ĉe
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/eo/updateprofile.txt b/inc/lang/eo/updateprofile.txt
new file mode 100644
index 000000000..a3de0c840
--- /dev/null
+++ b/inc/lang/eo/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Ĝisdatigi vian profilon ======
+
+Vi nur bezonas kompletigi tiujn kampojn, kiujn vi deziras ŝanĝi. Vi ne povas ŝanĝi vian uzantonomon. \ No newline at end of file
diff --git a/inc/lang/eo/uploadmail.txt b/inc/lang/eo/uploadmail.txt
new file mode 100644
index 000000000..e7c327a60
--- /dev/null
+++ b/inc/lang/eo/uploadmail.txt
@@ -0,0 +1,14 @@
+Dosiero estis alŝutita al via DokuVikio. Jen detaloj:
+
+Dosiero: @MEDIA@
+Dato: @DATE@
+Foliumilo: @BROWSER@
+IP-Adreso: @IPADDRESS@
+Ret-nodo: @HOSTNAME@
+Grandeco: @SIZE@
+Dosier-tipo: @MIME@
+Uzanto: @USER@
+
+--
+Tiu ĉi mesaĝo estis kreita de DokuWiki ĉe
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/es/admin.txt b/inc/lang/es/admin.txt
new file mode 100644
index 000000000..320b1c5be
--- /dev/null
+++ b/inc/lang/es/admin.txt
@@ -0,0 +1,3 @@
+====== Administración ======
+
+Abajo puedes encontrar una lista de las tareas de administración disponibles en Dokuwiki.
diff --git a/inc/lang/es/adminplugins.txt b/inc/lang/es/adminplugins.txt
new file mode 100644
index 000000000..8e1b0f813
--- /dev/null
+++ b/inc/lang/es/adminplugins.txt
@@ -0,0 +1 @@
+===== Plugins Adicionales ===== \ No newline at end of file
diff --git a/inc/lang/es/backlinks.txt b/inc/lang/es/backlinks.txt
new file mode 100644
index 000000000..4de93ef34
--- /dev/null
+++ b/inc/lang/es/backlinks.txt
@@ -0,0 +1,4 @@
+====== Referencias ======
+
+Esta es una lista de páginas que parecen hacer referencia a la página actual.
+
diff --git a/inc/lang/es/conflict.txt b/inc/lang/es/conflict.txt
new file mode 100644
index 000000000..265ac1ee6
--- /dev/null
+++ b/inc/lang/es/conflict.txt
@@ -0,0 +1,5 @@
+====== Existe una versión más reciente ======
+
+Existe una versión más reciente del documento que has editado. Esto sucede cuando otro usuario ha modificado el documento mientras lo estabas editando.
+
+Examina las diferencias mostradas abajo a fondo, y decide entonces cual conservar. Si eliges ''Guardar'', tu versión será guardada. Si eliges ''Cancelar'' se guardará la actual versión. \ No newline at end of file
diff --git a/inc/lang/es/denied.txt b/inc/lang/es/denied.txt
new file mode 100644
index 000000000..d7b37404b
--- /dev/null
+++ b/inc/lang/es/denied.txt
@@ -0,0 +1,3 @@
+====== Permiso Denegado ======
+
+Lo siento, no tienes suficientes permisos para continuar. ¿Quizás has olvidado identificarte? \ No newline at end of file
diff --git a/inc/lang/es/diff.txt b/inc/lang/es/diff.txt
new file mode 100644
index 000000000..e0e9e08ab
--- /dev/null
+++ b/inc/lang/es/diff.txt
@@ -0,0 +1,4 @@
+====== Diferencias ======
+
+Muestra las diferencias entre dos versiones de la página.
+
diff --git a/inc/lang/es/draft.txt b/inc/lang/es/draft.txt
new file mode 100644
index 000000000..054d618b3
--- /dev/null
+++ b/inc/lang/es/draft.txt
@@ -0,0 +1,6 @@
+====== Fichero borrador encontrado ======
+
+Su última sesión de edición en esta página no se completó correctamente. DokuWiki guardó automáticamente un borrador mientras usted trabajaba; puede utilizar el borrador para continuar editándolo. Abajo se ven los datos que fueron guardados en su última sesión.
+
+Por favor decida si desea //recuperar// su sesión perdida, //eliminar// el borrador guardado automáticamente o //cancelar// el proceso de edición.
+
diff --git a/inc/lang/es/edit.txt b/inc/lang/es/edit.txt
new file mode 100644
index 000000000..55c3c1dc5
--- /dev/null
+++ b/inc/lang/es/edit.txt
@@ -0,0 +1,2 @@
+Edita la página y pulsa ''Guardar''. Mira [[wiki:syntax]] para sintaxis Wiki. Por favor edita la página solo si puedes **mejorarla**. Si quieres testear algunas cosas aprende a dar tus primeros pasos en el [[playground:playground]].
+
diff --git a/inc/lang/es/editrev.txt b/inc/lang/es/editrev.txt
new file mode 100644
index 000000000..4b587b7ce
--- /dev/null
+++ b/inc/lang/es/editrev.txt
@@ -0,0 +1,2 @@
+**Has cargado una revisión vieja del documento!** Si la guardas crearás una versión nueva con estos datos.
+---- \ No newline at end of file
diff --git a/inc/lang/es/index.txt b/inc/lang/es/index.txt
new file mode 100644
index 000000000..148e5f406
--- /dev/null
+++ b/inc/lang/es/index.txt
@@ -0,0 +1,4 @@
+====== Índice ======
+
+Este es un índice de todas las páginas disponibles ordenado por [[doku>namespaces|espacios de nombres]].
+
diff --git a/inc/lang/es/install.html b/inc/lang/es/install.html
new file mode 100644
index 000000000..c16d4c47c
--- /dev/null
+++ b/inc/lang/es/install.html
@@ -0,0 +1,14 @@
+<p>Esta página lo asiste en la primera vez que instala y configura
+<a href="http://dokuwiki.org">Dokuwiki</a>.
+Más información sobre este instalador está disponible en la
+<a href="http://dokuwiki.org/installer">página de documentación</a>.
+</p>
+
+<p>DokuWiki usa ficheros comunes para el almacenamiento de las páginas del wiki y otra información asociada a esas páginas (por ejemplo, imágenes, índices de archivos, revisiones viejas, etc). Para funcionar correctamente DokuWiki <strong>debe</strong> tener permisos de escritura en los directorios que contienen esos ficheros. Este instalador no es capaz de establecer permisos en directorios. Normalmente eso debe ser hecho a través de una consola de comandos o si usted usa servicios de hosting a través de FTP o el panel de control brindado por su hosting (e.g. cPanel).</p>
+
+<p>Este instalador configurará una <acronym title="lista de control de acceso">ACL</acronym>, que a su vez permite el acceso al administrador y acceso a los menúes de administración para instalación
+de plugins, administración de usuarios, administración de permisos para las páginas wiki y modificación de la configuración. A pesar que no es necesario para que DokuWiki funcione, hará que sea más fácil la administración.</p>
+
+<p>Usuarios experimentados o usuarios con requerimientos especiales deben usar estos enlaces para detalles concernientes a
+<a href="http://dokuwiki.org/install">instrucciones de instalación</a>
+y <a href="http://dokuwiki.org/config">configuración</a>.</p>
diff --git a/inc/lang/es/lang.php b/inc/lang/es/lang.php
new file mode 100644
index 000000000..28ff17a16
--- /dev/null
+++ b/inc/lang/es/lang.php
@@ -0,0 +1,332 @@
+<?php
+/**
+ * spanish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Zigor Astarbe <zigor@astarbe.com>
+ * @author Adrián Ariza <adrian_ariza.ciudad.com.ar>
+ * @author Gabiel Molina <gabriel191@gmail.com>
+ * @author Paco Avila <monkiki@gmail.com>
+ * @author Bernardo Arlandis Mañó <bernardo@tsolucio.com>
+ * @author Miguel Pagano <miguel.pagano@gmail.com>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author Jordan Mero <hack.jord@gmail.com>
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Editar esta página';
+$lang['btn_source'] = 'Ver fuente';
+$lang['btn_show'] = 'Ver página';
+$lang['btn_create'] = 'Crear esta página';
+$lang['btn_search'] = 'Buscar';
+$lang['btn_save'] = 'Guardar';
+$lang['btn_preview'] = 'Previsualización';
+$lang['btn_top'] = 'Ir hasta arriba';
+$lang['btn_newer'] = '<< más reciente';
+$lang['btn_older'] = 'menos reciente >>';
+$lang['btn_revs'] = 'Revisiones antiguas';
+$lang['btn_recent'] = 'Cambios recientes';
+$lang['btn_upload'] = 'Cargar';
+$lang['btn_cancel'] = 'Cancelar';
+$lang['btn_index'] = 'Índice';
+$lang['btn_secedit'] = 'Editar';
+$lang['btn_login'] = 'Conectarse';
+$lang['btn_logout'] = 'Desconectarse';
+$lang['btn_admin'] = 'Administrar';
+$lang['btn_update'] = 'Actualizar';
+$lang['btn_delete'] = 'Borrar';
+$lang['btn_back'] = 'Atrás';
+$lang['btn_backlink'] = 'Enlaces anteriores';
+$lang['btn_backtomedia'] = 'Volver a la selección de archivos multimedia';
+$lang['btn_subscribe'] = 'Suscribirse a cambios de la página';
+$lang['btn_profile'] = 'Actualizar perfil';
+$lang['btn_reset'] = 'Restablecer';
+$lang['btn_resendpwd'] = 'Enviar nueva contraseña';
+$lang['btn_draft'] = 'Editar borrador';
+$lang['btn_recover'] = 'Recuperar borrador';
+$lang['btn_draftdel'] = 'Eliminar borrador';
+$lang['btn_revert'] = 'Restaurar';
+$lang['btn_register'] = 'Registrarse';
+$lang['btn_apply'] = 'Aplicar';
+$lang['btn_media'] = 'Gestor de ficheros';
+$lang['loggedinas'] = 'Conectado como ';
+$lang['user'] = 'Usuario';
+$lang['pass'] = 'Contraseña';
+$lang['newpass'] = 'Nueva contraseña';
+$lang['oldpass'] = 'Confirma tu contraseña actual';
+$lang['passchk'] = 'otra vez';
+$lang['remember'] = 'Recordarme';
+$lang['fullname'] = 'Nombre real';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'Perfil del usuario';
+$lang['badlogin'] = 'Lo siento, el usuario o la contraseña es incorrecto.';
+$lang['minoredit'] = 'Cambios menores';
+$lang['draftdate'] = 'Borrador guardado automáticamente:';
+$lang['nosecedit'] = 'La página ha cambiado en el lapso, la información de sección estaba anticuada, en su lugar se cargó la página completa.';
+$lang['regmissing'] = 'Lo siento, tienes que completar todos los campos.';
+$lang['reguexists'] = 'Lo siento, ya existe un usuario con este nombre.';
+$lang['regsuccess'] = 'El usuario ha sido creado y la contraseña se ha enviado por correo.';
+$lang['regsuccess2'] = 'El usuario ha sido creado.';
+$lang['regmailfail'] = 'Parece que ha habido un error al enviar el correo con la contraseña. ¡Por favor, contacta al administrador!';
+$lang['regbadmail'] = 'La dirección de correo no parece válida. Si piensas que esto es un error, contacta al administrador';
+$lang['regbadpass'] = 'Las dos contraseñas no son iguales, por favor inténtalo de nuevo.';
+$lang['regpwmail'] = 'Tu contraseña de DokuWiki';
+$lang['reghere'] = '¿No tienes una cuenta todavía? Consigue una';
+$lang['profna'] = 'Este wiki no permite la modificación del perfil';
+$lang['profnochange'] = 'Sin cambios, nada que hacer.';
+$lang['profnoempty'] = 'No se permite que el nombre o la dirección de correo electrónico estén vacíos.';
+$lang['profchanged'] = 'Se actualizó correctamente el perfil del usuario.';
+$lang['pwdforget'] = '¿Has olvidado tu contraseña? Consigue una nueva';
+$lang['resendna'] = 'Este wiki no brinda la posibilidad de reenvío de contraseña.';
+$lang['resendpwd'] = 'Enviar una nueva contraseña para';
+$lang['resendpwdmissing'] = 'Lo siento, debes completar todos los campos.';
+$lang['resendpwdnouser'] = 'Lo siento, no se encuentra este usuario en nuestra base de datos.';
+$lang['resendpwdbadauth'] = 'Lo siento, este código de autenticación no es válido. Asegúrate de haber usado el enlace de confirmación entero.';
+$lang['resendpwdconfirm'] = 'Un enlace para confirmación ha sido enviado por correo electrónico.';
+$lang['resendpwdsuccess'] = 'Tu nueva contraseña ha sido enviada por correo electrónico.';
+$lang['license'] = 'Excepto donde se indique lo contrario, el contenido de esta wiki se autoriza bajo la siguiente licencia:';
+$lang['licenseok'] = 'Nota: Al editar esta página, estás de acuerdo en autorizar su contenido bajo la siguiente licencia:';
+$lang['searchmedia'] = 'Buscar archivo:';
+$lang['searchmedia_in'] = 'Buscar en %s';
+$lang['txt_upload'] = 'Selecciona el archivo a subir';
+$lang['txt_filename'] = 'Subir como (opcional)';
+$lang['txt_overwrt'] = 'Sobreescribir archivo existente';
+$lang['lockedby'] = 'Actualmente bloqueado por';
+$lang['lockexpire'] = 'El bloqueo expira en';
+$lang['js']['willexpire'] = 'El bloqueo para la edición de esta página expira en un minuto.\nPAra prevenir conflictos uso el botón Previsualizar para restaurar el contador de bloqueo.';
+$lang['js']['notsavedyet'] = 'Los cambios que no se han guardado se perderán.
+¿Realmente quieres continuar?';
+$lang['js']['searchmedia'] = 'Buscar archivos';
+$lang['js']['keepopen'] = 'Mantener la ventana abierta luego de seleccionar';
+$lang['js']['hidedetails'] = 'Ocultar detalles';
+$lang['js']['mediatitle'] = 'Configuración del vínculo';
+$lang['js']['mediadisplay'] = 'Tipo de vínculo';
+$lang['js']['mediaalign'] = 'Alineación';
+$lang['js']['mediasize'] = 'Tamaño de la imagen';
+$lang['js']['mediatarget'] = 'Destino del vínculo';
+$lang['js']['mediaclose'] = 'Cerrar';
+$lang['js']['mediainsert'] = 'Insertar';
+$lang['js']['mediadisplayimg'] = 'Mostrar la imagen.';
+$lang['js']['mediadisplaylnk'] = 'Mostrar solo el vínculo.';
+$lang['js']['mediasmall'] = 'Versión en tamaño pequeño';
+$lang['js']['mediamedium'] = 'Versión en tamaño medio';
+$lang['js']['medialarge'] = 'Versión en tamaño grande';
+$lang['js']['mediaoriginal'] = 'Versión original';
+$lang['js']['medialnk'] = 'Vínculo a la pagina de descripción';
+$lang['js']['mediadirect'] = 'Vínculo al original';
+$lang['js']['medianolnk'] = 'Sin vínculo';
+$lang['js']['medianolink'] = 'No vincular la imagen';
+$lang['js']['medialeft'] = 'Alinear imagen a la izquierda';
+$lang['js']['mediaright'] = 'Alinear imagen a la derecha.';
+$lang['js']['mediacenter'] = 'Alinear imagen en el centro.';
+$lang['js']['medianoalign'] = 'No use alineación.';
+$lang['js']['nosmblinks'] = 'El enlace a recursos compartidos de Windows sólo funciona en Microsoft Internet Explorer.
+Lo que sí puedes hacer es copiar y pegar el enlace.';
+$lang['js']['linkwiz'] = 'Asistente de enlaces';
+$lang['js']['linkto'] = 'Enlazar a:';
+$lang['js']['del_confirm'] = '¿Quieres realmente borrar lo seleccionado?';
+$lang['js']['restore_confirm'] = '¿Estás seguro de querer restaurar esta versión?';
+$lang['js']['media_diff'] = 'Ver diferencias:';
+$lang['js']['media_diff_both'] = 'Lado por lado';
+$lang['js']['media_diff_opacity'] = 'A través de Shine';
+$lang['js']['media_diff_portions'] = 'Pasar';
+$lang['js']['media_select'] = 'Seleccionar ficheros';
+$lang['js']['media_upload_btn'] = 'Cargar';
+$lang['js']['media_done_btn'] = 'Hecho';
+$lang['js']['media_drop'] = 'Arrastra los ficheros aquí para cargar';
+$lang['js']['media_cancel'] = 'Eliminar';
+$lang['js']['media_overwrt'] = 'Sobreescribir ficheros exitentes';
+$lang['rssfailed'] = 'Se ha producido un error mientras se leían los datos de este feed: ';
+$lang['nothingfound'] = 'No se ha encontrado nada.';
+$lang['mediaselect'] = 'Archivos Multimedia';
+$lang['fileupload'] = 'Subida de archivos multimedia';
+$lang['uploadsucc'] = 'El archivo se ha subido satisfactoriamente';
+$lang['uploadfail'] = 'La subida del fichero ha fallado. ¿Permisos equivocados?';
+$lang['uploadwrong'] = 'Subida de fichero denegada. ¡Los ficheros con esta extensión están prohibidos!';
+$lang['uploadexist'] = 'El fichero ya existe. No se ha hecho nada.';
+$lang['uploadbadcontent'] = 'El contenido de la subida no coincide con la extensión de fichero %s';
+$lang['uploadspam'] = 'La subida ha sido bloqueada por una lista negra de spam';
+$lang['uploadxss'] = 'La subida ha sido bloqueada por contenido posiblemente malicioso';
+$lang['uploadsize'] = 'El fichero subido es demasiado grande. (max. %s)';
+$lang['deletesucc'] = 'El fichero "%s" ha sido borrado.';
+$lang['deletefail'] = '"%s" no pudo ser borrado; verifique los permisos.';
+$lang['mediainuse'] = 'El fichero "%s" no ha sido borrado, aún está en uso.';
+$lang['namespaces'] = 'Espacios de nombres';
+$lang['mediafiles'] = 'Ficheros disponibles en';
+$lang['accessdenied'] = 'No tiene permisos para ver esta página.';
+$lang['mediausage'] = 'Use la siguiente sintaxis para hacer referencia a este fichero:';
+$lang['mediaview'] = 'Ver el fichero original';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Subir aquí un fichero al espacio de nombres actual. Para crear sub-espacios de nombres, antepóngalos al nombre de fichero separándolos por dos puntos (:) en "Subir como".';
+$lang['mediaextchange'] = 'Extensión del fichero cambiada de .%s a .%s!';
+$lang['reference'] = 'Referencias para';
+$lang['ref_inuse'] = 'El fichero no puede ser borrado, porque todavía se está usando en las siguientes páginas:';
+$lang['ref_hidden'] = 'Algunas referencias están en páginas sobre las que no tienes permiso de lectura';
+$lang['hits'] = 'Entradas';
+$lang['quickhits'] = 'Páginas que coinciden';
+$lang['toc'] = 'Tabla de Contenidos';
+$lang['current'] = 'actual';
+$lang['yours'] = 'Tu versión';
+$lang['diff'] = 'Muestra diferencias a la versión actual';
+$lang['diff2'] = 'Muestra las diferencias entre las revisiones seleccionadas';
+$lang['difflink'] = 'Enlace a la vista de comparación';
+$lang['diff_type'] = 'Ver diferencias';
+$lang['diff_inline'] = 'En línea';
+$lang['diff_side'] = 'Lado a lado';
+$lang['line'] = 'Línea';
+$lang['breadcrumb'] = 'Traza';
+$lang['youarehere'] = 'Estás aquí';
+$lang['lastmod'] = 'Última modificación';
+$lang['by'] = 'por';
+$lang['deleted'] = 'borrado';
+$lang['created'] = 'creado';
+$lang['restored'] = 'se ha restaurado la vieja versión';
+$lang['external_edit'] = 'editor externo';
+$lang['summary'] = 'Resumen de la edición';
+$lang['noflash'] = 'Para mostrar este contenido es necesario el <a href="http://www.adobe.com/products/flashplayer/">Plugin Adobe Flash</a>.';
+$lang['download'] = 'Descargar trozo de código fuente';
+$lang['mail_newpage'] = 'página añadida:';
+$lang['mail_changed'] = 'página cambiada:';
+$lang['mail_subscribe_list'] = 'páginas cambiadas en el espacio de nombre:';
+$lang['mail_new_user'] = 'nuevo usuario:';
+$lang['mail_upload'] = 'archivo subido:';
+$lang['changes_type'] = 'Ver cambios de';
+$lang['pages_changes'] = 'Páginas';
+$lang['media_changes'] = 'Archivos multimedia';
+$lang['both_changes'] = 'Ambas páginas y archivos multimedia';
+$lang['qb_bold'] = 'Negrita';
+$lang['qb_italic'] = 'Itálica';
+$lang['qb_underl'] = 'Subrayado';
+$lang['qb_code'] = 'Código';
+$lang['qb_strike'] = 'Tachado';
+$lang['qb_h1'] = 'Título 1';
+$lang['qb_h2'] = 'Título 2';
+$lang['qb_h3'] = 'Título 3';
+$lang['qb_h4'] = 'Título 4';
+$lang['qb_h5'] = 'Título 5';
+$lang['qb_h'] = 'Título';
+$lang['qb_hs'] = 'Selecciona el título';
+$lang['qb_hplus'] = 'Título alto';
+$lang['qb_hminus'] = 'Título bajo';
+$lang['qb_hequal'] = 'Título del mismo nivel';
+$lang['qb_link'] = 'Enlace interno';
+$lang['qb_extlink'] = 'Enlace externo';
+$lang['qb_hr'] = 'Línea horizontal';
+$lang['qb_ol'] = 'Ítem de lista ordenada';
+$lang['qb_ul'] = 'Ítem de lista desordenada';
+$lang['qb_media'] = 'Añadir Imágenes u otros ficheros';
+$lang['qb_sig'] = 'Insertar firma';
+$lang['qb_smileys'] = 'Sonrisas';
+$lang['qb_chars'] = 'Caracteres especiales';
+$lang['upperns'] = 'Saltar al espacio de nombres superior';
+$lang['admin_register'] = 'Añadir nuevo usuario';
+$lang['metaedit'] = 'Editar metadatos';
+$lang['metasaveerr'] = 'La escritura de los metadatos ha fallado';
+$lang['metasaveok'] = 'Los metadatos han sido guardados';
+$lang['img_backto'] = 'Volver a';
+$lang['img_title'] = 'Título';
+$lang['img_caption'] = 'Epígrafe';
+$lang['img_date'] = 'Fecha';
+$lang['img_fname'] = 'Nombre de fichero';
+$lang['img_fsize'] = 'Tamaño';
+$lang['img_artist'] = 'Fotógrafo';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Formato';
+$lang['img_camera'] = 'Cámara';
+$lang['img_keywords'] = 'Palabras claves';
+$lang['img_width'] = 'Ancho';
+$lang['img_height'] = 'Alto';
+$lang['img_manager'] = 'Ver en el Administrador de medios';
+$lang['subscr_subscribe_success'] = 'Se agregó %s a las listas de suscripción para %s';
+$lang['subscr_subscribe_error'] = 'Error al agregar %s a las listas de suscripción para %s';
+$lang['subscr_subscribe_noaddress'] = 'No hay dirección asociada con tu registro, no se puede agregarte a la lista de suscripción';
+$lang['subscr_unsubscribe_success'] = 'Removido %s de la lista de suscripción para %s';
+$lang['subscr_unsubscribe_error'] = 'Error al remover %s de la lista de suscripción para %s';
+$lang['subscr_already_subscribed'] = '%s ya está suscrito a %s';
+$lang['subscr_not_subscribed'] = '%s no está suscrito a %s';
+$lang['subscr_m_not_subscribed'] = 'Actualmente no te encuentras suscrito a esta página o espacio de nombres';
+$lang['subscr_m_new_header'] = 'Agregar suscripción';
+$lang['subscr_m_current_header'] = 'Suscripciones actuales';
+$lang['subscr_m_unsubscribe'] = 'Darse de baja';
+$lang['subscr_m_subscribe'] = 'Suscribirse';
+$lang['subscr_m_receive'] = 'Recibir';
+$lang['subscr_style_every'] = 'enviar correo en cada cambio';
+$lang['subscr_style_digest'] = 'recopilar correo de cambios por cada página';
+$lang['subscr_style_list'] = 'lista de páginas con cambios desde el último correo';
+$lang['authmodfailed'] = 'Está mal configurada la autenticación de usuarios. Por favor, avisa al administrador del wiki.';
+$lang['authtempfail'] = 'La autenticación de usuarios no está disponible temporalmente. Si esta situación persiste, por favor avisa al administrador del wiki.';
+$lang['i_chooselang'] = 'Elija su idioma';
+$lang['i_installer'] = 'Instalador de DokuWiki';
+$lang['i_wikiname'] = 'Nombre del wiki';
+$lang['i_enableacl'] = 'Habilitar ACL (recomendado) (ACL: lista de control de acceso)';
+$lang['i_superuser'] = 'Super-usuario';
+$lang['i_problems'] = 'El instalador encontró algunos problemas, se muestran abajo. No se puede continuar la instalación hasta que usted no los corrija.';
+$lang['i_modified'] = 'Por razones de seguridad este script sólo funcionará con una instalación nueva y no modificada de Dokuwiki. Usted debe extraer nuevamente los ficheros del paquete bajado, o bien consultar las <a href="http://dokuwiki.org/install">instrucciones de instalación de Dokuwiki</a> completas.';
+$lang['i_funcna'] = 'La función de PHP <code>%s</code> no está disponible. ¿Tal vez su proveedor de hosting la ha deshabilitado por alguna razón?';
+$lang['i_phpver'] = 'Su versión de PHP <code>%s</code> es menor que la necesaria <code>%s</code>. Es necesario que actualice su instalación de PHP.';
+$lang['i_permfail'] = 'DokuWili no puede escribir <code>%s</code>. ¡Es necesario establecer correctamente los permisos de este directorio!';
+$lang['i_confexists'] = '<code>%s</code> ya existe';
+$lang['i_writeerr'] = 'Imposible crear <code>%s</code>. Se necesita que usted controle los permisos del fichero/directorio y que cree el fichero manualmente.';
+$lang['i_badhash'] = 'dokuwiki.php no reconocido o modificado (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - valor ilegal o vacío';
+$lang['i_success'] = 'La configuración ha concluido correctamente. Ahora puede eliminar el archivo install.php. Visite <a href="doku.php">su nuevo DokuWiki</a>.';
+$lang['i_failure'] = 'Han ocurrido algunos errores durante la escritura de los ficheros de configuración. Puede ser que necesite corregirlos manualmente antes de poder usar <a href="doku.php">su nuevo DokuWiki</a>.';
+$lang['i_policy'] = 'Política de ACL inicial';
+$lang['i_pol0'] = 'Wiki abierto (leer, escribir y subir archivos para todos)';
+$lang['i_pol1'] = 'Wiki público (leer para todos, escribir y subir archivos para usuarios registrados únicamente)';
+$lang['i_pol2'] = 'Wiki cerrado (leer, escribir y subir archivos para usuarios registrados únicamente)';
+$lang['i_retry'] = 'Reintentar';
+$lang['i_license'] = 'Por favor escoja una licencia bajo la que publicar su contenido:';
+$lang['recent_global'] = 'Actualmente estás viendo los cambios dentro del namespace <b>%s</b>. También puedes <a href="%s">ver los cambios recientes en el wiki completo</a>.';
+$lang['years'] = '%d años atrás';
+$lang['months'] = '%d meses atrás';
+$lang['weeks'] = '%d semanas atrás';
+$lang['days'] = '%d días atrás';
+$lang['hours'] = '%d horas atrás';
+$lang['minutes'] = '%d minutos atrás';
+$lang['seconds'] = '%d segundos atrás';
+$lang['wordblock'] = 'Sus cambios no se han guardado porque contienen textos bloqueados (spam).';
+$lang['media_uploadtab'] = 'Cargar';
+$lang['media_searchtab'] = 'Buscar';
+$lang['media_file'] = 'Fichero';
+$lang['media_viewtab'] = 'Ver';
+$lang['media_edittab'] = 'Editar';
+$lang['media_historytab'] = 'Historial';
+$lang['media_list_thumbs'] = 'Miniaturas';
+$lang['media_list_rows'] = 'Celdas';
+$lang['media_sort_name'] = 'Nombre';
+$lang['media_sort_date'] = 'Fecha';
+$lang['media_namespaces'] = 'Escoge "espacio de nombre"';
+$lang['media_files'] = 'Ficheros en %s';
+$lang['media_upload'] = 'Cargar a %s';
+$lang['media_search'] = 'Buscar en %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s en %s';
+$lang['media_edit'] = 'Editar %s';
+$lang['media_history'] = 'Historial de %s';
+$lang['media_meta_edited'] = 'Metadatos editados';
+$lang['media_perm_read'] = 'Disculpa, no tienes los permisos necesarios para leer ficheros.';
+$lang['media_perm_upload'] = 'Disculpa, no tienes los permisos necesarios para cargar ficheros.';
+$lang['media_update'] = 'Actualizar nueva versión';
+$lang['media_restore'] = 'Restaurar esta versión';
+$lang['plugin_install_err'] = 'Plugin instalado incorrectamente. Renombra el directorio de plugins \'%s\' to \'%s\'.';
diff --git a/inc/lang/es/locked.txt b/inc/lang/es/locked.txt
new file mode 100644
index 000000000..e151bf7e9
--- /dev/null
+++ b/inc/lang/es/locked.txt
@@ -0,0 +1,3 @@
+====== Página bloqueada ======
+
+Esta página está actualmente bloqueada porque la está editando otro usuario. Tienes que esperar a que termine de editarla o el bloqueo expire. \ No newline at end of file
diff --git a/inc/lang/es/login.txt b/inc/lang/es/login.txt
new file mode 100644
index 000000000..a8d9be7a9
--- /dev/null
+++ b/inc/lang/es/login.txt
@@ -0,0 +1,3 @@
+====== Login ======
+
+¡Actualmente no estás identificado! Introduce abajo tus datos de identificación para abrir una sesión. Necesitas tener las cookies activadas para identificarte.
diff --git a/inc/lang/es/mailtext.txt b/inc/lang/es/mailtext.txt
new file mode 100644
index 000000000..893ec1cb9
--- /dev/null
+++ b/inc/lang/es/mailtext.txt
@@ -0,0 +1,17 @@
+Se ha cambiado o añadido una página en tu DokuWiki. Aquí están los detalles:
+
+Fecha : @DATE@
+Navegador : @BROWSER@
+Dirección-IP : @IPADDRESS@
+Nombre de Host : @HOSTNAME@
+Revisión Vieja: @OLDPAGE@
+Revisión Nueva : @NEWPAGE@
+Resumen de la edición: @SUMMARY@
+Usuario : @USER@
+
+@DIFF@
+
+
+--
+Este correo ha sido generado por DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/es/newpage.txt b/inc/lang/es/newpage.txt
new file mode 100644
index 000000000..d119ca29d
--- /dev/null
+++ b/inc/lang/es/newpage.txt
@@ -0,0 +1,3 @@
+====== Este tema no existe todavía ======
+
+Has seguido un enlace a un tema que no existe todavía. Puedes crearlo usando el botón ''Crea esta página''.
diff --git a/inc/lang/es/norev.txt b/inc/lang/es/norev.txt
new file mode 100644
index 000000000..42ee6b5c2
--- /dev/null
+++ b/inc/lang/es/norev.txt
@@ -0,0 +1,4 @@
+====== No existe esta revision ======
+
+La revisión especificada no existe. Usa el botón ''Revisiones antiguas'' para una lista de revisiones antiguas de este documento.
+
diff --git a/inc/lang/es/password.txt b/inc/lang/es/password.txt
new file mode 100644
index 000000000..1312ed0a6
--- /dev/null
+++ b/inc/lang/es/password.txt
@@ -0,0 +1,9 @@
+Hola @FULLNAME@!
+
+Estos son los datos de usuario para @TITLE@ en @DOKUWIKIURL@
+
+Usuario : @LOGIN@
+Contraseña : @PASSWORD@
+
+--
+Este correo ha sido generado por DokuWiki en @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/es/preview.txt b/inc/lang/es/preview.txt
new file mode 100644
index 000000000..b4d5a2ed1
--- /dev/null
+++ b/inc/lang/es/preview.txt
@@ -0,0 +1,4 @@
+====== Previsualización ======
+
+Esto es una previsualización de cómo aparecerá tu texto. Recuerda: **no está guardado** todavía!
+
diff --git a/inc/lang/es/pwconfirm.txt b/inc/lang/es/pwconfirm.txt
new file mode 100644
index 000000000..c3dad116e
--- /dev/null
+++ b/inc/lang/es/pwconfirm.txt
@@ -0,0 +1,16 @@
+Hola @FULLNAME@!
+
+Alguien solicitó una nueva contraseña para su nombre de
+usuario @TITLE@ en @DOKUWIKIURL@
+
+Si usted no solicitó una nueva contraseña, simplemente ignore este email.
+
+Para confirmar que la solicitud fue realizada realmente por usted,
+por favor use el siguiente enlace.
+
+@CONFIRM@
+
+
+--
+Este mail ha sido generado por DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/es/read.txt b/inc/lang/es/read.txt
new file mode 100644
index 000000000..461b745fb
--- /dev/null
+++ b/inc/lang/es/read.txt
@@ -0,0 +1 @@
+Esta página es de solo lectura. Puedes ver la fuente pero no puedes cambiarla. Pregunta a tu administrador si crees que esto es incorrecto.
diff --git a/inc/lang/es/recent.txt b/inc/lang/es/recent.txt
new file mode 100644
index 000000000..432def26f
--- /dev/null
+++ b/inc/lang/es/recent.txt
@@ -0,0 +1,5 @@
+====== Cambios Recientes ======
+
+Las siguientes páginas han sido modificadas recientemente.
+
+
diff --git a/inc/lang/es/register.txt b/inc/lang/es/register.txt
new file mode 100644
index 000000000..98248269d
--- /dev/null
+++ b/inc/lang/es/register.txt
@@ -0,0 +1,3 @@
+====== Registro como nuevo usuario ======
+
+Completa toda la información del formulario para crear un nuevo usuario en este wiki. Asegúrate que escribes una **dirección de e-mail válida** puesto que allí se enviará tu contraseña. El nombre de usuario ha de ser un nombre válido según [[doku>pagename|pagename]].
diff --git a/inc/lang/es/registermail.txt b/inc/lang/es/registermail.txt
new file mode 100644
index 000000000..e773e3200
--- /dev/null
+++ b/inc/lang/es/registermail.txt
@@ -0,0 +1,14 @@
+Un nuevo usuario ha sido registrado. Aquí están los detalles:
+
+Usuario : @NEWUSER@
+Nombre completo : @NEWNAME@
+E-Mail : @NEWEMAIL@
+
+Fecha : @DATE@
+Navegador : @BROWSER@
+Dirección-IP : @IPADDRESS@
+Nombre del host : @HOSTNAME@
+
+--
+Este mail ha sido generado por DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/es/resendpwd.txt b/inc/lang/es/resendpwd.txt
new file mode 100644
index 000000000..1d74e79bb
--- /dev/null
+++ b/inc/lang/es/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Enviar nueva contraseña ======
+
+Completa la información requerida abajo para obtener una nueva contraseña para tu cuenta de usuario en este wiki. La nueva contraseña te será enviada a la dirección de mail que está registrada.
diff --git a/inc/lang/es/revisions.txt b/inc/lang/es/revisions.txt
new file mode 100644
index 000000000..b093e857f
--- /dev/null
+++ b/inc/lang/es/revisions.txt
@@ -0,0 +1,4 @@
+====== Revisiones Antiguas ======
+
+Estas son revisiones más antiguas del documento actual. Para volver a una revisión antigua selecciónala de abajo, pulsa ''Edita esta página'' y guárdala.
+
diff --git a/inc/lang/es/searchpage.txt b/inc/lang/es/searchpage.txt
new file mode 100644
index 000000000..47a1a90dd
--- /dev/null
+++ b/inc/lang/es/searchpage.txt
@@ -0,0 +1,5 @@
+====== Búsqueda ======
+
+Puedes encontrar los resultados de tu búsqueda abajo. Si no has encontrado lo que buscabas, puedes crear una nueva página con tu consulta utilizando el botón ''Crea esta página''.
+
+===== Resultados ===== \ No newline at end of file
diff --git a/inc/lang/es/showrev.txt b/inc/lang/es/showrev.txt
new file mode 100644
index 000000000..c84bbc01d
--- /dev/null
+++ b/inc/lang/es/showrev.txt
@@ -0,0 +1,2 @@
+**¡Esta es una revisión vieja del documento!**
+----
diff --git a/inc/lang/es/stopwords.txt b/inc/lang/es/stopwords.txt
new file mode 100644
index 000000000..256908925
--- /dev/null
+++ b/inc/lang/es/stopwords.txt
@@ -0,0 +1,171 @@
+# Esta es una lista de palabras que estan ignoradas por el indexador, una palabra por línea
+# Cuando se edita este archivo, asegúrese de usar la línea de terminaciones UNIX (una sola nueva línea)
+# No necesita incluir palabras cortas con 3 caracteres - estas son ignoradas de todos modos
+#Esta lista esta basada en las que encontramos en la siguiente url http://www.ranks.nl/stopwords/
+una
+unas
+unos
+uno
+sobre
+todo
+también
+tras
+otro
+algún
+alguno
+alguna
+algunos
+algunas
+ser
+soy
+eres
+somos
+sois
+estoy
+esta
+estamos
+estais
+estan
+como
+para
+atras
+porque
+por
+qué
+estado
+estaba
+ante
+antes
+siendo
+ambos
+pero
+poder
+puede
+puedo
+podemos
+podeis
+pueden
+fui
+fue
+fuimos
+fueron
+hacer
+hago
+hace
+hacemos
+haceis
+hacen
+cada
+fin
+incluso
+primero
+desde
+conseguir
+consigo
+consigue
+consigues
+conseguimos
+consiguen
+voy
+va
+vamos
+vais
+van
+vaya
+gueno
+tener
+tengo
+tiene
+tenemos
+teneis
+tienen
+las
+los
+aqui
+mio
+tuyo
+ellos
+ellas
+nos
+nosotros
+vosotros
+vosotras
+dentro
+solo
+solamente
+saber
+sabes
+sabe
+sabemos
+sabeis
+saben
+ultimo
+largo
+bastante
+haces
+muchos
+aquellos
+aquellas
+sus
+entonces
+tiempo
+verdad
+verdadero
+verdadera
+cierto
+ciertos
+cierta
+ciertas
+intentar
+intento
+intenta
+intentas
+intentamos
+intentais
+intentan
+dos
+bajo
+arriba
+encima
+usar
+uso
+usas
+usa
+usamos
+usais
+usan
+emplear
+empleo
+empleas
+emplean
+ampleamos
+empleais
+valor
+muy
+era
+eras
+eramos
+eran
+modo
+bien
+cual
+cuando
+donde
+mientras
+quien
+con
+entre
+sin
+trabajo
+trabajar
+trabajas
+trabaja
+trabajamos
+trabajais
+trabajan
+podria
+podrias
+podriamos
+podrian
+podriais
+aquel
diff --git a/inc/lang/es/subscr_digest.txt b/inc/lang/es/subscr_digest.txt
new file mode 100644
index 000000000..df03fcafc
--- /dev/null
+++ b/inc/lang/es/subscr_digest.txt
@@ -0,0 +1,20 @@
+Hola!
+
+La página @PAGE@ en @TITLE@ wiki ha cambiado.
+Estos son los cambios:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Revisión Anterior: @OLDPAGE@
+Revisión Nueva: @NEWPAGE@
+
+Para cancelar la página de notificaciones, entra a la wiki en
+@DOKUWIKIURL@ luego visita
+@SUBSCRIBE@
+y date de baja en la página y/o cambios en el espacio de nombre.
+
+--
+Este correo ha sido generado por DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/es/subscr_form.txt b/inc/lang/es/subscr_form.txt
new file mode 100644
index 000000000..3a8143c39
--- /dev/null
+++ b/inc/lang/es/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Administrador de Suscripciones ======
+
+Esta página te permite administrar tus suscripciones para la página actual y espacio de nombres. \ No newline at end of file
diff --git a/inc/lang/es/subscr_list.txt b/inc/lang/es/subscr_list.txt
new file mode 100644
index 000000000..80e8dc8a1
--- /dev/null
+++ b/inc/lang/es/subscr_list.txt
@@ -0,0 +1,17 @@
+Hola!
+
+Las páginas en el espacio de nombres @PAGE@ en @TITLE@ wiki ha cambiado.
+Estos son los cambios:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Para cancelar la página de notificaciones, entra a la wiki en
+@DOKUWIKIURL@ luego visita
+@SUBSCRIBE@
+y date de baja en la página y/o cambios en el espacio de nombre.
+
+--
+Este correo ha sido generado por DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/es/subscr_single.txt b/inc/lang/es/subscr_single.txt
new file mode 100644
index 000000000..e2a54c79f
--- /dev/null
+++ b/inc/lang/es/subscr_single.txt
@@ -0,0 +1,23 @@
+Hola!
+
+La página @PAGE@ en @TITLE@ wiki ha cambiado.
+Estos son los cambioss:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Fecha : @DATE@
+Usuario : @USER@
+Resúmen de edición: @SUMMARY@
+Revisión Anterior: @OLDPAGE@
+Nueva Revisión: @NEWPAGE@
+
+Para cancelar la página de notificaciones, entra a la wiki en
+@DOKUWIKIURL@ luego visita
+@SUBSCRIBE@
+y date de baja en la página y/o cambios en el espacio de nombre.
+
+--
+Este correo ha sido generado por DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/es/updateprofile.txt b/inc/lang/es/updateprofile.txt
new file mode 100644
index 000000000..822e558f8
--- /dev/null
+++ b/inc/lang/es/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Actualiza el perfil de tu cuenta de usuario ======
+
+Sólo necesitas completar aquellos campos que quieres cambiar. No puedes cambiar tu nombre de usuario.
diff --git a/inc/lang/es/uploadmail.txt b/inc/lang/es/uploadmail.txt
new file mode 100644
index 000000000..9d2f980d3
--- /dev/null
+++ b/inc/lang/es/uploadmail.txt
@@ -0,0 +1,14 @@
+Se ha subido un fichero a tu DokuWuki. Estos son los detalles:
+
+Archivo : @MEDIA@
+Fecha : @DATE@
+Navegador : @BROWSER@
+Dirección IP : @IPADDRESS@
+Hostname : @HOSTNAME@
+Tamaño : @SIZE@
+MIME Type : @MIME@
+Usuario : @USER@
+
+--
+Este correo fue generado por DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/et/admin.txt b/inc/lang/et/admin.txt
new file mode 100644
index 000000000..1934f482b
--- /dev/null
+++ b/inc/lang/et/admin.txt
@@ -0,0 +1,4 @@
+====== Administreerimine ======
+
+Alljärgnevalt leiate nimekirja administratiivsetest tegevustest, mida DokuWiki võimaldab.
+
diff --git a/inc/lang/et/backlinks.txt b/inc/lang/et/backlinks.txt
new file mode 100644
index 000000000..4b405cdfd
--- /dev/null
+++ b/inc/lang/et/backlinks.txt
@@ -0,0 +1,4 @@
+====== Siia lehele lingiga haagitud lehed ======
+
+Nimekiri nendest lehtedest, kuskohalt Sa lingi abil siia lehele saad.
+
diff --git a/inc/lang/et/conflict.txt b/inc/lang/et/conflict.txt
new file mode 100644
index 000000000..cf9f571ab
--- /dev/null
+++ b/inc/lang/et/conflict.txt
@@ -0,0 +1,6 @@
+====== Uus versioon täitsa olemas ======
+
+Sellest dokumendist, mis Sa toimetasid on tegelikult juba olemas ka uuem versioon. Selline asi juhtub siis kui sel ajal kui Sina vaikselt oma dokumendi kallal nokitsesid tegi keegi juba kähku omad Muutused sealsamas dokumendis ära.
+
+Vaata hoolikalt allpool näidatud erinevusi ja siis otsusta millise versiooni alles jätad. Kui Sa peaks valima ''salvesta'', siis juhtubki selline lugu, et Sinu versioon salvestatakse. kui Sa aga peaks klõpsama ''katkesta'' säilib hetkel kehtiv versioon.
+
diff --git a/inc/lang/et/denied.txt b/inc/lang/et/denied.txt
new file mode 100644
index 000000000..bb564ac57
--- /dev/null
+++ b/inc/lang/et/denied.txt
@@ -0,0 +1,3 @@
+====== Sul pole ligipääsuluba ======
+
+Kahju küll, aga sinu tublidusest ei piisa, et edasi liikuda, selleks on vastavaid õigusi vaja.
diff --git a/inc/lang/et/diff.txt b/inc/lang/et/diff.txt
new file mode 100644
index 000000000..d10a93b84
--- /dev/null
+++ b/inc/lang/et/diff.txt
@@ -0,0 +1,4 @@
+====== Erinevused ======
+
+Siin näed erinevusi valitud versiooni ja hetkel kehtiva lehekülje vahel.
+
diff --git a/inc/lang/et/draft.txt b/inc/lang/et/draft.txt
new file mode 100644
index 000000000..6669f3be5
--- /dev/null
+++ b/inc/lang/et/draft.txt
@@ -0,0 +1,6 @@
+====== Leidsin katkenud toimetamise ======
+
+Sinu viimane toimetamissessioon ei lõppenud eelmine kord korrapäraselt. DokuWiki automaatselt salvestas Sinu pooliku töö, mida võid nüüd kasutada töö jätkamiseks. Allpool näed teksti, mis suudeti päästa.
+
+Kas tahad //taastada// kaotused, //kustutada// poolik töö või //üldse mitte midagi teha//?
+
diff --git a/inc/lang/et/edit.txt b/inc/lang/et/edit.txt
new file mode 100644
index 000000000..6167c8552
--- /dev/null
+++ b/inc/lang/et/edit.txt
@@ -0,0 +1,2 @@
+Toimeta seda lehte ja klõpsa ''Salvesta'' peal. Wikis teksti kujundamise vahenditega tutvumiseks, st. kuidas teha rasvast ja kaldkirja jne., vaata [[wiki:syntax|süntaksitutvustus lehelt]]. Kui Sa tahad midagi testida, saad seda teha [[playground:playground|mängualal]].
+
diff --git a/inc/lang/et/editrev.txt b/inc/lang/et/editrev.txt
new file mode 100644
index 000000000..3ab6d7161
--- /dev/null
+++ b/inc/lang/et/editrev.txt
@@ -0,0 +1,3 @@
+**Sa oled omale tõmmanud selle dokumendi vana versiooni!** Kui Sa selle salvestad sünnib nende andmetega uus versioon.
+----
+
diff --git a/inc/lang/et/index.txt b/inc/lang/et/index.txt
new file mode 100644
index 000000000..8d2e25a68
--- /dev/null
+++ b/inc/lang/et/index.txt
@@ -0,0 +1,3 @@
+====== Sisukord ======
+
+See siin on nimekiri kõigist saadaval olevatest lehtedest järjestatud [[doku>namespaces|alajaotuste]] järgi.
diff --git a/inc/lang/et/lang.php b/inc/lang/et/lang.php
new file mode 100644
index 000000000..5d882f165
--- /dev/null
+++ b/inc/lang/et/lang.php
@@ -0,0 +1,234 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oliver S6ro <seem.iges@mail.ee>
+ * @author Aari Juhanson <aari@vmg.vil.ee>
+ * @author Kaiko Kaur <kaiko@kultuur.edu.ee>
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Toimeta seda lehte';
+$lang['btn_source'] = 'Näita lehepõhja';
+$lang['btn_show'] = 'Näita lehte';
+$lang['btn_create'] = 'Tekita selle lingi alla leht';
+$lang['btn_search'] = 'Otsi';
+$lang['btn_save'] = 'Salvesta';
+$lang['btn_preview'] = 'Eelvaade';
+$lang['btn_top'] = 'Tagasi lehe algusesse';
+$lang['btn_newer'] = '<< varajasemad';
+$lang['btn_older'] = '>> hilisemad';
+$lang['btn_revs'] = 'Eelmised versioonid';
+$lang['btn_recent'] = 'Viimased muudatused';
+$lang['btn_upload'] = 'Lae üles';
+$lang['btn_cancel'] = 'Katkesta';
+$lang['btn_index'] = 'Sisukord';
+$lang['btn_secedit'] = 'Toimeta';
+$lang['btn_login'] = 'Logi sisse';
+$lang['btn_logout'] = 'Logi välja';
+$lang['btn_admin'] = 'Administreeri';
+$lang['btn_update'] = 'Uuenda';
+$lang['btn_delete'] = 'Kustuta';
+$lang['btn_back'] = 'Tagasi';
+$lang['btn_backlink'] = 'Tagasilingid';
+$lang['btn_backtomedia'] = 'Tagasi faili valikusse';
+$lang['btn_subscribe'] = 'Jälgi seda lehte (teated meilile)';
+$lang['btn_profile'] = 'Minu info';
+$lang['btn_reset'] = 'Taasta';
+$lang['btn_resendpwd'] = 'Saada uus parool';
+$lang['btn_draft'] = 'Toimeta mustandit';
+$lang['btn_recover'] = 'Taata mustand';
+$lang['btn_draftdel'] = 'Kustuta mustand';
+$lang['btn_revert'] = 'Taasta';
+$lang['btn_register'] = 'Registreeri uus kasutaja';
+$lang['loggedinas'] = 'Logis sisse kui';
+$lang['user'] = 'Kasutaja';
+$lang['pass'] = 'Parool';
+$lang['newpass'] = 'Uus parool';
+$lang['oldpass'] = 'Vana parool';
+$lang['passchk'] = 'Korda uut parooli';
+$lang['remember'] = 'Pea mind meeles';
+$lang['fullname'] = 'Täielik nimi';
+$lang['email'] = 'E-post';
+$lang['profile'] = 'Kasutaja info';
+$lang['badlogin'] = 'Oops, Sinu kasutajanimi või parool oli vale.';
+$lang['minoredit'] = 'Ebaolulised muudatused';
+$lang['draftdate'] = 'Mustand automaatselt salvestatud';
+$lang['regmissing'] = 'Kõik väljad tuleb ära täita.';
+$lang['reguexists'] = 'Tegelikult on sellise nimega kasutaja juba olemas.';
+$lang['regsuccess'] = 'Kasutaja sai tehtud. Parool saadeti Sulle e-posti aadressil.';
+$lang['regsuccess2'] = 'Kasutaja sai tehtud.';
+$lang['regmailfail'] = 'Ilmselt tekkis e-posti teel parooli saatmisel mingi tõrge. Palun suhtle sel teemal
+oma serveri administraatoriga!';
+$lang['regbadmail'] = 'Tundub, et Sinu antud e-posti aadress ei toimi - kui Sa arvad, et tegemist on
+ekstitusega, suhtle oma serveri administraatoriga';
+$lang['regbadpass'] = 'Uus parool on kirjutatud erinevalt. Proovi uuesti.';
+$lang['regpwmail'] = 'Sinu DokuWiki parool';
+$lang['reghere'] = 'Sul ei olegi veel kasutajakontot? No aga tekita see siis endale!';
+$lang['profna'] = 'Viki ei toeta profiili muudatusi';
+$lang['profnochange'] = 'Muutused puuduvad.';
+$lang['profnoempty'] = 'Tühi nimi ega meiliaadress pole lubatud.';
+$lang['profchanged'] = 'Kasutaja info edukalt muudetud';
+$lang['pwdforget'] = 'Unustasid parooli? Tee uus';
+$lang['resendna'] = 'See wiki ei toeta parooli taassaatmist.';
+$lang['resendpwd'] = 'Saada uus parool';
+$lang['resendpwdmissing'] = 'Khmm... Sa pead täitma kõik väljad.';
+$lang['resendpwdnouser'] = 'Aga sellist kasutajat ei ole.';
+$lang['resendpwdbadauth'] = 'See autentimiskood ei ole õige. Kontrolli, et kopeerisid terve lingi.';
+$lang['resendpwdconfirm'] = 'Kinnituslink saadeti meilile.';
+$lang['resendpwdsuccess'] = 'Uus parool saadeti Sinu meilile.';
+$lang['searchmedia'] = 'Otsi failinime:';
+$lang['searchmedia_in'] = 'Otsi %s';
+$lang['txt_upload'] = 'Vali fail, mida üles laadida';
+$lang['txt_filename'] = 'Siseta oma Wikinimi (soovituslik)';
+$lang['txt_overwrt'] = 'Kirjutan olemasoleva faili üle';
+$lang['lockedby'] = 'Praegu on selle lukustanud';
+$lang['lockexpire'] = 'Lukustus aegub';
+$lang['js']['willexpire'] = 'Teie lukustus selle lehe toimetamisele aegub umbes minuti pärast.\nIgasugu probleemide vältimiseks kasuta eelvaate nuppu, et lukustusarvesti taas tööle panna.';
+$lang['js']['notsavedyet'] = 'Sul on seal salvestamata muudatusi, mis kohe kõige kaduva teed lähevad.
+Kas Sa ikka tahad edasi liikuda?';
+$lang['js']['searchmedia'] = 'Otsi faile';
+$lang['js']['keepopen'] = 'Jäta aken peale valiku sooritamist avatuks';
+$lang['js']['hidedetails'] = 'Peida detailid';
+$lang['js']['mediatitle'] = 'Lingi sätted';
+$lang['js']['mediadisplay'] = 'Lingi liik';
+$lang['js']['mediaalign'] = 'Joondus';
+$lang['js']['mediasize'] = 'Pildi mõõtmed';
+$lang['js']['mediatarget'] = 'Lingi siht';
+$lang['js']['mediaclose'] = 'Sulge';
+$lang['js']['mediainsert'] = 'Sisesta';
+$lang['js']['mediadisplayimg'] = 'Näita pilti.';
+$lang['js']['mediadisplaylnk'] = 'Näita ainult linki.';
+$lang['js']['mediasmall'] = 'Väiksem suurus';
+$lang['js']['mediamedium'] = 'Keskmine suurus';
+$lang['js']['medialarge'] = 'Suurem suurus';
+$lang['js']['mediaoriginal'] = 'Originaali suurus';
+$lang['js']['medialnk'] = 'Link üksikasjadele';
+$lang['js']['mediadirect'] = 'Otselink originaalile';
+$lang['js']['medianolnk'] = 'Ilma lingita';
+$lang['js']['medianolink'] = 'Ära lingi pilti';
+$lang['js']['medialeft'] = 'Joonda pilt vasakule.';
+$lang['js']['mediaright'] = 'Joonda pilt paremale.';
+$lang['js']['mediacenter'] = 'Joonda pilt keskele.';
+$lang['js']['medianoalign'] = 'Ära joonda.';
+$lang['js']['nosmblinks'] = 'Lingid \'Windows shares\'ile töötab ainult Microsoft Internet Exploreriga.
+Siiski võid kopeerida ja asetada lingi.';
+$lang['js']['linkwiz'] = 'Lingi nõustaja';
+$lang['js']['linkto'] = 'Lingi:';
+$lang['js']['del_confirm'] = 'Kas kustutame selle kirje?';
+$lang['rssfailed'] = 'Sinu soovitud info ammutamisel tekkis viga: ';
+$lang['nothingfound'] = 'Oops, aga mitte muhvigi ei leitud.';
+$lang['mediaselect'] = 'Hunnik faile';
+$lang['fileupload'] = 'Faili üleslaadimine';
+$lang['uploadsucc'] = 'Üleslaadimine läks ootuspäraselt hästi';
+$lang['uploadfail'] = 'Üleslaadimine läks nässu. Äkki pole Sa selleks lihtsalt piisavalt võimukas tegija?';
+$lang['uploadwrong'] = 'Ei saa Sa midagi üles laadida. Oops, aga seda tüüpi faili sul lihtsalt ei lubata üles laadida';
+$lang['uploadexist'] = 'Fail on juba olemas. Midagi ei muudetud.';
+$lang['uploadbadcontent'] = 'Üles laaditu ei sobinud %s faililaiendiga.';
+$lang['uploadsize'] = 'Üles laaditud fail on liiga suur (maksimaalne suurus on %s).';
+$lang['deletesucc'] = 'Fail nimega "%s" sai kustutatud.';
+$lang['deletefail'] = 'Faili nimega "%s" ei kustutatud (kontrolli õigusi).';
+$lang['mediainuse'] = 'Faili nimega "%s" ei kustutatud, sest see on kasutuses.';
+$lang['namespaces'] = 'Alajaotus';
+$lang['mediafiles'] = 'Failid on Sulle kättesaadavad';
+$lang['accessdenied'] = 'Ligipääs keelatud.';
+$lang['mediausage'] = 'Kasuta järgmist kirjapilti sellele failile viitamaks:';
+$lang['mediaview'] = 'Vaata faili algsel kujul.';
+$lang['mediaroot'] = 'juur';
+$lang['mediaupload'] = 'Lae fail sellesse nimeruumi (kataloogi). Et tekitada veel alam nimeruum kasuta koolonit Wiki nimes.';
+$lang['mediaextchange'] = 'Faili laiend .%s-st %s-ks!';
+$lang['reference'] = 'Viited';
+$lang['ref_inuse'] = 'Seda faili ei saa kustutada, sest teda kasutavad järgmised lehed:';
+$lang['ref_hidden'] = 'Mõned viidad failile on lehtedel, millele sul ei ole ligipääsu';
+$lang['hits'] = 'Päringu tabamused';
+$lang['quickhits'] = 'Päringule vastavad lehed';
+$lang['toc'] = 'Sisujuht';
+$lang['current'] = 'Hetkel kehtiv';
+$lang['yours'] = 'Sinu versioon';
+$lang['diff'] = 'Näita erinevusi hetkel kehtiva versiooniga';
+$lang['diff2'] = 'Näita valitud versioonide erinevusi';
+$lang['difflink'] = 'Lõlita võrdlemise vaatele';
+$lang['diff_type'] = 'Vaata erinevusi:';
+$lang['diff_side'] = 'Kõrvuti';
+$lang['line'] = 'Rida';
+$lang['breadcrumb'] = 'Käidud rada';
+$lang['youarehere'] = 'Sa oled siin';
+$lang['lastmod'] = 'Viimati muutnud';
+$lang['by'] = 'persoon';
+$lang['deleted'] = 'eemaldatud';
+$lang['created'] = 'tekitatud';
+$lang['restored'] = 'vana versioon taastatud';
+$lang['external_edit'] = 'väline muutmine';
+$lang['summary'] = 'kokkuvõte muudatustest';
+$lang['mail_newpage'] = 'leht lisatud:';
+$lang['mail_changed'] = 'leht muudetud';
+$lang['mail_new_user'] = 'Uus kasutaja:';
+$lang['qb_bold'] = 'Rasvane kiri';
+$lang['qb_italic'] = 'Kaldkiri';
+$lang['qb_underl'] = 'Alajoonega kiri';
+$lang['qb_code'] = 'Koodi tekst';
+$lang['qb_strike'] = 'Läbijoonitud tekst';
+$lang['qb_h1'] = '1. astme pealkiri';
+$lang['qb_h2'] = '2. astme pealkiri';
+$lang['qb_h3'] = '3. astme pealkiri';
+$lang['qb_h4'] = '4. astme pealkiri';
+$lang['qb_h5'] = '5. astme pealkiri';
+$lang['qb_h'] = 'Pealkiri';
+$lang['qb_hs'] = 'Vali pealkiri';
+$lang['qb_hplus'] = 'Kõrgem pealkiri';
+$lang['qb_hminus'] = 'Madalam pealkiri';
+$lang['qb_hequal'] = 'Sama taseme pealkiri';
+$lang['qb_link'] = 'Siselink';
+$lang['qb_extlink'] = 'Välislink';
+$lang['qb_hr'] = 'Horisontaalne vahejoon';
+$lang['qb_ol'] = 'Nummerdatud nimikiri';
+$lang['qb_ul'] = 'Mummuga nimekiri';
+$lang['qb_media'] = 'Lisa pilte ja muid faile';
+$lang['qb_sig'] = 'Lisa allkiri!';
+$lang['qb_smileys'] = 'Emotikonid';
+$lang['qb_chars'] = 'Erisümbolid';
+$lang['admin_register'] = 'Lisa kasutaja';
+$lang['metaedit'] = 'Muuda lisainfot';
+$lang['metasaveerr'] = 'Lisainfo salvestamine läks untsu.';
+$lang['metasaveok'] = 'Lisainfo salvestatud';
+$lang['img_backto'] = 'Tagasi';
+$lang['img_title'] = 'Tiitel';
+$lang['img_caption'] = 'Kirjeldus';
+$lang['img_date'] = 'Kuupäev';
+$lang['img_fname'] = 'Faili nimi';
+$lang['img_fsize'] = 'Suurus';
+$lang['img_artist'] = 'Autor';
+$lang['img_copyr'] = 'Autoriõigused';
+$lang['img_format'] = 'Formaat';
+$lang['img_camera'] = 'Kaamera';
+$lang['img_keywords'] = 'Võtmesõnad';
+$lang['authmodfailed'] = 'Vigane kasutajate autentimise konfiguratsioon. Palun teavita sellest serveri haldajat.';
+$lang['authtempfail'] = 'Kasutajate autentimine on ajutiselt rivist väljas. Kui see olukord mõne aja jooksul ei parane, siis teavita sellest serveri haldajat.';
+$lang['i_chooselang'] = 'Vali keel';
+$lang['i_installer'] = 'DokuWiki paigaldaja';
+$lang['i_wikiname'] = 'Wiki nimi';
+$lang['i_enableacl'] = 'Kas lubada kasutajate haldus (soovitatav)';
+$lang['i_superuser'] = 'Superkasutaja';
+$lang['i_problems'] = 'Paigaldaja leidis mõned vead, mis on allpool välja toodud. Enne vigade eemaldamist ei saa jätkata.';
+$lang['i_modified'] = 'Õnnetuste vältimiseks läheb see skript käima ainult värskelt paigaldatud ja muutmata Dokuwiki peal.
+ Sa peaksid ilmselt kogu koodi uuesti lahti pakkima. Vaata ka <a href="http://dokuwiki.org/install">Dokuwiki installeerimis juhendit</a>';
+$lang['i_funcna'] = 'PHP funktsiooni <code>%s</code> ei ole olemas.võibolla sinu serveri hooldaja on selle mingil põhjusel keelanud?';
+$lang['i_permfail'] = 'Dokuwiki ei saa kirjutada faili <code>%s</code>. Kontrolli serveris failide õigused üle.';
+$lang['i_confexists'] = '<code>%s</code> on juba olemas';
+$lang['i_writeerr'] = 'Faili <code>%s</code> ei lubata tekitada. Kontrolli kataloogi ja faili õigusi.';
+$lang['i_badval'] = '<code>%s</code> - lubamatu või tühi väärtus';
+$lang['i_success'] = 'Seadistamine on õnnelikult lõpule viidud. Sa võid nüüd kustutada faili install.php. Alusta oma <a href="doku.php">uue DokuWiki</a> täitmist.';
+$lang['i_failure'] = 'Konfiguratsiooni faili kirjutamisel esines vigu. Võimalik, et pead need käsitsi parandama enne <a href="doku.php">uue DokuWiki</a> täitma asumist.';
+$lang['i_policy'] = 'Wiki õiguste algne poliitika';
+$lang['i_pol0'] = 'Avatud (lugemine, kirjutamine ja üleslaadimine kõigile lubatud)';
+$lang['i_pol1'] = 'Avalikuks lugemiseks (lugeda saavad kõik, kirjutada ja üles laadida vaid registreeritud kasutajad)';
+$lang['i_pol2'] = 'Suletud (kõik õigused, kaasaarvatud lugemine on lubatud vaid registreeritud kasutajatele)';
+$lang['i_retry'] = 'Proovi uuesti';
diff --git a/inc/lang/et/locked.txt b/inc/lang/et/locked.txt
new file mode 100644
index 000000000..0fd2743ad
--- /dev/null
+++ b/inc/lang/et/locked.txt
@@ -0,0 +1,3 @@
+====== Leht lukustatud ======
+
+Hetkel on see leht lukustatud kuna teine kasutaja toimetab tema kallal. Sa pead ootama kuni ta kas lõpetab või lukustus aegub.
diff --git a/inc/lang/et/login.txt b/inc/lang/et/login.txt
new file mode 100644
index 000000000..3e746cd8d
--- /dev/null
+++ b/inc/lang/et/login.txt
@@ -0,0 +1,3 @@
+====== Logi sisse ======
+
+Hetkel pole Sa sisse logitud! Allpool saad sisestada kõik vajaliku, et sisse logida. Kui Sa oled oma arvuti taga ainukasutaja oleks hea kui Su arvutil oleks lubatud 'cookies', st. järgmine kord kui siia lehele tuled oled automaatselt sisse logitud.
diff --git a/inc/lang/et/mailtext.txt b/inc/lang/et/mailtext.txt
new file mode 100644
index 000000000..3214584f5
--- /dev/null
+++ b/inc/lang/et/mailtext.txt
@@ -0,0 +1,16 @@
+Sinu lehte DokuWiki-s on muudetud. Alljärgnevalt detailid:
+
+Kuupäev : @DATE@
+Brauser : @BROWSER@
+IP-Aadress : @IPADDRESS@
+Arvuti nimi : @HOSTNAME@
+Eelnev versioon : @OLDPAGE@
+Uus versioon : @NEWPAGE@
+Toimeta kokkuvõtet: @SUMMARY@
+Kasutaja : @USER@
+
+@DIFF@
+
+
+--
+Selle e-posti tekitas Sulle DokuWiki @DOKUWIKIURL@
diff --git a/inc/lang/et/newpage.txt b/inc/lang/et/newpage.txt
new file mode 100644
index 000000000..fb78e6434
--- /dev/null
+++ b/inc/lang/et/newpage.txt
@@ -0,0 +1,3 @@
+====== Seda teemat veel ei ole ======
+
+Sa klikkisid lingile, mille all teemat veel pole. Selle saad Sa tekitada kasutades ''Tekita see leht nuppu''.
diff --git a/inc/lang/et/norev.txt b/inc/lang/et/norev.txt
new file mode 100644
index 000000000..42d204f2d
--- /dev/null
+++ b/inc/lang/et/norev.txt
@@ -0,0 +1,4 @@
+====== Sellist versiooni pole ======
+
+Sellist versiooni ei ole olemas. Selle dokumendi eelmiste versioonide nägemiseks klõpsa ''Eelmised versioonid'' nupul.
+
diff --git a/inc/lang/et/password.txt b/inc/lang/et/password.txt
new file mode 100644
index 000000000..19db86d78
--- /dev/null
+++ b/inc/lang/et/password.txt
@@ -0,0 +1,9 @@
+Hi @FULLNAME@!
+
+Siin on sinu kasutajaandmed @TITLE@ks @DOKUWIKIURL@s
+
+Sisse logimisnimi : @LOGIN@
+Parool : @PASSWORD@
+
+--
+Selle kirja saatis DokuWiki @DOKUWIKIURL@st
diff --git a/inc/lang/et/preview.txt b/inc/lang/et/preview.txt
new file mode 100644
index 000000000..df45c65ae
--- /dev/null
+++ b/inc/lang/et/preview.txt
@@ -0,0 +1,3 @@
+====== Eelvaade ======
+
+Siin saad eelnevalt vaadata, milline su tekst välja näeks. Pea aga meeles, et see **ei ole veel salvestatud** !
diff --git a/inc/lang/et/pwconfirm.txt b/inc/lang/et/pwconfirm.txt
new file mode 100644
index 000000000..4f17140e0
--- /dev/null
+++ b/inc/lang/et/pwconfirm.txt
@@ -0,0 +1,12 @@
+Tere @FULLNAME@!
+
+Keegi on Sinu parooli uuendust soovinud kasutajale @TITLE@ (@DOKUWIKIURL@).
+
+Kui see ei olnud Sina, siis võid seda meili lihtsalt ignoreerida.
+Kinnitamaks uue parooli saamise soovi mine aadressile:
+
+@CONFIRM@
+
+--
+See meil on saadetud DokuWiki poolt
+@DOKUWIKIURL@
diff --git a/inc/lang/et/read.txt b/inc/lang/et/read.txt
new file mode 100644
index 000000000..64696f079
--- /dev/null
+++ b/inc/lang/et/read.txt
@@ -0,0 +1,2 @@
+Seda lehte saad ainult lugeda. Saad küll vaadata lehe põhja aga muuta midagi ei saa. Suhtle oma serveri administraatoriga kui Sa millegagi rahul pole.
+
diff --git a/inc/lang/et/recent.txt b/inc/lang/et/recent.txt
new file mode 100644
index 000000000..cf7a85420
--- /dev/null
+++ b/inc/lang/et/recent.txt
@@ -0,0 +1,5 @@
+====== Viimased muutused ======
+
+Viimati muudeti alljärgnevaid lehti.
+
+
diff --git a/inc/lang/et/register.txt b/inc/lang/et/register.txt
new file mode 100644
index 000000000..9cd0b911d
--- /dev/null
+++ b/inc/lang/et/register.txt
@@ -0,0 +1,4 @@
+====== Registreeri uus kasutaja ======
+
+Täida alljärgnevad lüngad et me saaks Sulle Wikis kasutajakonto tekitada. Ole nii kena ja kindlasti pane kirja oma **kehtiv e-posti aadress** - Sinu uus parool saadetakse sellele aadressile. Sisselogimise nimi peaks olema kehtiv [[doku>pagename|lehenimi]].
+
diff --git a/inc/lang/et/registermail.txt b/inc/lang/et/registermail.txt
new file mode 100644
index 000000000..47d2ef14c
--- /dev/null
+++ b/inc/lang/et/registermail.txt
@@ -0,0 +1,14 @@
+Uus kasutaja on registreeritud. Tema info:
+
+Kasutaja : @NEWUSER@
+Täielik nimi : @NEWNAME@
+E-post : @NEWEMAIL@
+
+Kuupäev : @DATE@
+Lehitseja : @BROWSER@
+IP-Aaddress : @IPADDRESS@
+Hosti nimi : @HOSTNAME@
+
+--
+See meil on saadetud DokuWiki poolt
+@DOKUWIKIURL@
diff --git a/inc/lang/et/resendpwd.txt b/inc/lang/et/resendpwd.txt
new file mode 100644
index 000000000..cd0ef8d10
--- /dev/null
+++ b/inc/lang/et/resendpwd.txt
@@ -0,0 +1,4 @@
+====== Saada uus parool ======
+
+Palun sisesta oma kasutaja nimi, et saada uut parooli. Soovi kinnitamiseks saadame Sinu meilile lingi.
+
diff --git a/inc/lang/et/revisions.txt b/inc/lang/et/revisions.txt
new file mode 100644
index 000000000..c546a1f14
--- /dev/null
+++ b/inc/lang/et/revisions.txt
@@ -0,0 +1,4 @@
+====== eelnevad versioonid ======
+
+Need on käesoleva dokumendi eelnevad versioonid. Vana versiooni juurde tagasi pöördumiseks vali sobiv, klõpsa ''Toimeta seda lehte'' peal ja salvesta see.
+
diff --git a/inc/lang/et/searchpage.txt b/inc/lang/et/searchpage.txt
new file mode 100644
index 000000000..bbc86b637
--- /dev/null
+++ b/inc/lang/et/searchpage.txt
@@ -0,0 +1,5 @@
+====== Otsi ======
+
+Leiad vasted oma otsingule. Kui Sa otsitavat ei leidnud võid tekitada oma otsingu nimelise uue lehe kasutades ''Toimeta seda lehte'' nuppu.
+
+===== Vasted =====
diff --git a/inc/lang/et/showrev.txt b/inc/lang/et/showrev.txt
new file mode 100644
index 000000000..ef73d74a2
--- /dev/null
+++ b/inc/lang/et/showrev.txt
@@ -0,0 +1,2 @@
+**See on dokumendi vana versioon!**
+----
diff --git a/inc/lang/et/stopwords.txt b/inc/lang/et/stopwords.txt
new file mode 100644
index 000000000..5dda5f797
--- /dev/null
+++ b/inc/lang/et/stopwords.txt
@@ -0,0 +1,15 @@
+# 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/
+ning
+ega
+see
+mina
+sina
+tema
+meie
+teie
+nemad
+com
+www
diff --git a/inc/lang/et/updateprofile.txt b/inc/lang/et/updateprofile.txt
new file mode 100644
index 000000000..35da12801
--- /dev/null
+++ b/inc/lang/et/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Uuenda oma kasutaja infot ======
+
+Täida ainult need väljad, mida tahad uuendada. Uuendada ei saa kasutajanime.
+
+
diff --git a/inc/lang/eu/admin.txt b/inc/lang/eu/admin.txt
new file mode 100644
index 000000000..13673263c
--- /dev/null
+++ b/inc/lang/eu/admin.txt
@@ -0,0 +1,3 @@
+====== Kudeaketa ======
+
+Jarraian wikia kudeatzeko erabilgarri dauden tresnak aurki ditzakezu.
diff --git a/inc/lang/eu/adminplugins.txt b/inc/lang/eu/adminplugins.txt
new file mode 100644
index 000000000..20709bfd6
--- /dev/null
+++ b/inc/lang/eu/adminplugins.txt
@@ -0,0 +1 @@
+===== Plugin Gehigarriak ===== \ No newline at end of file
diff --git a/inc/lang/eu/backlinks.txt b/inc/lang/eu/backlinks.txt
new file mode 100644
index 000000000..8cbb7b6d2
--- /dev/null
+++ b/inc/lang/eu/backlinks.txt
@@ -0,0 +1,3 @@
+====== Itzulera Estekak ======
+
+Orri honetara bueltan estekatzen dutela diruditen orrien lista bat da honakoa. \ No newline at end of file
diff --git a/inc/lang/eu/conflict.txt b/inc/lang/eu/conflict.txt
new file mode 100644
index 000000000..d7d0d337e
--- /dev/null
+++ b/inc/lang/eu/conflict.txt
@@ -0,0 +1,5 @@
+====== Bertsio berriago bat existitzen da ======
+
+Editatu duzun dokumentua baino bertsio berriago existitzen da. Editatzen ari zarela beste erabiltzaile batek dokumentua aldatzen duenean gertatzen da hau.
+
+Aztertu arretaz behean erakutsitako desberdintasunak eta erabaki zein bertsio mantendu. Zure aukera "Gorde" bada, zure bertsioa gordeko da. Uneko bertsioa mantentzeko "ezeztatu" sakatu. \ No newline at end of file
diff --git a/inc/lang/eu/denied.txt b/inc/lang/eu/denied.txt
new file mode 100644
index 000000000..257076a3d
--- /dev/null
+++ b/inc/lang/eu/denied.txt
@@ -0,0 +1,3 @@
+====== Ez duzu baimenik ======
+
+Barkatu, ez duzu baimenik orri hau ikusteko. Agian sesioa hastea ahaztu zaizu? \ No newline at end of file
diff --git a/inc/lang/eu/diff.txt b/inc/lang/eu/diff.txt
new file mode 100644
index 000000000..8d335ea2e
--- /dev/null
+++ b/inc/lang/eu/diff.txt
@@ -0,0 +1,4 @@
+====== Aldaketak ======
+
+Aukeratutako bertsioaren eta egungo bertsioaren arteko aldaketak aurkezten ditu.
+
diff --git a/inc/lang/eu/draft.txt b/inc/lang/eu/draft.txt
new file mode 100644
index 000000000..5d64b0b36
--- /dev/null
+++ b/inc/lang/eu/draft.txt
@@ -0,0 +1,5 @@
+====== Zirriborro fitxategia aurkitu da ======
+
+Zure azken edizio saioa orri honetan ez zen zuzen burutu. DokuWiki-k automatikoki zirriborro bat gorde zuen lanean ari zinen bitartean eta orain zure edizioa jarraitzeko erabili dezakezu. Behean ikusi dezakezu zure asken saioan gorde ziren datuak.
+
+Erabaki mesedez zure edizio saio galdua //berreskuratu// nahi duzun, automatikoki gordetako zirriborroa //ezabatu// nahi duzun edo edizio prozesua //ezeztatu// nahi duzun. \ No newline at end of file
diff --git a/inc/lang/eu/edit.txt b/inc/lang/eu/edit.txt
new file mode 100644
index 000000000..c117731ef
--- /dev/null
+++ b/inc/lang/eu/edit.txt
@@ -0,0 +1 @@
+Egin aldaketak eta ''Gorde'' pultsatu. Begiratu [[wiki:syntax]] Wiki-aren sintaxiarentzat. Mesedez aldaketak orrialdea **hobetzeko** bakarrik egin itzazu. Probak egin nahi badituzu, ikas ezazu [[playground:playground]] erabiltzen.
diff --git a/inc/lang/eu/editrev.txt b/inc/lang/eu/editrev.txt
new file mode 100644
index 000000000..920cd89ec
--- /dev/null
+++ b/inc/lang/eu/editrev.txt
@@ -0,0 +1,2 @@
+**Dokumentuaren bertsio zahar bat ireki duzu!** Gordetzen baduzu bertsio berri bat sortuko duzu datu hauekin.
+----
diff --git a/inc/lang/eu/index.txt b/inc/lang/eu/index.txt
new file mode 100644
index 000000000..30f88498a
--- /dev/null
+++ b/inc/lang/eu/index.txt
@@ -0,0 +1,4 @@
+====== Aurkibidea ======
+
+[[doku>namespaces|namespaces]] bitartez ordenatutako aurkibidea da hau.
+
diff --git a/inc/lang/eu/install.html b/inc/lang/eu/install.html
new file mode 100644
index 000000000..81f1efd95
--- /dev/null
+++ b/inc/lang/eu/install.html
@@ -0,0 +1,9 @@
+<p>Orri honek <a href="http://dokuwiki.org">Dokuwiki-ren</a> lehenengo instalazioan eta konfigurazioan gidatzen du. Instalatzaile honen informazio gehiago eskuragarri dago bere <a href="http://dokuwiki.org/installer">dokumentazio orrian</a>.</p>
+
+<p>DokuWikik fitxategi arruntak erabiltzen ditu wiki orriak eta orri horiekin erlazionatutako informazioa (adb. irudiak, bilaketa indizeak, azken berrikuspenak, etab.) gordetzeko. Modu egokian funtziona dezan, DokuWikik idazketa baimena <strong>behar</strong> du fitxategi horiek gordetzen dituzten direktorioetan. Instalatzaile hau ez da gai direktorio baimenak ezartzeko. Hori normalean komando bidez egin beharra dago, edo hosting bat erabiliz gero, FTP bidez edo hosting-aren kontrol panel bidez (adb. cPanel).</p>
+
+<p>Instalatzaile honek zure DokiWikiren konfigurazioa ezarriko du
+<acronym title="atzipen kontrol lista">AKL</acronym>rentzat, zeinak administratzaileei ahalbidetzen dien saioa hasi eta DokuWikiren administrazio menua atzitzea plugin-ak instalatu, erabiltzaileak kudeatu, wiki orrietara atzipenak kudeatu eta konfigurazio aukerak aldatzeko. Hau ez da beharrezkoa DokuWikirentzat funtziona ahal dezan, baina DokuWiki administratzeko errazagoa egingo du.</p>
+
+<p>Esperientziadun erabiltzaileek edo ezarpen behar bereziak dituzten erabiltzaileek honako estekak erabili beharko lituzkete xehetasun gehiago lortzeko
+<a href="http://dokuwiki.org/install">instalazio azalpenen</a> inguruan eta <a href="http://dokuwiki.org/config">konfigurazio ezarpenen</a> inguruan.</p> \ No newline at end of file
diff --git a/inc/lang/eu/lang.php b/inc/lang/eu/lang.php
new file mode 100644
index 000000000..367dfb5b5
--- /dev/null
+++ b/inc/lang/eu/lang.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Xabi Ezpeleta <xezpeleta@mendikute.com>
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Aldatu orri hau';
+$lang['btn_source'] = 'Kodea ikusi';
+$lang['btn_show'] = 'Orria ikusi';
+$lang['btn_create'] = 'Sortu orri hau';
+$lang['btn_search'] = 'Bilatu';
+$lang['btn_save'] = 'Gorde';
+$lang['btn_preview'] = 'Aurrebista';
+$lang['btn_top'] = 'Itzuli gora';
+$lang['btn_newer'] = '<< berriagoa';
+$lang['btn_older'] = 'zaharragoa >>';
+$lang['btn_revs'] = 'Berrikuspen zaharrak';
+$lang['btn_recent'] = 'Azken aldaketak';
+$lang['btn_upload'] = 'Ireki';
+$lang['btn_cancel'] = 'Ezeztatu';
+$lang['btn_index'] = 'Aurkibidea';
+$lang['btn_secedit'] = 'Aldatu';
+$lang['btn_login'] = 'Sartu';
+$lang['btn_logout'] = 'Irten';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Eguneratu';
+$lang['btn_delete'] = 'Ezabatu';
+$lang['btn_back'] = 'Atzera';
+$lang['btn_backlink'] = 'Itzulera estekak';
+$lang['btn_backtomedia'] = 'Atzera Multimedia Fitxategiaren Aukeraketara';
+$lang['btn_subscribe'] = 'Harpidetu Orri Aldaketetara';
+$lang['btn_profile'] = 'Eguneratu Profila ';
+$lang['btn_reset'] = 'Aldaketak Desegin';
+$lang['btn_resendpwd'] = 'Pasahitz berria bidali';
+$lang['btn_draft'] = 'Editatu zirriborroa';
+$lang['btn_recover'] = 'Berreskuratu zirriborroa';
+$lang['btn_draftdel'] = 'Ezabatu zirriborroa';
+$lang['btn_revert'] = 'Berrezarri';
+$lang['btn_register'] = 'Erregistratu';
+$lang['loggedinas'] = 'Erabiltzailea';
+$lang['user'] = 'Erabiltzailea';
+$lang['pass'] = 'Pasahitza';
+$lang['newpass'] = 'Pasahitz berria';
+$lang['oldpass'] = 'Baieztatu oraingo pasahitza';
+$lang['passchk'] = 'berriz';
+$lang['remember'] = 'Gogoratu';
+$lang['fullname'] = 'Izen Deiturak';
+$lang['email'] = 'E-Maila';
+$lang['profile'] = 'Erabiltzaile Profila';
+$lang['badlogin'] = 'Barkatu, prozesuak huts egin du; saiatu berriz';
+$lang['minoredit'] = 'Aldaketa Txikiak';
+$lang['draftdate'] = 'Zirriborroa automatikoki gorde da hemen:';
+$lang['nosecedit'] = 'Orria aldatua izan da bitartean, info atala zaharkituta geratu da, orri osoa kargatu da horren ordez.';
+$lang['regmissing'] = 'Barkatu, hutsune guztiak bete behar dituzu.';
+$lang['reguexists'] = 'Barkatu, izen bereko erabiltzailea existitzen da.';
+$lang['regsuccess'] = 'Erabiltzailea sortu da. Pasahitza mailez bidaliko zaizu.';
+$lang['regsuccess2'] = 'Erabiltzailea sortua izan da.';
+$lang['regmailfail'] = 'Badirudi arazoren bat egon dela pasahitza mailez bidaltzeko orduan. Administratzailearekin harremanetan jarri!';
+$lang['regbadmail'] = 'Emandako helbidea ez da zuzena - jarri harremanetan administratzailearekin hau akats bat dela uste baduzu';
+$lang['regbadpass'] = 'Idatzitako bi pasahitzak ez dira berdinak, berriz saiatu.';
+$lang['regpwmail'] = 'Zure DokuWiki pasahitza';
+$lang['reghere'] = 'Oraindik ez duzu konturik? Eginzazu bat!';
+$lang['profna'] = 'Wiki honek ez du profilaren aldaketa ahalbidetzen';
+$lang['profnochange'] = 'Aldaketarik ez, ez dago egiteko ezer.';
+$lang['profnoempty'] = 'Izen edota e-posta hutsa ez dago onartua.';
+$lang['profchanged'] = 'Erabiltzaile profila arrakastaz eguneratua.';
+$lang['pwdforget'] = 'Pasahitza ahaztu duzu? Eskuratu berri bat';
+$lang['resendna'] = 'Wiki honek ez du pasahitz berbidalketa onartzen.';
+$lang['resendpwd'] = 'Bidali pasahitz berria honentzat:';
+$lang['resendpwdmissing'] = 'Barkatu, eremu guztiak bete behar dituzu.';
+$lang['resendpwdnouser'] = 'Barkatu, ez dugu erabiltzaile hori datu-basean aurkitzen';
+$lang['resendpwdbadauth'] = 'Barkatu, kautotze kodea ez da baliozkoa. Ziurtatu baieztapen esteka osoa erabili duzula.';
+$lang['resendpwdconfirm'] = 'Baieztapen esteka bat e-postaz bidali da.';
+$lang['resendpwdsuccess'] = 'Zure pasahitz berria e-postaz bidali da.';
+$lang['license'] = 'Besterik esan ezean, wiki hontako edukia ondorengo lizentziapean argitaratzen da:';
+$lang['licenseok'] = 'Oharra: Orri hau editatzean, zure edukia ondorengo lizentziapean argitaratzea onartzen duzu: ';
+$lang['searchmedia'] = 'Bilatu fitxategi izena:';
+$lang['searchmedia_in'] = 'Bilatu %s-n';
+$lang['txt_upload'] = 'Ireki nahi den fitxategia aukeratu';
+$lang['txt_filename'] = 'Idatzi wikiname-a (aukerazkoa)';
+$lang['txt_overwrt'] = 'Oraingo fitxategiaren gainean idatzi';
+$lang['lockedby'] = 'Momentu honetan blokeatzen:';
+$lang['lockexpire'] = 'Blokeaketa iraungitzen da:';
+$lang['js']['willexpire'] = 'Zure blokeaketa orri hau aldatzeko minutu batean iraungitzen da.\nGatazkak saihesteko, aurreikusi botoia erabili blokeaketa denboragailua berrabiarazteko.';
+$lang['js']['notsavedyet'] = 'Gorde gabeko aldaketak galdu egingo dira.
+Benetan jarraitu nahi duzu?';
+$lang['js']['searchmedia'] = 'Bilatu fitxategiak';
+$lang['js']['keepopen'] = 'Mantendu leihoa irekita aukeraketan';
+$lang['js']['hidedetails'] = 'Xehetasunak Ezkutatu';
+$lang['js']['mediatitle'] = 'Esteken ezarpenak';
+$lang['js']['mediadisplay'] = 'Esteka mota';
+$lang['js']['mediaalign'] = 'Lerrokatzea';
+$lang['js']['mediasize'] = 'Irudi tamaina';
+$lang['js']['mediatarget'] = 'Estekaren helburua';
+$lang['js']['mediaclose'] = 'Itxi';
+$lang['js']['mediainsert'] = 'Txertatu';
+$lang['js']['mediadisplayimg'] = 'Irudia erakutsi';
+$lang['js']['mediadisplaylnk'] = 'Esteka bakarrik erakutsi';
+$lang['js']['mediasmall'] = 'Bertsio txikia';
+$lang['js']['mediamedium'] = 'Bertsio ertaina';
+$lang['js']['medialarge'] = 'Bertsio handia';
+$lang['js']['mediaoriginal'] = 'Jatorrizko bertsioa';
+$lang['js']['medialnk'] = 'Esteka xehetasunen orrira';
+$lang['js']['mediadirect'] = 'Jatorrizkora esteka zuzena';
+$lang['js']['medianolnk'] = 'Estekarik ez';
+$lang['js']['medianolink'] = 'Ez estekatu irudia';
+$lang['js']['medialeft'] = 'Irudia ezkerrean lerrokatu';
+$lang['js']['mediaright'] = 'Irudia eskuinean lerrokatu';
+$lang['js']['mediacenter'] = 'Irudia erdian lerrokatu';
+$lang['js']['medianoalign'] = 'Ez erabili lerrokatzerik';
+$lang['js']['nosmblinks'] = 'Window baliabide konpartituetara estekek Microsoft Internet Explorer-en bakarrik balio dute.
+Esteka kopiatu eta itsatsi dezakezu dena den.';
+$lang['js']['linkwiz'] = 'Estekatze Laguntzailea';
+$lang['js']['linkto'] = 'Estekatu hona:';
+$lang['js']['del_confirm'] = 'Benetan ezabatu aukeratutako fitxategia(k)?';
+$lang['rssfailed'] = 'Errorea gertatu da feed hau irakurtzean:';
+$lang['nothingfound'] = 'Ez da ezer aurkitu.';
+$lang['mediaselect'] = 'Aukeratu Multimedia fitxategia';
+$lang['fileupload'] = 'Igo Multimedia Fitxategia';
+$lang['uploadsucc'] = 'Igoera arrakastatsua';
+$lang['uploadfail'] = 'Igoerak huts egin du. Baimen arazoengatik agian?';
+$lang['uploadwrong'] = 'Fitxategi igoera ukatua. Fitxategi-luzapen hau debekatua dago!';
+$lang['uploadexist'] = 'Fitxategia lehenagotik existitzen da. Ez da ezer egin.';
+$lang['uploadbadcontent'] = 'Igotako edukia ez dator bat %s fitxategi-luzapenarekin.';
+$lang['uploadspam'] = 'Igoera spam zerrenda beltzak blokeatu du.';
+$lang['uploadxss'] = 'Igoera blokeatua izan da eduki maltzurra edukitzeko susmoagatik.';
+$lang['uploadsize'] = 'Igotako fitxategia handiegia zen. (max. %s)';
+$lang['deletesucc'] = 'Ezabatua izan da "%s" fitxategia.';
+$lang['deletefail'] = 'Ezin izan da "%s" ezabatu - egiaztatu baimenak.';
+$lang['mediainuse'] = 'Ez da "%s" fitxategia ezabatu - oraindik erabilia izaten ari da.';
+$lang['namespaces'] = 'Izen-espazioak';
+$lang['mediafiles'] = 'Fitxategiak eskuragarri hemen:';
+$lang['accessdenied'] = 'Ez zaude orri hau ikusteko baimendua';
+$lang['mediausage'] = 'Erabili ondoko sintaxia fitxategi honi erreferentzia egiteko:';
+$lang['mediaview'] = 'Ikusi jatorrizko fitxategia';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Igo fitxategi bat uneko izen-espaziora. Azpi-izen-espazioak sortzeko, zure "Honela igo" fitxategi izenaren aurretik ezarri, bi puntuz (:) bananduta.';
+$lang['mediaextchange'] = 'Fitxategi-luzapena aldatua .%s -tik .%s! -ra';
+$lang['reference'] = 'Erreferentziak honentzat:';
+$lang['ref_inuse'] = 'Fitxategia ezin da ezabatu, honako orri hauek erabiltzen dutelako:';
+$lang['ref_hidden'] = 'Erreferentzi batzuk irakurtzeko baimenik ez duzun orrietan daude';
+$lang['hits'] = 'Hits';
+$lang['quickhits'] = 'Matching pagenames';
+$lang['toc'] = 'Eduki Taula';
+$lang['current'] = 'egungoa';
+$lang['yours'] = 'Zure Bertsioa';
+$lang['diff'] = 'egungo bertsioarekin dituen aldaketak aurkezten ditu';
+$lang['diff2'] = 'Erakutsi desberdintasunak aukeratutako bertsioen artean';
+$lang['difflink'] = 'Estekatu konparaketa bista honetara';
+$lang['diff_type'] = 'Ikusi diferentziak:';
+$lang['diff_inline'] = 'Lerro tartean';
+$lang['diff_side'] = 'Ondoz ondo';
+$lang['line'] = 'Marra';
+$lang['breadcrumb'] = 'Traza';
+$lang['youarehere'] = 'Hemen zaude';
+$lang['lastmod'] = 'Azken aldaketa';
+$lang['by'] = 'egilea:';
+$lang['deleted'] = 'ezabatua';
+$lang['created'] = 'sortua';
+$lang['restored'] = 'bertsio zaharra berrezarria';
+$lang['external_edit'] = 'kanpoko aldaketa';
+$lang['summary'] = 'Aldatu laburpena';
+$lang['noflash'] = '<a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> beharrezkoa da eduki hau bistaratzeko.';
+$lang['download'] = 'Deskarga Snippet-a';
+$lang['mail_newpage'] = '[DokuWiki] gehitutako orria:';
+$lang['mail_changed'] = '[DokuWiki] aldatutako orria:';
+$lang['mail_subscribe_list'] = 'izen-espazioan aldatutako orriak:';
+$lang['mail_new_user'] = 'erabiltzaile berria:';
+$lang['mail_upload'] = 'fitxategia igota:';
+$lang['qb_bold'] = 'Letra beltzez';
+$lang['qb_italic'] = 'Letra italiarrez';
+$lang['qb_underl'] = 'Azpimarratua';
+$lang['qb_code'] = 'Kodea';
+$lang['qb_strike'] = 'Marratu Testua';
+$lang['qb_h1'] = 'Izenburua 1';
+$lang['qb_h2'] = 'Izenburua 2';
+$lang['qb_h3'] = 'Izenburua 3';
+$lang['qb_h4'] = 'Izenburua 4';
+$lang['qb_h5'] = 'Izenburua 5';
+$lang['qb_h'] = 'Izenburua';
+$lang['qb_hs'] = 'Izenburua Aukeratu';
+$lang['qb_hplus'] = 'Izenburu Handiagoa';
+$lang['qb_hminus'] = 'Izenburu Txikiagoa';
+$lang['qb_hequal'] = 'Maila Berdineko Izenburua';
+$lang['qb_link'] = 'Barruko Lotura';
+$lang['qb_extlink'] = 'Kanpoko Lotura';
+$lang['qb_hr'] = 'Horizontal Marra';
+$lang['qb_ol'] = 'Zerrenda ordenatuko gaia';
+$lang['qb_ul'] = 'Zerrenda desordenatuko gaia';
+$lang['qb_media'] = 'Irudiak eta beste fitxategiak gehitu';
+$lang['qb_sig'] = 'Gehitu sinadura';
+$lang['qb_smileys'] = 'Irrifartxoak';
+$lang['qb_chars'] = 'Karaktere Bereziak';
+$lang['upperns'] = 'Jauzi izen-espazio gurasora';
+$lang['admin_register'] = 'Erabiltzaile berria gehitu';
+$lang['metaedit'] = 'Metadatua Aldatu';
+$lang['metasaveerr'] = 'Metadatuaren idazketak huts egin du';
+$lang['metasaveok'] = 'Metadatua gordea';
+$lang['img_backto'] = 'Atzera hona';
+$lang['img_title'] = 'Izenburua';
+$lang['img_caption'] = 'Epigrafea';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Fitxategi izena';
+$lang['img_fsize'] = 'Tamaina';
+$lang['img_artist'] = 'Artista';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Formatua';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Hitz-gakoak';
+$lang['subscr_subscribe_success'] = '%s gehitua %s-ren harpidetza zerrendara';
+$lang['subscr_subscribe_error'] = 'Errorea %s gehitzen %s-ren harpidetza zerrendara';
+$lang['subscr_subscribe_noaddress'] = 'Ez dago helbiderik zure login-arekin lotuta, ezin zara harpidetza zerrendara gehitua izan.';
+$lang['subscr_unsubscribe_success'] = '%s ezabatua %s-ren harpidetza zerrendatik';
+$lang['subscr_unsubscribe_error'] = 'Errorea %s ezabatzen %s-ren harpidetza zerrendatik';
+$lang['subscr_already_subscribed'] = '%s lehendik harpidetua dago %s-n';
+$lang['subscr_not_subscribed'] = '%s ez dago %s-n harpidetua';
+$lang['subscr_m_not_subscribed'] = 'Momentu honetan ez zaude orri honetara edo izen-espazio honetara harpidetua.';
+$lang['subscr_m_new_header'] = 'Gehitu harpidetza';
+$lang['subscr_m_current_header'] = 'Uneko harpidetzak';
+$lang['subscr_m_unsubscribe'] = 'Kendu harpidetza';
+$lang['subscr_m_subscribe'] = 'Harpidetu';
+$lang['subscr_m_receive'] = 'Jaso';
+$lang['subscr_style_every'] = 'e-posta aldaketa bakoitzean';
+$lang['subscr_style_digest'] = 'e-posta laburbildua orri bakoitzeko aldaketentzat (%.2f egunero)';
+$lang['subscr_style_list'] = 'aldatutako orrien zerrenda azken e-postatik (%.2f egunero)';
+$lang['authmodfailed'] = 'Erabiltzaile kautotzearen konfigurazioa okerra da. Mesedez, eman honen berri Wiki administratzaileari';
+$lang['authtempfail'] = 'Erabiltzaile kautotzea denboraldi batez ez dago erabilgarri. Egoerak hala jarraitzen badu, mesedez, eman honen berri Wiki administratzaileari';
+$lang['i_chooselang'] = 'Hautatu zure hizkuntza';
+$lang['i_installer'] = 'DokuWiki instalatzailea';
+$lang['i_wikiname'] = 'Wiki Izena';
+$lang['i_enableacl'] = 'Gaitu ACL (gomendatua) (ACL: Atzipen Kontrol Lista)';
+$lang['i_superuser'] = 'Supererabiltzailea';
+$lang['i_problems'] = 'Instalatzaileak arazo batzuk aurkitu ditu, behean azalduak. Ezin duzu horiek konpondu arte jarraitu.';
+$lang['i_modified'] = 'Segurtasun arrazoiengatik, script hau DokuWikiren instalazio berri eta aldatu gabeko batekin bakarrik dabil. Deskargatutako paketetik fitxategiak berriz atera edo <a href="http://dokuwiki.org/install">DokuWikiren instalazio azalpenak</a> osorik irakurri beharko zenituzke.';
+$lang['i_funcna'] = 'PHP <code>%s</code> funtzioa ez dago erabilgarri. Agian zure hosting hornitzaileak arrazoiren batengatik ezgaituko zuen?';
+$lang['i_phpver'] = 'Zure PHP <code>%s</code> bertsioa behar den <code>%s</code> bertsioa baino zaharragoa da. PHP instalazioa eguneratu beharra daukazu.';
+$lang['i_permfail'] = 'DokuWiki ez da <code>%s</code> idazteko gai. Direktorio honen baimenen konfigurazioa konpondu behar duzu!';
+$lang['i_confexists'] = '<code>%s</code> lehendik existitzen da';
+$lang['i_writeerr'] = 'Ezin da <code>%s</code> sortu. Direktorioaren/fitxategiaren baimenak egiaztatu eta sortu fitxategia eskuz.';
+$lang['i_badhash'] = 'aldatutakoa edo ezezaguna den dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - balioa arauen aurka edo hutsa';
+$lang['i_success'] = 'Konfigurazioa arrakastaz amaitu da. Orain, install.php fitxategia ezabatu dezakezu. Jarraitu ezazu <a href="doku.php">zure DokuWiki berrian</a>.';
+$lang['i_failure'] = 'Akats batzuk gertatu dira konfigurazio fitxategiak idazterakoan. Hauek eskuz konpondu beharra izan dezakezu <a href="doku.php">zure DokuWiki berria</a> erabili ahal izan aurretik.';
+$lang['i_policy'] = 'Hasierako ACL politika';
+$lang['i_pol0'] = 'Wiki Irekia (irakurri, idatzi, fitxategiak igo edonorentzat)';
+$lang['i_pol1'] = 'Wiki Publikoa (irakurri edonorentzat, idatzi eta fitxategiak igo erregistratutako erabiltzaileentzat)';
+$lang['i_pol2'] = 'Wiki Itxia (irakurri, idatzi, fitxategiak igo erregistratutako erabiltzaileentzat soilik)';
+$lang['i_retry'] = 'Berriz saiatu';
+$lang['i_license'] = 'Mesedez, aukeratu zein lizentzipean ezarri nahi duzun zure edukia:';
+$lang['recent_global'] = 'Une honetan <b>%s</b> izen-espazioaren barneko aldaketak ikusten ari zara.<a href="%s"> Wiki osoaren azken aldaketak</a> ere ikusi ditzakezu.';
+$lang['years'] = 'duela %d urte';
+$lang['months'] = 'duela %d hilabete';
+$lang['weeks'] = 'duela %d aste';
+$lang['days'] = 'duela %d egun';
+$lang['hours'] = 'duela %d ordu';
+$lang['minutes'] = 'duela %d minutu';
+$lang['seconds'] = 'duela %d segundu';
+$lang['wordblock'] = 'Zure aldaketa ez da aldatua izan blokeatutako testua (spam) daukalako.';
diff --git a/inc/lang/eu/locked.txt b/inc/lang/eu/locked.txt
new file mode 100644
index 000000000..dc29e51a5
--- /dev/null
+++ b/inc/lang/eu/locked.txt
@@ -0,0 +1,3 @@
+====== Orria blokeatua ======
+
+Orrialde hau blokeatua dago beste erabiltzaile batengatik. Berak aldaketak bukatu arte itxaron beharko duzu.
diff --git a/inc/lang/eu/login.txt b/inc/lang/eu/login.txt
new file mode 100644
index 000000000..ebb1607d9
--- /dev/null
+++ b/inc/lang/eu/login.txt
@@ -0,0 +1,4 @@
+====== Login ======
+
+Ez duzu sesiorik hasi! Sar ezazu zure erabiltzaile izena eta pasahitza. Gogoratu coockie-ak baimenduta izan behar dituzula.
+
diff --git a/inc/lang/eu/mailtext.txt b/inc/lang/eu/mailtext.txt
new file mode 100644
index 000000000..86ab1a3a7
--- /dev/null
+++ b/inc/lang/eu/mailtext.txt
@@ -0,0 +1,17 @@
+DokuWiki-Eskuliburuetan orriren bat aldatu edo gehitu da. Hemen dituzu xehetasunak
+
+Data : @DATE@
+Nabigatzailea : @BROWSER@
+IP-Helbidea : @IPADDRESS@
+Host izena : @HOSTNAME@
+Bertsio zaharra : @OLDPAGE@
+Bertsio berria : @NEWPAGE@
+Aldatu laburpena : @SUMMARY@
+Erabiltzailea : @USER@
+
+@DIFF@
+
+
+--
+Email hau DokuWiki erabiliz sortu da;
+@DOKUWIKIURL@
diff --git a/inc/lang/eu/newpage.txt b/inc/lang/eu/newpage.txt
new file mode 100644
index 000000000..cac872ce1
--- /dev/null
+++ b/inc/lang/eu/newpage.txt
@@ -0,0 +1,3 @@
+====== Gai hau ez da existitzen oraindik ======
+
+Existitzen ez den gai batera doan lotura bat jarraitu duzu. Zuk zeuk sortu dezakezu ''Sortu orri hau'' erabiliz.
diff --git a/inc/lang/eu/norev.txt b/inc/lang/eu/norev.txt
new file mode 100644
index 000000000..7d9cc60d3
--- /dev/null
+++ b/inc/lang/eu/norev.txt
@@ -0,0 +1,3 @@
+====== Berrikuspen hau ez da existitzen ======
+
+Zehaztutako bertsioa ez da existitzen. Erabili ''Bertsio zaharrak'' dokumentu honen aurreko bertsioen zerrenda bat ikusi ahal izateko.
diff --git a/inc/lang/eu/password.txt b/inc/lang/eu/password.txt
new file mode 100644
index 000000000..cf2a01711
--- /dev/null
+++ b/inc/lang/eu/password.txt
@@ -0,0 +1,10 @@
+Kaixo @FULLNAME@!
+
+Hau da zure erabiltzailea @TITLE@ -rentzako @DOKUWIKIURL@
+
+Erabiltzailea : @LOGIN@
+Pasahitza : @PASSWORD@
+
+--
+eMail hau DokuWikiren bitartez sortu da;
+@DOKUWIKIURL@
diff --git a/inc/lang/eu/preview.txt b/inc/lang/eu/preview.txt
new file mode 100644
index 000000000..1f0d14f5e
--- /dev/null
+++ b/inc/lang/eu/preview.txt
@@ -0,0 +1,3 @@
+====== Aurreikuspena ======
+
+Hau zure testuaren aurrebista bat besterik ez da. Gogoratu: **ez da gorde** oraindik!
diff --git a/inc/lang/eu/pwconfirm.txt b/inc/lang/eu/pwconfirm.txt
new file mode 100644
index 000000000..0f0fd5e8f
--- /dev/null
+++ b/inc/lang/eu/pwconfirm.txt
@@ -0,0 +1,12 @@
+Kaixo @FULLNAME@!
+
+Norbaitek zure @TITLE@ erabiltzailearentzat pasahitz berria eskatu du @DOKUWIKIURL@ gunean.
+
+Ez baduzu zuk eskatu pasahitz berria, ez kasurik egin posta honi.
+
+Eskakizuna zuk bidalia dela egiaztatzeko, mesedez, ondorengo esteka erabili.
+
+@CONFIRM@
+
+--
+Posta hau @DOKUWIKIURL@ gunean DokuWikik sortua izan da. \ No newline at end of file
diff --git a/inc/lang/eu/read.txt b/inc/lang/eu/read.txt
new file mode 100644
index 000000000..f7ed7b071
--- /dev/null
+++ b/inc/lang/eu/read.txt
@@ -0,0 +1 @@
+Orri hau irakurtzeko bakarrik da. Jatorria ikusi dezakezu baina ezin duzu aldatu. Administratzailearekin kontaktuan jarri gaizki dagoela uste baduzu.
diff --git a/inc/lang/eu/recent.txt b/inc/lang/eu/recent.txt
new file mode 100644
index 000000000..4ab5482ce
--- /dev/null
+++ b/inc/lang/eu/recent.txt
@@ -0,0 +1,3 @@
+====== Azken Aldaketak ======
+
+Ondorengo orriak aldatu berriak izan dira:
diff --git a/inc/lang/eu/register.txt b/inc/lang/eu/register.txt
new file mode 100644
index 000000000..4a8a49bd7
--- /dev/null
+++ b/inc/lang/eu/register.txt
@@ -0,0 +1,3 @@
+====== Erregistratu erabiltzaile berri bezala ======
+
+Bete beheko informazio guztia wiki honetan kontu berri bat sortzeko. Ziurtatu **baliozko posta-e helbide** bat ematen duzula - ez bazaizu hemen eskatzen pasahitzik sartzeko, berri bat bidaliko zaizu helbide horretara. Saioa hasteko izenak baliozko [[doku>pagename|orri izena]] izan behar du. \ No newline at end of file
diff --git a/inc/lang/eu/registermail.txt b/inc/lang/eu/registermail.txt
new file mode 100644
index 000000000..a0154444e
--- /dev/null
+++ b/inc/lang/eu/registermail.txt
@@ -0,0 +1,13 @@
+Erabiltzaile berri bat erregistratu da. Hona hemen xehetasunak:
+
+Erabiltzaile izena : @NEWUSER@
+Izen osoa : @NEWNAME@
+Posta-e : @NEWEMAIL@
+
+Data : @DATE@
+Nabigatzailea : @BROWSER@
+IP-Helbidea : @IPADDRESS@
+Hostalari izena : @HOSTNAME@
+
+--
+Posta hau @DOKUWIKIURL@ gunean DokuWikik sortua izan da. \ No newline at end of file
diff --git a/inc/lang/eu/resendpwd.txt b/inc/lang/eu/resendpwd.txt
new file mode 100644
index 000000000..98f261cd8
--- /dev/null
+++ b/inc/lang/eu/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Bidali pasahitz berria ======
+
+Mesedez, sartu zure erabiltzaile izena beheko formularioan zure wiki honetako kontuarentzat pasahitz berria eskatzeko. Baieztapen esteka bat bidaliko zaizu erregistratutako zure posta-e helbidera. \ No newline at end of file
diff --git a/inc/lang/eu/revisions.txt b/inc/lang/eu/revisions.txt
new file mode 100644
index 000000000..203cb7e43
--- /dev/null
+++ b/inc/lang/eu/revisions.txt
@@ -0,0 +1,3 @@
+====== Bertsio zaharrak ======
+
+Hauek egungo dokumentua baino zaharragoak diren bertsioak dira. Hauetako bertsio batetara itzultzeko aukera ezazu behetik, pultsatu ''Sortu orri hau'' eta gorde.
diff --git a/inc/lang/eu/searchpage.txt b/inc/lang/eu/searchpage.txt
new file mode 100644
index 000000000..2a487a3bb
--- /dev/null
+++ b/inc/lang/eu/searchpage.txt
@@ -0,0 +1,5 @@
+====== Bilaketa ======
+
+Emaitzak ondorengo aurkiketan bilatu ditzakezu. Bilatzen zabiltzana aurkitu ez baduzu, zuk zeuk sortu dezakezu orri berri bat bilaketa ostean ''Sortu orri hau'' erabiliz.
+
+===== Bilaketa emaitzak: =====
diff --git a/inc/lang/eu/showrev.txt b/inc/lang/eu/showrev.txt
new file mode 100644
index 000000000..ad1b36057
--- /dev/null
+++ b/inc/lang/eu/showrev.txt
@@ -0,0 +1,2 @@
+**Hau dokumentuaren bertsio zahar bat da!**
+----
diff --git a/inc/lang/eu/stopwords.txt b/inc/lang/eu/stopwords.txt
new file mode 100644
index 000000000..1aeb868bc
--- /dev/null
+++ b/inc/lang/eu/stopwords.txt
@@ -0,0 +1,26 @@
+# Lista hau, indexatzaileak alde batera uzten dituen hitzen zerrenda da, hitz bat lerroko
+# Fitxategi hau editatzean, ziurtatu UNIX lerro bukaerak (lerro berri bakarra) erabiltzen duzula
+# Ez dago 3 letra baino motzagoak diren hitzik sartu beharrik - bestela ere baztertuak dira
+# This list is based upon the ones found at http://www.ranks.nl/stopwords/
+# FITXATEGI HONEK BEGIRATU BAT BEHAR DU!
+buruz
+dira
+da
+eta
+zure
+haiek
+haien
+com
+nondik
+nora
+nola
+zer
+hau
+zen
+noiz
+non
+nor
+nork
+und
+the
+www \ No newline at end of file
diff --git a/inc/lang/eu/subscr_digest.txt b/inc/lang/eu/subscr_digest.txt
new file mode 100644
index 000000000..e7962ca22
--- /dev/null
+++ b/inc/lang/eu/subscr_digest.txt
@@ -0,0 +1,20 @@
+Kaixo!
+
+@TITLE@ wikiko @PAGE@ orria aldatu egin da.
+Hemen aldaketak:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Berrikuste zaharra: @OLDPAGE@
+Berrikuste berria: @NEWPAGE@
+
+Orri jakinarazpenak ezeztatzeko, sartu wikian
+@DOKUWIKIURL@ helbidean, bisitatu
+@SUBSCRIBE@
+eta ezabatu orri eta/edo izen-espazio aldaketen harpidetza.
+
+--
+E-posta hau DokuWiki-k sortua izan da helbide honetan:
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/eu/subscr_form.txt b/inc/lang/eu/subscr_form.txt
new file mode 100644
index 000000000..02a117898
--- /dev/null
+++ b/inc/lang/eu/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Harpidetza Kudeaketa ======
+
+Orri honek, oraingo orriko eta izen-espazioko harpidetzak kudeatzeko aukera ematen dizu. \ No newline at end of file
diff --git a/inc/lang/eu/subscr_list.txt b/inc/lang/eu/subscr_list.txt
new file mode 100644
index 000000000..950cd352b
--- /dev/null
+++ b/inc/lang/eu/subscr_list.txt
@@ -0,0 +1,17 @@
+Kaixo!
+
+@TITLE@ wikiko @PAGE@ izen-espazioko orri batzuk aldatu egin dira.
+Hemen aldatutako orriak:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Orri jakinarazpenak ezeztatzeko, sartu wikian
+@DOKUWIKIURL@ helbidean, bisitatu
+@SUBSCRIBE@
+eta ezabatu orri eta/edo izen-espazio aldaketen harpidetza.
+
+--
+E-posta hau DokuWiki-k sortua izan da helbide honetan:
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/eu/subscr_single.txt b/inc/lang/eu/subscr_single.txt
new file mode 100644
index 000000000..490211784
--- /dev/null
+++ b/inc/lang/eu/subscr_single.txt
@@ -0,0 +1,23 @@
+Kaixo!
+
+@TITLE@ wikiko @PAGE@ orria aldatu egin da.
+Hemen aldaketak:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Data : @DATE@
+Erabiltzailea : @USER@
+Aldaketaren Laburpena: @SUMMARY@
+Berrikuste Zaharra: @OLDPAGE@
+Berrikuste Berria: @NEWPAGE@
+
+Orri jakinarazpenak ezeztatzeko, sartu wikian
+@DOKUWIKIURL@ helbidean, bisitatu
+@SUBSCRIBE@
+eta ezabatu orri eta/edo izen-espazio aldaketen harpidetza.
+
+--
+E-posta hau DokuWiki-k sortua izan da helbide honetan:
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/eu/updateprofile.txt b/inc/lang/eu/updateprofile.txt
new file mode 100644
index 000000000..233bfecf1
--- /dev/null
+++ b/inc/lang/eu/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Eguneratu zure kontuaren profila ======
+
+Aldatu nahi dituzun atalak bakarrik bete behar dituzu. Ezin duzu zure erabiltzaile izena aldatu. \ No newline at end of file
diff --git a/inc/lang/eu/uploadmail.txt b/inc/lang/eu/uploadmail.txt
new file mode 100644
index 000000000..639f3d95a
--- /dev/null
+++ b/inc/lang/eu/uploadmail.txt
@@ -0,0 +1,13 @@
+Fitxategi bat igo da zure DokuWikira. Hona hemen xehetasunak:
+
+Fitxategia : @MEDIA@
+Data : @DATE@
+Nabigatzailea : @BROWSER@
+IP-Helbide : @IPADDRESS@
+Hostalari izena : @HOSTNAME@
+Tamaina : @SIZE@
+MIME Mota : @MIME@
+Erabiltzailea : @USER@
+
+--
+Posta hau @DOKUWIKIURL@ gunean DokuWikik sortua izan da. \ No newline at end of file
diff --git a/inc/lang/fa/admin.txt b/inc/lang/fa/admin.txt
new file mode 100644
index 000000000..ce7550977
--- /dev/null
+++ b/inc/lang/fa/admin.txt
@@ -0,0 +1,3 @@
+====== مدیریت ======
+
+در اینجا لیستی از وظیفه‌های مدیریتی را مشاهده می‌کنید. \ No newline at end of file
diff --git a/inc/lang/fa/adminplugins.txt b/inc/lang/fa/adminplugins.txt
new file mode 100644
index 000000000..3d2bb4a5b
--- /dev/null
+++ b/inc/lang/fa/adminplugins.txt
@@ -0,0 +1 @@
+===== برنامه های جانبی دیگر ===== \ No newline at end of file
diff --git a/inc/lang/fa/backlinks.txt b/inc/lang/fa/backlinks.txt
new file mode 100644
index 000000000..6864e22d6
--- /dev/null
+++ b/inc/lang/fa/backlinks.txt
@@ -0,0 +1,3 @@
+====== پیوندهای بازگشتی ======
+
+در این‌جا لیستی از صفحاتی که به این صفحه پیوند داده‌اند را مشاهده می‌کنید. \ No newline at end of file
diff --git a/inc/lang/fa/conflict.txt b/inc/lang/fa/conflict.txt
new file mode 100644
index 000000000..9de037024
--- /dev/null
+++ b/inc/lang/fa/conflict.txt
@@ -0,0 +1,5 @@
+====== یک نگارش جدید وجود دارد ======
+
+این نگارش جدید از مطلبی که ویرایش کرده‌اید وجود دارد. این اتفاق زمانی رخ می‌دهد که یک کاربر دیگر زمانی که شما ویرایش می‌کرده‌اید، ان را تغییر داده است.
+
+تفاوت‌های زیر را بررسی کنید، و تصمیم بگیرید که کدام نگارش حفظ شود. اگر دکمه‌ی «ذخیره» را بفشارید، نسخه‌ی شما ذخیره می‌شود و اگر دکمه‌ی «لغو» را بفشارید، نسخه‌ی کنونی حفظ خواهد شد. \ No newline at end of file
diff --git a/inc/lang/fa/denied.txt b/inc/lang/fa/denied.txt
new file mode 100644
index 000000000..827f73e2b
--- /dev/null
+++ b/inc/lang/fa/denied.txt
@@ -0,0 +1,3 @@
+====== دسترسی ممکن نیست ======
+
+شرمنده، شما اجازه‌ی دسترسی ب این صفحه را ندارید. ممکن است فراموش کرده باشید که وارد سایت شوید! \ No newline at end of file
diff --git a/inc/lang/fa/diff.txt b/inc/lang/fa/diff.txt
new file mode 100644
index 000000000..d5354f727
--- /dev/null
+++ b/inc/lang/fa/diff.txt
@@ -0,0 +1,3 @@
+====== تفاوت‌ها ======
+
+تفاوت دو نسخه‌ی متفاوت از صفحه را مشاهده می‌کنید. \ No newline at end of file
diff --git a/inc/lang/fa/draft.txt b/inc/lang/fa/draft.txt
new file mode 100644
index 000000000..164b217b7
--- /dev/null
+++ b/inc/lang/fa/draft.txt
@@ -0,0 +1,5 @@
+====== فایل چرک‌نویس یافت شد ======
+
+آخرین سشن ویرایش شما با موفقیت به پایان نرسیده. Dokuwiki به طور خودکار چرک‌نویسی از صفحه‌ی شما ذخیره می‌کند که شما می‌توانید آن را کامل کنید. در زیر مقادیر موجود در چرک‌نویس را مشاهده می‌کنید.
+
+خواهشمندیم تصمیم بگیرید که می‌خواهید چرک‌نویس را //بازیابی//، یا آن را //حذف// کنید و یا ویرایش را //لغو// نمایید. \ No newline at end of file
diff --git a/inc/lang/fa/edit.txt b/inc/lang/fa/edit.txt
new file mode 100644
index 000000000..7c3873af4
--- /dev/null
+++ b/inc/lang/fa/edit.txt
@@ -0,0 +1 @@
+این صفحه را ویرایش کنید و کلید «ذخیره» را فشار دهید. صفحه [[wiki:syntax|قوانین نگارشی]] را برای روش نگارش ویکی مشاهده کنید. خواهشمندیم فقط در صورتی این صفحه را ویرایش کنید که توانایی **بهبود بخشیدن** به آن را دارید. اگر تصمیم دارید چیزی را تست کنید یا اولین قدم‌های‌تان را در نگارش ویکی بردارید، به [[playground:playground|زمین بازی]] بروید. \ No newline at end of file
diff --git a/inc/lang/fa/editrev.txt b/inc/lang/fa/editrev.txt
new file mode 100644
index 000000000..ca896feeb
--- /dev/null
+++ b/inc/lang/fa/editrev.txt
@@ -0,0 +1 @@
+**شما یک نگارش قدیمی را مشاهده می‌کنید!** اگر این نگارش را ذخیره کنید، شما یک نگارش جدید ایجاد کرده‌اید! \ No newline at end of file
diff --git a/inc/lang/fa/index.txt b/inc/lang/fa/index.txt
new file mode 100644
index 000000000..89ed74b7d
--- /dev/null
+++ b/inc/lang/fa/index.txt
@@ -0,0 +1,3 @@
+====== فهرست ======
+
+این صفحه فهرست تمامی صفحات بر اساس [[doku>namespaces|فضای‌نام‌ها]] است. \ No newline at end of file
diff --git a/inc/lang/fa/install.html b/inc/lang/fa/install.html
new file mode 100644
index 000000000..b76e9443f
--- /dev/null
+++ b/inc/lang/fa/install.html
@@ -0,0 +1,12 @@
+<p>این صفحه به شما در نصب و تنظیم
+<a href="http://dokuwiki.org">Dokuwiki</a> کمک می‌کند. اطلاعات بیشتری در این مورد را می‌توانید در <a href="http://dokuwiki.org/installer">بخش راهنما</a> مشاهده کنید.</p>
+
+<p>DokuWiki از فایل‌های معمولی برای ذخیره‌ی صفحات ویکی و اطلاعات مربوط به آن‌ها استفاده می‌کند (مثل تصاویر، فهرست‌های جستجو، نگارش‌های پیشین و غیره). برای نصب موفقیت آمیز DokuWiki
+<strong>باید</strong> دسترسی نوشتن برای شاخه‌های این فایل‌ها داشته باشید. این کار باید توسط دستورات خط فرمان و یا دسترسی FTP و یا از طریق کنترل پنل خدمات میزبانی‌تون انجام شود. </p>
+
+<p>این برنامه <acronym title="access control list">دسترسی‌ها</acronym>ی DokuWiki را برای شما تنظیم خواهد کرد،
+به این معنی که مدیر سیستم می‌تواند به صفحه‌ی مدیران وارد شود، افزونه نصب کنید، کاربران را مدیریت کند، دسترسی به صفحات ویکی را مدیریت کند و یا تنظیمات را تغییر دهد.</p>
+
+<p>برای اطلاعات بیشتر در مورد نصب می‌توانید از این پیوند‌ها استفاده کنید
+<a href="http://dokuwiki.org/install">روش نصب</a>
+و <a href="http://dokuwiki.org/config">تنظیمات پیکربندی</a>.</p> \ No newline at end of file
diff --git a/inc/lang/fa/lang.php b/inc/lang/fa/lang.php
new file mode 100644
index 000000000..6609d243d
--- /dev/null
+++ b/inc/lang/fa/lang.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * fa language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesFa.php?view=co
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'rtl';
+$lang['doublequoteopening'] = '«';
+$lang['doublequoteclosing'] = '»';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'ویرایش این صفحه';
+$lang['btn_source'] = 'نمایش مبدا';
+$lang['btn_show'] = 'نمایش صفحه';
+$lang['btn_create'] = 'ساخت این صفحه';
+$lang['btn_search'] = 'جستجو';
+$lang['btn_save'] = 'ذخیره';
+$lang['btn_preview'] = 'پیش‌نمایش';
+$lang['btn_top'] = 'برگشت به بالا';
+$lang['btn_newer'] = 'نتایج بیشتر »';
+$lang['btn_older'] = '« نتایج کمتر';
+$lang['btn_revs'] = 'نگارش‌های پیشین';
+$lang['btn_recent'] = 'تغییرات اخیر';
+$lang['btn_upload'] = 'ارسال';
+$lang['btn_cancel'] = 'لغو';
+$lang['btn_index'] = 'فهرست';
+$lang['btn_secedit'] = 'ویرایش';
+$lang['btn_login'] = 'ورود به سیستم';
+$lang['btn_logout'] = 'خروج از سیستم';
+$lang['btn_admin'] = 'مدیر';
+$lang['btn_update'] = 'به روز رسانی';
+$lang['btn_delete'] = 'حذف';
+$lang['btn_back'] = 'عقب';
+$lang['btn_backlink'] = 'پیوندهای به این صفحه';
+$lang['btn_backtomedia'] = 'بازگشت به انتخاب فایل';
+$lang['btn_subscribe'] = 'عضویت در تغییرات صفحه';
+$lang['btn_profile'] = 'به روز رسانی پروفایل';
+$lang['btn_reset'] = 'بازنشاندن';
+$lang['btn_resendpwd'] = 'یک گذرواژه‌ی جدید برای شما فرستاده شود';
+$lang['btn_draft'] = 'ویرایش پیش‌نویس';
+$lang['btn_recover'] = 'بازیابی پیش‌نویس';
+$lang['btn_draftdel'] = 'حذف پیش‌نویس';
+$lang['btn_revert'] = 'بازیابی';
+$lang['btn_register'] = 'یک حساب جدید بسازید';
+$lang['loggedinas'] = 'به عنوان کاربر روبرو وارد شده‌اید:';
+$lang['user'] = 'نام کاربری:';
+$lang['pass'] = 'گذرواژه‌ی شما';
+$lang['newpass'] = 'گذروازه‌ی جدید';
+$lang['oldpass'] = 'گذرواژه‌ی پیشین';
+$lang['passchk'] = 'گذرواژه را دوباره وارد کنید';
+$lang['remember'] = 'گذرواژه را به یاد بسپار.';
+$lang['fullname'] = '*نام واقعی شما';
+$lang['email'] = 'ایمیل شما*';
+$lang['profile'] = 'پروفایل کاربر';
+$lang['badlogin'] = 'خطا در ورود به سیستم';
+$lang['minoredit'] = 'این ویرایش خُرد است';
+$lang['draftdate'] = 'ذخیره خودکار پیش‌نویس';
+$lang['nosecedit'] = 'این صفحه در این میان تغییر کرده است، اطلاعات بخش قدیمی شده است، در عوض محتوای کل نمایش داده می‌شود.';
+$lang['regmissing'] = 'متاسفم، شما باید همه قسمت‌ها را پر کنید.';
+$lang['reguexists'] = 'نام کاربری‌ای که وارد کردید قبلن استفاده شده است. خواهشمندیم یک نام دیگر انتخاب کنید.';
+$lang['regsuccess'] = 'کاربر ساخته شد و گذرواژه به صورت ایمیل ارسال گردید.';
+$lang['regsuccess2'] = 'حساب ایجاد شد.';
+$lang['regmailfail'] = 'مشکلی در ارسال ایمیل پیش آمده است، با مدیر تماس بگیرید!';
+$lang['regbadmail'] = 'نشانی واردشده‌ی ایمیل قابل‌قبول نیست، چرا که دارای ساختار نامعتبری است. خواهشمندیم نشانی‌ای با ساختار صحیح وارد کنید و یا بخش مربوط را خالی بگذارید.';
+$lang['regbadpass'] = 'گذرواژه‌هایی که وارد کردید یکسان نیستند.';
+$lang['regpwmail'] = 'گذرواژه‌ی DokuWiki شما';
+$lang['reghere'] = 'شما هنوز حسابی در اینجا ندارید؟ یکی ایجاد کنید';
+$lang['profna'] = 'این ویکی اجازه ویرایش پروفایل را نمی‌دهد';
+$lang['profnochange'] = 'تغییری صورت نگرفت';
+$lang['profnoempty'] = 'نام و آدرس ایمیل باید پر شود';
+$lang['profchanged'] = 'پروفایل کاربر با موفقیت به روز شد';
+$lang['pwdforget'] = 'گذرواژه‌ی خود را فراموش کرده‌اید؟ جدید دریافت کنید';
+$lang['resendna'] = 'این ویکی ارسال مجدد گذرواژه را پشتیبانی نمی‌کند';
+$lang['resendpwd'] = 'گذرواژه‌ی جدید ارسال شد';
+$lang['resendpwdmissing'] = 'متاسفم، شما باید تمام قسمت‌ها را پر کنید';
+$lang['resendpwdnouser'] = 'متاسفم، ما نتوانستیم این نام کاربری را در بانک خود پیدا کنیم';
+$lang['resendpwdbadauth'] = 'متاسفم، کد شناسایی معتبر نیست. از صحت لینک تاییدیه اطمینان حاصل کنید.';
+$lang['resendpwdconfirm'] = 'یک ایمیل تاییدیه‌ی آدرس به آدرس مورنظر ارسال شد. قبل از اینکه نامه‌ی دیگری قابل ارسال به این آدرس باشد، باید دستوراتی که در آن نامه آمده است را جهت تایید این مساله که این آدرس متعلق به شماست، اجرا کنید.';
+$lang['resendpwdsuccess'] = 'گذرواژه‌ی جدید شما توسط ایمیل ارسال شد';
+$lang['license'] = 'به جز مواردی که ذکر می‌شود، مابقی محتویات ویکی تحت مجوز زیر می‌باشند:';
+$lang['licenseok'] = 'توجه: با ویرایش این صفحه، شما مجوز زیر را تایید می‌کنید:';
+$lang['searchmedia'] = 'نام فایل برای جستجو:';
+$lang['searchmedia_in'] = 'جستجو در %s';
+$lang['txt_upload'] = 'فایل را برای ارسال انتخاب کنید';
+$lang['txt_filename'] = 'ارسال به صورت (اختیاری)';
+$lang['txt_overwrt'] = 'بر روی فایل موجود بنویس';
+$lang['lockedby'] = 'در حال حاضر قفل شده است';
+$lang['lockexpire'] = 'قفل منقضی شده است';
+$lang['js']['willexpire'] = 'حالت قفل شما مدتی است منقضی شده است \n برای جلوگیری از تداخل دکمه‌ی پیش‌نمایش را برای صفر شدن ساعت قفل بزنید.';
+$lang['js']['notsavedyet'] = 'تغییرات ذخیره شده از بین خواهد رفت.
+ می‌خواهید ادامه دهید؟';
+$lang['js']['searchmedia'] = 'جستجو برای فایل';
+$lang['js']['keepopen'] = 'پنجره را ر زمان انتخاب باز نگه‌دار';
+$lang['js']['hidedetails'] = 'پتهان کردن جزییات';
+$lang['js']['mediatitle'] = 'تنظیمات پیوند';
+$lang['js']['mediadisplay'] = 'نوع پیوند';
+$lang['js']['mediaalign'] = 'هم‌ترازی';
+$lang['js']['mediasize'] = 'اندازه تصویر';
+$lang['js']['mediatarget'] = 'هدف پیوند';
+$lang['js']['mediaclose'] = 'بستن';
+$lang['js']['mediainsert'] = 'درج کردن';
+$lang['js']['mediadisplayimg'] = 'نمایش تصویر';
+$lang['js']['mediadisplaylnk'] = 'فقط پیوند را نمایش بده.';
+$lang['js']['mediasmall'] = 'نگارش کوچک';
+$lang['js']['mediamedium'] = 'نگارش متوسط';
+$lang['js']['medialarge'] = 'نگارش بزرگ';
+$lang['js']['mediaoriginal'] = 'نگارش اصلی';
+$lang['js']['medialnk'] = 'پیوند به صفحه‌ی جزییات';
+$lang['js']['mediadirect'] = 'پیوند مستقیم به اصلی';
+$lang['js']['medianolnk'] = 'بدون پیوند';
+$lang['js']['medianolink'] = 'تصویر را پیوند نکن';
+$lang['js']['medialeft'] = 'تصویر را با چپ هم‌تراز کن.';
+$lang['js']['mediaright'] = 'تصویر را با راست هم‌تراز کن.';
+$lang['js']['mediacenter'] = 'تصویر را با وسط هم‌تراز کن.';
+$lang['js']['medianoalign'] = 'هم‌تراز نکن.';
+$lang['js']['nosmblinks'] = 'پیوند به Windows share فقط در اینترنت‌اکسپلورر قابل استفاده است.
+شما می‌توانید پیوند‌ها رو کپی کنید.';
+$lang['js']['linkwiz'] = 'ویزارد پیوند';
+$lang['js']['linkto'] = 'پیوند به:';
+$lang['js']['del_confirm'] = 'واقعن تصمیم به حذف این موارد دارید؟';
+$lang['rssfailed'] = 'بروز خطا در هنگام واکشی';
+$lang['nothingfound'] = 'چیزی پیدا نشد';
+$lang['mediaselect'] = 'فایل‌ها';
+$lang['fileupload'] = 'ارسال پرونده';
+$lang['uploadsucc'] = 'ارسال با موفقیت انجام شد';
+$lang['uploadfail'] = 'خطا در ارسال';
+$lang['uploadwrong'] = 'ارسال متوقف شد. این توسعه‌ی فایل ممنوع می‌باشد.';
+$lang['uploadexist'] = 'این فابل وجود دارد. عملی انجام نشد.';
+$lang['uploadbadcontent'] = 'محتوای فایل ارسال شده با توسعه‌ی %s متناقض است.';
+$lang['uploadspam'] = 'فایل ارسال شده توسط لیست سیاه اسپم‌ها مسدود شده است.';
+$lang['uploadxss'] = 'این صفحه حاوی اسکریپت یا کد اچ‌تی‌ام‌ال است که ممکن است به نادرست توسط مرورگر وب تفسیر شود.';
+$lang['uploadsize'] = 'فایل ارسال شده سنگین است. (بیشینه، %s)';
+$lang['deletesucc'] = 'فایل «%s» حذف شد.';
+$lang['deletefail'] = '«%s» حذف نمی‌شود، دسترسی‌ها را بررسی کنید.';
+$lang['mediainuse'] = 'فایل «%s» حذف نمی‌شود، چون هنوز در حال استفاده است.';
+$lang['namespaces'] = 'فضای‌نام';
+$lang['mediafiles'] = 'فایل‌های موجود در';
+$lang['accessdenied'] = 'شما اجازه‌ی مشاهده‌ی این صفحه را ندارید.';
+$lang['mediausage'] = 'برای ارجاع دادن به فایل از نگارش زیر استفاده کنید.';
+$lang['mediaview'] = 'مشاهده‌ی فایل اصلی';
+$lang['mediaroot'] = 'ریشه';
+$lang['mediaupload'] = 'ارسال فایل به فضای‌نام کنونی. برای ایجاد زیرفضای‌نام‌ها، نام‌های آن‌ها را به عنوان پیشوندهایی که با دونقطه «:» جدا شده‌اند به نام فایل، در قسمت «ارسال به صورت» اضافه کنید.';
+$lang['mediaextchange'] = 'توسعه‌ی فایل از %s به %s تغییر داده شد.';
+$lang['reference'] = 'ارجاع‌های';
+$lang['ref_inuse'] = 'این فایل نمی‌تواند حذف شود، زیرا هم‌چنان در این صفحه استفاده شده است:';
+$lang['ref_hidden'] = 'تعدادی مرجع در صفحاتی که شما دسترسی خواندن ندارید وجود دارد.';
+$lang['hits'] = 'بازدید';
+$lang['quickhits'] = 'جور کردن نام صفحات';
+$lang['toc'] = 'فهرست مندرجات';
+$lang['current'] = 'فعلی';
+$lang['yours'] = 'نسخه‌ی شما';
+$lang['diff'] = 'تفاوت‌ها را با نگارش کنونی نمایش بده.';
+$lang['diff2'] = 'تفاوت‌ها را با نگارش انتخابی نمایش بده.';
+$lang['difflink'] = 'پیوند به صفحه‌ی تفاوت‌ها';
+$lang['diff_type'] = 'مشاهده تغییرات:';
+$lang['diff_inline'] = 'خطی';
+$lang['diff_side'] = 'کلی';
+$lang['line'] = 'خط';
+$lang['breadcrumb'] = 'ردپا';
+$lang['youarehere'] = 'محل شما';
+$lang['lastmod'] = 'آخرین ویرایش';
+$lang['by'] = 'توسط';
+$lang['deleted'] = 'حذف شد';
+$lang['created'] = 'ایجاد شد';
+$lang['restored'] = 'یک نگارش پیشین واگردانی شد.';
+$lang['external_edit'] = 'ویرایش خارجی';
+$lang['summary'] = 'پیش‌نمایش';
+$lang['noflash'] = 'برای نمایش محتویات <a href="http://www.adobe.com/products/flashplayer/">افزونه‌ی فلش</a> مورد نیاز است.';
+$lang['download'] = 'دیافت فایل منقطع گردید';
+$lang['mail_newpage'] = 'صفحه اضافه شد:';
+$lang['mail_changed'] = 'صفحه تغییر داده شد:';
+$lang['mail_subscribe_list'] = 'صفحات تغییر داده شده در فضای‌نام';
+$lang['mail_new_user'] = 'کاربر جدید:';
+$lang['mail_upload'] = 'فایل ارسال شده:';
+$lang['qb_bold'] = 'متن پُررنگ';
+$lang['qb_italic'] = 'متن ایتالیک';
+$lang['qb_underl'] = 'متن زیرخط‌دار';
+$lang['qb_code'] = 'کد';
+$lang['qb_strike'] = 'متن وسط‌خط‌دار';
+$lang['qb_h1'] = 'عنوان سطح ۱';
+$lang['qb_h2'] = 'عنوان سطح ۲';
+$lang['qb_h3'] = 'عنوان سطح ۳';
+$lang['qb_h4'] = 'عنوان سطح ۴';
+$lang['qb_h5'] = 'عنوان سطح ۵';
+$lang['qb_h'] = 'تیتر';
+$lang['qb_hs'] = 'تیتر مورد نظر را انتخاب نمایید';
+$lang['qb_hplus'] = 'تیتر بالاتر';
+$lang['qb_hminus'] = 'تیتر پایین تر';
+$lang['qb_hequal'] = 'تیتر در یک سطح';
+$lang['qb_link'] = 'پیوند داخلی';
+$lang['qb_extlink'] = 'پیوند به بیرون (پیشوند http:// را فراموش نکنید)';
+$lang['qb_hr'] = 'خط افقی';
+$lang['qb_ol'] = 'لیست‌های مرتب';
+$lang['qb_ul'] = 'لیست‌های بدون ترتیب';
+$lang['qb_media'] = 'افزودن تصویر و فایل';
+$lang['qb_sig'] = 'افزودن امضا';
+$lang['qb_smileys'] = 'شکلک';
+$lang['qb_chars'] = 'حروف ویژه';
+$lang['upperns'] = 'پرش به فضای‌نام بالا';
+$lang['admin_register'] = 'یک حساب جدید بسازید';
+$lang['metaedit'] = 'ویرایش داده‌های متا';
+$lang['metasaveerr'] = 'نوشتن داده‌نما با مشکل مواجه شد';
+$lang['metasaveok'] = 'داده‌نما ذخیره شد';
+$lang['img_backto'] = 'بازگشت به ';
+$lang['img_title'] = 'عنوان تصویر';
+$lang['img_caption'] = 'عنوان';
+$lang['img_date'] = 'تاریخ';
+$lang['img_fname'] = 'نام فایل';
+$lang['img_fsize'] = 'اندازه';
+$lang['img_artist'] = 'عکاس/هنرمند';
+$lang['img_copyr'] = 'دارنده‌ی حق تکثیر';
+$lang['img_format'] = 'فرمت';
+$lang['img_camera'] = 'دوربین';
+$lang['img_keywords'] = 'واژه‌های کلیدی';
+$lang['subscr_subscribe_success'] = '%s به لیست آبونه %s افزوده شد';
+$lang['subscr_subscribe_error'] = 'اشکال در افزودن %s به لیست آبونه %s';
+$lang['subscr_subscribe_noaddress'] = 'هیچ آدرسی برای این عضویت اضافه نشده است، شما نمی‌توانید به لیست آبونه اضافه شوید';
+$lang['subscr_unsubscribe_success'] = '%s از لیست آبونه %s پاک شد';
+$lang['subscr_unsubscribe_error'] = 'اشکال در پاک کردن %s از لیست آبونه %s';
+$lang['subscr_already_subscribed'] = '%s پیش‌تر در %s آبونه شده است';
+$lang['subscr_not_subscribed'] = '%s در %s آبونه نشده است';
+$lang['subscr_m_not_subscribed'] = 'شما در این صفحه یا فضای‌نام آبونه نشده‌اید';
+$lang['subscr_m_new_header'] = 'افزودن آبونه';
+$lang['subscr_m_current_header'] = 'آبونه‌های کنونی';
+$lang['subscr_m_unsubscribe'] = 'لغو آبونه';
+$lang['subscr_m_subscribe'] = 'آبونه شدن';
+$lang['subscr_m_receive'] = 'دریافت کردن';
+$lang['subscr_style_every'] = 'ارسال رای‌نامه در تمامی تغییرات';
+$lang['subscr_style_digest'] = 'ارسال ایمیل‌های فشرده برای تغییرات هر صفحه';
+$lang['subscr_style_list'] = 'لیست صفحات تغییر داده شده از آخرین رای‌نامه';
+$lang['authmodfailed'] = 'اشکال در نوع معتبرسازی کاربران، مدیر ویکی را باخبر سازید.';
+$lang['authtempfail'] = 'معتبرسازی کابران موقتن مسدود می‌باشد. اگر این حالت پایدار بود، مدیر ویکی را باخبر سازید.';
+$lang['i_chooselang'] = 'انتخاب زبان';
+$lang['i_installer'] = 'نصب کننده‌ی Dokuwiki';
+$lang['i_wikiname'] = 'نام ویکی';
+$lang['i_enableacl'] = 'فعال بودن کنترل دسترسی‌ها (توصیه شده)';
+$lang['i_superuser'] = 'کاربر اصلی';
+$lang['i_problems'] = 'نصب کننده با مشکلات زیر مواجه شد. در صورت رفع این مشکلات، امکان ادامه نصب خواهد بود.';
+$lang['i_modified'] = 'به دلایل امنیتی، این اسکریپت فقط با نصب تازه و بدون تغییر DokuWiki کار خواهد کرد.شما باید دوباره فایل فشرده را باز کنید <a href="http://dokuwiki.org/install">راهنمای نصب DokuWiki</a> را بررسی کنید.';
+$lang['i_funcna'] = 'تابع <code>%s</code> در PHP موجود نیست. ممکن است شرکت خدمات وب شما آن را مسدود کرده باشد.';
+$lang['i_phpver'] = 'نگارش پی‌اچ‌پی <code>%s</code> پایین‌تر از نگارش مورد نیاز، یعنی <code>%s</code> می‌باشد. خواهشمندیم به روز رسانی کنید.';
+$lang['i_permfail'] = 'شاخه‌ی <code>%s</code> قابلیت نوشتن ندارد. شما باید دسترسی‌های این شاخه را تنظیم کنید!';
+$lang['i_confexists'] = '<code>%s</code> پیش‌تر موجود است';
+$lang['i_writeerr'] = 'توانایی ایجاد <code>%s</code> نیست. شما باید دسترسی‌های شاخه یا فایل را بررسی کنید و فایل را به طور دستی ایجاد کنید.';
+$lang['i_badhash'] = 'فایل dokuwiki.php غیرقابل تشخیص بوده یا تغییر کرده است (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - غیرقانونی و یا مقادیر تهی';
+$lang['i_success'] = 'تنظیمات با موفقیت به پایان رسید. بهتر است فایل install.php رو حذف کنید. برای ادامه <a href="doku.php">این‌جا</a> کلیک کنید.';
+$lang['i_failure'] = 'مشکلاتی در زمان نوشتن فایل تنظیمات پیش آمده است. شما باید این مشکلات را پیش از استفاده از <a href="doku.php">DokuWiki</a> برطرف کنید.';
+$lang['i_policy'] = 'کنترل دسترسی‌های اولیه';
+$lang['i_pol0'] = 'ویکی باز (همه می‌توانند بخوانند، بنویسند و فایل ارسال کنند)';
+$lang['i_pol1'] = 'ویکی عمومی (همه می‌توانند بخوانند، کاربران ثبت شده می‌توانند بنویسند و فایل ارسال کنند)';
+$lang['i_pol2'] = 'ویکی بسته (فقط کاربران ثبت شده می‌توانند بخوانند، بنویسند و فایل ارسال کنند)';
+$lang['i_retry'] = 'تلاش مجدد';
+$lang['i_license'] = 'لطفن مجوز این محتوا را وارد کنید:';
+$lang['recent_global'] = 'شما هم‌اکنون تغییرات فضای‌نام <b>%s</b> را مشاهده می‌کنید. شما هم‌چنین می‌توانید <a href="%s">تغییرات اخیر در کل ویکی را مشاهده نمایید</a>.';
+$lang['years'] = '%d سال پیش';
+$lang['months'] = '%d ماه پیش';
+$lang['weeks'] = '%d هفته‌ی پیش';
+$lang['days'] = '%d روز پیش';
+$lang['hours'] = '%d ساعت پیش';
+$lang['minutes'] = '%d دقیقه‌ی پیش';
+$lang['seconds'] = '%d ثانیه‌ی پیش';
+$lang['wordblock'] = 'تغییرات شما به دلیل داشتن محتوای مشکوک (مثل اسپم) ذخیره نشد.';
diff --git a/inc/lang/fa/locked.txt b/inc/lang/fa/locked.txt
new file mode 100644
index 000000000..1400e22da
--- /dev/null
+++ b/inc/lang/fa/locked.txt
@@ -0,0 +1,3 @@
+====== قفل شده است ======
+
+این صفحه توسط یک کاربر دیگر، برای ویرایش، قفل شده است. شما باید تا پایان ویرایش این کاربر یا پایان زمان ویرایش، صبر کنید. \ No newline at end of file
diff --git a/inc/lang/fa/login.txt b/inc/lang/fa/login.txt
new file mode 100644
index 000000000..0b1b3f9fc
--- /dev/null
+++ b/inc/lang/fa/login.txt
@@ -0,0 +1,3 @@
+====== ورود ======
+
+شما وارد سایت نشده‌اید! موارد زیر را تایپ کنید تا وارد شوید. برای ورود، نیاز دارید که کوکی‌های مرورگر فعال باشد. \ No newline at end of file
diff --git a/inc/lang/fa/mailtext.txt b/inc/lang/fa/mailtext.txt
new file mode 100644
index 000000000..44e98db06
--- /dev/null
+++ b/inc/lang/fa/mailtext.txt
@@ -0,0 +1,17 @@
+یک صفحه در ویکی افزوده شده یا تغییر کرده، اطلاعات آن را می‌توانید در زیر بینید:
+
+تاریخ: @DATE@
+مرورگر: @BROWSER@
+آدرس IP: @IPADDRESS@
+نام هوست: @HOSTNAME@
+نگارش پیشین: @OLDPAGE@
+نگارش نو: @NEWPAGE@
+خلاصه ویرایش: @SUMMARY@
+کاربر: @USER@
+
+@DIFF@
+
+
+--
+این ایمیل توسط DokuWiki تولید شده است
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fa/newpage.txt b/inc/lang/fa/newpage.txt
new file mode 100644
index 000000000..06377a94a
--- /dev/null
+++ b/inc/lang/fa/newpage.txt
@@ -0,0 +1,3 @@
+====== این صفحه وجود ندارد ======
+
+شما به این صفحه که وجود ندارد رسیده‌اید. اگر دسترسی‌ها به شما اجازه می‌دهند، می‌توانید این صفحه را با کلیلک کردن روی دکمه‌ی «ساخت این صفحه» ایجاد کنید. \ No newline at end of file
diff --git a/inc/lang/fa/norev.txt b/inc/lang/fa/norev.txt
new file mode 100644
index 000000000..78a3d94be
--- /dev/null
+++ b/inc/lang/fa/norev.txt
@@ -0,0 +1,3 @@
+====== نگارشی یافت نشد ======
+
+نگارش موردنظر یافت نشد. از دکمه‌ی «نگارش‌های پیشین» برای مشاهده‌ی نگارش‌های پیشین این صفحه استفاده کنید. \ No newline at end of file
diff --git a/inc/lang/fa/password.txt b/inc/lang/fa/password.txt
new file mode 100644
index 000000000..3f552c585
--- /dev/null
+++ b/inc/lang/fa/password.txt
@@ -0,0 +1,10 @@
+سلام @FULLNAME@!
+
+اطلاعات شخصی خود را با عنوان @TITLE@ در @DOKUWIKIURL@ را در زیر مشاهده کنید:
+
+نام کاربری: @LOGIN@
+گذرواژه: @PASSWORD@
+
+--
+این ایمیل توسط DokuWiki تولید شده است
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fa/preview.txt b/inc/lang/fa/preview.txt
new file mode 100644
index 000000000..3a67326df
--- /dev/null
+++ b/inc/lang/fa/preview.txt
@@ -0,0 +1,3 @@
+====== پیش‌نمایش ======
+
+این پیش‌نمایش متن شماست. به یاد داشته باشید که این متن **هنوز ذخیره نشده‌است** \ No newline at end of file
diff --git a/inc/lang/fa/pwconfirm.txt b/inc/lang/fa/pwconfirm.txt
new file mode 100644
index 000000000..fd76b7ddd
--- /dev/null
+++ b/inc/lang/fa/pwconfirm.txt
@@ -0,0 +1,13 @@
+سلام @FULLNAME@!
+
+یک نفر برای ورود به @DOKUWIKIURL@ با عنوان @TITLE@ درخواست گذرواژه‌ای جدید کرده است:
+
+اگر شما چنین درخواستی نداده‌اید، این ایمیل را پاک کنید.
+
+اگر این درخواست توسط شما داده شده است، باید آن را تایید کنید، پس روی پیوند زیر کلیک کنید.
+
+@CONFIRM@
+
+--
+این ایمیل توسط DokuWiki تولید شده است
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fa/read.txt b/inc/lang/fa/read.txt
new file mode 100644
index 000000000..1acfdb466
--- /dev/null
+++ b/inc/lang/fa/read.txt
@@ -0,0 +1 @@
+این صفحه فقط خواندنی است. شما می‌توانید متن صفحه را مشاهده کنید، اما نمی‌توانید آن را تغییر دهید. اگر فکر می‌کنید که مشکلی رخ داده است، مدیر ویکی را در جریان بگذارید. \ No newline at end of file
diff --git a/inc/lang/fa/recent.txt b/inc/lang/fa/recent.txt
new file mode 100644
index 000000000..5d5b5b795
--- /dev/null
+++ b/inc/lang/fa/recent.txt
@@ -0,0 +1,3 @@
+====== تغییرات اخیر ======
+
+این صفحه‌ها اخیرن تغییر کرده‌اند. \ No newline at end of file
diff --git a/inc/lang/fa/register.txt b/inc/lang/fa/register.txt
new file mode 100644
index 000000000..c6e1f0d4a
--- /dev/null
+++ b/inc/lang/fa/register.txt
@@ -0,0 +1,3 @@
+====== ثبت نام ======
+
+تمامی فیلدها را پر کنید و اطمینان پیدا کنید که ایمیل معتبر وارد کرده‌اید - اگر شما گذرواژه‌ای وارد نکردید، یک مقدار جدید برای‌تان ارسال خواهد شد. نام کاربری شما باید یک [[doku>pagename|صفحه‌ی]] معتبر باشد. \ No newline at end of file
diff --git a/inc/lang/fa/registermail.txt b/inc/lang/fa/registermail.txt
new file mode 100644
index 000000000..e22c2d0ad
--- /dev/null
+++ b/inc/lang/fa/registermail.txt
@@ -0,0 +1,14 @@
+یک کاربر تازه با مشخصات زیر عضو ویکی شده است:
+
+نام کاربری: @NEWUSER@
+اسم کامل: @NEWNAME@
+ایمیل: @NEWEMAIL@
+
+تاریخ: @DATE@
+مرورگر: @BROWSER@
+آدرس IP: @IPADDRESS@
+نام هوست: @HOSTNAME@
+
+--
+این ایمیل توسط DokuWiki تولید شده است
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fa/resendpwd.txt b/inc/lang/fa/resendpwd.txt
new file mode 100644
index 000000000..8b7b0d387
--- /dev/null
+++ b/inc/lang/fa/resendpwd.txt
@@ -0,0 +1,3 @@
+====== ارسال گذرواژه‌ی جدید ======
+
+خواهشمندیم نام کاربری خود را در فرم زیر بنویسید تا گذرواژه‌ی جدید برای تان ارسال شود. یک پیوند تاییدیه برای ایمیل ثبت شده ارسال می‌شود. \ No newline at end of file
diff --git a/inc/lang/fa/revisions.txt b/inc/lang/fa/revisions.txt
new file mode 100644
index 000000000..7714ae674
--- /dev/null
+++ b/inc/lang/fa/revisions.txt
@@ -0,0 +1,3 @@
+====== نگارش‌های پیشین ======
+
+در اینجا نگارش‌های پیشین این صفحه را مشاهده می‌کنید. برای بازگشتن به آن‌ها، آن را انتخاب کنید و کلید «ویرایش این صفحه» را انتخاب کنید و سپس ذخیره نمایید. \ No newline at end of file
diff --git a/inc/lang/fa/searchpage.txt b/inc/lang/fa/searchpage.txt
new file mode 100644
index 000000000..3f0378ed3
--- /dev/null
+++ b/inc/lang/fa/searchpage.txt
@@ -0,0 +1,5 @@
+====== جستجو ======
+
+نتایج جستجو در زیر آمده است. اگر به نتیجه‌ی مطلوبی نرسیده‌اید، می‌توانید صفحه‌ی مورد نظر را ایجاد کنید.
+
+===== نتایج ===== \ No newline at end of file
diff --git a/inc/lang/fa/showrev.txt b/inc/lang/fa/showrev.txt
new file mode 100644
index 000000000..9d0500860
--- /dev/null
+++ b/inc/lang/fa/showrev.txt
@@ -0,0 +1 @@
+**این یک نگارش قدیمی از این مطلب است!** \ No newline at end of file
diff --git a/inc/lang/fa/stopwords.txt b/inc/lang/fa/stopwords.txt
new file mode 100644
index 000000000..58d3ca0f3
--- /dev/null
+++ b/inc/lang/fa/stopwords.txt
@@ -0,0 +1,445 @@
+# 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
+من
+تو
+او
+ما
+شما
+آنها
+ایشان
+ایشون
+از
+را
+ای
+یا
+باید
+شاید
+چرا
+چون
+چگونه
+چه
+اگر
+الان
+سلام
+ممنون
+موفق
+باشید
+باش
+باشند
+باشی
+باشم
+باشد
+است
+نیست
+شد
+شدن
+شدند
+شدیم
+شدید
+درباره
+یک
+دو
+سه
+چهار
+پنج
+شش
+هفت
+هشت
+ده
+در
+هست
+هستم
+هستی
+هستیم
+هستید
+هستند
+برای
+این
+آن
+اون
+روی
+رو
+بود
+بودم
+بودی
+بودیم
+بودید
+بودند
+کجا
+کی
+با
+کس
+کسی
+پیرامون
+نزدیک
+بالا
+پایین
+بالای
+بالاتر
+موافق
+مطابق
+طبق
+برطبق
+همان
+سر
+درمیان
+عرض
+طرف
+عملا
+واقعا
+بعد
+قبل
+جستجو
+سپس
+دوباره
+رفتم
+رفتی
+رفت
+رفتیم
+رفتید
+رفتند
+بای
+اوه
+آه
+اه
+برابر
+بااینکه
+همواره
+همیشه
+پیوسته
+وقت
+هزار
+دیگر
+جدا
+شخص
+کدام
+هیچگونه
+بهرحال
+هرچیز
+هیچکار
+درهرصورت
+پدیدار
+درک
+باشه
+جنوب
+ضبط
+حوالی
+نزدیکی
+چنانچه
+بطوریکه
+هنگامیکه
+مثال
+مانند
+پرسیدن
+جویا
+خواهش
+خواستن
+انجمن
+کنار
+پیک
+بیرون
+خارج
+مرتبا
+آغاز
+پایان
+آمد
+امد
+به
+زیرا
+چونکه
+آمدن
+بودن
+درخور
+بوده
+پیش
+پس
+قبلا
+راحت
+مقدم
+کار
+برو
+بیا
+باور
+گمان
+بمیر
+چپ
+راست
+شمال
+غرب
+شرق
+دور
+گذشته
+آینده
+بهتر
+بهترین
+بدترین
+عظیم
+کوچک
+نیک
+بدتر
+خوب
+بد
+زشت
+میان
+هردو
+هم
+یکی
+کوتاه
+بلند
+مختصر
+حکم
+اما
+ولی
+لیکن
+حز
+مگر
+فقط
+بدون
+محض
+بخش
+بدست
+وسیله
+درجه
+اول
+دوم
+سوم
+چهارم
+پنجم
+ششم
+هفتم
+هشتم
+نهم
+دهم
+امکان
+داشتن
+داشتیم
+داشتی
+داشتند
+داشتید
+سبب
+علت
+موجب
+هدف
+صفر
+محتوی
+دارا
+شامل
+نیا
+چیز
+نرو
+مسیر
+روش
+جهت
+دقیقا
+درطی
+درضمن
+بسرعت
+رایج
+جاری
+طورقطعی
+شرح
+کرد
+انجام
+عدد
+غیر
+بریم
+کاملا
+قلم
+آب
+سایه
+مساوی
+صاف
+هموار
+حتی
+جفت
+هرگز
+درست
+کامل
+چنین
+دومین
+سومین
+چهارمین
+پنجمین
+ششمین
+هشتمین
+نهمین
+دهمین
+برید
+رفتن
+راه
+درود
+خداحافظ
+حاجی
+واقع
+سخت
+آسان
+مشکل
+اینجا
+آنجا
+خودش
+هنوز
+بلافاصله
+نگاه
+نگه
+آخر
+اخر
+عمرا
+کمترین
+کوچکترین
+اقل
+مثل
+شکل
+نظر
+چندین
+زیاد
+احتمالا
+متوسط
+یعنی
+اساسا
+عالی
+وای
+خودم
+خودت
+خودمان
+خودمون
+اسم
+نام
+آره
+حال
+حالا
+اینک
+خیلی
+بارها
+بسیار
+کن
+وسط
+ممکن
+راستی
+فعلا
+صحیح
+واقعی
+گفت
+گفتم
+گفتیم
+امثال
+آنکه
+مهم
+جدی
+چنان
+چندان
+زیادی
+بعضی
+گاهگاهی
+زود
+بزودی
+بگیر
+ببر
+بردن
+گیرنده
+تا
+تشکر
+سپاس
+ان
+آنان
+بکلی
+تماما
+بنا
+همدیگر
+جلو
+معمولا
+مقدار
+موقع
+اونجا
+آیا
+که
+بچه
+حاضر
+میخواستم
+بلی
+خیر
+فوروم
+خواهم
+داره
+نداره
+داری
+همون
+میبینم
+اینجوریه
+بهش
+هستن
+امضام
+اولی
+دومی
+سومی
+چهارمی
+بگذار
+بکنه
+امروز
+صدمین
+همش
+همگی
+هوا
+اعلام
+اخرین
+خودشون
+حد
+شده
+اینکه
+خب
+یه
+اینجوری
+گاه
+گهگاه
+گاهی
+گهگدار
+گهگداری
+ها
+میشه
+کمی
+راجبه
+توضیح
+بدی
+راجع
+می
+شه
+روز
+کنی
+اصلا \ No newline at end of file
diff --git a/inc/lang/fa/subscr_digest.txt b/inc/lang/fa/subscr_digest.txt
new file mode 100644
index 000000000..0ba4c898d
--- /dev/null
+++ b/inc/lang/fa/subscr_digest.txt
@@ -0,0 +1,16 @@
+سلام،
+
+صفحه‌ی @PAGE@ با عنوان @TITLE@ در ویکی تغییر کرد.
+تغییرات عبارت است از:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+نگارش پیشین: @OLDPAGE@
+نگارش نو: @NEWPAGE@
+
+برای از بین بردن آگاهی‌های این صفحه، از طریق آدرس @DOKUWIKIURL@ وارد ویکی شده و صفحه‌ی @SUBSCRIBE@ را مرور کنید و عضویت خود را از صفحه یا فضای‌نام پاک کنید.
+
+--
+این رای‌نامه با نرم‌افزار DokuWiki در آدرس @DOKUWIKIURL@ ساخته شده است. \ No newline at end of file
diff --git a/inc/lang/fa/subscr_form.txt b/inc/lang/fa/subscr_form.txt
new file mode 100644
index 000000000..39764d0a2
--- /dev/null
+++ b/inc/lang/fa/subscr_form.txt
@@ -0,0 +1,3 @@
+====== مدیریت عضویت‌ها ======
+
+این صفحه به شما امکان مدیریت عضویت‌تان را برای این صفحه یا فضای‌نام می‌دهد. \ No newline at end of file
diff --git a/inc/lang/fa/subscr_list.txt b/inc/lang/fa/subscr_list.txt
new file mode 100644
index 000000000..92ac92b74
--- /dev/null
+++ b/inc/lang/fa/subscr_list.txt
@@ -0,0 +1,16 @@
+سلام،
+
+صفحه‌های فضای‌نام @PAGE@ با عنوان @TITLE@ در ویکی تغییر کرد.
+تغییرات عبارت است از:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+نگارش پیشین: @OLDPAGE@
+نگارش نو: @NEWPAGE@
+
+برای از بین بردن آگاهی‌های این صفحه، از طریق آدرس @DOKUWIKIURL@ وارد ویکی شده و صفحه‌ی @SUBSCRIBE@ را مرور کنید و عضویت خود را از صفحه یا فضای‌نام پاک کنید.
+
+--
+این رای‌نامه با نرم‌افزار DokuWiki در آدرس @DOKUWIKIURL@ ساخته شده است. \ No newline at end of file
diff --git a/inc/lang/fa/subscr_single.txt b/inc/lang/fa/subscr_single.txt
new file mode 100644
index 000000000..a0d2a5d49
--- /dev/null
+++ b/inc/lang/fa/subscr_single.txt
@@ -0,0 +1,19 @@
+سلام،
+
+صفحه‌ی @PAGE@ با عنوان @TITLE@ در ویکی تغییر کرد.
+تغییرات عبارت است از:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+تاریخ : @DATE@
+نام‌کاربری: @USER@
+خلاصه ویرایش: @SUMMARY@
+نگارش پیشین: @OLDPAGE@
+نگارش نو: @NEWPAGE@
+
+برای از بین بردن آگاهی‌های این صفحه، از طریق آدرس @DOKUWIKIURL@ وارد ویکی شده و صفحه‌ی @NEWPAGE@ را مرور کنید و عضویت خود را از صفحه یا فضای‌نام پاک کنید.
+
+--
+این رای‌نامه با نرم‌افزار DokuWiki در آدرس @DOKUWIKIURL@ ساخته شده است. \ No newline at end of file
diff --git a/inc/lang/fa/updateprofile.txt b/inc/lang/fa/updateprofile.txt
new file mode 100644
index 000000000..d79083306
--- /dev/null
+++ b/inc/lang/fa/updateprofile.txt
@@ -0,0 +1,3 @@
+====== به روز رسانی پروفایل ======
+
+شما می‌توانید مقادیر زیر را تغییر دهید. \ No newline at end of file
diff --git a/inc/lang/fa/uploadmail.txt b/inc/lang/fa/uploadmail.txt
new file mode 100644
index 000000000..625df73dc
--- /dev/null
+++ b/inc/lang/fa/uploadmail.txt
@@ -0,0 +1,14 @@
+یک فایل به ویکی ارسال شد:
+
+فایل: @MEDIA@
+تاریخ: @DATE@
+مرورگر: @BROWSER@
+آدرس IP: @IPADDRESS@
+نام هوست: @HOSTNAME@
+اندازه: @SIZE@
+MIME: @MIME@
+کاربر: @USER@
+
+--
+این ایمیل توسط DokuWiki تولید شده است
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fi/admin.txt b/inc/lang/fi/admin.txt
new file mode 100644
index 000000000..b57b6080c
--- /dev/null
+++ b/inc/lang/fi/admin.txt
@@ -0,0 +1,3 @@
+====== Ylläpito ======
+
+Alla on lista DokuWiki:ssä käytössä olevista ylläpitotoiminnoista.
diff --git a/inc/lang/fi/adminplugins.txt b/inc/lang/fi/adminplugins.txt
new file mode 100644
index 000000000..fa3571e46
--- /dev/null
+++ b/inc/lang/fi/adminplugins.txt
@@ -0,0 +1 @@
+===== Muita liitännäisiä ===== \ No newline at end of file
diff --git a/inc/lang/fi/backlinks.txt b/inc/lang/fi/backlinks.txt
new file mode 100644
index 000000000..457720241
--- /dev/null
+++ b/inc/lang/fi/backlinks.txt
@@ -0,0 +1,4 @@
+====== Linkitykset ======
+
+Tässä lista tälle sivuille linkittävistä sivuista.
+
diff --git a/inc/lang/fi/conflict.txt b/inc/lang/fi/conflict.txt
new file mode 100644
index 000000000..be788a116
--- /dev/null
+++ b/inc/lang/fi/conflict.txt
@@ -0,0 +1,5 @@
+====== On olemassa uudempi versio ======
+
+Muokkaamastasi dokumentista on olemassa uudempi versio. Näin käy, kun toinen käyttäjä muuttaa dokumenttia sillä aikaa, kun sinä olit muokkaamassa sitä.
+
+Tutki alla näkyvät eroavaisuudet kunnolla ja päätä mikä versio säilytetään. Jos valitset "tallenna", sinun versiosi tallennetaan. Valitse ''peru'' pitääksesi tämänhetkisen, toisen käyttäjän muuttaman version.
diff --git a/inc/lang/fi/denied.txt b/inc/lang/fi/denied.txt
new file mode 100644
index 000000000..cd31da06b
--- /dev/null
+++ b/inc/lang/fi/denied.txt
@@ -0,0 +1,3 @@
+====== Lupa evätty ======
+
+Sinulla ei ole tarpeeksi valtuuksia jatkaa. Ehkä unohdit kirjautua sisään?
diff --git a/inc/lang/fi/diff.txt b/inc/lang/fi/diff.txt
new file mode 100644
index 000000000..fbf62b78c
--- /dev/null
+++ b/inc/lang/fi/diff.txt
@@ -0,0 +1,3 @@
+====== Erot ======
+
+Tämä näyttää erot valitun ja nykyisen version kesken tästä sivusta.
diff --git a/inc/lang/fi/draft.txt b/inc/lang/fi/draft.txt
new file mode 100644
index 000000000..859f4d9f9
--- /dev/null
+++ b/inc/lang/fi/draft.txt
@@ -0,0 +1,5 @@
+====== Vedos löydetty ======
+
+Edellinen muokkauksesi tälle sivulle ei ole päivittynyt oikein. DokuWiki on automaattisesti tallentanut vedoksen muokkauksen aikana. Voit nyt jatkaa muokkausta. Alla näet tallennetun version edellisestä istunnostasi.
+
+Valitse jos haluat //palauttaa// edellisen muutoksesi, //poistaa// automaattisesti tallennetun vedoksen, vai //peruuttaa// muutokset. \ No newline at end of file
diff --git a/inc/lang/fi/edit.txt b/inc/lang/fi/edit.txt
new file mode 100644
index 000000000..81b7714d8
--- /dev/null
+++ b/inc/lang/fi/edit.txt
@@ -0,0 +1 @@
+Muokkaa sivua ja paina ''Tallenna''. Katso [[wiki:syntax]] nähdäksesi Wikisyntaksi. Muuta sivua vain jos voit **parantaa** sitä. Jos haluat kokeilla Wikiä hyvä paikka siihen on [[playground:playground]].
diff --git a/inc/lang/fi/editrev.txt b/inc/lang/fi/editrev.txt
new file mode 100644
index 000000000..fd4d9a3de
--- /dev/null
+++ b/inc/lang/fi/editrev.txt
@@ -0,0 +1,2 @@
+**Olet ladannut vanhan version dokumentista** Jos tallennat tämän, tästä tulee uusin versio dokumentista.
+----
diff --git a/inc/lang/fi/index.txt b/inc/lang/fi/index.txt
new file mode 100644
index 000000000..9086e220e
--- /dev/null
+++ b/inc/lang/fi/index.txt
@@ -0,0 +1,3 @@
+====== hakemisto ======
+
+Tämä on hakemisto kaikista saatavilla olevista sivuista järjestettynä [[doku>namespace|nimiavaruuksittain]].
diff --git a/inc/lang/fi/install.html b/inc/lang/fi/install.html
new file mode 100644
index 000000000..8d20e045c
--- /dev/null
+++ b/inc/lang/fi/install.html
@@ -0,0 +1,21 @@
+<p>Tämä sivu avustaa <a href="http://dokuwiki.org">Dokuwikin</a> ensiasennuksessa ja
+ asetuksissa. Lisätietoa asennusohjelmasta löytyy ohjelman
+ <a href="http://dokuwiki.org/installer">dokumentaatiosta</a>.</p>
+
+<p>DokuWiki käyttää tavallisia tiedostoja wiki-sivujen, sekä muiden niihin liittyvien
+ tietojen kuten kuvien, hakuindeksien, versionhallinnan jne. tallentamiseen. Toimiakseen
+ oikein DokuWikillä <strong>täytyy</strong> olla kirjoitusoikeus niihin hakemistoihin joissa nämä
+ tiedostot sijaitsevat. Asennusohjelma ei pysty asettamaan näitä oikeuksia. Tämä täytyy
+ useimmiten tehdä suoraan komentoriviltä tai muulla, esimerkiksi
+ internet-palveluntarjoajan määrittämällä tavalla, kuten FTP -ohjelmalla tai erillisen
+ asetusvalikon kautta. (cPanel).</p>
+
+<p>Asennusohjelma määrittelee DokuWikin <acronym title="käyttöoikeudet">käyttöoikeudet (ACL)</acronym>,
+ jotka mahdollistavat ylläpitäjän sisäänkirjautumisen ja pääsyn DokuWikin ylläpito -valikkoon,
+ josta voidaan asentaa plugineja, hallita käyttäjätietoja, wiki-sivujen luku- ja
+ kirjoitusoikeuksia sekä muita asetuksia. Käyttöoikeuksien käyttäminen ei ole pakollista,
+ mutta se helpottaa DokuWikin ylläpitämistä.</p>
+
+<p>Kokeneille käyttäjille tai käyttäjille joilla on erityisvaatimuksia asennukselle
+ löytyy lisätietoa <a href="http://dokuwiki.org/install">asennuksesta</a> sekä
+ <a href="http://dokuwiki.org/config">asetuksista</a>.</p>
diff --git a/inc/lang/fi/lang.php b/inc/lang/fi/lang.php
new file mode 100644
index 000000000..eb2f57b0e
--- /dev/null
+++ b/inc/lang/fi/lang.php
@@ -0,0 +1,314 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Petteri <petteri@gmail.com>
+ * @author Matti Pöllä <mpo@iki.fi>
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '”';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '’';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Muokkaa tätä sivua';
+$lang['btn_source'] = 'Näytä sivun lähdekoodi';
+$lang['btn_show'] = 'Näytä sivu';
+$lang['btn_create'] = 'Luo tämä sivu';
+$lang['btn_search'] = 'Etsi';
+$lang['btn_save'] = 'Tallenna';
+$lang['btn_preview'] = 'Esikatselu';
+$lang['btn_top'] = 'Takaisin ylös';
+$lang['btn_newer'] = '<< uudemmat';
+$lang['btn_older'] = 'vanhemmat >>';
+$lang['btn_revs'] = 'Vanhat versiot';
+$lang['btn_recent'] = 'Viimeiset muutokset';
+$lang['btn_upload'] = 'Lähetä tiedosto';
+$lang['btn_cancel'] = 'Peru';
+$lang['btn_index'] = 'Hakemisto';
+$lang['btn_secedit'] = 'Muokkaa';
+$lang['btn_login'] = 'Kirjaudu sisään';
+$lang['btn_logout'] = 'Kirjaudu ulos';
+$lang['btn_admin'] = 'Ylläpito';
+$lang['btn_update'] = 'Päivitä';
+$lang['btn_delete'] = 'Poista';
+$lang['btn_back'] = 'Takaisin';
+$lang['btn_backlink'] = 'Paluulinkit';
+$lang['btn_backtomedia'] = 'Takaisin mediatiedostojen valintaan';
+$lang['btn_subscribe'] = 'Tilaa muutokset';
+$lang['btn_profile'] = 'Päivitä profiili';
+$lang['btn_reset'] = 'Tyhjennä';
+$lang['btn_resendpwd'] = 'Lähetä uusi salasana';
+$lang['btn_draft'] = 'Muokkaa luonnosta';
+$lang['btn_recover'] = 'Palauta luonnos';
+$lang['btn_draftdel'] = 'Poista luonnos';
+$lang['btn_revert'] = 'palauta';
+$lang['btn_register'] = 'Rekisteröidy';
+$lang['btn_apply'] = 'Toteuta';
+$lang['btn_media'] = 'Media manager';
+$lang['loggedinas'] = 'Kirjautunut nimellä';
+$lang['user'] = 'Käyttäjänimi';
+$lang['pass'] = 'Salasana';
+$lang['newpass'] = 'Uusi salasana';
+$lang['oldpass'] = 'Vahvista nykyinen salasana';
+$lang['passchk'] = 'uudelleen';
+$lang['remember'] = 'Muista minut';
+$lang['fullname'] = 'Koko nimi';
+$lang['email'] = 'Sähköposti';
+$lang['profile'] = 'Käyttäjän profiili';
+$lang['badlogin'] = 'Käyttäjänimi tai salasana oli väärä.';
+$lang['minoredit'] = 'Pieni muutos';
+$lang['draftdate'] = 'Luonnos tallennettu automaattisesti';
+$lang['nosecedit'] = 'Sivu on muuttunut välillä ja kappaleen tiedot olivat vanhentuneet. Koko sivu ladattu.';
+$lang['regmissing'] = 'Kaikki kentät tulee täyttää.';
+$lang['reguexists'] = 'Käyttäjä tällä käyttäjänimellä on jo olemassa.';
+$lang['regsuccess'] = 'Käyttäjä luotiin ja salasana lähetettiin sähköpostilla.';
+$lang['regsuccess2'] = 'Käyttäjänimi on luotu.';
+$lang['regmailfail'] = 'Näyttää siltä, että salasanan lähettämisessä tapahtui virhe. Ota yhteys ylläpitäjään!';
+$lang['regbadmail'] = 'Antamasi sähköpostiosoite näyttää epäkelvolta. Jos pidät tätä virheenä ota yhteys ylläpitäjään.';
+$lang['regbadpass'] = 'Annetut kaksi salasanaa eivät täsmää. Yritä uudelleen.';
+$lang['regpwmail'] = 'DokuWiki salasanasi';
+$lang['reghere'] = 'Puuttuuko sinulta käyttäjätili? Hanki sellainen';
+$lang['profna'] = 'Tässä wikissä profiilien muokkaaminen ei ole mahdollista';
+$lang['profnochange'] = 'Ei muutoksia.';
+$lang['profnoempty'] = 'Tyhjä nimi tai sähköpostiosoite ei ole sallittu.';
+$lang['profchanged'] = 'Käyttäjän profiilin päivitys onnistui.';
+$lang['pwdforget'] = 'Unohtuiko salasana? Hanki uusi';
+$lang['resendna'] = 'Tämä wiki ei tue salasanan uudelleenlähettämistä.';
+$lang['resendpwd'] = 'Lähetä uusi salasana käyttäjälle';
+$lang['resendpwdmissing'] = 'Kaikki kentät on täytettävä.';
+$lang['resendpwdnouser'] = 'Käyttäjää ei löydy tietokannastamme.';
+$lang['resendpwdbadauth'] = 'Tunnistuskoodi on virheellinen. Varmista, että käytit koko varmistuslinkkiä.';
+$lang['resendpwdconfirm'] = 'Varmistuslinkki on lähetetty sähköpostilla';
+$lang['resendpwdsuccess'] = 'Uusi salasanasi on lähetetty sähköpostilla.';
+$lang['license'] = 'Jollei muuta ole mainittu, niin sisältö tässä wikissä on lisensoitu seuraavalla lisenssillä:';
+$lang['licenseok'] = 'Huom: Muokkaamalla tätä sivua suostut lisensoimaan sisällön seuraavan lisenssin mukaisesti:';
+$lang['searchmedia'] = 'Etsi tiedostoa nimeltä:';
+$lang['searchmedia_in'] = 'Etsi kohteesta %s';
+$lang['txt_upload'] = 'Valitse tiedosto lähetettäväksi';
+$lang['txt_filename'] = 'Lähetä nimellä (valinnainen)';
+$lang['txt_overwrt'] = 'Ylikirjoita olemassa oleva';
+$lang['lockedby'] = 'Tällä hetkellä tiedoston on lukinnut';
+$lang['lockexpire'] = 'Lukitus päättyy';
+$lang['js']['willexpire'] = 'Lukituksesi tämän sivun muokkaukseen päättyy minuutin kuluttua.\nRistiriitojen välttämiseksi paina esikatselu-nappia nollataksesi lukitusajan.';
+$lang['js']['notsavedyet'] = 'Dokumentissa on tallentamattomia muutoksia, jotka häviävät.
+ Haluatko varmasti jatkaa?';
+$lang['js']['searchmedia'] = 'Etsi tiedostoja';
+$lang['js']['keepopen'] = 'Pidä valinnan ikkuna avoinna.';
+$lang['js']['hidedetails'] = 'Piilota yksityiskohdat';
+$lang['js']['mediatitle'] = 'Linkkien asetukset';
+$lang['js']['mediadisplay'] = 'Linkin tyyppi';
+$lang['js']['mediaalign'] = 'Tasaus';
+$lang['js']['mediasize'] = 'Kuvan koko';
+$lang['js']['mediatarget'] = 'Linkin kohde';
+$lang['js']['mediaclose'] = 'Sulje';
+$lang['js']['mediainsert'] = 'Liitä';
+$lang['js']['mediadisplayimg'] = 'Näytä kuva.';
+$lang['js']['mediadisplaylnk'] = 'Näytä vain linkki';
+$lang['js']['mediasmall'] = 'Pieni versio';
+$lang['js']['mediamedium'] = 'Keskikokoinen versio';
+$lang['js']['medialarge'] = 'Iso versio';
+$lang['js']['mediaoriginal'] = 'Alkuperäinen versio';
+$lang['js']['medialnk'] = 'Linkki tietosivuun';
+$lang['js']['mediadirect'] = 'Suora linkki alkuperäiseen';
+$lang['js']['medianolnk'] = 'Ei linkkiä';
+$lang['js']['medianolink'] = 'Älä linkitä kuvaa';
+$lang['js']['medialeft'] = 'Tasaa kuva vasemmalle.';
+$lang['js']['mediaright'] = 'Tasaa kuva oikealle.';
+$lang['js']['mediacenter'] = 'Tasaa kuva keskelle.';
+$lang['js']['medianoalign'] = 'Älä tasaa.';
+$lang['js']['nosmblinks'] = 'Linkit Windows-jakoihin toimivat vain Microsoft Internet Explorerilla.
+Voit silti kopioida ja liittää linkin.';
+$lang['js']['linkwiz'] = 'Linkkivelho';
+$lang['js']['linkto'] = 'Linkki kohteeseen:';
+$lang['js']['del_confirm'] = 'Haluatko todella poistaa valitut kohteet?';
+$lang['js']['restore_confirm'] = 'Haluatko varmasti palauttaa tämän version?';
+$lang['js']['media_diff'] = 'Näytä erot:';
+$lang['js']['media_diff_both'] = 'Vierekkäin';
+$lang['js']['media_diff_opacity'] = 'Päällä';
+$lang['js']['media_diff_portions'] = 'Liukusäädin';
+$lang['js']['media_select'] = 'Valitse tiedostot...';
+$lang['js']['media_upload_btn'] = 'Lähetä';
+$lang['js']['media_done_btn'] = 'Valmis';
+$lang['js']['media_drop'] = 'Pudota lähetettävät tiedostot tähän';
+$lang['js']['media_cancel'] = 'Poista';
+$lang['js']['media_overwrt'] = 'Ylikirjoita olemassa olevat tiedostot';
+$lang['rssfailed'] = 'Virhe tapahtui noudettaessa tätä syötettä: ';
+$lang['nothingfound'] = 'Mitään ei löytynyt.';
+$lang['mediaselect'] = 'Mediatiedoston valinta';
+$lang['fileupload'] = 'Mediatiedoston lähetys';
+$lang['uploadsucc'] = 'Tiedoston lähetys onnistui';
+$lang['uploadfail'] = 'Tiedoston lähetys epäonnistui. Syynä ehkä väärät oikeudet?';
+$lang['uploadwrong'] = 'Tiedoston lähetys evätty. Tämä tiedostopääte on kielletty';
+$lang['uploadexist'] = 'Tiedosto on jo olemassa. Mitään ei tehty.';
+$lang['uploadbadcontent'] = 'Tiedoston sisältö ei vastannut päätettä %s';
+$lang['uploadspam'] = 'Roskapostin estolista esti tiedoston lähetyksen.';
+$lang['uploadxss'] = 'Tiedoston lähetys estettiin mahdollisen haitallisen sisällön vuoksi.';
+$lang['uploadsize'] = 'Lähetetty tiedosto oli liian iso. (max %s)';
+$lang['deletesucc'] = 'Tiedosto "%s" on poistettu.';
+$lang['deletefail'] = 'Kohdetta "%s" poistaminen ei onnistunut - tarkista oikeudet.';
+$lang['mediainuse'] = 'Tiedostoa "%s" ei ole poistettu - se on vielä käytössä.';
+$lang['namespaces'] = 'Nimiavaruudet';
+$lang['mediafiles'] = 'Tarjolla olevat tiedostot';
+$lang['accessdenied'] = 'Sinulla ei ole oikeuksia tämän sivun katsomiseen';
+$lang['mediausage'] = 'Käytä seuraavaa merkintätapaa viittausta tehtäessä:';
+$lang['mediaview'] = 'Katsele alkuperäistä tiedostoa';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Siirrä tiedosto nykyiseen nimiavaruuteen täällä. Voit luoda uusia alinimiavaruuksia laittamalla lisäämällä sen nimen ja kaksoispisteen "Lähetä nimellä" eteen.';
+$lang['mediaextchange'] = 'Tiedoston pääte muutettu: .%s on nyt .%s!';
+$lang['reference'] = 'Viitteet';
+$lang['ref_inuse'] = 'Tiedostoa ei voi poistaa, koska seuraavat sivut käyttävät sitä:';
+$lang['ref_hidden'] = 'Osa viitteistä on sivuilla, joihin sinulla ei ole lukuoikeutta';
+$lang['hits'] = 'Osumia';
+$lang['quickhits'] = 'Sopivat sivunimet';
+$lang['toc'] = 'Sisällysluettelo';
+$lang['current'] = 'nykyinen';
+$lang['yours'] = 'Sinun versiosi';
+$lang['diff'] = 'Näytä eroavaisuudet nykyiseen versioon';
+$lang['diff2'] = 'Näytä eroavaisuudet valittuun versioon';
+$lang['difflink'] = 'Linkki vertailunäkymään';
+$lang['diff_type'] = 'Näytä eroavaisuudet:';
+$lang['diff_inline'] = 'Sisäkkäin';
+$lang['diff_side'] = 'Vierekkäin';
+$lang['line'] = 'Rivi';
+$lang['breadcrumb'] = 'Jäljet';
+$lang['youarehere'] = 'Olet täällä';
+$lang['lastmod'] = 'Viimeksi muutettu';
+$lang['by'] = '/';
+$lang['deleted'] = 'poistettu';
+$lang['created'] = 'luotu';
+$lang['restored'] = 'vanha versio palautettu';
+$lang['external_edit'] = 'ulkoinen muokkaus';
+$lang['summary'] = 'Yhteenveto muokkauksesta';
+$lang['noflash'] = 'Tarvitset <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash-liitännäisen</a> nähdäksesi tämän sisällön.';
+$lang['download'] = 'Lataa palanen';
+$lang['mail_newpage'] = 'sivu lisätty:';
+$lang['mail_changed'] = 'sivu muutettu:';
+$lang['mail_subscribe_list'] = 'muuttuneet sivut nimiavaruudessa:';
+$lang['mail_new_user'] = 'uusi käyttäjä:';
+$lang['mail_upload'] = 'tiedosto lähetetty:';
+$lang['changes_type'] = 'Näytä muutokset:';
+$lang['pages_changes'] = 'Sivut';
+$lang['media_changes'] = 'Mediatiedostot';
+$lang['both_changes'] = 'Sivut ja mediatiedostot';
+$lang['qb_bold'] = 'Lihavoitu teksti';
+$lang['qb_italic'] = 'Kursivoitu teksti';
+$lang['qb_underl'] = 'Alleviivattu teksti';
+$lang['qb_code'] = 'Kooditeksti';
+$lang['qb_strike'] = 'Yliviivattu teksti';
+$lang['qb_h1'] = 'Taso 1 otsikko';
+$lang['qb_h2'] = 'Taso 2 otsikko';
+$lang['qb_h3'] = 'Taso 3 otsikko';
+$lang['qb_h4'] = 'Taso 4 otsikko';
+$lang['qb_h5'] = 'Taso 5 otsikko';
+$lang['qb_h'] = 'Otsikko';
+$lang['qb_hs'] = 'Valitse otsikko';
+$lang['qb_hplus'] = 'Ylempi otsikko';
+$lang['qb_hminus'] = 'Alempi otsikko';
+$lang['qb_hequal'] = 'Saman tason otsikko';
+$lang['qb_link'] = 'Sisäinen linkki';
+$lang['qb_extlink'] = 'Ulkoinen linkki';
+$lang['qb_hr'] = 'Vaakaerotin';
+$lang['qb_ol'] = 'Järjestetyn listan osa ';
+$lang['qb_ul'] = 'Epäjärjestetyn listan osa';
+$lang['qb_media'] = 'Lisää kuvia ja muita tiedostoja';
+$lang['qb_sig'] = 'Lisää allekirjoitus';
+$lang['qb_smileys'] = 'Hymiöt';
+$lang['qb_chars'] = 'Erikoismerkit';
+$lang['upperns'] = 'Hyppää edelliseen nimiavaruuteen';
+$lang['admin_register'] = 'Lisää uusi käyttäjä';
+$lang['metaedit'] = 'Muokkaa metadataa';
+$lang['metasaveerr'] = 'Metadatan kirjoittaminen epäonnistui';
+$lang['metasaveok'] = 'Metadata tallennettu';
+$lang['img_backto'] = 'Takaisin';
+$lang['img_title'] = 'Otsikko';
+$lang['img_caption'] = 'Kuvateksti';
+$lang['img_date'] = 'Päivämäärä';
+$lang['img_fname'] = 'Tiedoston nimi';
+$lang['img_fsize'] = 'Koko';
+$lang['img_artist'] = 'Kuvaaja';
+$lang['img_copyr'] = 'Tekijänoikeus';
+$lang['img_format'] = 'Formaatti';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Avainsanat';
+$lang['img_width'] = 'Leveys';
+$lang['img_height'] = 'Korkeus';
+$lang['img_manager'] = 'Näytä mediamanagerissa';
+$lang['subscr_subscribe_success'] = '%s lisätty %s tilauslistalle';
+$lang['subscr_subscribe_error'] = 'Virhe lisättäessä %s tilauslistalle %s';
+$lang['subscr_subscribe_noaddress'] = 'Login tiedoissasi ei ole sähköpostiosoitetta. Sinua ei voi lisätä tilaukseen';
+$lang['subscr_unsubscribe_success'] = '%s poistettu tilauslistalta %s';
+$lang['subscr_unsubscribe_error'] = 'Virhe tapahtui poistaessa %s tilauslistalta %s';
+$lang['subscr_already_subscribed'] = '%s on jo tilannut %s';
+$lang['subscr_not_subscribed'] = '%s ei ole tilannut %s';
+$lang['subscr_m_not_subscribed'] = 'Et ole tilannut sivua tai nimiavaruutta';
+$lang['subscr_m_new_header'] = 'Lisää tilaus';
+$lang['subscr_m_current_header'] = 'Voimassaolevat tilaukset';
+$lang['subscr_m_unsubscribe'] = 'Poista tilaus';
+$lang['subscr_m_subscribe'] = 'Tilaa';
+$lang['subscr_m_receive'] = 'Vastaanota';
+$lang['subscr_style_every'] = 'Sähköposti joka muutoksesta';
+$lang['subscr_style_digest'] = 'yhteenveto-sähköposti joka sivusta (joka %.2f. päivä)';
+$lang['subscr_style_list'] = 'lista muuttuneista sivuista edellisen sähköpostin jälkeen (joka %.2f. päivä)';
+$lang['authmodfailed'] = 'Käyttäjien autentikoinnin asetukset ovat virheelliset. Ilmoita asiasta wikin ylläpitäjälle.';
+$lang['authtempfail'] = 'Käyttäjien autentikointi ei tällä hetkellä onnistu. Jos ongelma jatkuu, ota yhteyttä wikin ylläpitäjään.';
+$lang['i_chooselang'] = 'Valitse kieli';
+$lang['i_installer'] = 'DokuWikin asentaja';
+$lang['i_wikiname'] = 'Wikin nimi';
+$lang['i_enableacl'] = 'Käytä käyttöoikeuksien hallintaa (ACL) (Suositeltu)';
+$lang['i_superuser'] = 'Pääkäyttäjä';
+$lang['i_problems'] = 'Asennusohjelma löysi alla listattuja ongelmia ongelmia. Et voi jatkaa ennen kuin ne on korjattu.';
+$lang['i_modified'] = 'Turvallisuussyistä tämä ohjelma toimii vain uusien ja muokkaamattomien Dokuwiki-asennusten kanssa. Pura tiedostot uudestaan asennuspaketista, tai lue <a href="http://dokuwiki.org/install">Dokuwikin asennusohje (englanniksi)</a>';
+$lang['i_funcna'] = 'PHP:n funktio <code>%s</code> ei ole käytettävissä. Palveluntarjoajasi on saattanut poistaa sen jostain syystä.';
+$lang['i_phpver'] = 'Käyttämäsi PHP-ohjelmiston versio <code>%s</code> on pienempi, kuin tarvitaan <code>%s</code>. PHP-asennuksesi pitää päivittää.';
+$lang['i_permfail'] = '<code>%s</code> ei ole DokuWikin kirjoitettavissa. Muokkaa hakemiston oikeuksia!';
+$lang['i_confexists'] = '<code>%s</code> on jo olemassa';
+$lang['i_writeerr'] = '<code>%s</code>n luonti epäonnistui. Tarkista hakemiston/tiedoston oikeudet ja luo tiedosto käsin.';
+$lang['i_badhash'] = 'tunnistamaton tai muokattu dokuwiki.php (tarkistussumma=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - väärä tai tyhjä arvo';
+$lang['i_success'] = 'Kokoonpano tehty onnistuneesti. Voit poistaa install.php tiedoston. Jatka <a href="doku.php">uuteen DokuWikiisi</a>.';
+$lang['i_failure'] = 'Joitain virheitä tapahtui kirjoitettaessa vaadittavia tiedostoja. Sinun pitää korjata ne käsin ennen kuin voit käyttää <a href="doku.php">uutta DokuWikiäsi</a>.';
+$lang['i_policy'] = 'Käyttöoikeuksien oletusmenettelytapa';
+$lang['i_pol0'] = 'Avoin Wiki (luku, kirjoitus, tiedostojen lähetys on sallittu kaikille)';
+$lang['i_pol1'] = 'Julkinen Wiki (luku kaikilla, kirjoitus ja tiedostojen lähetys rekisteröidyillä käyttäjillä)';
+$lang['i_pol2'] = 'Suljettu Wiki (luku, kirjoitus ja tiedostojen lähetys vain rekisteröityneillä käyttäjillä)';
+$lang['i_retry'] = 'Yritä uudelleen';
+$lang['i_license'] = 'Valitse lisenssi, jonka alle haluat sisältösi laittaa:';
+$lang['recent_global'] = 'Seuraat tällä hetkellä muutoksia nimiavaruuden <b>%s</b> sisällä. Voit myös <a href="%s">katsoa muutoksia koko wikissä</a>';
+$lang['years'] = '%d vuotta sitten';
+$lang['months'] = '%d kuukautta sitten';
+$lang['weeks'] = '%d viikkoa sitten';
+$lang['days'] = '%d päivää sitten';
+$lang['hours'] = '%d tuntia sitten';
+$lang['minutes'] = '%d minuuttia sitten';
+$lang['seconds'] = '%d sekuntia sitten';
+$lang['wordblock'] = 'Muutostasi ei talletettu, koska se sisältää estettyä tekstiä (spam).';
+$lang['media_uploadtab'] = 'Lähetä';
+$lang['media_searchtab'] = 'Etsi';
+$lang['media_file'] = 'Tiedosto';
+$lang['media_viewtab'] = 'Näytä';
+$lang['media_edittab'] = 'Muokkaa';
+$lang['media_historytab'] = 'Historia';
+$lang['media_list_thumbs'] = 'Thumbnails';
+$lang['media_list_rows'] = 'Rivit';
+$lang['media_sort_name'] = 'nimen mukaan';
+$lang['media_sort_date'] = 'päivämäärän mukaan';
+$lang['media_namespaces'] = 'Valitse nimiavaruus';
+$lang['media_files'] = 'Tiedostoja %s';
+$lang['media_upload'] = 'Lähetä <strong>%s</strong> nimiavaruuteen';
+$lang['media_search'] = 'Etsi <strong>%s</strong> nimiavaruudesta';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s at %s';
+$lang['media_edit'] = 'Muokkaa %s';
+$lang['media_history'] = 'Nämä ovat vanhat versiot tiedostosta %s';
+$lang['media_meta_edited'] = 'Metadataa muokattu';
+$lang['media_perm_read'] = 'Anteeksi. Sinulla ei ole riittävästi oikeuksia lukeaksesi tiedostoja.';
+$lang['media_perm_upload'] = 'Anteeksi. Sinulla ei ole riittävästi oikeuksia lähettääksesi tiedostoja.';
+$lang['media_update'] = 'Lähetä uusi versio';
+$lang['media_restore'] = 'Palauta tämä versio';
+$lang['plugin_install_err'] = 'Liitännäinen asentui virheellisesti. Nimeä liitännäisen hakemisto \'%s\' -> \'%s\'';
diff --git a/inc/lang/fi/locked.txt b/inc/lang/fi/locked.txt
new file mode 100644
index 000000000..3a48ff8ae
--- /dev/null
+++ b/inc/lang/fi/locked.txt
@@ -0,0 +1,3 @@
+====== Sivu lukittu ======
+
+Tämä sivu on tällä hetkellä lukittuna, koska se on toisen käyttäjän muokkauksessa. Joudut odottamaan, kunnes hän lopettaa muokkauksen, tai kunnes lukko aukeaa.
diff --git a/inc/lang/fi/login.txt b/inc/lang/fi/login.txt
new file mode 100644
index 000000000..efba26286
--- /dev/null
+++ b/inc/lang/fi/login.txt
@@ -0,0 +1,3 @@
+====== Sisäänkirjautuminen ======
+
+Et ole tällä hetkellä kirjautunut sisään! Anna käyttäjätunnus ja salasana alle kirjautuaksesi. Muista, että evästeiden käyttö tulee olla päällä, jotta sisäänkirjautuminen onnistuu.
diff --git a/inc/lang/fi/mailtext.txt b/inc/lang/fi/mailtext.txt
new file mode 100644
index 000000000..1808ebc38
--- /dev/null
+++ b/inc/lang/fi/mailtext.txt
@@ -0,0 +1,17 @@
+DokuWikiisi lisättiin tai siellä muutettiin sivua. Tässä yksityiskohdat
+
+Päivämäärä : @DATE@
+Selain: @BROWSER@
+IP-Osoite: @IPADDRESS@
+Isäntänimi: @HOSTNAME@
+Vanha versio: @OLDPAGE@
+Uusi versio: @NEWPAGE@
+Yhteenveto: @SUMMARY@
+Käyttäjä : @USER@
+
+@DIFF@
+
+
+--
+Tämän postin loi DokuWiki osoitteessa
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fi/newpage.txt b/inc/lang/fi/newpage.txt
new file mode 100644
index 000000000..fc6379be7
--- /dev/null
+++ b/inc/lang/fi/newpage.txt
@@ -0,0 +1,3 @@
+====== Tätä otsikkoa ei vielä ole ======
+
+Olet seurannut linkkiä otsikkoon jota ei vielä ole. Voit luoda tämän käyttämällä ''Luo tämä sivu'' -nappia.
diff --git a/inc/lang/fi/norev.txt b/inc/lang/fi/norev.txt
new file mode 100644
index 000000000..a5138cfc3
--- /dev/null
+++ b/inc/lang/fi/norev.txt
@@ -0,0 +1,3 @@
+====== Ei tällaista versiota ======
+
+Kyseistä versiota ei ole. Käytä ''Vanha versio''-nappia nähdäksesi listan tämän dokumentin vanhoista versioista
diff --git a/inc/lang/fi/password.txt b/inc/lang/fi/password.txt
new file mode 100644
index 000000000..51e16046c
--- /dev/null
+++ b/inc/lang/fi/password.txt
@@ -0,0 +1,10 @@
+Terve @FULLNAME@!
+
+Tässä käyttäjätietosi sivulla @TITLE@ osoitteessa @DOKUWIKIURL@
+
+Käyttäjätunnus : @LOGIN@
+Salasana : @PASSWORD@
+
+--
+Tämän postin loi DokuWiki osoitteessa
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fi/preview.txt b/inc/lang/fi/preview.txt
new file mode 100644
index 000000000..848780701
--- /dev/null
+++ b/inc/lang/fi/preview.txt
@@ -0,0 +1,3 @@
+====== Esikatselu ======
+
+Tämä on esikatselu siitä, miltä tekstisi tulee näyttämään. Muista, että tätä **ei ole tallennettu** vielä!
diff --git a/inc/lang/fi/pwconfirm.txt b/inc/lang/fi/pwconfirm.txt
new file mode 100644
index 000000000..e552f5cdc
--- /dev/null
+++ b/inc/lang/fi/pwconfirm.txt
@@ -0,0 +1,13 @@
+Hei @FULLNAME@!
+
+Joku pyysi uutta salasanaa login nimellesi @TITLE@ sivustolla @DOKUWIKIURL@
+
+Jos sinä ei pyytänyt uutta salasanaa, niin voit unohtaa tämän postin.
+
+Käytä alla olevaa linkkiä vahvistaaksesi, että pyynnön lähettäjä todella olet sinä.
+
+@CONFIRM@
+
+--
+Tämän postin loi DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/fi/read.txt b/inc/lang/fi/read.txt
new file mode 100644
index 000000000..eb4380229
--- /dev/null
+++ b/inc/lang/fi/read.txt
@@ -0,0 +1 @@
+Tämä sivu on vain luettavissa. Voit katsoa sen lähdekoodia, mutta et muuttaa sitä. Kysy ylläpitäjältä jos pidät tätä estoa virheellisenä.
diff --git a/inc/lang/fi/recent.txt b/inc/lang/fi/recent.txt
new file mode 100644
index 000000000..ffb08107e
--- /dev/null
+++ b/inc/lang/fi/recent.txt
@@ -0,0 +1,4 @@
+====== Viimeiset muutokset ======
+
+Seuraavat sivut ovat muuttuneet viime aikoina.
+
diff --git a/inc/lang/fi/register.txt b/inc/lang/fi/register.txt
new file mode 100644
index 000000000..cf7a62557
--- /dev/null
+++ b/inc/lang/fi/register.txt
@@ -0,0 +1,3 @@
+====== Rekisteröi uusi käyttäjä ======
+
+Täytä alla olevat tiedot luodaksesi uuden käyttäjätilin tähän wikiin. Muista antaa **toimiva sähköpostiosoite**. Jos sinulta ei kysytä uutta salasanaa, niin uusi salasanasi lähetetään sähköpostiisi. Käyttäjänimi pitää olla myös käypä [[doku>pagename|sivunimi]].
diff --git a/inc/lang/fi/registermail.txt b/inc/lang/fi/registermail.txt
new file mode 100644
index 000000000..c276873f0
--- /dev/null
+++ b/inc/lang/fi/registermail.txt
@@ -0,0 +1,14 @@
+Uusi käyttäjä on rekisteröitynyt. Tässä tiedot:
+
+Käyttäjänimi : @NEWUSER@
+Kokonimi : @NEWNAME@
+Sähköposti : @NEWEMAIL@
+
+Päivämäärä : @DATE@
+Selain : @BROWSER@
+IP-osoite : @IPADDRESS@
+Hostname : @HOSTNAME@
+
+--
+Tämän postin loi DokuWiki osoitteessa
+@DOKUWIKIURL@
diff --git a/inc/lang/fi/resendpwd.txt b/inc/lang/fi/resendpwd.txt
new file mode 100644
index 000000000..5a567b022
--- /dev/null
+++ b/inc/lang/fi/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Lähetä uusi salasana ======
+
+Täytä käyttäjätunnuksesi kaavakkeeseen pyytääksesi uutta salasanaa wikin käyttäjätilillesi. Vahvistuslinkki lähetetään kirjautumisen yhteydessä antamaan sähköpostiosoitteeseen.
diff --git a/inc/lang/fi/revisions.txt b/inc/lang/fi/revisions.txt
new file mode 100644
index 000000000..a48cd3366
--- /dev/null
+++ b/inc/lang/fi/revisions.txt
@@ -0,0 +1,3 @@
+====== Vanha versio ======
+
+Nämä ovat vanhoja versioita nykyisestä dokumentista. Jos haluat palauttaa vanhan version valitse se alhaalta, paina ''Muokkaa tätä sivua'' ja tallenna se.
diff --git a/inc/lang/fi/searchpage.txt b/inc/lang/fi/searchpage.txt
new file mode 100644
index 000000000..aa9fbf52f
--- /dev/null
+++ b/inc/lang/fi/searchpage.txt
@@ -0,0 +1,5 @@
+====== Etsi ======
+
+Löydät etsinnän tulokset alta. Jos et löytänyt etsimääsi voit luoda uuden sivun tiedustelusi pohjalta käyttämällä ''Muokkaa tätä sivua'' -napilla.
+
+===== Tulokset =====
diff --git a/inc/lang/fi/showrev.txt b/inc/lang/fi/showrev.txt
new file mode 100644
index 000000000..243f8d01e
--- /dev/null
+++ b/inc/lang/fi/showrev.txt
@@ -0,0 +1,2 @@
+**Tämä on vanha versio dokumentista!**
+----
diff --git a/inc/lang/fi/stopwords.txt b/inc/lang/fi/stopwords.txt
new file mode 100644
index 000000000..82d3daa44
--- /dev/null
+++ b/inc/lang/fi/stopwords.txt
@@ -0,0 +1,11 @@
+# Tämä on lista sanoista, jotka indeksoija ohittaa. Yksi sana riviä kohti
+# Kun muokkaat sivua, varmista että käytät UNIX rivinvaihtoa (yksi newline)
+# Ei tarvitse lisätä alle kolmen merkin sanoja. NE ohitetaan automaattisesti.
+# Jos wikissäsin muita kieliä, lisää sanoja listaan esimerkiksi sivulta http://www.ranks.nl/stopwords/
+www
+eli
+tai
+sinä
+sinun
+com
+oli
diff --git a/inc/lang/fi/subscr_digest.txt b/inc/lang/fi/subscr_digest.txt
new file mode 100644
index 000000000..466484486
--- /dev/null
+++ b/inc/lang/fi/subscr_digest.txt
@@ -0,0 +1,20 @@
+Hei!
+
+Sivu @PAGE@ wikissä @TITLE@ on muuttunut.
+Tässä ovat muutokset:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Vanha versio: @OLDPAGE@
+Uusi versio: @NEWPAGE@
+
+Peruttaaksesi sivuilmoitukset kirjaudu wikiin osoitteessa
+@DOKUWIKIURL@ , jonka jälkeen katso
+@SUBSCRIBE@
+ja peruuta tilauksesi sivun ja/tai nimiavaruuden muutoksista.
+
+--
+Tämän postin loi DokuWiki osoitteessa
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fi/subscr_form.txt b/inc/lang/fi/subscr_form.txt
new file mode 100644
index 000000000..70f2fdeb5
--- /dev/null
+++ b/inc/lang/fi/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Tilausten hallinta ======
+
+Tämä sivu avulla voit hallita silauksiasi nykyiseltä sivulta ja nimiavaruudelta. \ No newline at end of file
diff --git a/inc/lang/fi/subscr_list.txt b/inc/lang/fi/subscr_list.txt
new file mode 100644
index 000000000..cd39014e8
--- /dev/null
+++ b/inc/lang/fi/subscr_list.txt
@@ -0,0 +1,18 @@
+Hei!
+
+Sivut nimiavaruudessa @PAGE@ wikissä @TITLE@ ovat muuttuneet.
+Tässä ovat muuttuneet sivut:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Peruuttaaksesi sivuilmoitukset kirjaudu wikiin osoitteessa
+@DOKUWIKIURL@ , jonka jälkeen katso
+@SUBSCRIBE@
+ja peruuta tilauksesi sivun ja/tai nimiavaruuden muutoksista.
+
+
+--
+Tämän postin loi DokuWiki osoitteessa
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fi/subscr_single.txt b/inc/lang/fi/subscr_single.txt
new file mode 100644
index 000000000..0fd83e266
--- /dev/null
+++ b/inc/lang/fi/subscr_single.txt
@@ -0,0 +1,23 @@
+Hei!
+
+Sivu @PAGE@ wikissä @TITLE@ on muuttunut.
+Tässä ovat muutokset:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Päivä : @DATE@
+Käyttäjä : @USER@
+Yhteenveto: @SUMMARY@
+Vanha versio: @OLDPAGE@
+Uusi versio: @NEWPAGE@
+
+Peruttaaksesi sivuilmoitukset kirjaudu wikiin osoitteessa
+@DOKUWIKIURL@ , jonka jälkeen katso
+@SUBSCRIBE@
+ja peruuta tilauksesi sivun ja/tai nimiavaruuden muutoksista.
+
+--
+Tämän postin loi DokuWiki osoitteessa
+@DOKUWIKIURL@
diff --git a/inc/lang/fi/updateprofile.txt b/inc/lang/fi/updateprofile.txt
new file mode 100644
index 000000000..71407954a
--- /dev/null
+++ b/inc/lang/fi/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Päivitä käyttäjätilisi profiilia ======
+
+Täytä vain ne kentät, joita haluat muuttaa. Et voi muuttaa käyttäjätunnustasi. \ No newline at end of file
diff --git a/inc/lang/fi/uploadmail.txt b/inc/lang/fi/uploadmail.txt
new file mode 100644
index 000000000..0c116a78b
--- /dev/null
+++ b/inc/lang/fi/uploadmail.txt
@@ -0,0 +1,14 @@
+Tiedosto ladattiin DokuWikillesi. Tässä yksityiskohtaiset tiedot:
+
+Tiedosto : @MEDIA@
+PVM : @DATE@
+Selain : @BROWSER@
+IP-Osoite : @IPADDRESS@
+Hostname : @HOSTNAME@
+Koko : @SIZE@
+MIME Type : @MIME@
+Käyttäjä : @USER@
+
+--
+Tämän postin loi DokuWiki osoitteessa
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fo/admin.txt b/inc/lang/fo/admin.txt
new file mode 100644
index 000000000..27743223d
--- /dev/null
+++ b/inc/lang/fo/admin.txt
@@ -0,0 +1,4 @@
+====== Fyrisiting ======
+
+Niðanfyri kanst tú finna eina røð av amboðum til fyrisiting.
+
diff --git a/inc/lang/fo/backlinks.txt b/inc/lang/fo/backlinks.txt
new file mode 100644
index 000000000..422377f62
--- /dev/null
+++ b/inc/lang/fo/backlinks.txt
@@ -0,0 +1,4 @@
+====== Ávísing afturúr ======
+
+Hetta er ein listi yvur øll tey skjøl sum vísa aftur á tað núverandi skjali.
+
diff --git a/inc/lang/fo/conflict.txt b/inc/lang/fo/conflict.txt
new file mode 100644
index 000000000..df3fe52be
--- /dev/null
+++ b/inc/lang/fo/conflict.txt
@@ -0,0 +1,5 @@
+====== Ein níggjari útgáva av skjalinum er til ======
+
+Ein nýggjari útgáva av hesum skjalinum er til. Hetta hendur tá fleiri brúkarir rætta í skjalinum samstundis.
+
+Eftirkanna tær vístu broytingar nágreiniliga, og avgerð hvat fyri útgávu sum skal goymast. Um tú velur ''Goym'', verður tín útgáva av skalinum goymd. Velur tú ''Angra'' varðveittur tú tí núverandi útgávuna.
diff --git a/inc/lang/fo/denied.txt b/inc/lang/fo/denied.txt
new file mode 100644
index 000000000..505b249b4
--- /dev/null
+++ b/inc/lang/fo/denied.txt
@@ -0,0 +1,3 @@
+====== Atgongd nokta! ======
+
+Tú hevur ikki rættindi til at halda áfram. Møguliga hevur tú ikki rita inn.
diff --git a/inc/lang/fo/diff.txt b/inc/lang/fo/diff.txt
new file mode 100644
index 000000000..343818b40
--- /dev/null
+++ b/inc/lang/fo/diff.txt
@@ -0,0 +1,4 @@
+====== Munir ======
+
+Hetta vísur munir millum tí valdu og núverandu útgávu av skjalinum. Gular eru linjur sum er at finna í gomlu útgávuni, og grønar eru linjur sum eru at finna í núvarandi útgávuni.
+
diff --git a/inc/lang/fo/edit.txt b/inc/lang/fo/edit.txt
new file mode 100644
index 000000000..2ba92a2d2
--- /dev/null
+++ b/inc/lang/fo/edit.txt
@@ -0,0 +1,2 @@
+Rætta hetta skjal og trýst so á **''[Goym]''** knappin. Sí [[wiki:syntax|snið ábending]] fyri Wiki setningsbygnað. Rætta vinarliga bert hetta skjali um tú kanst **fyrireika** tað. Nýt vinarliga [[playground:playground|sandkassan]] til at testa áðrenn tú rættar í einum røttum skjali. Minst eisini til at brúkar **''[Forskoðan]''** áðrenn tú goymur skjalið.
+
diff --git a/inc/lang/fo/editrev.txt b/inc/lang/fo/editrev.txt
new file mode 100644
index 000000000..274d423af
--- /dev/null
+++ b/inc/lang/fo/editrev.txt
@@ -0,0 +1,2 @@
+**Tú hevur heinta eina gamla útgávu av hesum skjalinum!** Um tú goymur skjali vilt tú skriva útyvir núverandi við gomlu útgávuni.
+----
diff --git a/inc/lang/fo/index.txt b/inc/lang/fo/index.txt
new file mode 100644
index 000000000..640edfbc3
--- /dev/null
+++ b/inc/lang/fo/index.txt
@@ -0,0 +1,3 @@
+====== Evnisyvirlit ======
+
+Hetta er eitt yvirlit yvur øll atkomandi skjøl, flokka eftir [[doku>namespaces|navnarúm]].
diff --git a/inc/lang/fo/lang.php b/inc/lang/fo/lang.php
new file mode 100644
index 000000000..4cb895f72
--- /dev/null
+++ b/inc/lang/fo/lang.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * faroese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Poul J. Clementsen <poul@diku.dk>
+ * @author Einar Petersen <einar.petersen@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = 'Vanligt gásareygað byrjan';
+$lang['doublequoteclosing'] = 'Vanligt gásareygað endi';
+$lang['singlequoteopening'] = 'Einstakt gásareygað byrjan';
+$lang['singlequoteclosing'] = 'Einstakt gásareygað endi';
+$lang['apostrophe'] = 'Apostroff';
+$lang['btn_edit'] = 'Rætta hetta skjal';
+$lang['btn_source'] = 'Vís keldu';
+$lang['btn_show'] = 'Vís skjal';
+$lang['btn_create'] = 'Býrja uppá hetta skjal';
+$lang['btn_search'] = 'Leita';
+$lang['btn_save'] = 'Goym';
+$lang['btn_preview'] = 'Forskoðan';
+$lang['btn_top'] = 'Aftur til toppin';
+$lang['btn_newer'] = '<< undan síða';
+$lang['btn_older'] = 'næsta síðe >>';
+$lang['btn_revs'] = 'Gamlar útgávur';
+$lang['btn_recent'] = 'Nýggj broyting';
+$lang['btn_upload'] = 'Legg fílu upp';
+$lang['btn_cancel'] = 'Angra';
+$lang['btn_index'] = 'Evnisyvirlit';
+$lang['btn_secedit'] = 'Rætta';
+$lang['btn_login'] = 'Rita inn';
+$lang['btn_logout'] = 'Rita út';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Dagfør';
+$lang['btn_delete'] = 'Strika';
+$lang['btn_back'] = 'Aftur';
+$lang['btn_backlink'] = 'Ávísingar afturúr';
+$lang['btn_backtomedia'] = 'Aftur til val av miðlafílu';
+$lang['btn_subscribe'] = 'Tilmelda broytingar';
+$lang['btn_profile'] = 'Dagføra vangamynd';
+$lang['btn_reset'] = 'Nullstilla';
+$lang['btn_resendpwd'] = 'Send nýtt loyniorð';
+$lang['btn_draft'] = 'Broyt kladdu';
+$lang['btn_recover'] = 'Endurbygg kladdu';
+$lang['btn_draftdel'] = 'Sletta';
+$lang['btn_revert'] = 'Endurbygg';
+$lang['btn_register'] = 'Melda til';
+$lang['loggedinas'] = 'Ritavur inn sum';
+$lang['user'] = 'Brúkaranavn';
+$lang['pass'] = 'Loyniorð';
+$lang['newpass'] = 'Nýtt loyniorð';
+$lang['oldpass'] = 'Vátta núverandi loyniorð';
+$lang['passchk'] = 'Endurtak nýtt loyniorð';
+$lang['remember'] = 'Minst til loyniorðið hjá mær';
+$lang['fullname'] = 'Navn';
+$lang['email'] = 'T-postur';
+$lang['profile'] = 'Brúkara vangamynd';
+$lang['badlogin'] = 'Skeivt brúkaranavn ella loyniorð.';
+$lang['minoredit'] = 'Smærri broytingar';
+$lang['draftdate'] = 'Goym kladdu sett frá';
+$lang['nosecedit'] = 'Hendan síðan var broytt undir tilevnan, brotið var ikki rætt dagfest, heintaði fulla síðu í staðin';
+$lang['regmissing'] = 'Tú skalt fylla út øll øki.';
+$lang['reguexists'] = 'Hetta brúkaranavn er upptiki.';
+$lang['regsuccess'] = 'Tú ert nú stovnavur sum brúkari. Títt loyniorð verður sent til tín í einum T-posti.';
+$lang['regsuccess2'] = 'Tú ert nú stovnavur sum brúkari.';
+$lang['regmailfail'] = 'Títt loyniorð bleiv ikki sent. Fá vinarliga samband við administratorin.';
+$lang['regbadmail'] = 'T-post adressan er ógildig. Fá vinarliga samband við administratorin, um tú heldur at hetta er eitt brek.';
+$lang['regbadpass'] = 'Bæði loyniorðini eru ikki eins, royn vinarliga umaftur.';
+$lang['regpwmail'] = 'Títt DokuWiki loyniorð';
+$lang['reghere'] = 'Upprætta eina DokuWiki-konto her';
+$lang['profna'] = 'Tað er ikki møguligt at broyta tína vangamynd í hesu wiki';
+$lang['profnochange'] = 'Ongar broytingar, onki tillaga.';
+$lang['profnoempty'] = 'Tómt navn ella t-post adressa er ikki loyvt.';
+$lang['profchanged'] = 'Brúkara vangamynd dagført rætt.';
+$lang['pwdforget'] = 'Gloymt títt loyniorð? Fá eitt nýtt';
+$lang['resendna'] = 'Tað er ikki møguligt at fá sent nýtt loyniorð við hesu wiki.';
+$lang['resendpwd'] = 'Send nýtt loyniorð til';
+$lang['resendpwdmissing'] = 'Tú skal filla út øll økir.';
+$lang['resendpwdnouser'] = 'Vit kunna ikki finna hendan brúkara í okkara dátagrunni.';
+$lang['resendpwdbadauth'] = 'Hald til góðar, hendan góðkenningar kodan er ikki gildug. Kanna eftir at tú nýtti tað fulfíggjaðu góðkenningarleinkjuna';
+$lang['resendpwdconfirm'] = 'Ein góðkenningarleinkja er send við e-posti';
+$lang['resendpwdsuccess'] = 'Títt nýggja loyniorð er sent við t-posti.';
+$lang['license'] = 'Um ikki annað er tilskilað, so er tilfar á hesari wiki loyvt margfaldað undir fylgjandi treytum:';
+$lang['licenseok'] = 'Legg til merkis: Við at dagføra hesa síðu samtykkir tú at loyva margfalding av tilfarinum undir fylgjandi treytum:';
+$lang['searchmedia'] = 'Leita eftir fíl navn:';
+$lang['searchmedia_in'] = 'Leita í %s';
+$lang['txt_upload'] = 'Vel tí fílu sum skal leggjast upp';
+$lang['txt_filename'] = 'Sláa inn wikinavn (valfrítt)';
+$lang['txt_overwrt'] = 'Yvurskriva verandi fílu';
+$lang['lockedby'] = 'Fyribils læst av';
+$lang['lockexpire'] = 'Lásið ferð úr gildi kl.';
+$lang['js']['willexpire'] = 'Títt lás á hetta skjalið ferð úr gildi um ein minnutt.\nTrýst á Forskoðan-knappin fyri at sleppa undan trupulleikum.';
+$lang['js']['notsavedyet'] = 'Tað eru gjørdar broytingar í skjalinum, um tú haldur fram vilja broytingar fara fyri skeytið.
+Ynskir tú at halda fram?';
+$lang['js']['searchmedia'] = 'Leita eftir dátufílum';
+$lang['js']['mediasize'] = 'Mynda stødd';
+$lang['js']['mediatarget'] = 'Leinkja til';
+$lang['js']['mediaclose'] = 'Læt aftur';
+$lang['js']['mediainsert'] = 'Set inn';
+$lang['js']['mediadisplayimg'] = 'Vís myndina';
+$lang['js']['mediadisplaylnk'] = 'Vís bert leinkjuna';
+$lang['js']['nosmblinks'] = 'Ávísingar til Windows shares virka bert í Microsoft Internet Explorer.
+Tú kanst enn avrita og sata inn slóðina.';
+$lang['js']['del_confirm'] = 'Strika post(ar)?';
+$lang['rssfailed'] = 'Eitt brek koma fyri tá roynt var at fáa: ';
+$lang['nothingfound'] = 'Leiting gav onki úrslit.';
+$lang['mediaselect'] = 'Vel miðlafílu';
+$lang['fileupload'] = 'Legg miðla fílu upp';
+$lang['uploadsucc'] = 'Upp legg av fílu var væl eydna';
+$lang['uploadfail'] = 'Brek við upp legg av fílu. Tað er møguliga trupuleikar við rættindunum';
+$lang['uploadwrong'] = 'Upp legg av fílu víst burtur. Fíluslag er ikki loyvt';
+$lang['uploadexist'] = 'Fílan er longu til.';
+$lang['deletesucc'] = 'Fílan "%s" er nú strika.';
+$lang['deletefail'] = '"%s" kundi ikki strikast - kanna rættindini.';
+$lang['mediainuse'] = 'Fíla "%s" er ikki strika - hen verður enn nýtt.';
+$lang['namespaces'] = 'Navnarúm';
+$lang['mediafiles'] = 'Atkomandi fílur í';
+$lang['reference'] = 'Ávísing til';
+$lang['ref_inuse'] = 'Fílan kan ikki strikast, síðan hon enn verður nýtt á fylgjandi síðum:';
+$lang['ref_hidden'] = 'Nakrar ávísingar eru í skjølum sum tú ikki hevur lesi rættindi til';
+$lang['hits'] = 'Hits';
+$lang['quickhits'] = 'Samsvarandi skjøl';
+$lang['toc'] = 'Innihaldsyvirlit';
+$lang['current'] = 'núverandi';
+$lang['yours'] = 'Tín útgáva';
+$lang['diff'] = 'vís broytingar í mun til núverandi útgávu';
+$lang['line'] = 'Linja';
+$lang['breadcrumb'] = 'Leið';
+$lang['youarehere'] = 'Tú ert her';
+$lang['lastmod'] = 'Seinast broytt';
+$lang['by'] = 'av';
+$lang['deleted'] = 'strika';
+$lang['created'] = 'stovna';
+$lang['restored'] = 'gomul útgáva endurstovna';
+$lang['summary'] = 'Samandráttur';
+$lang['mail_newpage'] = 'skjal skoyta uppí:';
+$lang['mail_changed'] = 'skjal broytt:';
+$lang['qb_bold'] = 'Feit';
+$lang['qb_italic'] = 'Skák';
+$lang['qb_underl'] = 'Undurstrika';
+$lang['qb_code'] = 'Skrivimaskinu tekstur';
+$lang['qb_strike'] = 'Gjøgnumstrika';
+$lang['qb_h1'] = 'Stig 1 yvirskrift';
+$lang['qb_h2'] = 'Stig 2 yvirskrift';
+$lang['qb_h3'] = 'Stig 3 yvirskrift';
+$lang['qb_h4'] = 'Stig 4 yvirskrift';
+$lang['qb_h5'] = 'Stig 5 yvirskrift';
+$lang['qb_link'] = 'Innanhýsis slóð';
+$lang['qb_extlink'] = 'Útvortis slóð';
+$lang['qb_hr'] = 'Vatnrætt linja';
+$lang['qb_ol'] = 'Talmerktur listi';
+$lang['qb_ul'] = 'Ótalmerktur listi';
+$lang['qb_media'] = 'Leggja myndir og aðrar fílur afturat';
+$lang['qb_sig'] = 'Set inn undirskrift';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Sertekn';
+$lang['admin_register'] = 'Upprætta nýggjan brúkara';
+$lang['metaedit'] = 'Rætta metadáta';
+$lang['metasaveerr'] = 'Brek við skriving av metadáta';
+$lang['metasaveok'] = 'Metadáta goymt';
+$lang['img_backto'] = 'Aftur til';
+$lang['img_title'] = 'Heitið';
+$lang['img_caption'] = 'Myndatekstur';
+$lang['img_date'] = 'Dato';
+$lang['img_fname'] = 'Fílunavn';
+$lang['img_fsize'] = 'Stødd';
+$lang['img_artist'] = 'Myndafólk';
+$lang['img_copyr'] = 'Upphavsrættur';
+$lang['img_format'] = 'Snið';
+$lang['img_camera'] = 'Fototól';
+$lang['img_keywords'] = 'Evnisorð';
+$lang['authmodfailed'] = 'Brek við validering av brúkarasamansetingv. Fá samband við umboðsstjóran á hesi wiki.';
+$lang['authtempfail'] = 'Validering av brúkara virkar fyribils ikki. Um hetta er varandi, fá so samband við umboðsstjóran á hesi wiki.';
diff --git a/inc/lang/fo/locked.txt b/inc/lang/fo/locked.txt
new file mode 100644
index 000000000..2e65a064c
--- /dev/null
+++ b/inc/lang/fo/locked.txt
@@ -0,0 +1,3 @@
+====== Læst skjal ======
+
+Hetta skjal er fyribils læst av einum øðrum brúkara. Bíða vinarliga til brúkarin er liðugur við at rætta skjali, ella at lásið er fara úr gildi.
diff --git a/inc/lang/fo/login.txt b/inc/lang/fo/login.txt
new file mode 100644
index 000000000..31a4c544f
--- /dev/null
+++ b/inc/lang/fo/login.txt
@@ -0,0 +1,3 @@
+====== Rita inn ======
+
+Tú hevur ikki rita inn! Slá inn brúkaranavn og loyniorð. Tín kagi skal loyva at cookies verða goymdar fyri at tú kanst rita inn.
diff --git a/inc/lang/fo/mailtext.txt b/inc/lang/fo/mailtext.txt
new file mode 100644
index 000000000..358a23be0
--- /dev/null
+++ b/inc/lang/fo/mailtext.txt
@@ -0,0 +1,17 @@
+Eitt skjal í tíni DokuWiki bleiv broytt ella skoytt uppí. Her er ein lýsing:
+
+Dato : @DATE@
+Browser : @BROWSER@
+IP-adressa : @IPADDRESS@
+Hostnavn : @HOSTNAME@
+Gomul útgáva : @OLDPAGE@
+Nýggj útgáva : @NEWPAGE@
+Rætti samandráttur : @SUMMARY@
+Brúkari : @USER@
+
+@DIFF@
+
+
+--
+Hesin t-postur var skaptur av DokuWiki á:
+@DOKUWIKIURL@
diff --git a/inc/lang/fo/newpage.txt b/inc/lang/fo/newpage.txt
new file mode 100644
index 000000000..6eeb1ef31
--- /dev/null
+++ b/inc/lang/fo/newpage.txt
@@ -0,0 +1,3 @@
+====== Hetta skjal er ikki til (enn) ======
+
+Tú fylgdi ein ávísing til eitt skjal sum ikki er til (enn). Tú kanst stovna skjali við at trýsta á **''[Stovna hetta skjal]''** knappin.
diff --git a/inc/lang/fo/norev.txt b/inc/lang/fo/norev.txt
new file mode 100644
index 000000000..d0b463a40
--- /dev/null
+++ b/inc/lang/fo/norev.txt
@@ -0,0 +1,4 @@
+====== Valda útgávan er ikki til ======
+
+Valda útgávan av skjalinum er ikki til! Trýst á knappin **''[Gamlar útgávur]''** fyri at síggja ein lista yvur gamlar útgávur av hesum skjali.
+
diff --git a/inc/lang/fo/password.txt b/inc/lang/fo/password.txt
new file mode 100644
index 000000000..1e4797ba1
--- /dev/null
+++ b/inc/lang/fo/password.txt
@@ -0,0 +1,10 @@
+Hey @FULLNAME@!
+
+Her eru tínar brúkaraupplýsingar @TITLE@ at @DOKUWIKIURL@
+
+Brúkaranavn : @LOGIN@
+Loyniorð : @PASSWORD@
+
+--
+Hesin t-postur var skaptur av DokuWiki á:
+@DOKUWIKIURL@
diff --git a/inc/lang/fo/preview.txt b/inc/lang/fo/preview.txt
new file mode 100644
index 000000000..e3e65d805
--- /dev/null
+++ b/inc/lang/fo/preview.txt
@@ -0,0 +1,4 @@
+====== Forskoðan ======
+
+Hetta er ein forskoðan skjalinum, sum vísur hvussi tað fer at síggja út. Minst til: Tað er //**IKKI**// goymt enn! Um tað sær rætt út, trýst so á **''[Goym]''** knappin
+
diff --git a/inc/lang/fo/read.txt b/inc/lang/fo/read.txt
new file mode 100644
index 000000000..bacf79026
--- /dev/null
+++ b/inc/lang/fo/read.txt
@@ -0,0 +1,2 @@
+Hetta skjal kan bert læsast. Tú kanst síggja kelduna, men ikki goyma broytingar í tí. Um tú heldur at hetta er eitt brek, skriva so vinarliga í [[wiki:brek-yvirlit]].
+
diff --git a/inc/lang/fo/recent.txt b/inc/lang/fo/recent.txt
new file mode 100644
index 000000000..4704f3781
--- /dev/null
+++ b/inc/lang/fo/recent.txt
@@ -0,0 +1,5 @@
+====== Nýggjar broytingar ======
+
+Fylgjandi skjøl er broytt nýliga.
+
+
diff --git a/inc/lang/fo/register.txt b/inc/lang/fo/register.txt
new file mode 100644
index 000000000..24438afe8
--- /dev/null
+++ b/inc/lang/fo/register.txt
@@ -0,0 +1,4 @@
+====== Upprætta eina wiki-konti ======
+
+Fylla út niðanfyrista skema fyri at upprætta eina konti í hesu wiki. Minst til at nýta eina **galdandi t-post-adressu** - títt loyniorð verður sent til tín. Títt brúkaranavn skal verða galdandi [[doku>pagename|skjalanavn]].
+
diff --git a/inc/lang/fo/resendpwd.txt b/inc/lang/fo/resendpwd.txt
new file mode 100644
index 000000000..450202c12
--- /dev/null
+++ b/inc/lang/fo/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Send nýtt loyniorð ======
+
+Fyll út øll niðanfyristandandi øki fyri at fáa sent eitt nýtt loyniorð til hesa wiki. Títt nýggja loyniorð verður sent til tí uppgivnu t-postadressu. Brúkaranavn eigur at verða títt wiki brúkaranavn.
diff --git a/inc/lang/fo/revisions.txt b/inc/lang/fo/revisions.txt
new file mode 100644
index 000000000..dcd845c10
--- /dev/null
+++ b/inc/lang/fo/revisions.txt
@@ -0,0 +1,3 @@
+====== Gamlar útgávur ======
+
+Her eru tær gomlu útgávurnar av hesum skalinum. Tú kanst venda aftur til eina eldri útgávu av skjalinum við at velja tað niðanfyri, trýst á **''[Rætta hetta skjal]''** knappin, og til síðst goyma skjali.
diff --git a/inc/lang/fo/searchpage.txt b/inc/lang/fo/searchpage.txt
new file mode 100644
index 000000000..6304a8901
--- /dev/null
+++ b/inc/lang/fo/searchpage.txt
@@ -0,0 +1,5 @@
+====== Leiting ======
+
+Tú kanst síggja úrslitini av tíni leiting niðanfyri. Um úrslitini ikki innihalda tað sum tú leitaði eftir kanst tú upprætta eitt nýtt skjal við sama navni sum leitingin við at trýsta á **''[Upprætta hetta skjal]''** knappin.
+
+===== Leitiúrslit =====
diff --git a/inc/lang/fo/showrev.txt b/inc/lang/fo/showrev.txt
new file mode 100644
index 000000000..515f80aad
--- /dev/null
+++ b/inc/lang/fo/showrev.txt
@@ -0,0 +1,2 @@
+**Hetta er ein gomul útgáva av skjalinum!**
+----
diff --git a/inc/lang/fo/stopwords.txt b/inc/lang/fo/stopwords.txt
new file mode 100644
index 000000000..210e85902
--- /dev/null
+++ b/inc/lang/fo/stopwords.txt
@@ -0,0 +1,87 @@
+# 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/
+annar
+báðir
+eg
+eingin
+einhvør
+eini
+eitt
+ella
+enn
+fim
+fleiri
+flestir
+frá
+fyri
+fyrr
+fýra
+góður
+hann
+hansara
+har
+hendan
+hennara
+her
+hetta
+hevur
+hon
+hvar
+hvat
+hvussi
+hví
+hvør
+ikki
+inn
+kan
+koma
+lítil
+man
+maður
+meira
+men
+miðan
+niður
+nær
+næstan
+næsti
+nógv
+nýtt
+okkurt
+ongin
+onki
+onkur
+seks
+sindur
+sjey
+smáur
+stórur
+større
+størst
+sum
+síggjast
+tann
+tað
+teir
+tey
+til
+tríggir
+trý
+tvey
+tykkara
+tær
+tí
+tín
+tó
+tú
+um
+undan
+var
+vera
+við
+yvur
+átta
+áðrenn
+øll
diff --git a/inc/lang/fo/subscr_digest.txt b/inc/lang/fo/subscr_digest.txt
new file mode 100644
index 000000000..3d9f097ad
--- /dev/null
+++ b/inc/lang/fo/subscr_digest.txt
@@ -0,0 +1,20 @@
+Halló!
+
+Síðan @PAGE@ í @TITLE@ wiki er broytt.
+Her eru broytinganar:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Gamla skjalið: @OLDPAGE@
+Nýggja skjalið: @NEWPAGE@
+
+Fyri at avmelda síðu kunngerðir, logga inn í wikiina á
+@DOKUWIKIURL@ vitja so
+@SUBSCRIBE@
+og avmelda hald á síðu og/ella navnaøkis broytingar.
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fo/updateprofile.txt b/inc/lang/fo/updateprofile.txt
new file mode 100644
index 000000000..10ee40d30
--- /dev/null
+++ b/inc/lang/fo/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Dagføra vangamynd fyri tína konti ======
+
+Tú nýtist bert at fylla út tey øki sum tú ynskjur at broyta. Tú kanst ikki broyta títt brúkaranavn.
diff --git a/inc/lang/fr/admin.txt b/inc/lang/fr/admin.txt
new file mode 100644
index 000000000..4477a512b
--- /dev/null
+++ b/inc/lang/fr/admin.txt
@@ -0,0 +1,4 @@
+====== Administration ======
+
+Ci-dessous, vous trouverez une liste des tâches administratives disponibles dans DokuWiki.
+
diff --git a/inc/lang/fr/adminplugins.txt b/inc/lang/fr/adminplugins.txt
new file mode 100644
index 000000000..42a3538ab
--- /dev/null
+++ b/inc/lang/fr/adminplugins.txt
@@ -0,0 +1 @@
+===== Modules supplémentaires ===== \ No newline at end of file
diff --git a/inc/lang/fr/backlinks.txt b/inc/lang/fr/backlinks.txt
new file mode 100644
index 000000000..6902b43e3
--- /dev/null
+++ b/inc/lang/fr/backlinks.txt
@@ -0,0 +1,4 @@
+====== Pages pointant sur la page en cours ======
+
+Ceci est la liste des pages qui pointent sur la page en cours.
+
diff --git a/inc/lang/fr/conflict.txt b/inc/lang/fr/conflict.txt
new file mode 100644
index 000000000..8f527ee21
--- /dev/null
+++ b/inc/lang/fr/conflict.txt
@@ -0,0 +1,6 @@
+====== Une version plus récente existe déjà ======
+
+Une version plus récente du document que vous avez modifié existe déjà. Cela se produit lorsqu'un autre utilisateur enregistre le document pendant que vous le modifiez.
+
+Examinez attentivement les différences ci-dessous et décidez quelle version conserver. Si vous choisissez « Enregistrer », votre version sera enregistrée. Cliquez sur « Annuler » pour conserver la version actuelle.
+
diff --git a/inc/lang/fr/denied.txt b/inc/lang/fr/denied.txt
new file mode 100644
index 000000000..20d4d6755
--- /dev/null
+++ b/inc/lang/fr/denied.txt
@@ -0,0 +1,3 @@
+====== Autorisation refusée ======
+
+Désolé, vous n'avez pas les droits pour continuer. Peut-être avez-vous oublié de vous identifier ?
diff --git a/inc/lang/fr/diff.txt b/inc/lang/fr/diff.txt
new file mode 100644
index 000000000..773695d6d
--- /dev/null
+++ b/inc/lang/fr/diff.txt
@@ -0,0 +1,4 @@
+====== Différences ======
+
+Cette page vous donne les différences entre la révision choisie et la version actuelle de la page.
+
diff --git a/inc/lang/fr/draft.txt b/inc/lang/fr/draft.txt
new file mode 100644
index 000000000..a48554298
--- /dev/null
+++ b/inc/lang/fr/draft.txt
@@ -0,0 +1,6 @@
+====== Un fichier brouillon a été trouvé ======
+
+La dernière modification de cette page ne s'est pas terminée proprement. Dokuwiki a enregistré automatiquement un brouillon de votre travail que vous pouvez utiliser pour votre modification. Ci-dessous figurent les données enregistrées lors de votre dernière session.
+
+À vous de décider si vous souhaitez //récupérer// votre session de modification passée, //supprimer// le brouillon enregistré automatiquement ou //annuler// le processus d'édition.
+
diff --git a/inc/lang/fr/edit.txt b/inc/lang/fr/edit.txt
new file mode 100644
index 000000000..e30f1b78b
--- /dev/null
+++ b/inc/lang/fr/edit.txt
@@ -0,0 +1,2 @@
+Modifiez cette page et cliquez sur « Enregistrer ». Voyez le [[:wiki:syntax|guide de la mise en page]] pour une aide à propos du formatage. Veuillez ne modifier cette page que si vous pouvez l'**améliorer**. Si vous souhaitez faire des tests, faites vos premiers pas dans le [[:playground:playground|bac à sable]].
+
diff --git a/inc/lang/fr/editrev.txt b/inc/lang/fr/editrev.txt
new file mode 100644
index 000000000..d3fa36682
--- /dev/null
+++ b/inc/lang/fr/editrev.txt
@@ -0,0 +1,2 @@
+**Vous affichez une ancienne révision du document !** Si vous l'enregistrez, vous créerez une nouvelle version avec ce contenu.
+----
diff --git a/inc/lang/fr/index.txt b/inc/lang/fr/index.txt
new file mode 100644
index 000000000..c66c656ab
--- /dev/null
+++ b/inc/lang/fr/index.txt
@@ -0,0 +1,4 @@
+====== Index ======
+
+Voici un index de toutes les pages disponibles, triées par [[doku>fr:namespaces|catégorie]].
+
diff --git a/inc/lang/fr/install.html b/inc/lang/fr/install.html
new file mode 100644
index 000000000..b057becfe
--- /dev/null
+++ b/inc/lang/fr/install.html
@@ -0,0 +1,13 @@
+<p>Cette page vous assiste dans la premi&egrave;re installation et la
+configuration de <a href="http://dokuwiki.org">DokuWiki</a>.
+Pour plus d'information sur cet installeur, reportez-vous &agrave; sa
+<a href="http://dokuwiki.org/installer">page de
+documentation</a>.</p>
+
+<p>DokuWiki utilise des fichiers textes ordinaires pour stocker les pages du
+wiki et les autres informations associ&eacute;es &agrave; ces pages
+(tel que images, index de recherche, anciennes r&eacute;visions, etc.). Pour fonctionner correctement, DokuWiki <strong>doit</strong> avoir acc&egrave;s en &eacute;criture aux diff&eacute;rents r&eacute;pertoires qui contiennent ces fichiers. L'installeur n'est pas capable de modifier les permissions sur les r&eacute;pertoires. Ceci doit &ecirc;tre effectu&eacute; directement sur la ligne de commande de votre shell, ou, si vous &ecirc;tes h&eacute;berg&eacute;, <em>via</em> FTP ou votre panneau de contr&ocirc;le (tel que cPanel).</p>
+
+<p>Cet installeur va param&eacute;trer votre configuration de DokuWiki pour des <acronym title="Access Control List - Liste de contrôle d'acc&egrave;s">ACL</acronym>, qui permettront l'acc&egrave;s &agrave; un identifiant administrateur et l'acc&egrave;s au menu d'administration de DokuWiki pour l'ajout de modules externes (greffons), la gestion d'utilisateurs, la gestion de l'acc&egrave;s aux pages du wiki et les modifications des param&egrave;tres de configuration. Il n'est pas n&eacute;cessaire au fonctionnement de DokuWiki, n&eacute;anmoins il facilite l'administration de DokuWiki.</p>
+
+<p>Les utilisateurs exp&eacute;riment&eacute;s ou ceux n&eacute;cessitant des param&eacute;trages particuliers devraient se reporter aux liens suivants pour les d&eacute;tails concernant les <a href="http://dokuwiki.org/install">instructions d'installation</a> et les <a href="http://dokuwiki.org/config">param&egrave;tres de configuration</a>.</p>
diff --git a/inc/lang/fr/lang.php b/inc/lang/fr/lang.php
new file mode 100644
index 000000000..309ac22e3
--- /dev/null
+++ b/inc/lang/fr/lang.php
@@ -0,0 +1,327 @@
+<?php
+/**
+ * french language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Sébastien Bauer <sebastien.bauer@advalvas.be>
+ * @author Antoine Fixary <antoine.fixary@freesbee.fr>
+ * @author cumulus <pta-n56@myamail.com>
+ * @author Gwenn Gueguen <contact@demisel.net>
+ * @author Guy Brand <gb@unistra.fr>
+ * @author Fabien Chabreuil <fabien@integralpersonality.com>
+ * @author Stéphane Chamberland <stephane.chamberland@ec.gc.ca>
+ * @author Delassaux Julien <julien@delassaux.fr>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz <samuel.dorsaz@novelion.net>
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Modifier cette page';
+$lang['btn_source'] = 'Afficher le texte source';
+$lang['btn_show'] = 'Afficher la page';
+$lang['btn_create'] = 'Créer cette page';
+$lang['btn_search'] = 'Rechercher';
+$lang['btn_save'] = 'Enregistrer';
+$lang['btn_preview'] = 'Aperçu';
+$lang['btn_top'] = 'Haut de page';
+$lang['btn_newer'] = '<< Plus récent';
+$lang['btn_older'] = 'Moins récent >>';
+$lang['btn_revs'] = 'Anciennes révisions';
+$lang['btn_recent'] = 'Derniers changements';
+$lang['btn_upload'] = 'Envoyer';
+$lang['btn_cancel'] = 'Annuler';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit'] = 'Modifier';
+$lang['btn_login'] = 'Connexion';
+$lang['btn_logout'] = 'Déconnexion';
+$lang['btn_admin'] = 'Administrer';
+$lang['btn_update'] = 'Mettre à jour';
+$lang['btn_delete'] = 'Effacer';
+$lang['btn_back'] = 'Retour';
+$lang['btn_backlink'] = 'Liens vers cette page';
+$lang['btn_backtomedia'] = 'Retour à la sélection du fichier média';
+$lang['btn_subscribe'] = 'S\'abonner à la page';
+$lang['btn_profile'] = 'Mettre à jour le profil';
+$lang['btn_reset'] = 'Réinitialiser';
+$lang['btn_resendpwd'] = 'Envoyer le mot de passe';
+$lang['btn_draft'] = 'Modifier le brouillon';
+$lang['btn_recover'] = 'Récupérer le brouillon';
+$lang['btn_draftdel'] = 'Effacer le brouillon';
+$lang['btn_revert'] = 'Restaurer';
+$lang['btn_register'] = 'S\'enregistrer';
+$lang['btn_apply'] = 'Appliquer';
+$lang['btn_media'] = 'Gestionnaire de médias';
+$lang['loggedinas'] = 'Connecté en tant que ';
+$lang['user'] = 'Utilisateur';
+$lang['pass'] = 'Mot de passe';
+$lang['newpass'] = 'Nouveau mot de passe';
+$lang['oldpass'] = 'Mot de passe actuel';
+$lang['passchk'] = 'Répéter nouveau mot de passe';
+$lang['remember'] = 'Mémoriser';
+$lang['fullname'] = 'Nom';
+$lang['email'] = 'Adresse de courriel';
+$lang['profile'] = 'Profil utilisateur';
+$lang['badlogin'] = 'L\'utilisateur ou le mot de passe est incorrect.';
+$lang['minoredit'] = 'Modification mineure';
+$lang['draftdate'] = 'Brouillon auto-enregistré le';
+$lang['nosecedit'] = 'La page a changé entre temps, les informations de la section sont obsolètes ; la page complète a été chargée à la place.';
+$lang['regmissing'] = 'Désolé, vous devez remplir tous les champs.';
+$lang['reguexists'] = 'Désolé, ce nom d\'utilisateur est déjà pris.';
+$lang['regsuccess'] = 'L\'utilisateur a été créé. Le mot de passe a été expédié par courriel.';
+$lang['regsuccess2'] = 'L\'utilisateur a été créé.';
+$lang['regmailfail'] = 'Il semble y avoir un problème à l\'envoi du courriel. Contactez l\'administrateur.';
+$lang['regbadmail'] = 'L\'adresse de courriel semble incorrecte. Si vous pensez que c\'est une erreur, contactez l\'administrateur.';
+$lang['regbadpass'] = 'Les deux mots de passe fournis sont différents, veuillez recommencez.';
+$lang['regpwmail'] = 'Votre mot de passe DokuWiki';
+$lang['reghere'] = 'Vous n\'avez pas encore de compte ? Enregistrez-vous ici ';
+$lang['profna'] = 'Ce wiki ne permet pas de modifier les profils';
+$lang['profnochange'] = 'Pas de changement, rien à faire.';
+$lang['profnoempty'] = 'Un nom ou une adresse de courriel vide n\'est pas permis.';
+$lang['profchanged'] = 'Mise à jour du profil réussie.';
+$lang['pwdforget'] = 'Mot de passe oublié ? Faites-vous envoyer votre mot de passe ';
+$lang['resendna'] = 'Ce wiki ne permet pas le renvoi de mot de passe.';
+$lang['resendpwd'] = 'Renvoyer le mot de passe de';
+$lang['resendpwdmissing'] = 'Désolé, vous devez remplir tous les champs.';
+$lang['resendpwdnouser'] = 'Désolé, cet utilisateur est introuvable dans notre base.';
+$lang['resendpwdbadauth'] = 'Désolé, ce code d\'authentification est invalide. Assurez-vous d\'avoir utilisé le lien de confirmation.';
+$lang['resendpwdconfirm'] = 'Un lien de confirmation vous a été envoyé par courriel.';
+$lang['resendpwdsuccess'] = 'Votre nouveau mot de passe vous a été expédié par courriel.';
+$lang['license'] = 'Sauf mention contraire, le contenu de ce wiki est placé sous la licence suivante :';
+$lang['licenseok'] = 'Note : En modifiant cette page, vous acceptez que le contenu soit placé sous les termes de la licence suivante :';
+$lang['searchmedia'] = 'Chercher le nom de fichier :';
+$lang['searchmedia_in'] = 'Chercher dans %s';
+$lang['txt_upload'] = 'Sélectionnez un fichier à envoyer ';
+$lang['txt_filename'] = 'Donnez un « wikiname » (optionnel) ';
+$lang['txt_overwrt'] = 'Écraser le fichier cible';
+$lang['lockedby'] = 'Actuellement bloqué par';
+$lang['lockexpire'] = 'Le blocage expire à';
+$lang['js']['willexpire'] = 'Votre verrouillage pour la modification de cette page expire dans une minute.\nPour éviter les conflits, utilisez le bouton « Aperçu » pour réinitialiser le minuteur.';
+$lang['js']['notsavedyet'] = 'Les modifications non enregistrées seront perdues. Voulez-vous vraiment continuer ?';
+$lang['js']['searchmedia'] = 'Chercher des fichiers';
+$lang['js']['keepopen'] = 'Gardez cette fenêtre toujours ouverte';
+$lang['js']['hidedetails'] = 'Masquer détails';
+$lang['js']['mediatitle'] = 'Paramètres de lien';
+$lang['js']['mediadisplay'] = 'Type de lien';
+$lang['js']['mediaalign'] = 'Alignement';
+$lang['js']['mediasize'] = 'Taille d\'image';
+$lang['js']['mediatarget'] = 'Cible du lien';
+$lang['js']['mediaclose'] = 'Fermer';
+$lang['js']['mediainsert'] = 'Insérer';
+$lang['js']['mediadisplayimg'] = 'Afficher l\'image.';
+$lang['js']['mediadisplaylnk'] = 'N\'afficher que le lien.';
+$lang['js']['mediasmall'] = 'Petite taille';
+$lang['js']['mediamedium'] = 'taille moyenne';
+$lang['js']['medialarge'] = 'Grande taille';
+$lang['js']['mediaoriginal'] = 'taille d\'origine';
+$lang['js']['medialnk'] = 'Lien vers la page de détail';
+$lang['js']['mediadirect'] = 'Lien direct vers l\'original';
+$lang['js']['medianolnk'] = 'Aucun lien';
+$lang['js']['medianolink'] = 'Ne pas lier l\'image';
+$lang['js']['medialeft'] = 'Aligner l\'image sur la gauche.';
+$lang['js']['mediaright'] = 'Aligner l\'image sur la droite.';
+$lang['js']['mediacenter'] = 'Centrer l\'image';
+$lang['js']['medianoalign'] = 'Ne pas aligner.';
+$lang['js']['nosmblinks'] = 'Les liens vers les partages Windows ne fonctionnent qu\'avec Microsoft Internet Explorer.\nVous pouvez toujours copier puis coller le lien.';
+$lang['js']['linkwiz'] = 'Assistant Lien';
+$lang['js']['linkto'] = 'Lien vers :';
+$lang['js']['del_confirm'] = 'Effacer cette entrée ?';
+$lang['js']['restore_confirm'] = 'Voulez vous vraiment restaurer cette version ?';
+$lang['js']['media_diff'] = 'Voir les différences:';
+$lang['js']['media_diff_both'] = 'Côte à côte';
+$lang['js']['media_diff_opacity'] = 'Calque';
+$lang['js']['media_diff_portions'] = 'Curseur';
+$lang['js']['media_select'] = 'Sélection de fichiers…';
+$lang['js']['media_upload_btn'] = 'Télécharger';
+$lang['js']['media_done_btn'] = 'Terminé';
+$lang['js']['media_drop'] = 'Déposez des fichiers ici pour les télécharger';
+$lang['js']['media_cancel'] = 'supprimer';
+$lang['js']['media_overwrt'] = 'Écraser les fichiers existants';
+$lang['rssfailed'] = 'Une erreur s\'est produite en récupérant ce flux : ';
+$lang['nothingfound'] = 'Pas de réponse.';
+$lang['mediaselect'] = 'Sélection de fichier';
+$lang['fileupload'] = 'Envoi de fichier';
+$lang['uploadsucc'] = 'Téléversement réussi';
+$lang['uploadfail'] = 'Le téléversement n\'a pas réussi. Les permissions sont-elles correctes ?';
+$lang['uploadwrong'] = 'Téléversement refusé. Cette extension de fichier est interdite !';
+$lang['uploadexist'] = 'Le fichier existe. Téléversement avorté.';
+$lang['uploadbadcontent'] = 'Le contenu envoyé ne correspond pas à l\'extension du fichier %s.';
+$lang['uploadspam'] = 'Le téléversement a été bloqué par la liste noire antispam.';
+$lang['uploadxss'] = 'Le téléversement a été bloqué car son contenu est peut-être malveillant.';
+$lang['uploadsize'] = 'Le fichier téléversé était trop gros. (max. %s)';
+$lang['deletesucc'] = 'Le fichier « %s » a été effacé.';
+$lang['deletefail'] = 'Le fichier « %s » n\'a pu être effacé, vérifier les permissions.';
+$lang['mediainuse'] = 'Le fichier « %s » n\'a pas été effacé, il est en cours d\'utilisation.';
+$lang['namespaces'] = 'Catégories';
+$lang['mediafiles'] = 'Fichiers disponibles dans';
+$lang['accessdenied'] = 'Vous n\'êtes pas autorisé à voir cette page.';
+$lang['mediausage'] = 'Utilisez la syntaxe suivante pour faire référence à ce fichier :';
+$lang['mediaview'] = 'Afficher le fichier original';
+$lang['mediaroot'] = 'racine';
+$lang['mediaupload'] = 'Téléverser un fichier dans la catégorie actuelle. Pour créer des sous-catégories, préfixez le nom du fichier par le nom de la sous-catégorie séparée par un double-point.';
+$lang['mediaextchange'] = 'Extension du fichier changée de .%s en .%s !';
+$lang['reference'] = 'Références pour';
+$lang['ref_inuse'] = 'Le fichier ne peut être effacé car il est utilisé par les pages suivantes :';
+$lang['ref_hidden'] = 'Des références existent dans des pages que vous n\'avez pas la permission de lire';
+$lang['hits'] = 'Occurrences trouvées';
+$lang['quickhits'] = 'Pages trouvées ';
+$lang['toc'] = 'Table des matières';
+$lang['current'] = 'Version actuelle';
+$lang['yours'] = 'Votre version';
+$lang['diff'] = 'Différences avec la version actuelle';
+$lang['diff2'] = 'Différences entre les versions sélectionnées';
+$lang['difflink'] = 'Lien vers cette vue';
+$lang['diff_type'] = 'Voir les différences :';
+$lang['diff_inline'] = 'Sur une seule ligne';
+$lang['diff_side'] = 'Côte à côte';
+$lang['line'] = 'Ligne';
+$lang['breadcrumb'] = 'Piste';
+$lang['youarehere'] = 'Vous êtes ici';
+$lang['lastmod'] = 'Dernière modification';
+$lang['by'] = 'par';
+$lang['deleted'] = 'effacée';
+$lang['created'] = 'créée';
+$lang['restored'] = 'ancienne révision restaurée';
+$lang['external_edit'] = 'modification externe';
+$lang['summary'] = 'Résumé';
+$lang['noflash'] = 'Le greffon <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash</a> est nécessaire pour afficher ce contenu.';
+$lang['download'] = 'Télécharger un extrait';
+$lang['mail_newpage'] = 'page ajoutée :';
+$lang['mail_changed'] = 'page modifiée :';
+$lang['mail_subscribe_list'] = 'pages modifiées dans la catégorie :';
+$lang['mail_new_user'] = 'nouvel utilisateur :';
+$lang['mail_upload'] = 'fichier envoyé :';
+$lang['changes_type'] = 'Voir les changements';
+$lang['pages_changes'] = 'Pages';
+$lang['media_changes'] = 'Fichier multimédias';
+$lang['both_changes'] = 'Pages et fichiers multimédias';
+$lang['qb_bold'] = 'Emphase forte (gras)';
+$lang['qb_italic'] = 'Emphase (italique)';
+$lang['qb_underl'] = 'Souligné';
+$lang['qb_code'] = 'Code « machine à écrire »';
+$lang['qb_strike'] = 'Texte barré';
+$lang['qb_h1'] = 'Titre de niveau 1';
+$lang['qb_h2'] = 'Titre de niveau 2';
+$lang['qb_h3'] = 'Titre de niveau 3';
+$lang['qb_h4'] = 'Titre de niveau 4';
+$lang['qb_h5'] = 'Titre de niveau 5';
+$lang['qb_h'] = 'Titre';
+$lang['qb_hs'] = 'Sélectionner la ligne de titre';
+$lang['qb_hplus'] = 'Titre de niveau supérieur';
+$lang['qb_hminus'] = 'Titre de niveau inférieur';
+$lang['qb_hequal'] = 'Titre de même niveau';
+$lang['qb_link'] = 'Lien interne';
+$lang['qb_extlink'] = 'Lien externe';
+$lang['qb_hr'] = 'Ligne horizontale';
+$lang['qb_ol'] = 'Liste numérotée';
+$lang['qb_ul'] = 'Liste à puce';
+$lang['qb_media'] = 'Ajouter des images ou d\'autres fichiers';
+$lang['qb_sig'] = 'Insérer une signature';
+$lang['qb_smileys'] = 'Émoticones';
+$lang['qb_chars'] = 'Caractères spéciaux';
+$lang['upperns'] = 'Aller à la catégorie parente';
+$lang['admin_register'] = 'Ajouter un nouvel utilisateur';
+$lang['metaedit'] = 'Modifier les métadonnées';
+$lang['metasaveerr'] = 'Erreur lors de l\'écriture des métadonnées';
+$lang['metasaveok'] = 'Métadonnées enregistrées';
+$lang['img_backto'] = 'Retour à';
+$lang['img_title'] = 'Titre';
+$lang['img_caption'] = 'Légende';
+$lang['img_date'] = 'Date';
+$lang['img_fname'] = 'Nom de fichier';
+$lang['img_fsize'] = 'Taille';
+$lang['img_artist'] = 'Auteur';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Appareil photo';
+$lang['img_keywords'] = 'Mots-clés';
+$lang['img_width'] = 'Largeur';
+$lang['img_height'] = 'Hauteur';
+$lang['img_manager'] = 'Voir dans le gestionnaire de médias';
+$lang['subscr_subscribe_success'] = '%s a été ajouté à la liste de souscription de %s';
+$lang['subscr_subscribe_error'] = 'Erreur en ajoutant %s à la liste de souscription de %s';
+$lang['subscr_subscribe_noaddress'] = 'Il n\'y a pas d\'adresse associée à votre identifiant, vous ne pouvez pas être ajouté à la liste de souscription';
+$lang['subscr_unsubscribe_success'] = '%s a été retiré de la liste de souscription de %s';
+$lang['subscr_unsubscribe_error'] = 'Erreur en retirant %s de la liste de souscription de %s';
+$lang['subscr_already_subscribed'] = '%s est déjà souscrit à %s';
+$lang['subscr_not_subscribed'] = '%s n\'est pas souscrit à %s';
+$lang['subscr_m_not_subscribed'] = 'Vous n\'avez pas souscrit pour l\'instant à la page actuelle ou la catégorie';
+$lang['subscr_m_new_header'] = 'Ajouter une souscription';
+$lang['subscr_m_current_header'] = 'Souscriptions actives';
+$lang['subscr_m_unsubscribe'] = 'Annuler la souscription';
+$lang['subscr_m_subscribe'] = 'Souscrire';
+$lang['subscr_m_receive'] = 'Recevoir';
+$lang['subscr_style_every'] = 'Envoyer un courriel à chaque modification';
+$lang['subscr_style_digest'] = 'Courriel, tous les %.2f jours, résumant les modifications de chaque page';
+$lang['subscr_style_list'] = 'Liste des pages modifiées depuis le dernier courriel (tous les %.2f jours)';
+$lang['authmodfailed'] = 'Mauvais paramétrage de l\'authentification. Merci d\'informer l\'administrateur du Wiki.';
+$lang['authtempfail'] = 'L\'authentification est temporairement indisponible. Si cela perdure, merci d\'informer l\'administrateur du Wiki.';
+$lang['i_chooselang'] = 'Choisissez votre langue';
+$lang['i_installer'] = 'Installeur DokuWiki';
+$lang['i_wikiname'] = 'Nom du wiki';
+$lang['i_enableacl'] = 'Activer les ACL (recommandé)';
+$lang['i_superuser'] = 'Super-utilisateur';
+$lang['i_problems'] = 'L\'installeur a détecté les problèmes indiqués ci-dessous. Vous ne pouvez poursuivre tant qu\'ils n\'auront pas été corrigés.';
+$lang['i_modified'] = 'Pour des raisons de sécurité ce script ne fonctionne qu\'avec une installation neuve et non modifiée de DokuWiki. Vous devriez ré-extraire les fichiers depuis le paquet téléchargé ou consulter les <a href="http://dokuwiki.org/install">instructions d\'installation de DokuWiki</a>';
+$lang['i_funcna'] = 'La fonction PHP <code>%s</code> n\'est pas disponible. Peut-être que votre hébergeur l\'a désactivée ?';
+$lang['i_phpver'] = 'Votre version de PHP (%s) est antérieure à la version requise (%s). Vous devez mettre à jour votre installation de PHP.';
+$lang['i_permfail'] = '<code>%s</code> n\'est pas accessible en écriture pour DokuWiki. Vous devez corriger les permissions de ce répertoire !';
+$lang['i_confexists'] = '<code>%s</code> existe déjà';
+$lang['i_writeerr'] = 'Impossible de créer <code>%s</code>. Vous devez vérifier les permissions des répertoires/fichiers et créer le fichier manuellement.';
+$lang['i_badhash'] = 'dokuwiki.php non reconnu ou modifié (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - valeur interdite ou vide';
+$lang['i_success'] = 'L\'installation s\'est terminée avec succès. Vous pouvez maintenant supprimer le fichier « install.php ». Continuer avec <a href="doku.php">votre nouveau DokuWiki</a>.';
+$lang['i_failure'] = 'Des erreurs sont survenues lors de l\'écriture des fichiers de configuration. Il vous faudra les corriger manuellement avant de pouvoir utiliser <a href="doku.php">votre nouveau DokuWiki</a>.';
+$lang['i_policy'] = 'Politique d\'ACL initiale';
+$lang['i_pol0'] = 'Wiki ouvert (lecture, écriture, envoi de fichiers pour tout le monde)';
+$lang['i_pol1'] = 'Wiki public (lecture pour tout le monde, écriture et envoi de fichiers pour les utilisateurs enregistrés)';
+$lang['i_pol2'] = 'Wiki fermé (lecture, écriture, envoi de fichiers pour les utilisateurs enregistrés uniquement)';
+$lang['i_retry'] = 'Réessayer';
+$lang['i_license'] = 'Veuillez choisir la licence sous laquelle placer votre contenu :';
+$lang['recent_global'] = 'Vous êtes actuellement en train de regarder les modifications au sein de la catégorie <strong>%s</strong>. Vous pouvez aussi <a href="%s">voir les récentes modifications sur tout le wiki</a>.';
+$lang['years'] = 'il y a %d ans';
+$lang['months'] = 'il y a %d mois';
+$lang['weeks'] = 'il y a %d semaines';
+$lang['days'] = 'il y a %d jours';
+$lang['hours'] = 'il y a %d heures';
+$lang['minutes'] = 'il y a %d minutes';
+$lang['seconds'] = 'il y a %d secondes';
+$lang['wordblock'] = 'Vos modifications n\'ont pas été sauvegardées parce qu\'elles contiennent des textes non autorisé (spam).';
+$lang['media_uploadtab'] = 'Télécharger';
+$lang['media_searchtab'] = 'Rechercher';
+$lang['media_file'] = 'Fichier';
+$lang['media_viewtab'] = 'Voir';
+$lang['media_edittab'] = 'Éditer';
+$lang['media_historytab'] = 'Historique';
+$lang['media_list_thumbs'] = 'Aperçus';
+$lang['media_list_rows'] = 'Lignes';
+$lang['media_sort_name'] = 'Tri par nom';
+$lang['media_sort_date'] = 'Tri par date';
+$lang['media_namespaces'] = 'Choisissez un espace de nom';
+$lang['media_files'] = 'Fichiers de %s';
+$lang['media_upload'] = 'Télécharger dans %s.';
+$lang['media_search'] = 'Chercher dans %s.';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s dans %s';
+$lang['media_edit'] = 'Éditer %s';
+$lang['media_history'] = 'Historique de %s';
+$lang['media_meta_edited'] = 'métadonnées éditées';
+$lang['media_perm_read'] = 'Désolé, vous n\'avez pas les droits pour lire les fichiers.';
+$lang['media_perm_upload'] = 'Désolé, vous n\'avez pas les droits pour télécharger des fichiers.';
+$lang['media_update'] = 'Télécharger une nouvelle version';
+$lang['media_restore'] = 'Restaurer cette version';
+$lang['plugin_install_err'] = 'Extension mal installée. Renommez le dossier de l\'extension \'%s\' en \'%s\'.';
diff --git a/inc/lang/fr/locked.txt b/inc/lang/fr/locked.txt
new file mode 100644
index 000000000..82cdd7373
--- /dev/null
+++ b/inc/lang/fr/locked.txt
@@ -0,0 +1,3 @@
+====== Page bloquée ======
+
+Cette page est actuellement bloquée pour modification par un autre utilisateur. Vous devez attendre que l'autre utilisateur ait terminé ou que le blocage de la page expire.
diff --git a/inc/lang/fr/login.txt b/inc/lang/fr/login.txt
new file mode 100644
index 000000000..c8d40c86d
--- /dev/null
+++ b/inc/lang/fr/login.txt
@@ -0,0 +1,3 @@
+====== Connexion ======
+
+Vous n'êtes pas connecté ! Entrez vos identifiants ci-dessous pour vous connecter. Votre navigateur doit accepter les cookies pour pouvoir vous connecter.
diff --git a/inc/lang/fr/mailtext.txt b/inc/lang/fr/mailtext.txt
new file mode 100644
index 000000000..add3b2779
--- /dev/null
+++ b/inc/lang/fr/mailtext.txt
@@ -0,0 +1,19 @@
+Une page dans votre wiki a été ajoutée ou modifiée. Voici les
+détails :
+
+Date : @DATE@
+Navigateur : @BROWSER@
+Adresse IP : @IPADDRESS@
+Nom d'hôte : @HOSTNAME@
+Ancienne révision : @OLDPAGE@
+Nouvelle révision : @NEWPAGE@
+Différences : @OLDPAGE@&do=diff
+Résumé : @SUMMARY@
+Utilisateur : @USER@
+
+@DIFF@
+
+
+--
+Ce courriel a été généré par DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/fr/newpage.txt b/inc/lang/fr/newpage.txt
new file mode 100644
index 000000000..0ed2b25af
--- /dev/null
+++ b/inc/lang/fr/newpage.txt
@@ -0,0 +1,4 @@
+====== Cette page n'existe pas encore ======
+
+Vous avez suivi un lien vers une page qui n'existe pas encore. Si vos droits sont suffisants, vous pouvez utiliser le bouton ou le lien « Créer cette page ».
+
diff --git a/inc/lang/fr/norev.txt b/inc/lang/fr/norev.txt
new file mode 100644
index 000000000..3f96b6aff
--- /dev/null
+++ b/inc/lang/fr/norev.txt
@@ -0,0 +1,4 @@
+====== Révision non trouvée ======
+
+La révision demandée n'existe pas. Utilisez le bouton ou le lien « Anciennes révisions » pour une liste des révisions de ce document.
+
diff --git a/inc/lang/fr/password.txt b/inc/lang/fr/password.txt
new file mode 100644
index 000000000..f4500fc85
--- /dev/null
+++ b/inc/lang/fr/password.txt
@@ -0,0 +1,10 @@
+Bonjour @FULLNAME@ !
+
+Voici vos identifiants pour @TITLE@ sur @DOKUWIKIURL@
+
+Utilisateur : @LOGIN@
+Mot de passe : @PASSWORD@
+
+--
+Ce courriel a été envoyé par DokuWiki de
+@DOKUWIKIURL@
diff --git a/inc/lang/fr/preview.txt b/inc/lang/fr/preview.txt
new file mode 100644
index 000000000..26fbcd9c2
--- /dev/null
+++ b/inc/lang/fr/preview.txt
@@ -0,0 +1,4 @@
+====== Aperçu ======
+
+Ceci est un aperçu de votre document. Attention ! Il n'est **pas encore enregistré** !
+
diff --git a/inc/lang/fr/pwconfirm.txt b/inc/lang/fr/pwconfirm.txt
new file mode 100644
index 000000000..af84833df
--- /dev/null
+++ b/inc/lang/fr/pwconfirm.txt
@@ -0,0 +1,15 @@
+Bonjour @FULLNAME@ !
+
+Quelqu'un a demandé un nouveau mot de passe pour votre identifiant
+@TITLE@ sur @DOKUWIKIURL@
+
+Si vous n'êtes pas à l'origine de cette requête d'un nouveau mot de
+passe, ignorez ce message.
+
+Pour confirmer que cette requête émane bien de vous, merci de suivre le lien ci-dessous.
+
+@CONFIRM@
+
+--
+Ce courriel a été généré par DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/fr/read.txt b/inc/lang/fr/read.txt
new file mode 100644
index 000000000..faa756e8b
--- /dev/null
+++ b/inc/lang/fr/read.txt
@@ -0,0 +1,2 @@
+Cette page est en lecture seule. Vous pouvez afficher le texte source, mais pas le modifier. Contactez votre administrateur si vous pensez qu'il s'agit d'une erreur.
+
diff --git a/inc/lang/fr/recent.txt b/inc/lang/fr/recent.txt
new file mode 100644
index 000000000..b41972fc1
--- /dev/null
+++ b/inc/lang/fr/recent.txt
@@ -0,0 +1,5 @@
+====== Derniers changements ======
+
+Les pages suivantes ont été modifiées récemment.
+
+
diff --git a/inc/lang/fr/register.txt b/inc/lang/fr/register.txt
new file mode 100644
index 000000000..e2d02f55c
--- /dev/null
+++ b/inc/lang/fr/register.txt
@@ -0,0 +1,3 @@
+====== S'enregistrer comme nouvel utilisateur ======
+
+Remplissez toutes les informations ci-dessous pour vous créer un compte sur ce Wiki. Assurez-vous de fournir une **adresse de courriel valide** car votre mot de passe sera envoyé à cette adresse. Le nom d'utilisateur doit être un [[doku>pagename|nom de page]] valide.
diff --git a/inc/lang/fr/registermail.txt b/inc/lang/fr/registermail.txt
new file mode 100644
index 000000000..1beae8522
--- /dev/null
+++ b/inc/lang/fr/registermail.txt
@@ -0,0 +1,14 @@
+Un nouvel utilisateur s'est enregistré. Voici les détails :
+
+Utilisateur : @NEWUSER@
+Nom : @NEWNAME@
+Adresse de courriel : @NEWEMAIL@
+
+Date : @DATE@
+Navigateur : @BROWSER@
+Adresse IP : @IPADDRESS@
+Nom d'hôte : @HOSTNAME@
+
+--
+Ce courriel a été généré par DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/fr/resendpwd.txt b/inc/lang/fr/resendpwd.txt
new file mode 100644
index 000000000..44fbeef03
--- /dev/null
+++ b/inc/lang/fr/resendpwd.txt
@@ -0,0 +1,4 @@
+====== Envoyer un nouveau mot de passe ======
+
+Veuillez compléter les champs ci-dessous pour obtenir un nouveau mot de passe pour votre compte dans ce wiki. Un lien de confirmation vous sera envoyé à l'adresse de courriel utilisée lors de votre enregistrement.
+
diff --git a/inc/lang/fr/revisions.txt b/inc/lang/fr/revisions.txt
new file mode 100644
index 000000000..29c17137f
--- /dev/null
+++ b/inc/lang/fr/revisions.txt
@@ -0,0 +1,4 @@
+====== Anciennes révisions ======
+
+Voici les anciennes révisions de la page en cours. Pour revenir à une ancienne révision, sélectionnez-la ci-dessous, cliquez sur le bouton « Modifier cette page » et enregistrez-la.
+
diff --git a/inc/lang/fr/searchpage.txt b/inc/lang/fr/searchpage.txt
new file mode 100644
index 000000000..a9bd91608
--- /dev/null
+++ b/inc/lang/fr/searchpage.txt
@@ -0,0 +1,5 @@
+====== Recherche ======
+
+Voici les résultats de votre recherche. Si vous n'avez pas trouvé ce que vous cherchiez, vous pouvez créer ou modifier la page correspondante à votre requête en cliquant sur le bouton approprié.
+
+===== Résultats =====
diff --git a/inc/lang/fr/showrev.txt b/inc/lang/fr/showrev.txt
new file mode 100644
index 000000000..2e36199b1
--- /dev/null
+++ b/inc/lang/fr/showrev.txt
@@ -0,0 +1,2 @@
+**Ceci est une ancienne révision du document !**
+----
diff --git a/inc/lang/fr/stopwords.txt b/inc/lang/fr/stopwords.txt
new file mode 100644
index 000000000..981bae26b
--- /dev/null
+++ b/inc/lang/fr/stopwords.txt
@@ -0,0 +1,112 @@
+# Cette liste regroupe des mots ignorés par l'indexeur
+# Chaque ligne comporte un mot
+# Les fins de ligne de ce fichier doivent être de type UNIX
+# Les mots de moins de 3 lettres sont ignorés par défaut.
+# Cette liste est basée sur http://www.ranks.nl/stopwords/
+alors
+aucuns
+aussi
+autre
+avant
+avec
+avoir
+bon
+car
+cela
+ces
+ceux
+chaque
+comme
+comment
+dans
+des
+dedans
+dehors
+depuis
+deux
+devrait
+doit
+donc
+dos
+droite
+début
+elle
+elles
+encore
+essai
+est
+fait
+faites
+fois
+font
+force
+haut
+hors
+ici
+ils
+juste
+les
+leur
+là
+maintenant
+mais
+mes
+mine
+moins
+mon
+mot
+même
+nommés
+notre
+nous
+nouveaux
+où
+par
+parce
+parole
+pas
+personnes
+peut
+peu
+pièce
+plupart
+pour
+pourquoi
+quand
+que
+quel
+quelle
+quelles
+quels
+qui
+sans
+ses
+seulement
+sien
+son
+sont
+sous
+soyez
+sujet
+sur
+tandis
+tellement
+tels
+tes
+ton
+tous
+tout
+trop
+très
+valeur
+voie
+voient
+vont
+votre
+vous
+ça
+étaient
+état
+étions
+été
+être
diff --git a/inc/lang/fr/subscr_digest.txt b/inc/lang/fr/subscr_digest.txt
new file mode 100644
index 000000000..1803407fa
--- /dev/null
+++ b/inc/lang/fr/subscr_digest.txt
@@ -0,0 +1,19 @@
+Bonjour,
+
+La page « @PAGE@ » dans le wiki « @TITLE@ » a été modifiée. Voici ces modifications :
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Révision précédente : @OLDPAGE@
+Nouvelle révision : @NEWPAGE@
+
+Pour annuler les notifications de page, connectez-vous au wiki à l'adresse
+@DOKUWIKIURL@ puis visitez
+@SUBSCRIBE@
+et désabonnez-vous de la page ou de la catégorie.
+
+--
+Ce courriel a été généré par Dokuwiki :
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fr/subscr_form.txt b/inc/lang/fr/subscr_form.txt
new file mode 100644
index 000000000..528f77475
--- /dev/null
+++ b/inc/lang/fr/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Gestion de l'abonnement ======
+
+Cette page vous permet de gérer vos abonnements à la page ou à la catégorie courantes \ No newline at end of file
diff --git a/inc/lang/fr/subscr_list.txt b/inc/lang/fr/subscr_list.txt
new file mode 100644
index 000000000..3387b11ee
--- /dev/null
+++ b/inc/lang/fr/subscr_list.txt
@@ -0,0 +1,16 @@
+Bonjour,
+
+Des pages dans la catégorie « @PAGE@ » du wiki « @TITLE@ » ont été modifiées. Voici ces modifications :
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Pour annuler les notifications de page, connectez-vous au wiki à l'adresse
+@DOKUWIKIURL@ puis visitez
+@SUBSCRIBE@
+et désabonnez-vous de la page ou de la catégorie.
+
+--
+Ce courriel a été généré par Dokuwiki :
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fr/subscr_single.txt b/inc/lang/fr/subscr_single.txt
new file mode 100644
index 000000000..1b9d5e1b5
--- /dev/null
+++ b/inc/lang/fr/subscr_single.txt
@@ -0,0 +1,22 @@
+Bonjour,
+
+La page « @PAGE@ » dans le wiki « @TITLE@ » a été modifiée. Voici ces modifications :
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Date : @DATE@
+Utilisateur : @USER@
+Résumé : @SUMMARY@
+Révision précédente : @OLDPAGE@
+Nouvelle révision : @NEWPAGE@
+
+Pour annuler les notifications de page, connectez-vous au wiki à l'adresse
+@DOKUWIKIURL@ puis visitez
+@SUBSCRIBE@
+et désabonnez-vous de la page ou de la catégorie.
+
+--
+Ce courriel a été généré par Dokuwiki :
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/fr/updateprofile.txt b/inc/lang/fr/updateprofile.txt
new file mode 100644
index 000000000..623d75e88
--- /dev/null
+++ b/inc/lang/fr/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Mise à jour de votre profil ======
+
+Ne complétez que les champs que vous souhaitez modifier. Vous ne pouvez pas modifier votre nom d'utilisateur.
+
+
diff --git a/inc/lang/fr/uploadmail.txt b/inc/lang/fr/uploadmail.txt
new file mode 100644
index 000000000..05b3205d7
--- /dev/null
+++ b/inc/lang/fr/uploadmail.txt
@@ -0,0 +1,14 @@
+Un fichier a été téléversé dans votre wiki. En voici les détails :
+
+Fichier : @MEDIA@
+Date : @DATE@
+Navigateur : @BROWSER@
+Adresse IP : @IPADDRESS@
+Nom d'hôte : @HOSTNAME@
+Taille : @SIZE@
+Type MIME : @MIME@
+Utilisateur : @USER@
+
+--
+Ce message a été généré par DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/gl/admin.txt b/inc/lang/gl/admin.txt
new file mode 100644
index 000000000..eeaed992a
--- /dev/null
+++ b/inc/lang/gl/admin.txt
@@ -0,0 +1,4 @@
+====== Administración ======
+
+De seguido podes atopar unha lista de tarefas administrativas dispoñíbeis no DokuWiki.
+
diff --git a/inc/lang/gl/adminplugins.txt b/inc/lang/gl/adminplugins.txt
new file mode 100644
index 000000000..e52172ebc
--- /dev/null
+++ b/inc/lang/gl/adminplugins.txt
@@ -0,0 +1 @@
+===== Extensións adicionais ===== \ No newline at end of file
diff --git a/inc/lang/gl/backlinks.txt b/inc/lang/gl/backlinks.txt
new file mode 100644
index 000000000..f77b74bbd
--- /dev/null
+++ b/inc/lang/gl/backlinks.txt
@@ -0,0 +1,4 @@
+====== Ligazóns entrantes ======
+
+Isto é unha listaxe de páxinas que semellan ligar coa páxina actual.
+
diff --git a/inc/lang/gl/conflict.txt b/inc/lang/gl/conflict.txt
new file mode 100644
index 000000000..dcd87c7a5
--- /dev/null
+++ b/inc/lang/gl/conflict.txt
@@ -0,0 +1,6 @@
+====== Hai unha versión máis nova ======
+
+Hai unha versión máis nova do documento que editaches. Isto sucede cando outro usuario mudou o documento mentres ti estabas a editalo.
+
+Examina as diferenzas amosadas embaixo polo miúdo, e logo decide que versión queres manter. Se escolleres ''Gardar'', gardarase a túa versión. Preme en ''Cancelar'' para manteres a versión actual.
+
diff --git a/inc/lang/gl/denied.txt b/inc/lang/gl/denied.txt
new file mode 100644
index 000000000..69408a4f3
--- /dev/null
+++ b/inc/lang/gl/denied.txt
@@ -0,0 +1,4 @@
+====== Permiso Denegado ======
+
+Sentímolo, mais non tes permisos de abondo para continuares. Pode que esqueceses iniciar a sesión?
+
diff --git a/inc/lang/gl/diff.txt b/inc/lang/gl/diff.txt
new file mode 100644
index 000000000..df87707f0
--- /dev/null
+++ b/inc/lang/gl/diff.txt
@@ -0,0 +1,4 @@
+====== Diferenzas ======
+
+Isto amosa as diferenzas entre a revisión seleccionada e a versión actual da páxina.
+
diff --git a/inc/lang/gl/draft.txt b/inc/lang/gl/draft.txt
new file mode 100644
index 000000000..ac36dc01a
--- /dev/null
+++ b/inc/lang/gl/draft.txt
@@ -0,0 +1,6 @@
+====== Arquivo de rascuño atopado ======
+
+A túa última sesión de edición desta páxina non foi completada de xeito correcto. O DokuWiki gravou automaticamente un rascuño durante o teu traballo que agora podes usar para continuares coa edición. De seguido podes ver os datos que foron gardados da túa última sesión.
+
+Por favor, escolle se queres //Recuperar// a túa sesión de edición perdida, //Eliminar// o borrador autogardado ou //Cancelar// o proceso de edición.
+
diff --git a/inc/lang/gl/edit.txt b/inc/lang/gl/edit.txt
new file mode 100644
index 000000000..1cc124300
--- /dev/null
+++ b/inc/lang/gl/edit.txt
@@ -0,0 +1,2 @@
+Edita a páxina e preme en ''Gardar''. Bótalle un ollo á [[wiki:syntax|sintaxe]] para veres a sintaxe do Wiki. Por favor, edita a páxina só se podes **mellorala**. Se quixeres facer probas, aprende como levar a cabo os teus primeiros pasos na [[playground:playground|eira]].
+
diff --git a/inc/lang/gl/editrev.txt b/inc/lang/gl/editrev.txt
new file mode 100644
index 000000000..d6a0490a3
--- /dev/null
+++ b/inc/lang/gl/editrev.txt
@@ -0,0 +1,2 @@
+**Cargaches unha revisión antiga do documento!** Se o gardares, crearás unha nova versión con estes datos.
+----
diff --git a/inc/lang/gl/index.txt b/inc/lang/gl/index.txt
new file mode 100644
index 000000000..b0b100bda
--- /dev/null
+++ b/inc/lang/gl/index.txt
@@ -0,0 +1,4 @@
+====== Índice ======
+
+Isto é un índice de todas as páxinas dispoñíbeis, ordenadas por [[doku>namespaces|nomes de espazo]].
+
diff --git a/inc/lang/gl/install.html b/inc/lang/gl/install.html
new file mode 100644
index 000000000..ca26f7961
--- /dev/null
+++ b/inc/lang/gl/install.html
@@ -0,0 +1,25 @@
+<p>Esta páxina é unha axuda na primeira vez que se instala e configura o
+<a href="http://dokuwiki.org">Dokuwiki</a>. Se queres máis información
+verbo deste instalador está dispoñible na súa propia
+<a href="http://dokuwiki.org/installer">páxina de documentación</a>.</p>
+
+<p>O DokuWiki emprega arquivos normais para a almacenaxe das páxinas do wiki
+e outra información asociada coas mesmas (p.e. imaxes, índices de procura,
+revisións antigas, etc). Por iso, para poder operar correctamente, o DokuWiki
+<strong>precisa</strong> ter acceso de escritura aos directorios que conteñen
+eses arquivos. Este instalador non é quen de configurar os permisos dos directorios.
+Isto debe facerse normalmente de xeito directo na liña de comandos ou, se estás a
+usar unha hospedaxe, a través do FTP ou do panel de control da túa hospedaxe (p.e.
+o cPanel).</p>
+
+<p>Este instalador configurará o teu DokuWiki para o uso da
+<acronym title="access control list">ACL</acronym>, o cal permitirá ao administrador
+iniciar sesión e acceder ao menú de administración do DokuWiki para instalar extensións,
+xestionar usuarios e accesos ás páxinas do wiki, ademais de modificar a configuración.
+Non é imprescindíbel para o funcionamento do DokuWiki, porén, fai moito máis doada a
+administración do mesmo.</p>
+
+<p>Os usuarios expertos ou con requisitos especiais de configuración poden visitar
+as seguintes ligazóns para obter pormenores relativos ás
+<a href="http://dokuwiki.org/install">instruccións de instalación</a>
+e á <a href="http://dokuwiki.org/config">configuración</a>.</p>
diff --git a/inc/lang/gl/lang.php b/inc/lang/gl/lang.php
new file mode 100644
index 000000000..329820333
--- /dev/null
+++ b/inc/lang/gl/lang.php
@@ -0,0 +1,315 @@
+<?php
+/**
+ * galician language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Editar esta páxina';
+$lang['btn_source'] = 'Amosar a fonte da páxina';
+$lang['btn_show'] = 'Amosar páxina';
+$lang['btn_create'] = 'Crear esta páxina';
+$lang['btn_search'] = 'Procurar';
+$lang['btn_save'] = 'Gardar';
+$lang['btn_preview'] = 'Previsualizar';
+$lang['btn_top'] = 'Comezo da páxina';
+$lang['btn_newer'] = '<< máis recente';
+$lang['btn_older'] = 'menos recente >>';
+$lang['btn_revs'] = 'Revisións antigas';
+$lang['btn_recent'] = 'Trocos recentes';
+$lang['btn_upload'] = 'Subir';
+$lang['btn_cancel'] = 'Cancelar';
+$lang['btn_index'] = 'Índice';
+$lang['btn_secedit'] = 'Editar';
+$lang['btn_login'] = 'Iniciar sesión';
+$lang['btn_logout'] = 'Rematar sesión';
+$lang['btn_admin'] = 'Administración';
+$lang['btn_update'] = 'Actualizar';
+$lang['btn_delete'] = 'Borrar';
+$lang['btn_back'] = 'Atrás';
+$lang['btn_backlink'] = 'Ligazóns con isto';
+$lang['btn_backtomedia'] = 'Volver á Selección de Arquivos-Media';
+$lang['btn_subscribe'] = 'Avísame dos trocos na páxina';
+$lang['btn_profile'] = 'Actualizar Perfil';
+$lang['btn_reset'] = 'Reiniciar';
+$lang['btn_resendpwd'] = 'Envíame un novo contrasinal';
+$lang['btn_draft'] = 'Editar borrador';
+$lang['btn_recover'] = 'Recuperar borrador';
+$lang['btn_draftdel'] = 'Eliminar borrador';
+$lang['btn_revert'] = 'Restaurar';
+$lang['btn_register'] = 'Rexístrate';
+$lang['btn_apply'] = 'Aplicar';
+$lang['btn_media'] = 'Xestor de Arquivos-Media';
+$lang['loggedinas'] = 'Iniciaches sesión como';
+$lang['user'] = 'Nome de Usuario';
+$lang['pass'] = 'Contrasinal';
+$lang['newpass'] = 'Novo Contrasinal';
+$lang['oldpass'] = 'Confirmar contrasinal actual';
+$lang['passchk'] = 'de novo';
+$lang['remember'] = 'Lémbrame';
+$lang['fullname'] = 'Nome Completo';
+$lang['email'] = 'Correo-e';
+$lang['profile'] = 'Perfil de Usuario';
+$lang['badlogin'] = 'Sentímolo, mais o nome de usuario ou o contrasinal non son correctos.';
+$lang['minoredit'] = 'Trocos Menores';
+$lang['draftdate'] = 'Borrador gardado automaticamente en';
+$lang['nosecedit'] = 'A páxina mudou entrementres, a información da sección estaba desfasada polo que se cargou a páxina completa no seu lugar.';
+$lang['regmissing'] = 'Sentímolo, mais tes que cubrir todos os campos.';
+$lang['reguexists'] = 'Sentímolo, mais xa existe un usuario con ese nome.';
+$lang['regsuccess'] = 'O usuario foi creado e o contrasinal enviado por correo-e.';
+$lang['regsuccess2'] = 'O usuario foi creado.';
+$lang['regmailfail'] = 'Semella que houbo un erro ao tentar enviar o correo-e co contrasinal. Por favor, contacta co administrador!';
+$lang['regbadmail'] = 'O enderezo de correo-e proporcionado semella incorrecto - se consideras que isto é un erro, contacta co administrador';
+$lang['regbadpass'] = 'Os dous contrasinais inseridos non coinciden, por favor téntao de novo.';
+$lang['regpwmail'] = 'O teu contrasinal do DokuWiki';
+$lang['reghere'] = 'Aínda non tes unha conta? Crea a túa';
+$lang['profna'] = 'Este wiki non permite modificacións dos perfís';
+$lang['profnochange'] = 'Non hai trocos, nada que facer.';
+$lang['profnoempty'] = 'Non se permite un nome ou un enderezo de correo-e baleiros.';
+$lang['profchanged'] = 'Perfil de usuario actualizado correctamente.';
+$lang['pwdforget'] = 'Esqueceches o teu contrasinal? Consegue un novo';
+$lang['resendna'] = 'Este wiki non permite o reenvío de contrasinais.';
+$lang['resendpwd'] = 'Enviar novo contrasinal para';
+$lang['resendpwdmissing'] = 'Sentímolo, tes que cubrir todos os campos.';
+$lang['resendpwdnouser'] = 'Sentímolo, non atopamos este usuario no noso banco de datos.';
+$lang['resendpwdbadauth'] = 'Sentímolo, mais este código de autorización non é válido. Asegúrate de que usaches a ligazón completa de confirmación.';
+$lang['resendpwdconfirm'] = 'Enviouse unha ligazón de confirmación por correo-e.';
+$lang['resendpwdsuccess'] = 'O teu novo contrasinal foi enviado por correo-e.';
+$lang['license'] = 'O contido deste wiki, agás onde se indique o contrario, ofrécese baixo da seguinte licenza:';
+$lang['licenseok'] = 'Nota: Ao editares esta páxina estás a aceptar o licenciamento do contido baixo da seguinte licenza:';
+$lang['searchmedia'] = 'Procurar nome de arquivo:';
+$lang['searchmedia_in'] = 'Procurar en %s';
+$lang['txt_upload'] = 'Escolle o arquivo para subir';
+$lang['txt_filename'] = 'Subir como (opcional)';
+$lang['txt_overwrt'] = 'Sobrescribir arquivo existente';
+$lang['lockedby'] = 'Bloqueado actualmente por';
+$lang['lockexpire'] = 'O bloqueo remata o';
+$lang['js']['willexpire'] = 'O teu bloqueo para editares esta páxina vai caducar nun minuto.\nPara de evitar conflitos, emprega o botón de previsualización para reiniciares o contador do tempo de bloqueo.';
+$lang['js']['notsavedyet'] = 'Perderanse os trocos non gardados.
+Está certo de quereres continuar?';
+$lang['js']['searchmedia'] = 'Procurar ficheiros';
+$lang['js']['keepopen'] = 'Manter a fiestra aberta na selección';
+$lang['js']['hidedetails'] = 'Agochar Pormenores';
+$lang['js']['mediatitle'] = 'Configuración de ligazón';
+$lang['js']['mediadisplay'] = 'Tipo de ligazón';
+$lang['js']['mediaalign'] = 'Aliñamento';
+$lang['js']['mediasize'] = 'Tamaño de imaxe';
+$lang['js']['mediatarget'] = 'Albo da ligazón';
+$lang['js']['mediaclose'] = 'Fechar';
+$lang['js']['mediainsert'] = 'Inserir';
+$lang['js']['mediadisplayimg'] = 'Amosar a imaxe';
+$lang['js']['mediadisplaylnk'] = 'Amosar só a ligazón';
+$lang['js']['mediasmall'] = 'Versión reducida';
+$lang['js']['mediamedium'] = 'Versión media';
+$lang['js']['medialarge'] = 'Versión grande';
+$lang['js']['mediaoriginal'] = 'Versión orixinal';
+$lang['js']['medialnk'] = 'Ligazón para a páxina de pormenores';
+$lang['js']['mediadirect'] = 'Ligazón directa para o orixinal';
+$lang['js']['medianolnk'] = 'Sen ligazón';
+$lang['js']['medianolink'] = 'Non ligar a imaxe';
+$lang['js']['medialeft'] = 'Aliñar a imaxe á esquerda';
+$lang['js']['mediaright'] = 'Aliñar a imaxe á dereita';
+$lang['js']['mediacenter'] = 'Aliñar a iamxe ao medio';
+$lang['js']['medianoalign'] = 'Non empregar aliñamento';
+$lang['js']['nosmblinks'] = 'A ligazón aos compartidos do Windows só funciona no Microsoft Internet Explorer.
+Sempre podes copiar e colar a ligazón.';
+$lang['js']['linkwiz'] = 'Asistente de ligazóns';
+$lang['js']['linkto'] = 'Ligazón para:';
+$lang['js']['del_confirm'] = 'Estás certo de quereres eliminar os elementos seleccionados?';
+$lang['js']['restore_confirm'] = 'Realmente desexas restaurar esta versión?';
+$lang['js']['media_diff'] = 'Ver as diferencias:';
+$lang['js']['media_diff_both'] = 'Cara a Cara';
+$lang['js']['media_diff_opacity'] = 'Opacidade';
+$lang['js']['media_diff_portions'] = 'Porcións';
+$lang['js']['media_select'] = 'Selecciona arquivos...';
+$lang['js']['media_upload_btn'] = 'Subir';
+$lang['js']['media_done_btn'] = 'Feito';
+$lang['js']['media_drop'] = 'Solta aquí os arquivos a subir';
+$lang['js']['media_cancel'] = 'eliminar';
+$lang['js']['media_overwrt'] = 'Sobreescribir os arquivos existentes';
+$lang['rssfailed'] = 'Houbo un erro ao tentar obter esta corrente RSS: ';
+$lang['nothingfound'] = 'Non se atopou nada.';
+$lang['mediaselect'] = 'Arquivos-Media';
+$lang['fileupload'] = 'Subida de Arquivos-Media';
+$lang['uploadsucc'] = 'Subida correcta';
+$lang['uploadfail'] = 'Erra na subida. Pode que sexa un problema de permisos?';
+$lang['uploadwrong'] = 'Subida denegada. Esta extensión de arquivo non está permitida!';
+$lang['uploadexist'] = 'Xa existe o arquivo. Non se fixo nada.';
+$lang['uploadbadcontent'] = 'O contido subido non concorda coa extensión do arquivo %s.';
+$lang['uploadspam'] = 'A subida foi bloqueada pola lista negra de correo-lixo.';
+$lang['uploadxss'] = 'A subida foi bloqueada por un posíbel contido malicioso.';
+$lang['uploadsize'] = 'O arquivo subido é grande de máis. (máx. %s)';
+$lang['deletesucc'] = 'O arquivo "%s" foi eliminado.';
+$lang['deletefail'] = '"%s" non puido ser eliminado - comproba os permisos.';
+$lang['mediainuse'] = 'O arquivo "%s" non foi eliminado - aínda está en uso.';
+$lang['namespaces'] = 'Nomes de espazos';
+$lang['mediafiles'] = 'Arquivos dispoñíbeis en';
+$lang['accessdenied'] = 'Non tes permitido ver esta páxina.';
+$lang['mediausage'] = 'Emprega a seguinte sintaxe para inserires unha referencia a este arquivo:';
+$lang['mediaview'] = 'Ver arquivo orixinal';
+$lang['mediaroot'] = 'raigaña';
+$lang['mediaupload'] = 'Sube aquí un arquivo ao nome de espazo actual. Para creares sub-nomes de espazos deberás antepoñelos ao nome indicado en "Subir como" separados por dous puntos.';
+$lang['mediaextchange'] = 'Extensión de arquivo mudada de .%s a .%s!';
+$lang['reference'] = 'Referencias para';
+$lang['ref_inuse'] = 'O arquivo non pode ser eliminado, xa que aínda está a ser usado polas seguintes páxinas:';
+$lang['ref_hidden'] = 'Algunhas referencias están en páxinas para as cales non tes permisos de lectura';
+$lang['hits'] = 'Vistas';
+$lang['quickhits'] = 'Nomes de páxinas coincidentes';
+$lang['toc'] = 'Táboa de Contidos';
+$lang['current'] = 'actual';
+$lang['yours'] = 'A túa Versión';
+$lang['diff'] = 'Amosar diferenzas coa versión actual';
+$lang['diff2'] = 'Amosar diferenzas entre as revisións seleccionadas';
+$lang['difflink'] = 'Enlazar a esta vista de comparación';
+$lang['diff_type'] = 'Ver diferenzas:';
+$lang['diff_inline'] = 'Por liña';
+$lang['diff_side'] = 'Cara a Cara';
+$lang['line'] = 'Liña';
+$lang['breadcrumb'] = 'Trazado';
+$lang['youarehere'] = 'Estás aquí';
+$lang['lastmod'] = 'Última modificación';
+$lang['by'] = 'por';
+$lang['deleted'] = 'eliminado';
+$lang['created'] = 'creado';
+$lang['restored'] = 'revisión antiga restaurada';
+$lang['external_edit'] = 'edición externa';
+$lang['summary'] = 'Resumo da edición';
+$lang['noflash'] = 'Precísase o <a href="http://www.adobe.com/products/flashplayer/">Extensión Adobe Flash</a> para amosar este contido.';
+$lang['download'] = 'Descargar Retallo (Snippet)';
+$lang['mail_newpage'] = 'páxina engadida:';
+$lang['mail_changed'] = 'páxina mudada:';
+$lang['mail_subscribe_list'] = 'páxinas mudadas en nome de espazo:';
+$lang['mail_new_user'] = 'Novo usuario:';
+$lang['mail_upload'] = 'arquivo subido:';
+$lang['changes_type'] = 'Ver cambios';
+$lang['pages_changes'] = 'Páxinas';
+$lang['media_changes'] = 'Arquivos-Media';
+$lang['both_changes'] = 'Ambos, páxinas e arquivos-media';
+$lang['qb_bold'] = 'Texto Resaltado';
+$lang['qb_italic'] = 'Texto en Cursiva';
+$lang['qb_underl'] = 'Texto Subliñado';
+$lang['qb_code'] = 'Texto de Código';
+$lang['qb_strike'] = 'Texto Riscado';
+$lang['qb_h1'] = 'Liña de Cabeceira de Nivel 1';
+$lang['qb_h2'] = 'Liña de Cabeceira de Nivel 2';
+$lang['qb_h3'] = 'Liña de Cabeceira de Nivel 3';
+$lang['qb_h4'] = 'Liña de Cabeceira de Nivel 4';
+$lang['qb_h5'] = 'Liña de Cabeceira de Nivel 5';
+$lang['qb_h'] = 'Liña de Cabeceira';
+$lang['qb_hs'] = 'Escoller Liña de Cabeceira';
+$lang['qb_hplus'] = 'Liña de Cabeceira Máis Alta';
+$lang['qb_hminus'] = 'Liña de Cabeceira Máis Baixa';
+$lang['qb_hequal'] = 'Liña de Cabeceira ao Mesmo Nivel';
+$lang['qb_link'] = 'Ligazón Interna';
+$lang['qb_extlink'] = 'Ligazón Externa';
+$lang['qb_hr'] = 'Liña Horizontal';
+$lang['qb_ol'] = 'Elemento de Lista Ordenada';
+$lang['qb_ul'] = 'Elemento de Lista Desordenada';
+$lang['qb_media'] = 'Engadir Imaxes e Outros Arquivos';
+$lang['qb_sig'] = 'Inserir Sinatura';
+$lang['qb_smileys'] = 'Risoños';
+$lang['qb_chars'] = 'Caracteres Especiais';
+$lang['upperns'] = 'choutar ao nome de espazo pai';
+$lang['admin_register'] = 'Engadir novo usuario';
+$lang['metaedit'] = 'Editar Metadatos';
+$lang['metasaveerr'] = 'Non se puideron escribir os metadatos';
+$lang['metasaveok'] = 'Metadatos gardados';
+$lang['img_backto'] = 'Volver a';
+$lang['img_title'] = 'Título';
+$lang['img_caption'] = 'Lenda';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Nome de arquivo';
+$lang['img_fsize'] = 'Tamaño';
+$lang['img_artist'] = 'Fotógrafo';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Formato';
+$lang['img_camera'] = 'Cámara';
+$lang['img_keywords'] = 'Verbas chave';
+$lang['img_width'] = 'Ancho';
+$lang['img_height'] = 'Alto';
+$lang['img_manager'] = 'Ver no xestor de arquivos-media';
+$lang['subscr_subscribe_success'] = 'Engadido %s á lista de subscrición para %s';
+$lang['subscr_subscribe_error'] = 'Erro ao tentar engadir %s á lista de subscrición para %s';
+$lang['subscr_subscribe_noaddress'] = 'Non hai enderezos asociados co teu inicio de sesión, non é posíbel engadirte á lista de subscrición';
+$lang['subscr_unsubscribe_success'] = 'Eliminado %s da lista de subscrición para %s';
+$lang['subscr_unsubscribe_error'] = 'Erro ao tentar eliminar %s da lista de subscrición para %s';
+$lang['subscr_already_subscribed'] = '%s xa está subscrito a %s';
+$lang['subscr_not_subscribed'] = '%s non está subscrito a %s';
+$lang['subscr_m_not_subscribed'] = 'Agora mesmo non estás subscrito á páxina ou nome de espazo actual';
+$lang['subscr_m_new_header'] = 'Engadir subscrición';
+$lang['subscr_m_current_header'] = 'Subscricións actuais';
+$lang['subscr_m_unsubscribe'] = 'Desubscribir';
+$lang['subscr_m_subscribe'] = 'Subscribir';
+$lang['subscr_m_receive'] = 'Recibir';
+$lang['subscr_style_every'] = 'correo-e en cada troco';
+$lang['subscr_style_digest'] = 'correo-e con resumo de trocos para cada páxina';
+$lang['subscr_style_list'] = 'lista de páxinas mudadas dende o último correo-e';
+$lang['authmodfailed'] = 'Configuración de autenticación de usuario incorrecta. Por favor, informa ao Administrador do teu Wiki.';
+$lang['authtempfail'] = 'A autenticación de usuario non está dispoñible de xeito temporal. De persistir esta situación, por favor, informa ao Administrador do teu Wiki.';
+$lang['i_chooselang'] = 'Escolle o teu idioma';
+$lang['i_installer'] = 'Instalador do DokuWiki';
+$lang['i_wikiname'] = 'Nome do Wiki';
+$lang['i_enableacl'] = 'Activar ACL (recomendado)';
+$lang['i_superuser'] = 'Super-usuario';
+$lang['i_problems'] = 'O instalador atopou algúns problemas, que se amosan de seguido. Non poderás continuar até que os soluciones.';
+$lang['i_modified'] = 'Por razóns de seguridade este script só funcionará cunha instalación nova e sen modificar do Dokuwiki.
+ Podes ou ben extraer de novo os arquivos dende o paquete descargado ou consultar as
+ <a href="http://dokuwiki.org/install">instruccións completas de instalación do Dokuwiki</a>';
+$lang['i_funcna'] = 'A función <code>%s</code> do PHP non está dispoñíbel. Pode que o teu provedor de hospedaxe a desactivase por algún motivo?';
+$lang['i_phpver'] = 'A túa versión <code>%s</code> do PHP é inferior á <code>%s</code> precisa. Debes actualizar a túa instalación do PHP.';
+$lang['i_permfail'] = '<code>%s</code> non é escribíbel polo DokuWiki. Debes corrixir a configuración de permisos deste directorio!';
+$lang['i_confexists'] = '<code>%s</code> xa existe';
+$lang['i_writeerr'] = 'Non se puido crear <code>%s</code>. Terás de comprobar os permisos do directorio/arquivo e crear o ficheiro de xeito manual.';
+$lang['i_badhash'] = 'dokuwiki.php irrecoñecíbel ou modificado (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - ilegal ou valor baleiro';
+$lang['i_success'] = 'A configuración rematou correctamente. Agora podes eliminar o arquivo install.php. Continúa deica o
+ <a href="doku.php">teu novo DokuWiki</a>.';
+$lang['i_failure'] = 'Houbo algúns erros ao tentar escribir os arquivos de configuración. Pode que precises solucionalos de xeito manual antes
+ de poderes empregar <a href="doku.php">o teu novo DokuWiki</a>.';
+$lang['i_policy'] = 'Regras iniciais da ACL';
+$lang['i_pol0'] = 'Wiki Aberto (lectura, escritura, subida de arquivos para todas as persoas)';
+$lang['i_pol1'] = 'Wiki Público (lectura para todas as persoas, escritura e subida de arquivos para usuarios rexistrados)';
+$lang['i_pol2'] = 'Wiki Fechado (lectura, escritura, subida de arquivos só para usuarios rexistrados)';
+$lang['i_retry'] = 'Tentar de novo';
+$lang['i_license'] = 'Por favor escolla a licenza para o contido:';
+$lang['recent_global'] = 'Agora mesmo estás a ver os trocos no nome de espazo <b>%s</b>. Tamén podes <a href="%s">ver os trocos recentes no Wiki enteiro</a>.';
+$lang['years'] = 'hai %d anos';
+$lang['months'] = 'hai %d meses';
+$lang['weeks'] = 'hai %d semanas';
+$lang['days'] = 'hai %d días';
+$lang['hours'] = 'hai %d horas';
+$lang['minutes'] = 'hai %d minutos';
+$lang['seconds'] = 'hai %d segundos';
+$lang['wordblock'] = 'Non se gardaron os cambios porque conteñen texto bloqueado (spam).';
+$lang['media_uploadtab'] = 'Subir';
+$lang['media_searchtab'] = 'Buscar';
+$lang['media_file'] = 'Arquivo';
+$lang['media_viewtab'] = 'Ver';
+$lang['media_edittab'] = 'Editar';
+$lang['media_historytab'] = 'Histórico';
+$lang['media_list_thumbs'] = 'Miniaturas';
+$lang['media_list_rows'] = 'Filas';
+$lang['media_sort_name'] = 'Nome';
+$lang['media_sort_date'] = 'Data';
+$lang['media_namespaces'] = 'Escolla espazo';
+$lang['media_files'] = 'Arquivos en %s';
+$lang['media_upload'] = 'Subir a %s';
+$lang['media_search'] = 'Buscar en %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s en %s';
+$lang['media_edit'] = 'Editar %s';
+$lang['media_history'] = 'Historia de %s';
+$lang['media_meta_edited'] = 'datos meta editados';
+$lang['media_perm_read'] = 'Sentímolo, non tes permisos suficientes para ler arquivos.';
+$lang['media_perm_upload'] = 'Sentímolo, non tes permisos suficientes para subir arquivos.';
+$lang['media_update'] = 'Subir nova versión';
+$lang['media_restore'] = 'Restaurar esta versión';
+$lang['plugin_install_err'] = 'Extensión instalada correctamente. Re-nomea o directorio da extensión de \'%s\' a \'%s\'.';
diff --git a/inc/lang/gl/locked.txt b/inc/lang/gl/locked.txt
new file mode 100644
index 000000000..90f9ab082
--- /dev/null
+++ b/inc/lang/gl/locked.txt
@@ -0,0 +1,3 @@
+====== Páxina bloqueada ======
+
+Esta páxina está actualmente bloqueada para a edición por outro usuario. Terás que agardar até que este usuario remate coa edición ou a que expire o bloqueo.
diff --git a/inc/lang/gl/login.txt b/inc/lang/gl/login.txt
new file mode 100644
index 000000000..506b30c6a
--- /dev/null
+++ b/inc/lang/gl/login.txt
@@ -0,0 +1,4 @@
+====== Inicio de Sesión ======
+
+Actualmente non iniciaches sesión ningunha! Insire as túas credenciais de identificación para iniciares a sesión. Debes ter as cookies activadas para poderes iniciar unha sesión.
+
diff --git a/inc/lang/gl/mailtext.txt b/inc/lang/gl/mailtext.txt
new file mode 100644
index 000000000..a6799d697
--- /dev/null
+++ b/inc/lang/gl/mailtext.txt
@@ -0,0 +1,17 @@
+Engadiuse ou mudouse unha páxina no teu DokuWiki. Aquí van os pormenores:
+
+Data : @DATE@
+Navegador : @BROWSER@
+Enderezo IP : @IPADDRESS@
+Nome do Host : @HOSTNAME@
+Revisión Antiga : @OLDPAGE@
+Revision Nova : @NEWPAGE@
+Resumo da Edición : @SUMMARY@
+Usuario : @USER@
+
+@DIFF@
+
+
+--
+Este correo foi xerado polo DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/gl/newpage.txt b/inc/lang/gl/newpage.txt
new file mode 100644
index 000000000..c073f1194
--- /dev/null
+++ b/inc/lang/gl/newpage.txt
@@ -0,0 +1,4 @@
+====== Este tema aínda non existe ======
+
+Seguiches unha ligazón deica un tema que aínda non existe. Se tes permisos axeitados, podes crealo ti premendo no botón ''Crear esta páxina''.
+
diff --git a/inc/lang/gl/norev.txt b/inc/lang/gl/norev.txt
new file mode 100644
index 000000000..af7383da8
--- /dev/null
+++ b/inc/lang/gl/norev.txt
@@ -0,0 +1,4 @@
+======Non hai tal revisión======
+
+A revisión especificada non existe. Utiliza o botón de ''Revisións Antigas'' para obteres unha listaxe das revisións antigas deste documento.
+
diff --git a/inc/lang/gl/password.txt b/inc/lang/gl/password.txt
new file mode 100644
index 000000000..652a55828
--- /dev/null
+++ b/inc/lang/gl/password.txt
@@ -0,0 +1,10 @@
+Ola @FULLNAME@!
+
+Aquí tes os teus datos de usuario para @TITLE@ en @DOKUWIKIURL@
+
+Usuario : @LOGIN@
+Contrasinal : @PASSWORD@
+
+--
+Este correo foi xerado polo DokuWiki en
+@DOKUWIKIURL@
diff --git a/inc/lang/gl/preview.txt b/inc/lang/gl/preview.txt
new file mode 100644
index 000000000..e0f749ff0
--- /dev/null
+++ b/inc/lang/gl/preview.txt
@@ -0,0 +1,4 @@
+====== Previsualización ======
+
+Isto é unha previsualización de como aparecerá o teu texto. Lembra: **Non está gardado** aínda!
+
diff --git a/inc/lang/gl/pwconfirm.txt b/inc/lang/gl/pwconfirm.txt
new file mode 100644
index 000000000..ef20212ff
--- /dev/null
+++ b/inc/lang/gl/pwconfirm.txt
@@ -0,0 +1,15 @@
+Ola @FULLNAME@!
+
+Alguén solicitou un novo contrasinal para o teu inicio de sesión
+@TITLE@ en @DOKUWIKIURL@
+
+Se non fuches ti quen o fixo podes ignorar este correo-e.
+
+Para confirmares que esta solicitude foi realmente enviada por ti,
+por favor, visita a seguinte ligazón.
+
+@CONFIRM@
+
+--
+Este correo-e foi xerado polo DokuWiki de
+@DOKUWIKIURL@
diff --git a/inc/lang/gl/read.txt b/inc/lang/gl/read.txt
new file mode 100644
index 000000000..28f3e1a95
--- /dev/null
+++ b/inc/lang/gl/read.txt
@@ -0,0 +1,2 @@
+Esta páxina é só de lectura. Podes ver o código fonte, mais non podes mudala. Coméntallo ao teu administrador se consideras que é un erro.
+
diff --git a/inc/lang/gl/recent.txt b/inc/lang/gl/recent.txt
new file mode 100644
index 000000000..622e4d938
--- /dev/null
+++ b/inc/lang/gl/recent.txt
@@ -0,0 +1,5 @@
+====== Trocos Recentes ======
+
+As seguintes páxinas foron mudadas recentemente.
+
+
diff --git a/inc/lang/gl/register.txt b/inc/lang/gl/register.txt
new file mode 100644
index 000000000..4f51f3878
--- /dev/null
+++ b/inc/lang/gl/register.txt
@@ -0,0 +1,4 @@
+====== Rexistro como novo usuario ======
+
+Cubre toda a información requirida a continuación para creares unha nova conta neste wiki. Asegúrate de forneceres un **enderezo de correo-e válido** - se non se che pide aquí que insiras un contrasinal, recibirás un novo nese enderezo. O nome de usuario deberá ser un [[doku>pagename|nome de páxina]] válido.
+
diff --git a/inc/lang/gl/registermail.txt b/inc/lang/gl/registermail.txt
new file mode 100644
index 000000000..7d4017481
--- /dev/null
+++ b/inc/lang/gl/registermail.txt
@@ -0,0 +1,14 @@
+Rexistrouse un novo usuario. Aquí van os pormenores:
+
+Nome de usuario : @NEWUSER@
+Nome completo : @NEWNAME@
+Correo-e : @NEWEMAIL@
+
+Data : @DATE@
+Navegador : @BROWSER@
+Enderezo IP : @IPADDRESS@
+Nome do Host : @HOSTNAME@
+
+--
+Este correo-e foi xerado polo DokuWiki de
+@DOKUWIKIURL@
diff --git a/inc/lang/gl/resendpwd.txt b/inc/lang/gl/resendpwd.txt
new file mode 100644
index 000000000..0ee2d6cb4
--- /dev/null
+++ b/inc/lang/gl/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Enviar novo contrasinal ======
+
+Insire o teu nome de usuario no seguinte formulario para obteres un novo contrasinal da túa conta neste wiki. Enviarase unha ligazón de confirmación ao teu enderezo rexistrado de correo-e.
diff --git a/inc/lang/gl/revisions.txt b/inc/lang/gl/revisions.txt
new file mode 100644
index 000000000..3d5cccd7f
--- /dev/null
+++ b/inc/lang/gl/revisions.txt
@@ -0,0 +1,4 @@
+======Revisións Antigas======
+
+Estas son as revisións antigas do documento actual. Para retomar unha revisión antiga selecciónaa na seguinte lista, preme en ''Editar esta páxina'' e gárdaa.
+
diff --git a/inc/lang/gl/searchpage.txt b/inc/lang/gl/searchpage.txt
new file mode 100644
index 000000000..227ca5dbc
--- /dev/null
+++ b/inc/lang/gl/searchpage.txt
@@ -0,0 +1,5 @@
+====== Procura ======
+
+Podes atopar os resultados da túa procura a continuación. Se non atopaches o que estabas a procurar, podes crear ou editar a páxina co nome relacionado coa túa procura empregando o botón axeitado.
+
+===== Resultados =====
diff --git a/inc/lang/gl/showrev.txt b/inc/lang/gl/showrev.txt
new file mode 100644
index 000000000..88fb0c39d
--- /dev/null
+++ b/inc/lang/gl/showrev.txt
@@ -0,0 +1,2 @@
+**Esta é unha revisión antiga do documento!**
+----
diff --git a/inc/lang/gl/stopwords.txt b/inc/lang/gl/stopwords.txt
new file mode 100644
index 000000000..5520cd275
--- /dev/null
+++ b/inc/lang/gl/stopwords.txt
@@ -0,0 +1,692 @@
+# Isto é unha lista das verbas que o indexador ignora, unha por liña
+# Cando edites este arquivo asegúrate de usar remates de liña UNIX (nova liña única)
+# Non precisas incluír verbas de menos de 3 caracteres - estas son ignoradas de todas formas
+# Esta lista está baseada nas atopadas en http://www.ranks.nl/stopwords/ (en proceso aínda)
+aberto
+abonda
+abrir
+acabo
+acceder
+acceso
+acordo
+actitude
+actividade
+actividades
+actual
+actualización
+actualizar
+actualmente
+ademais
+ademáis
+adiante
+agardar
+agora
+agás
+ainda
+aínda
+aiquí
+algo
+alguen
+algun
+algunha
+algunhas
+alguén
+algún
+algúns
+alta
+amigos
+ando
+anima
+anos
+ante
+anterior
+anteriores
+antes
+aparece
+aparecen
+apartado
+aperta
+apertas
+apoio
+aqui
+aquí
+arquivo
+arquivos
+artigo
+artigos
+asunto
+atención
+atopar
+atopei
+axuda
+axudar
+baixo
+banda
+base
+bastante
+benvido
+boas
+botar
+buscador
+buscar
+cabo
+cada
+cadra
+caixa
+cales
+calidade
+calquer
+calquera
+cambio
+camiño
+campanha
+campaña
+campañas
+campo
+cando
+cantidade
+canto
+cantos
+cara
+carallo
+cartos
+casa
+case
+caso
+casos
+catro
+centro
+certo
+chea
+chega
+chegar
+chisco
+cidade
+civil
+claro
+coas
+coido
+colaboración
+colaborar
+coma
+comentar
+comentario
+comentarios
+comezar
+como
+comunicación
+comunidade
+común
+concreto
+condicións
+conforme
+conseguir
+conta
+contactar
+contacto
+contas
+contido
+contidos
+contra
+contrario
+control
+copia
+correcto
+correio
+correo
+correoe
+correos
+correspondente
+cousa
+cousas
+coñecemento
+coñezo
+crear
+creo
+cuestión
+cuestións
+cunha
+curioso
+dabondo
+dacordo
+dados
+darlle
+data
+datos
+debate
+debe
+debemos
+deben
+deberiamos
+debería
+decidir
+decisión
+defecto
+defensa
+deica
+deixa
+deixar
+deixo
+deles
+demais
+demasiado
+demáis
+dende
+dentro
+dereitos
+desde
+dese
+deseño
+despois
+desta
+deste
+destes
+diante
+dias
+dicir
+diferentes
+difícil
+digo
+dirección
+directamente
+directorio
+discusión
+discutir
+distintas
+distintos
+distribución
+dixen
+dixo
+doado
+dous
+duas
+dunha
+durante
+días
+dúas
+dúbida
+efectivamente
+eiqui
+eiquí
+eles
+eliminar
+email
+empregar
+emprego
+empresa
+empresas
+enderezo
+enderezos
+engadir
+enlace
+enquisa
+enriba
+entendo
+entidades
+entrada
+entrar
+entre
+entón
+enviar
+envio
+eran
+erro
+erros
+esas
+escribir
+eses
+especial
+especialmente
+espero
+esta
+estaba
+estades
+estado
+estamos
+estan
+estar
+estaría
+estas
+este
+estea
+estes
+estilo
+estiven
+esto
+estou
+está
+están
+estás
+evidentemente
+evitar
+exactamente
+exemplo
+existe
+facelo
+facemos
+facendo
+facer
+faga
+fagan
+fago
+fala
+falamos
+falando
+falar
+falla
+falo
+falta
+favor
+fazer
+feita
+feito
+ferreira
+final
+finalmente
+fios
+fixen
+fixo
+fondo
+fora
+forma
+formas
+foro
+foron
+foros
+fose
+fotos
+funciona
+funcionamento
+futuro
+fóra
+gracias
+gran
+grande
+grandes
+grazas
+grupo
+grupos
+gusta
+haber
+haberá
+habería
+había
+haxa
+historia
+home
+hora
+horas
+houbese
+houbo
+hoxe
+idea
+ideas
+ideia
+igual
+imos
+importancia
+importante
+importantes
+inda
+info
+información
+informar
+informe
+inicial
+iniciativa
+inicio
+intención
+interesa
+interesante
+interese
+iste
+isto
+lado
+lembro
+letras
+leva
+levamos
+levar
+libre
+libro
+lista
+listas
+liña
+liñas
+lles
+local
+logo
+longo
+lugar
+lugo
+maior
+maiores
+maioría
+mais
+mandar
+maneira
+manter
+marcha
+material
+mañá
+media
+mediante
+medida
+medio
+mellor
+membros
+menos
+mensaxe
+mensaxes
+mentres
+menú
+mesa
+meses
+mesma
+mesmo
+mesmos
+meter
+meus
+milhor
+millor
+minha
+mirar
+miña
+modificar
+moita
+moitas
+moito
+moitos
+momento
+mudar
+mundo
+máis
+mínimo
+nada
+nbsp
+necesario
+necesidade
+nese
+nesta
+neste
+nestes
+ningunha
+ninguén
+ningún
+noite
+nome
+normal
+nosa
+nosas
+noso
+nosos
+nota
+nova
+novas
+novo
+novos
+nunca
+nunha
+número
+ofrece
+ofrecer
+ollo
+onde
+onte
+oops
+opción
+opcións
+opinión
+orixinal
+outra
+outras
+outro
+outros
+paga
+palabras
+para
+parabens
+parece
+pareceme
+parte
+partes
+participación
+participar
+partido
+paréceme
+pasa
+pasado
+pasar
+paso
+pedir
+pena
+pendente
+pendentes
+pensades
+pensando
+pensar
+penso
+pequena
+pequeno
+perfectamente
+perfecto
+permite
+pero
+persoa
+persoal
+persoas
+pode
+podedes
+podemos
+poden
+poder
+poderiamos
+podería
+poderíamos
+podes
+podo
+poida
+poidan
+pois
+pola
+polas
+polo
+polos
+por
+porque
+porén
+posibel
+posibilidade
+posibilidades
+posible
+posta
+posto
+pouco
+poucos
+poñer
+precisamente
+preciso
+pregos
+pregunta
+presente
+primeira
+primeiro
+principal
+principio
+proba
+probar
+probas
+problema
+problemas
+proceso
+prol
+propia
+propio
+proposta
+propostas
+propoño
+propoñovos
+proxecto
+proxectos
+publicar
+punto
+pódese
+queda
+quedar
+quedou
+queira
+quen
+quere
+queredes
+queremos
+queren
+queres
+quero
+quizáis
+quot
+razón
+real
+realidade
+realmente
+recibir
+referencia
+relación
+rematar
+remate
+respecto
+resposta
+respostar
+respostas
+resto
+resulta
+resultado
+revisar
+revisión
+riba
+sabe
+sabedes
+saber
+sacar
+saúdo
+saúdos
+segue
+seguinte
+seguintes
+seguir
+segunda
+segundo
+seguramente
+seguro
+seica
+semana
+semanas
+semella
+semellante
+sempre
+sendo
+senon
+sentido
+senón
+seria
+serie
+será
+serán
+sería
+seus
+sexa
+sexan
+similar
+simplemente
+sitio
+sitios
+situación
+soamente
+sobre
+solución
+somos
+suas
+superior
+suponho
+suposto
+supoño
+sábado
+súas
+tamen
+tampouco
+tamén
+tanto
+tarde
+tedes
+temos
+tempo
+tempos
+tendo
+tenho
+tentar
+tería
+teña
+teñamos
+teñan
+teñen
+teño
+timos
+tipo
+tiven
+tiña
+toda
+todas
+todo
+todos
+tomar
+total
+totalmente
+trabalho
+traballando
+traballar
+traballo
+traballos
+tras
+trata
+través
+tres
+troco
+trocos
+troques
+tódalas
+tódolos
+última
+último
+últimos
+unha
+unhas
+única
+únicamente
+únicousar
+usuario
+usuarios
+utilizar
+vaia
+vale
+vamos
+varias
+varios
+veces
+verdade
+vexo
+veño
+vida
+vindeiro
+visitantes
+visitas
+vista
+visto
+volta
+vosa
+wink
+xeito
+xeitos
+xente
+xerais
+xeral
+xunto
+zona
diff --git a/inc/lang/gl/subscr_digest.txt b/inc/lang/gl/subscr_digest.txt
new file mode 100644
index 000000000..4ebd14dd9
--- /dev/null
+++ b/inc/lang/gl/subscr_digest.txt
@@ -0,0 +1,20 @@
+Ola.
+
+Houbo mudanzas na páxina @PAGE@ do wiki @TITLE@.
+Estes son os trocos:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Revisión Antiga: @OLDPAGE@
+Revisión Nova: @NEWPAGE@
+
+Para cancelares as notificacións da páxina inicia sesión no wiki en
+@DOKUWIKIURL@ e logo visita
+@SUBSCRIBE@
+e desubscríbete do seguimento dos trocos da páxina e/ou nome de espazo.
+
+--
+Este correo-e foi xerado polo DokuWiki de
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/gl/subscr_form.txt b/inc/lang/gl/subscr_form.txt
new file mode 100644
index 000000000..e8a6fe6cf
--- /dev/null
+++ b/inc/lang/gl/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Xestión de Subscrición ======
+
+Esta páxina permíteche xestionar as túas subscricións para a páxina e nome de espazo actuais. \ No newline at end of file
diff --git a/inc/lang/gl/subscr_list.txt b/inc/lang/gl/subscr_list.txt
new file mode 100644
index 000000000..b62aae35d
--- /dev/null
+++ b/inc/lang/gl/subscr_list.txt
@@ -0,0 +1,17 @@
+Ola.
+
+Houbo trocos en páxinas do nome de espazo @PAGE@ do wiki @TITLE@.
+Estas son as páxinas que mudaron:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Para cancelares as notificacións da páxina inicia sesión no wiki en
+@DOKUWIKIURL@ e logo visita
+@SUBSCRIBE@
+e desubscríbete do seguimento dos trocos da páxina e/ou nome de espazo.
+
+--
+Este correo-e foi xerado polo DokuWiki de
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/gl/subscr_single.txt b/inc/lang/gl/subscr_single.txt
new file mode 100644
index 000000000..77102d470
--- /dev/null
+++ b/inc/lang/gl/subscr_single.txt
@@ -0,0 +1,23 @@
+Ola.
+
+Houbo trocos na páxina @PAGE@ do wiki @TITLE@.
+Estes son os trocos:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Data : @DATE@
+Usuario : @USER@
+Resumo do Edición: @SUMMARY@
+Revisión Antiga: @OLDPAGE@
+Revisión Nova: @NEWPAGE@
+
+Para cancelares as notificacións da páxina inicia sesión no wiki en
+@DOKUWIKIURL@ e logo visita
+@SUBSCRIBE@
+e desubscríbete do seguimento dos trocos da páxina e/ou nome de espazo.
+
+--
+Este correo-e foi xerado polo DokuWiki de
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/gl/updateprofile.txt b/inc/lang/gl/updateprofile.txt
new file mode 100644
index 000000000..8620dea12
--- /dev/null
+++ b/inc/lang/gl/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Actualizar o perfil da túa conta ======
+
+Só precisas cubrir os campos que desexes mudar. Non podes mudar o teu nome de usuario.
+
+
diff --git a/inc/lang/gl/uploadmail.txt b/inc/lang/gl/uploadmail.txt
new file mode 100644
index 000000000..2a7c24762
--- /dev/null
+++ b/inc/lang/gl/uploadmail.txt
@@ -0,0 +1,14 @@
+Subiuse un arquivo ao teu DokuWiki. Aquí van os pormenores:
+
+Arquivo : @MEDIA@
+Data : @DATE@
+Navegador : @BROWSER@
+Enderezo IP : @IPADDRESS@
+Nome do Host : @HOSTNAME@
+Tamaño : @SIZE@
+Tipo MIME : @MIME@
+Usuario : @USER@
+
+--
+Este correo foi xerado polo DokuWiki en
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/gl/wordblock.txt b/inc/lang/gl/wordblock.txt
new file mode 100644
index 000000000..ec8d67aff
--- /dev/null
+++ b/inc/lang/gl/wordblock.txt
@@ -0,0 +1,4 @@
+====== Bloqueo por Correo-lixo ======
+
+Os teus trocos **non** foron gardados porque conteñen unha ou varias verbas bloqueadas. Se tentaches deixar correo-lixo no wiki -- Estívoche ben! Se consideras que é un erro, contacta co administrador deste Wiki.
+
diff --git a/inc/lang/he/admin.txt b/inc/lang/he/admin.txt
new file mode 100644
index 000000000..ada73e5d4
--- /dev/null
+++ b/inc/lang/he/admin.txt
@@ -0,0 +1,4 @@
+====== ניהול ======
+
+ניתן למצוא מטה רשימה של משימות ניהול זמינות ב-DokuWiki.
+
diff --git a/inc/lang/he/adminplugins.txt b/inc/lang/he/adminplugins.txt
new file mode 100644
index 000000000..a7a6471f0
--- /dev/null
+++ b/inc/lang/he/adminplugins.txt
@@ -0,0 +1 @@
+===== תוספים נוספים ===== \ No newline at end of file
diff --git a/inc/lang/he/backlinks.txt b/inc/lang/he/backlinks.txt
new file mode 100644
index 000000000..dfcdd22dd
--- /dev/null
+++ b/inc/lang/he/backlinks.txt
@@ -0,0 +1,3 @@
+====== קישורים לאחור ======
+
+זוהי רשימת דפים אשר נראה כי הם מקשרים לדף ממנו הגעת.
diff --git a/inc/lang/he/conflict.txt b/inc/lang/he/conflict.txt
new file mode 100644
index 000000000..c1cccdfcf
--- /dev/null
+++ b/inc/lang/he/conflict.txt
@@ -0,0 +1,6 @@
+====== קיימת גרסה עדכנית יותר של הקובץ ======
+
+ישנה גרסה עדכנית יותר של המסמך. מצב כזה קורה כאשר משתמש אחר שינה את המסמך בזמן שערכת אותו.
+
+מומלץ לעיין בהבדלים המופיעים להלן ולאחר מכן להחליט איזו גרסה כדאי לשמור. לחיצה על הכפתור "שמירה" תשמור את הגרסה שערכת. לחיצה על הכפתור "ביטול" תשמור את הגרסה הקיימת.
+
diff --git a/inc/lang/he/denied.txt b/inc/lang/he/denied.txt
new file mode 100644
index 000000000..a366fc198
--- /dev/null
+++ b/inc/lang/he/denied.txt
@@ -0,0 +1,3 @@
+====== הרשאה נדחתה ======
+
+אנו מצטערים אך אין לך הרשאות מתאימות כדי להמשיך. אולי שכחת להיכנס למערכת? \ No newline at end of file
diff --git a/inc/lang/he/diff.txt b/inc/lang/he/diff.txt
new file mode 100644
index 000000000..f1216bb4a
--- /dev/null
+++ b/inc/lang/he/diff.txt
@@ -0,0 +1,4 @@
+====== הבדלים ======
+
+כאן מוצגים ההבדלים בין הגרסה שנבחרה והגרסה הנוכחית של הדף.
+
diff --git a/inc/lang/he/draft.txt b/inc/lang/he/draft.txt
new file mode 100644
index 000000000..b999cc187
--- /dev/null
+++ b/inc/lang/he/draft.txt
@@ -0,0 +1,5 @@
+====== נמצא קובץ טיוטה ======
+
+העריכה האחרונה שבוצעה לדף זה לא הושלמה כראוי. DokuWiki שמר באופן אוטומטי טיוטה של העבודה ובאפשרותך להשתמש בה כדי להמשיך את העריכה. ניתן לראות להלן את הנתונים שנשמרו מהפעם הקודמת.
+
+באפשרותך לבחור ב//שחזור הטיוטה// של אותה עריכה //מחיקת הטיוטה// או //ביטול// העריכה כליל. \ No newline at end of file
diff --git a/inc/lang/he/edit.txt b/inc/lang/he/edit.txt
new file mode 100644
index 000000000..74b3cefeb
--- /dev/null
+++ b/inc/lang/he/edit.txt
@@ -0,0 +1 @@
+עריכת הדף ולחיצה על הלחצן "שמירה" תעדכן את תוכנו. מומלץ לעיין בדף ה[[wiki:syntax|תחביר]] כדי להכיר את כללי תחביר הוויקי. נא לערוך את הדף רק אם הדבר נעשה כדי **לשפר** אותו. אם העריכה היא לצורך התנסות מומלץ לבקר ב[[playground:playground|ארגז החול]].
diff --git a/inc/lang/he/editrev.txt b/inc/lang/he/editrev.txt
new file mode 100644
index 000000000..e33001fa3
--- /dev/null
+++ b/inc/lang/he/editrev.txt
@@ -0,0 +1,2 @@
+**הדף שנפתח הוא גרסה ישנה של המסמך!** לחיצה על הלחצן "שמירה" תשחזר את המסמך לגרסה המוצגת כעת.
+---- \ No newline at end of file
diff --git a/inc/lang/he/index.txt b/inc/lang/he/index.txt
new file mode 100644
index 000000000..4b0623f84
--- /dev/null
+++ b/inc/lang/he/index.txt
@@ -0,0 +1,4 @@
+====== מפת אתר ======
+
+זהו קובץ מפת אתר הנמצא מעל לכל הדפים המאורגנים ב[[ויקי:דוקיוויקי]].
+
diff --git a/inc/lang/he/install.html b/inc/lang/he/install.html
new file mode 100644
index 000000000..3832fb5fb
--- /dev/null
+++ b/inc/lang/he/install.html
@@ -0,0 +1,13 @@
+<p>דף זה מסייע בהליכי ההתקנה וההגדרה הראשוניים של
+<a href="http://dokuwiki.org">Dokuwiki</a>. מידע נוסף על תכנית התקנה זו זמין בדף
+<a href="http://dokuwiki.org/installer">התיעוד שלו</a>.</p>
+
+<p>DokuWiki עושה שימוש בקבצים רגילים לשמירת דפי ויקי ומידע נוסף הקשור לדפים אלו (לדוגמה: תמונות, רשימות חיפוש, גרסאות קודמות וכו׳).
+לצורך תפקוד תקין DokuWiki <strong>חייב</strong> גישה לכתיבה לתיקיות המכילות קבצים אלו. תכנית התקנה זו אינה יכולה להגדיר הרשאות לתיקיות.
+פעולה זו צריכה בד״כ להתבצע ישירות משורת הפקודה או במקרה שנעשה שימוש בשרת מארח דרך FTP או מנשק הניהול של המארח (cPanell לדוגמה).</p>
+
+<p>מתקין זה יגדיר את תצורת ה־<acronym title="access control list">ACL</acronym> ב-DokuWiki שלך
+, זה בתורו מאפשר גישת מנהל לתפריט הניהול של DokuWiki כדי להתקין הרחבות, לנהל משתמשים, לנהל גישות לדפי ויקי ושינויים בהגדרות התצורה.
+אין הוא הכרחי לתפקוד DokuWiki אך הוא יהפוך את Dokuwiki לפשוט יותר לניהול.</p>
+
+<p>על משתמשים מנוסים או כאלו עם דרישות מיוחדות להתקנה להשתמש בקישורים אלו לפרטים בנוגע ל<a href="http://dokuwiki.org/install">הוראות התקנה</a> ול<a href="http://dokuwiki.org/config">הגדרות תצורה</a>.</p>
diff --git a/inc/lang/he/lang.php b/inc/lang/he/lang.php
new file mode 100644
index 000000000..1c0c82212
--- /dev/null
+++ b/inc/lang/he/lang.php
@@ -0,0 +1,270 @@
+<?php
+/**
+ * Hebrew language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @link http://sourceforge.net/projects/hebdokuwiki/
+ * @author גיא שפר <guysoft@ort.org.il>
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'rtl';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'עריכת דף זה';
+$lang['btn_source'] = 'הצגת מקור הדף';
+$lang['btn_show'] = 'הצגת דף';
+$lang['btn_create'] = 'יצירת דף';
+$lang['btn_search'] = 'חיפוש';
+$lang['btn_save'] = 'שמירה';
+$lang['btn_preview'] = 'תצוגה מקדימה';
+$lang['btn_top'] = 'חזרה למעלה';
+$lang['btn_newer'] = '<< חדש יותר';
+$lang['btn_older'] = 'פחות חדש >>';
+$lang['btn_revs'] = 'גרסאות קודמות';
+$lang['btn_recent'] = 'שינויים אחרונים';
+$lang['btn_upload'] = 'העלאה';
+$lang['btn_cancel'] = 'ביטול';
+$lang['btn_index'] = 'מפת האתר';
+$lang['btn_secedit'] = 'עריכה';
+$lang['btn_login'] = 'כניסה';
+$lang['btn_logout'] = 'יציאה';
+$lang['btn_admin'] = 'ניהול';
+$lang['btn_update'] = 'עדכון';
+$lang['btn_delete'] = 'מחיקה';
+$lang['btn_back'] = 'חזרה';
+$lang['btn_backlink'] = 'קישורים לכאן';
+$lang['btn_backtomedia'] = 'חזרה לבחירת קובץ מדיה';
+$lang['btn_subscribe'] = 'מעקב אחרי שינוים';
+$lang['btn_profile'] = 'עדכון הפרופיל';
+$lang['btn_reset'] = 'איפוס';
+$lang['btn_resendpwd'] = 'שליחת ססמה חדשה';
+$lang['btn_draft'] = 'עריכת טיוטה';
+$lang['btn_recover'] = 'שחזור טיוטה';
+$lang['btn_draftdel'] = 'מחיקת טיוטה';
+$lang['btn_revert'] = 'שחזור';
+$lang['btn_register'] = 'הרשמה';
+$lang['loggedinas'] = 'נכנסת בשם';
+$lang['user'] = 'שם משתמש';
+$lang['pass'] = 'ססמה';
+$lang['newpass'] = 'ססמה חדשה';
+$lang['oldpass'] = 'אישור הססמה הנוכחית';
+$lang['passchk'] = 'פעם נוספת';
+$lang['remember'] = 'שמירת הפרטים שלי';
+$lang['fullname'] = 'שם מלא';
+$lang['email'] = 'דוא״ל';
+$lang['profile'] = 'פרופיל המשתמש';
+$lang['badlogin'] = 'שם המשתמש או הססמה שגויים, עמך הסליחה';
+$lang['minoredit'] = 'שינוים מזעריים';
+$lang['draftdate'] = 'הטיוטה נשמרה אוטומטית ב־';
+$lang['nosecedit'] = 'הדף השתנה בינתיים, הקטע שערכת אינו מעודכן - העמוד כולו נטען במקום זאת.';
+$lang['regmissing'] = 'עליך למלא את כל השדות, עמך הסליחה.';
+$lang['reguexists'] = 'משתמש בשם זה כבר נרשם, עמך הסליחה.';
+$lang['regsuccess'] = 'ההרשמה הצליחה, המשתמש נרשם והודעה נשלחה בדוא״ל.';
+$lang['regsuccess2'] = 'ההרשמה הצליחה, המשתמש נוצר.';
+$lang['regmailfail'] = 'שליחת הודעת הדוא״ל כשלה, נא ליצור קשר עם מנהל האתר!';
+$lang['regbadmail'] = 'יתכן כי כתובת הדוא״ל אינה תקפה, אם לא כך הדבר ליצור קשר עם מנהל האתר';
+$lang['regbadpass'] = 'שתי הססמאות אינן זהות זו לזו, נא לנסות שוב.';
+$lang['regpwmail'] = 'ססמת הדוקוויקי שלך';
+$lang['reghere'] = 'עדיין אין לך חשבון? ההרשמה כאן';
+$lang['profna'] = 'בוויקי הזה לא ניתן לשנות פרופיל';
+$lang['profnochange'] = 'אין שינויים, הפרופיל לא עודכן';
+$lang['profnoempty'] = 'השם וכתובת הדוא״ל לא יכולים להיות ריקים';
+$lang['profchanged'] = 'הפרופיל עודכן בהצלחה';
+$lang['pwdforget'] = 'שכחת את הססמה שלך? ניתן לקבל חדשה';
+$lang['resendna'] = 'הוויקי הזה אינו תומך בחידוש ססמה';
+$lang['resendpwd'] = 'שליחת ססמה חדשה עבור';
+$lang['resendpwdmissing'] = 'עליך למלא את כל השדות, עמך הסליחה.';
+$lang['resendpwdnouser'] = 'משתמש בשם זה לא נמצא במסד הנתונים, עמך הסליחה.';
+$lang['resendpwdbadauth'] = 'קוד אימות זה אינו תקף. יש לוודא כי נעשה שימוש בקישור האימות המלא, עמך הסליחה.';
+$lang['resendpwdconfirm'] = 'נשלח קישור לאימות נשלח בדוא״ל.';
+$lang['resendpwdsuccess'] = 'נשלחה ססמה חדשה בדוא״ל';
+$lang['license'] = 'למעט מקרים בהם צוין אחרת, התוכן בוויקי זה זמין לפי הרישיון הבא:';
+$lang['licenseok'] = 'נא לשים לב: עריכת דף זה מהווה הסכמה מצדך להצגת התוכן שהוספת בהתאם הרישיון הבא:';
+$lang['searchmedia'] = 'חיפוש שם קובץ:';
+$lang['searchmedia_in'] = 'חיפוש תחת %s';
+$lang['txt_upload'] = 'בחירת קובץ להעלות';
+$lang['txt_filename'] = 'העלאה בשם (נתון לבחירה)';
+$lang['txt_overwrt'] = 'שכתוב על קובץ קיים';
+$lang['lockedby'] = 'נעול על ידי';
+$lang['lockexpire'] = 'הנעילה פגה';
+$lang['js']['willexpire'] = 'הנעילה תחלוף עוד זמן קצר. \nלמניעת התנגשויות יש להשתמש בכפתור הרענון מטה כדי לאפס את מד משך הנעילה.';
+$lang['js']['notsavedyet'] = 'שינויים שלא נשמרו ילכו לאיבוד.';
+$lang['js']['searchmedia'] = 'חיפוש אחר קבצים';
+$lang['js']['keepopen'] = 'השארת חלון פתוח על הבחירה';
+$lang['js']['hidedetails'] = 'הסתרת פרטים';
+$lang['js']['mediatitle'] = 'הגדרות הקישור';
+$lang['js']['mediadisplay'] = 'סוג הקישור';
+$lang['js']['mediaalign'] = 'יישור';
+$lang['js']['mediasize'] = 'גודל התמונה';
+$lang['js']['mediatarget'] = 'יעד הקישור';
+$lang['js']['mediaclose'] = 'סגירה';
+$lang['js']['mediainsert'] = 'הוספה';
+$lang['js']['mediadisplayimg'] = 'הצגת התמונה.';
+$lang['js']['mediadisplaylnk'] = 'הצגת הקישור בלבד.';
+$lang['js']['mediasmall'] = 'גרסה קטנה';
+$lang['js']['mediamedium'] = 'גרסה בינונית';
+$lang['js']['medialarge'] = 'גרסה גדולה';
+$lang['js']['mediaoriginal'] = 'הגרסה המקורית';
+$lang['js']['medialnk'] = 'קישור לעמוד הפרטים';
+$lang['js']['mediadirect'] = 'הקישור הישיר למקור';
+$lang['js']['medianolnk'] = 'אין קישור';
+$lang['js']['medianolink'] = 'אין לקשר לתמונה';
+$lang['js']['medialeft'] = 'יישור התמונה לשמאל.';
+$lang['js']['mediaright'] = 'יישור התמונה לימין.';
+$lang['js']['mediacenter'] = 'מרכוז התמונה.';
+$lang['js']['medianoalign'] = 'לא להשתמש ביישור.';
+$lang['js']['nosmblinks'] = 'קישור לכונני שיתוף של Windows עובד רק באמצעות Microsoft Internet Explorer.
+עדיין ניתן להעתיק ולהדביק את הקישור.';
+$lang['js']['linkwiz'] = 'אשף הקישורים';
+$lang['js']['linkto'] = 'קישור אל:';
+$lang['js']['del_confirm'] = 'באמת למחוק?';
+$lang['rssfailed'] = 'אירע כשל בעת קבלת הזנה זו:';
+$lang['nothingfound'] = 'לא נמצאו תוצאות.';
+$lang['mediaselect'] = 'קובצי מדיה';
+$lang['fileupload'] = 'העלאת קובצי מדיה';
+$lang['uploadsucc'] = 'ההעלאה הושלמה בהצלחה';
+$lang['uploadfail'] = 'אירעה שגיאה בעת העלאת הקובץ. היתכן שתקלה זו נוצרה עקב הרשאות שגיות?';
+$lang['uploadwrong'] = 'ההעלאה לא אושרה. קבצים בסיומת זו אסורים!';
+$lang['uploadexist'] = 'הקובץ כבר קיים. הפעולה בוטלה.';
+$lang['uploadbadcontent'] = 'התוכן שהועלה לא תאם את הסיומת %s של הקובץ.';
+$lang['uploadspam'] = 'ההעלאה נחסמה על ידי רשימת חסימת הספאם.';
+$lang['uploadxss'] = 'ההעלאה נחסמה בשל חשד לתוכן זדוני.';
+$lang['uploadsize'] = 'הקובץ שהועלה היה גדול מדי. (%s לכל היותר)';
+$lang['deletesucc'] = 'הקובץ %s נמחק.';
+$lang['deletefail'] = 'לא ניתן למחוק את "%s" -- נא לבדוק את ההרשאות.';
+$lang['mediainuse'] = 'הקובץ "%s" לא נמחק - הוא עדיין בשימוש.';
+$lang['namespaces'] = 'שמות מתחם';
+$lang['mediafiles'] = 'קבצים זמינים תחת';
+$lang['accessdenied'] = 'אין לך הרשאה לצפות בדף זה.';
+$lang['mediausage'] = 'יש להשתמש בתחביר הבא כדי להפנות לקובץ זה:';
+$lang['mediaview'] = 'הצגת הקובץ המקורי';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'כאן ניתן להעלות קובץ למרחב השם הנוכחי. ליצירת תת־מרחבי שם יש לצרף אותם לתחילת שם הקובץ, מופרדים בפסיקים, בשם הקובץ תחת "העלאה בתור".';
+$lang['mediaextchange'] = 'סיומת הקובץ השתנתה מ־‎.%s ל־‎.%s!';
+$lang['reference'] = 'הפניות אל';
+$lang['ref_inuse'] = 'לא ניתן למחוק קובץ זה, כיוון שהדפים הבאים עדיין משתמשים בו:';
+$lang['ref_hidden'] = 'חלק מההפניות נמצאות בדפים שאין לך הרשאות לקרוא אותם';
+$lang['hits'] = 'ביקורים';
+$lang['quickhits'] = 'שמות דפים שנמצאו';
+$lang['toc'] = 'תוכן עניינים';
+$lang['current'] = 'הגרסה הנוכחית';
+$lang['yours'] = 'הגרסה שלך';
+$lang['diff'] = 'הצגת שינוים מגרסה זו ועד הנוכחית';
+$lang['diff2'] = 'הצגת הבדלים בין הגרסאות שנבחרו';
+$lang['difflink'] = 'קישור לתצוגה השוואה זו';
+$lang['line'] = 'שורה';
+$lang['breadcrumb'] = 'ביקורים אחרונים';
+$lang['youarehere'] = 'זהו מיקומך';
+$lang['lastmod'] = 'מועד השינוי האחרון';
+$lang['by'] = 'על ידי';
+$lang['deleted'] = 'נמחק';
+$lang['created'] = 'נוצר';
+$lang['restored'] = 'שוחזר';
+$lang['external_edit'] = 'עריכה חיצונית';
+$lang['summary'] = 'תקציר העריכה';
+$lang['noflash'] = '<a href="http://www.adobe.com/products/flashplayer/">תוסף פלאש לדפדפן</a> נדרש כדי להציג תוכן זה.';
+$lang['download'] = 'הורדת מקטע';
+$lang['mail_newpage'] = 'דף נוסף:';
+$lang['mail_changed'] = 'דף שונה:';
+$lang['mail_subscribe_list'] = 'דפים שהשתנו במרחב השם:';
+$lang['mail_new_user'] = 'משתמש חדש:';
+$lang['mail_upload'] = 'קובץ הועלה:';
+$lang['qb_bold'] = 'טקסט מודגש';
+$lang['qb_italic'] = 'טקסט נטוי';
+$lang['qb_underl'] = 'טקסט עם קו תחתון';
+$lang['qb_code'] = 'קוד';
+$lang['qb_strike'] = 'טקסט מחוק';
+$lang['qb_h1'] = 'כותרת רמה 1';
+$lang['qb_h2'] = 'כותרת רמה 2';
+$lang['qb_h3'] = 'כותרת רמה 3';
+$lang['qb_h4'] = 'כותרת רמה 4';
+$lang['qb_h5'] = 'כותרת רמה 5';
+$lang['qb_h'] = 'כותרת';
+$lang['qb_hs'] = 'כותרת נבחרת';
+$lang['qb_hplus'] = 'כותרת ברמה גבוהה יותר';
+$lang['qb_hminus'] = 'כותרת ברמה נמוכה יותר';
+$lang['qb_hequal'] = 'כותרת באותה רמה';
+$lang['qb_link'] = 'קישור פנימי';
+$lang['qb_extlink'] = 'קישור חיצוני';
+$lang['qb_hr'] = 'קו אופקי';
+$lang['qb_ol'] = 'איבר ברשימה ממוספרת';
+$lang['qb_ul'] = 'איבר ברשימה לא ממוספרת';
+$lang['qb_media'] = 'תמונות וקבצים אחרים';
+$lang['qb_sig'] = 'הוספת חתימה';
+$lang['qb_smileys'] = 'חייכנים';
+$lang['qb_chars'] = 'תווים מיוחדים';
+$lang['upperns'] = 'מעבר למרחב השם שברמה שמעל הנוכחית';
+$lang['admin_register'] = 'הוספת משתמש חדש';
+$lang['metaedit'] = 'עריכת נתוני העל';
+$lang['metasaveerr'] = 'אירע כשל בשמירת נתוני העל';
+$lang['metasaveok'] = 'נתוני העל נשמרו';
+$lang['img_backto'] = 'חזרה אל';
+$lang['img_title'] = 'שם';
+$lang['img_caption'] = 'כותרת';
+$lang['img_date'] = 'תאריך';
+$lang['img_fname'] = 'שם הקובץ';
+$lang['img_fsize'] = 'גודל';
+$lang['img_artist'] = 'צלם';
+$lang['img_copyr'] = 'זכויות יוצרים';
+$lang['img_format'] = 'מבנה';
+$lang['img_camera'] = 'מצלמה';
+$lang['img_keywords'] = 'מילות מפתח';
+$lang['subscr_subscribe_success'] = '%s נוסף לרשימת המינויים לדף %s';
+$lang['subscr_subscribe_error'] = 'אירעה שגיאה בהוספת %s לרשימת המינויים לדף %s';
+$lang['subscr_subscribe_noaddress'] = 'אין כתובת המשויכת עם הכניסה שלך, נא ניתן להוסיף אותך לרשימת המינויים';
+$lang['subscr_unsubscribe_success'] = 'המשתמש %s הוסר מרשימת המינויים לדף %s';
+$lang['subscr_unsubscribe_error'] = 'אירעה שגיאה בהסרת %s מרשימת המינויים לדף %s';
+$lang['subscr_already_subscribed'] = 'המשתמש %s כבר מנוי לדף %s';
+$lang['subscr_not_subscribed'] = 'המשתמש %s איננו רשום לדף %s';
+$lang['subscr_m_not_subscribed'] = 'המשתמש שלך אינו רשום, נכון לעכשיו, לדף הנוכחי או למרחב השם.';
+$lang['subscr_m_new_header'] = 'הוספת מינוי';
+$lang['subscr_m_current_header'] = 'המינויים הנוכחיים';
+$lang['subscr_m_unsubscribe'] = 'ביטול המינוי';
+$lang['subscr_m_subscribe'] = 'מינוי';
+$lang['subscr_m_receive'] = 'קבלת';
+$lang['subscr_style_every'] = 'דוא״ל עם כל שינוי';
+$lang['subscr_style_digest'] = 'הודעת דוא״ל המציגה את כל השינויים בכל עמוד (בכל %.2f ימים)';
+$lang['subscr_style_list'] = 'רשימת השינויים בדפים מאז הודעת הדוא״ל האחרונה (בכל %.2f ימים)';
+$lang['authmodfailed'] = 'תצורת אימות המשתמשים אינה תקינה. נא ליידע את מנהל הוויקי.';
+$lang['authtempfail'] = 'אימות משתמשים אינו זמין כרגע. אם מצב זה נמשך נא ליידע את מנהל הוויקי.';
+$lang['i_chooselang'] = 'נא לבחור שפה';
+$lang['i_installer'] = 'תכנית ההתקנה של DokuWiki';
+$lang['i_wikiname'] = 'שם הוויקי';
+$lang['i_enableacl'] = 'הפעלת ACL (מומלץ)';
+$lang['i_superuser'] = 'משתמש־על';
+$lang['i_problems'] = 'תכנית ההתקנה זיהתה מספר בעיות המפורטות להלן. אין באפשרותך להמשיך לפני תיקונן.';
+$lang['i_modified'] = 'משיקולי אבטחה סקריפט זה יעבוד אך ורק עם התקנת DokuWiki חדשה שלא עברה כל שינוי.
+ עליך לחלץ שנית את הקבצים מהחבילה שהורדה או להיעזר בדף
+ <a href="http://dokuwiki.org/install">Dokuwiki installation instructions</a>';
+$lang['i_funcna'] = 'פונקציית ה-PHP&rlm; <code>%s</code> אינה זמינה. יתכן כי מארח האתר חסם אותה מסיבה כלשהי?';
+$lang['i_phpver'] = 'גרסת ה־PHP שלך <code>%s</code> נמוכה מהדרוש. עליך לשדרג את התקנת ה־PHP שלך.';
+$lang['i_permfail'] = '<code>%s</code> אינה ניתנת לכתיבה על ידי DokuWiki. עליך לשנות הרשאות תיקייה זו!';
+$lang['i_confexists'] = '<code>%s</code> כבר קיים';
+$lang['i_writeerr'] = 'אין אפשרות ליצור את <code>%s</code>. נא לבדוק את הרשאות הקובץ/תיקייה וליצור את הקובץ ידנית.';
+$lang['i_badhash'] = 'הקובץ Dokuwiki.php אינו מזוהה או שעבר שינויים (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - הערך אינו חוקי או ריק';
+$lang['i_success'] = 'תהליך ההגדרה הסתיים בהצלחה. כעת ניתן למחוק את הקובץ install.php ולהמשיך אל ה־<a href="doku.php">DokuWiki החדש שלך</a>.';
+$lang['i_failure'] = 'מספר שגיאות אירעו בעת כתיבת קובצי התצורה. יתכן כי יהיה צורך לתקנם ידנית לפני שניתן יהיה להשתמש ב־<a href="doku.php">DokuWiki החדש שלך</a>.';
+$lang['i_policy'] = 'מדיניות ACL התחלתית';
+$lang['i_pol0'] = 'ויקי פתוח (קריאה, כתיבה והעלאה לכולם)';
+$lang['i_pol1'] = ' ויקי ציבורי (קריאה לכולם, כתיבה והעלאה למשתמשים רשומים)';
+$lang['i_pol2'] = 'ויקי סגור (קריאה, כתיבה והעלאה למשתמשים רשומים בלבד)';
+$lang['i_retry'] = 'ניסיון נוסף';
+$lang['i_license'] = 'נא לבחור את הרישיון שיחול על התוכן שבוויקי שלך:';
+$lang['recent_global'] = 'נכון לעכשיו מתנהל על ידיך מעקב אחר מרחב השם <b>%s</b>. כמו כן, באפשרותך <a href="%s">לצפות בשינויים האחרונים בוויקי כולו</a>.';
+$lang['years'] = 'לפני %d שנים';
+$lang['months'] = 'לפני %d חודשים';
+$lang['weeks'] = 'לפני %d שבועות';
+$lang['days'] = 'לפני %d ימים';
+$lang['hours'] = 'לפני %d שעות';
+$lang['minutes'] = 'לפני %d דקות';
+$lang['seconds'] = 'לפני %d שניות';
+$lang['wordblock'] = 'השינויים שלך לא נשמרו כיוון שהם מכילים טקסט חסום (ספאם).';
diff --git a/inc/lang/he/locked.txt b/inc/lang/he/locked.txt
new file mode 100644
index 000000000..307874a73
--- /dev/null
+++ b/inc/lang/he/locked.txt
@@ -0,0 +1,3 @@
+====== דף נעול ======
+
+דף זה נעול כרגע לעריכה על ידי משתמש אחר. עליך להמתין עד שהמשתמש יסיים את העריכה או עד שהנעילה תפוג.
diff --git a/inc/lang/he/login.txt b/inc/lang/he/login.txt
new file mode 100644
index 000000000..5a575f1f8
--- /dev/null
+++ b/inc/lang/he/login.txt
@@ -0,0 +1,3 @@
+====== כניסה ======
+
+אינך ברשומות המערכת כרגע! יש להזין את נתוני ההזדהות מטה לכניסה. יש לאפשר עוגיות (cookies) כדי להכנס.
diff --git a/inc/lang/he/mailtext.txt b/inc/lang/he/mailtext.txt
new file mode 100644
index 000000000..222ee1b6d
--- /dev/null
+++ b/inc/lang/he/mailtext.txt
@@ -0,0 +1,17 @@
+דף בDokuWiki נוסף או שונה. להלן הפרטים:
+
+תאריך : @DATE@
+דפדפן : @BROWSER@
+כתובת ה־IP&rlm; : @IPADDRESS@
+שם המארח : @HOSTNAME@
+המהדורה הישנה: @OLDPAGE@
+המהדורה החדשה: @NEWPAGE@
+תקציר העריכה: @SUMMARY@
+משתמש : @USER@
+
+@DIFF@
+
+--
+
+דף זה נוצר ע״י ה־DokuWiki הזמין בכתובת
+@DOKUWIKIURL@
diff --git a/inc/lang/he/newpage.txt b/inc/lang/he/newpage.txt
new file mode 100644
index 000000000..ac6fb7386
--- /dev/null
+++ b/inc/lang/he/newpage.txt
@@ -0,0 +1,3 @@
+====== דף זה עדיין לא קיים ======
+
+הדף אליו הגעת עדיין לא קיים. לחיצה על הכפתור "יצירת דף" תצור אותו. \ No newline at end of file
diff --git a/inc/lang/he/norev.txt b/inc/lang/he/norev.txt
new file mode 100644
index 000000000..3d08e16db
--- /dev/null
+++ b/inc/lang/he/norev.txt
@@ -0,0 +1,4 @@
+====== גרסה לא קיימת ======
+
+הגרסה שהוזנה אינה קיימת. נא להשתמש בכפתור ''גרסאות קודמות'' להצגת רשימת הגרסאות של מסמך זה.
+
diff --git a/inc/lang/he/password.txt b/inc/lang/he/password.txt
new file mode 100644
index 000000000..745c5cb5c
--- /dev/null
+++ b/inc/lang/he/password.txt
@@ -0,0 +1,10 @@
+שלום @FULLNAME@!
+
+הנה נתוני המשתמש שלך עבור @TITLE@ ב־@DOKUWIKIURL@
+
+שם כניסה : @LOGIN@
+ססמה : @PASSWORD@
+
+--
+מכתב זה נוצר על ידי ה־DokuWiki הזמין בכתובת
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/he/preview.txt b/inc/lang/he/preview.txt
new file mode 100644
index 000000000..1331c23ad
--- /dev/null
+++ b/inc/lang/he/preview.txt
@@ -0,0 +1,4 @@
+====== תצוגה מקדימה ======
+
+זו תצוגה מקדימה של הדף לעתיד. להזכירך: **הדף עדיין לא נשמר!**
+
diff --git a/inc/lang/he/pwconfirm.txt b/inc/lang/he/pwconfirm.txt
new file mode 100644
index 000000000..7dc46c340
--- /dev/null
+++ b/inc/lang/he/pwconfirm.txt
@@ -0,0 +1,13 @@
+שלום @FULLNAME@!
+
+מישהו ביקש ססמה חדשה עבור שם הכניסה שלך לוויקי @TITLE@ בכתובת @DOKUWIKIURL@
+
+אם לא ביקשת ססמה חדשה באפשרותך פשוט להתעלם מהודעת דוא״ל זו.
+
+כדי לאשר שהבקשה באמת נשלחה על ידך עליך השתמש בקישור הבא.
+
+@CONFIRM@
+
+--
+הודעת דוא״ל זו נוצרה על ידי ה־DokuWiki הזמין בכתובת
+@DOKUWIKIURL@
diff --git a/inc/lang/he/read.txt b/inc/lang/he/read.txt
new file mode 100644
index 000000000..18efc5e03
--- /dev/null
+++ b/inc/lang/he/read.txt
@@ -0,0 +1,2 @@
+דף זה הוא דף לקריאה בלבד. ניתן לצפות בקוד המקור שלו, אך לא ניתן לערוך אותו. ניתן לפנות למנהל הוויקי אם לדעתך נפלה טעות.
+
diff --git a/inc/lang/he/recent.txt b/inc/lang/he/recent.txt
new file mode 100644
index 000000000..0febd96e5
--- /dev/null
+++ b/inc/lang/he/recent.txt
@@ -0,0 +1,5 @@
+====== שינויים אחרונים ======
+
+הדפים הבאים עברו שינויים לאחרונה.
+
+
diff --git a/inc/lang/he/register.txt b/inc/lang/he/register.txt
new file mode 100644
index 000000000..c4dfad752
--- /dev/null
+++ b/inc/lang/he/register.txt
@@ -0,0 +1,3 @@
+====== הרשמה כמשתמש חדש ======
+
+יש למלא את כל המידע להלן כדי ליצור חשבון חדש בוויקי זה. עליך לוודא כי הזנת **כתובת דוא״ל תקפה**- ססמתך החדשה תשלח לכתובת זו. על שם המשתמש להיות [[hdoku>ויקי:שם דף|שם דף]] תקף.
diff --git a/inc/lang/he/registermail.txt b/inc/lang/he/registermail.txt
new file mode 100644
index 000000000..3edca3fa0
--- /dev/null
+++ b/inc/lang/he/registermail.txt
@@ -0,0 +1,14 @@
+משתמש חדש נרשם. להלן הפרטים:
+
+שם משתמש : @NEWUSER@
+שם מלא : @NEWNAME@
+דוא״ל : @NEWEMAIL@
+
+תאריך : @DATE@
+דפדפן : @BROWSER@
+כתובת IP&rlm; : @IPADDRESS@
+שם המארח : @HOSTNAME@
+
+--
+הודעת דוא״ל זו נוצרה על ידי ה־DokuWiki הזמין בכתובת
+@DOKUWIKIURL@
diff --git a/inc/lang/he/resendpwd.txt b/inc/lang/he/resendpwd.txt
new file mode 100644
index 000000000..8ca27207b
--- /dev/null
+++ b/inc/lang/he/resendpwd.txt
@@ -0,0 +1,4 @@
+====== שליחת ססמה חדשה ======
+
+יש להזין את שם המשתמש בטופס מטה ולבקש ססמה חדשה לחשבון שלך בוויקי זה. הקישור לאימות יישלח לכתובת הדוא״ל באמצעותה נרשמת.
+
diff --git a/inc/lang/he/revisions.txt b/inc/lang/he/revisions.txt
new file mode 100644
index 000000000..6b23402f5
--- /dev/null
+++ b/inc/lang/he/revisions.txt
@@ -0,0 +1,4 @@
+====== גרסאות ישנות ======
+
+אלה גרסאות מוקדמות יותר של המסמך הנוכחי. כדי לשחזר גרסה מוקדמת יותר יש ללחוץ על הכפתור ''עריכה'' ולשמור את הדף.
+
diff --git a/inc/lang/he/searchpage.txt b/inc/lang/he/searchpage.txt
new file mode 100644
index 000000000..aed23be24
--- /dev/null
+++ b/inc/lang/he/searchpage.txt
@@ -0,0 +1,5 @@
+====== חיפוש ======
+
+ניתן לראות את תוצאות החיפוש למטה. אם לא נמצאו דפים בחיפוש, לחיצה על הכפתור "עריכה" תיצור דף חדש על שם מילת החיפוש שהוזנה.
+
+===== תוצאות ===== \ No newline at end of file
diff --git a/inc/lang/he/showrev.txt b/inc/lang/he/showrev.txt
new file mode 100644
index 000000000..22ca0c3ae
--- /dev/null
+++ b/inc/lang/he/showrev.txt
@@ -0,0 +1,2 @@
+**זו גרסה ישנה של המסמך!** לחיצה על כותרת המסמך תציג את גרסתו הנוכחית.
+---- \ No newline at end of file
diff --git a/inc/lang/he/stopwords.txt b/inc/lang/he/stopwords.txt
new file mode 100644
index 000000000..ca85eb2e0
--- /dev/null
+++ b/inc/lang/he/stopwords.txt
@@ -0,0 +1,29 @@
+# זוהי רשימת מילים ממנה מתעלם סורק התוכן, אחת בכל שורה
+# בעורכך קובץ זה עליך לודא כי נעשה שימוש בסימני סוף שורה של UNIX (שורה חדשה ללא החזרת הסמן)
+# אין צורך לכלול מילים בנות פחות משלוש אותיות - אלו נפסחות בכל מקרה
+# רשימה זו מבוססת על אלו הנמצאות ב- http://www.ranks.nl/stopwords
+about
+are
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/he/subscr_digest.txt b/inc/lang/he/subscr_digest.txt
new file mode 100644
index 000000000..af5220229
--- /dev/null
+++ b/inc/lang/he/subscr_digest.txt
@@ -0,0 +1,20 @@
+שלום!
+
+הדף @PAGE@ שבאתר הוויקי @TITLE@ השתנה.
+להלן השינויים:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+המהדורה הישנה: @OLDPAGE@
+המהדורה החדשה: @NEWPAGE@
+
+כדי לבטל את ההתרעות לשינויי העמוד, יש להיכנס לאתר הוויקי בכתובת
+@DOKUWIKIURL@ ואז לבקר באגף
+@SUBSCRIBE@
+ולבטל את המינוי לשינויים בדף ו/או במרחב השם.
+
+--
+הודעת דוא״ל זו נוצרה על ידי ה־DokuWiki שבכתובת
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/he/subscr_single.txt b/inc/lang/he/subscr_single.txt
new file mode 100644
index 000000000..123b186c8
--- /dev/null
+++ b/inc/lang/he/subscr_single.txt
@@ -0,0 +1,22 @@
+שלום!
+
+הדף @PAGE@ באתר הוויקי @TITLE@ השתנה.
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+תאריך : @DATE@
+משתמש : @USER@
+תקציר העריכה: @SUMMARY@
+המהדורה הישנה: @OLDPAGE@
+המהדורה החדשה: @NEWPAGE@
+
+לביטול התרעות בנוגע לעמוד, יש להיכנס לאתר הוויקי בכתובת
+@DOKUWIKIURL@ ואז לבקר בדף
+@NEWPAGE@
+ולבטל את המינוי לקבלת שינויים בדף ו/או במרחב השם.
+
+--
+הודעת דוא״ל זו נוצרה על ידי ה־DokuWiki הזמין בכתובת
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/he/updateprofile.txt b/inc/lang/he/updateprofile.txt
new file mode 100644
index 000000000..494d8389d
--- /dev/null
+++ b/inc/lang/he/updateprofile.txt
@@ -0,0 +1,5 @@
+====== עידכון פרטי חשבונך ======
+
+אין צורך למלא מעבר לפרטים המיועדים לשינוי. לא ניתן לשנות את שם המשתמש.
+
+
diff --git a/inc/lang/he/uploadmail.txt b/inc/lang/he/uploadmail.txt
new file mode 100644
index 000000000..fd670796c
--- /dev/null
+++ b/inc/lang/he/uploadmail.txt
@@ -0,0 +1,14 @@
+קובץ הועלה אל הדוקוויקי שלך. הנה פרטיו:
+
+קובץ : @MEDIA@
+תאריך : @DATE@
+דפדפן : @BROWSER@
+כתובת IP : @IPADDRESS@
+מארח : @HOSTNAME@
+גודל : @SIZE@
+סיווג : @MIME@
+משתמש : @USER@
+
+--
+דואר זה נוצר על ידי דוקוויקי בתובת
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/hi/lang.php b/inc/lang/hi/lang.php
new file mode 100644
index 000000000..2a9e20a9e
--- /dev/null
+++ b/inc/lang/hi/lang.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * hi language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesHi.php?view=co
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'यह पृष्ठ संपादित करें';
+$lang['btn_source'] = 'पृष्ठ का श्रोत दिखाएँ';
+$lang['btn_show'] = 'पृष्ठ दिखाएँ';
+$lang['btn_create'] = 'इस पृष्ठ को बनायें';
+$lang['btn_search'] = 'खोजें';
+$lang['btn_save'] = 'सुरक्षित करें';
+$lang['btn_preview'] = 'पूर्वावलोकन';
+$lang['btn_top'] = 'वापस शीर्ष पर';
+$lang['btn_newer'] = '<< अधिक विगत';
+$lang['btn_older'] = 'अमूल विगत >>';
+$lang['btn_revs'] = 'पुराने संशोधन';
+$lang['btn_recent'] = 'विगत परिवर्तन';
+$lang['btn_upload'] = 'अपलोड करें';
+$lang['btn_cancel'] = 'रद्द करें';
+$lang['btn_index'] = 'सूचकांक';
+$lang['btn_secedit'] = 'संपादित करें';
+$lang['btn_login'] = 'लॉग इन';
+$lang['btn_logout'] = 'लॉगआउट';
+$lang['btn_admin'] = 'व्यवस्थापक';
+$lang['btn_update'] = 'अद्यतन करना';
+$lang['btn_delete'] = 'मिटाना';
+$lang['btn_back'] = 'पीछे';
+$lang['btn_backlink'] = 'पिछली कड़ियाँ';
+$lang['btn_backtomedia'] = 'मीडिया फाइल चयन पर पीछे जायें';
+$lang['btn_subscribe'] = 'सदस्यता प्रबंधन';
+$lang['btn_profile'] = 'परिचय संपादित करें';
+$lang['user'] = 'उपयोगकर्ता का नाम';
+$lang['pass'] = 'गुप्त शब्द';
+$lang['newpass'] = 'नव गुप्त शब्द';
+$lang['passchk'] = 'पासवर्ड दुबारा लिखें';
+$lang['remember'] = 'मुझे स्मृत रखना';
+$lang['fullname'] = 'सही नाम';
+$lang['email'] = 'ईमेल';
+$lang['badlogin'] = 'छमा करें, उपयोगकर्ता का नाम व गुप्त शब्द ग़लत था |';
+$lang['minoredit'] = 'अमूल चूल परिवर्तन';
+$lang['regmissing'] = 'छमा करें, आपको सारे रिक्त स्थान भरने पड़ेंगे |';
+$lang['regbadpass'] = 'दोनो दिए गये गुप्तशब्द समान नहीं हैं | दोबारा प्रयास करें |';
+$lang['regpwmail'] = 'आपकी डोकुविकी का गुप्तशब्द';
+$lang['reghere'] = 'आपके पास अभी तक कोई खाता नहीं है? बस एक लें |';
+$lang['profna'] = 'यह विकी प्रोफ़ाइल संशोधन का समर्थन नहीं करता |';
+$lang['profnochange'] = 'कोई परिवर्तन नहीं, कुछ नहीं करना |';
+$lang['resendpwd'] = 'नवगुप्तशब्द भेजें';
+$lang['resendpwdmissing'] = 'छमा करें, आपको सारे रिक्त स्थान भरने पड़ेंगे |';
+$lang['resendpwdsuccess'] = 'आपका नवगुप्तशब्द ईमेल द्वारा सम्प्रेषित कर दिया गया है |';
+$lang['txt_upload'] = 'अपलोड करने के लिए फ़ाइल चुनें';
+$lang['txt_filename'] = 'के रूप में अपलोड करें (वैकल्पिक)';
+$lang['txt_overwrt'] = 'अधिलेखित उपस्थित फ़ाइल';
+$lang['lockedby'] = 'इस समय तक बंद';
+$lang['lockexpire'] = 'बंद समाप्त होगा';
+$lang['js']['hidedetails'] = 'विवरण छिपाएँ';
+$lang['nothingfound'] = 'कुच्छ नहीं मिला |';
+$lang['uploadexist'] = 'फ़ाइल पहले से उपस्थित है. कुछ भी नहीं किया |';
+$lang['mediafiles'] = 'उपलब्ध फाइलों में';
+$lang['mediaview'] = 'मूल फ़ाइल देखें';
+$lang['reference'] = 'संदर्भ के लिए';
+$lang['ref_hidden'] = 'कुच्छ संदर्भ उन पन्नो पर हैं जिनको पड़ने की आपको अनुमति नहीं है|';
+$lang['toc'] = 'विषय सूची';
+$lang['current'] = 'वर्तमान';
+$lang['yours'] = 'आपका संस्करणः';
+$lang['diff'] = 'वर्तमान संशोधन में मतभेद दिखाइये |';
+$lang['diff2'] = 'चयनित संशोधन के बीच में मतभेद दिखाइये |';
+$lang['line'] = 'रेखा';
+$lang['youarehere'] = 'आप यहाँ हैं |';
+$lang['lastmod'] = 'अंतिम बार संशोधित';
+$lang['by'] = 'के द्वारा';
+$lang['deleted'] = 'हटाया';
+$lang['created'] = 'निर्मित';
+$lang['restored'] = 'पुराने संशोधन बहाल';
+$lang['external_edit'] = 'बाह्य सम्पादित';
+$lang['summary'] = 'सारांश संपादित करें';
+$lang['mail_newpage'] = 'पृष्ठ जोड़ा:';
+$lang['mail_changed'] = 'पृष्ठ बदला:';
+$lang['mail_new_user'] = 'नये उपयोगकर्ता:';
+$lang['mail_upload'] = 'अपलोड की गई फ़ाइल:';
+$lang['qb_bold'] = 'बोल्ड पाठ्य';
+$lang['qb_h1'] = 'स्तर 1 शीर्षपंक्ति';
+$lang['qb_h2'] = 'स्तर 2 शीर्षपंक्ति';
+$lang['qb_h3'] = 'स्तर 3 शीर्षपंक्ति';
+$lang['qb_h4'] = 'स्तर 4 शीर्षपंक्ति';
+$lang['qb_h5'] = 'स्तर 5 शीर्षपंक्ति';
+$lang['qb_link'] = 'आंतरिक कड़ी';
+$lang['qb_extlink'] = 'बाह्य कड़ी';
+$lang['qb_hr'] = 'खड़ी रेखा';
+$lang['qb_sig'] = 'हस्ताक्षर डालें';
+$lang['admin_register'] = 'नया उपयोगकर्ता जोड़ें';
+$lang['img_backto'] = 'वापस जाना';
+$lang['img_title'] = 'शीर्षक';
+$lang['img_caption'] = 'सहशीर्षक';
+$lang['img_date'] = 'तिथि';
+$lang['img_fsize'] = 'आकार';
+$lang['img_artist'] = 'फोटोग्राफर';
+$lang['img_format'] = 'प्रारूप';
+$lang['img_camera'] = 'कैमरा';
+$lang['i_chooselang'] = 'अपनी भाषा चुनें';
+$lang['i_installer'] = 'डोकुविकी इंस्टॉलर';
+$lang['i_wikiname'] = 'विकी का नाम';
+$lang['i_superuser'] = 'महाउपयोगकर्ता';
+$lang['i_retry'] = 'पुनःप्रयास';
diff --git a/inc/lang/hr/admin.txt b/inc/lang/hr/admin.txt
new file mode 100644
index 000000000..15a2a2b13
--- /dev/null
+++ b/inc/lang/hr/admin.txt
@@ -0,0 +1,3 @@
+====== Administracija ======
+
+Slijedi spisak svih administracijskih poslova koji su trenutno dostupni.
diff --git a/inc/lang/hr/backlinks.txt b/inc/lang/hr/backlinks.txt
new file mode 100644
index 000000000..e7115a6b6
--- /dev/null
+++ b/inc/lang/hr/backlinks.txt
@@ -0,0 +1,3 @@
+====== Linkovi na stranicu ======
+
+Slijedi spisak svih dokumenata koji imaju link na trenutni.
diff --git a/inc/lang/hr/conflict.txt b/inc/lang/hr/conflict.txt
new file mode 100644
index 000000000..e33d7020a
--- /dev/null
+++ b/inc/lang/hr/conflict.txt
@@ -0,0 +1,5 @@
+====== Postoji novija verzija ======
+
+Već postoji novija verzija dokumenta kojeg ste mijenjali. To se dešava jer je neki drugi korisnik snimio dokument za vrijeme dok ste ga Vi mijenjali.
+
+Proučite promjene koje slijede i odaberite koje želite preuzeti. Odaberite ''Snimi'' da biste snimili Vašu verziju ili ''Poništi'' da ostavite sačuvanu trenutnu verziju dokumenta.
diff --git a/inc/lang/hr/denied.txt b/inc/lang/hr/denied.txt
new file mode 100644
index 000000000..216eea582
--- /dev/null
+++ b/inc/lang/hr/denied.txt
@@ -0,0 +1,5 @@
+====== Niste autorizirani ======
+
+Nemate autorizaciju.
+
+Niste li se možda zaboravili prijaviti u aplikaciju?
diff --git a/inc/lang/hr/diff.txt b/inc/lang/hr/diff.txt
new file mode 100644
index 000000000..ce6c8c4cb
--- /dev/null
+++ b/inc/lang/hr/diff.txt
@@ -0,0 +1,3 @@
+====== Razlike ======
+
+Slijede sve razlike između odabrane i trenutne verzije dokumenta
diff --git a/inc/lang/hr/edit.txt b/inc/lang/hr/edit.txt
new file mode 100644
index 000000000..8cd57d524
--- /dev/null
+++ b/inc/lang/hr/edit.txt
@@ -0,0 +1 @@
+Nakon što ste napravili sve potrebne promjene - odaberite ''Snimi'' za snimanje dokumenta.
diff --git a/inc/lang/hr/editrev.txt b/inc/lang/hr/editrev.txt
new file mode 100644
index 000000000..911855f47
--- /dev/null
+++ b/inc/lang/hr/editrev.txt
@@ -0,0 +1,2 @@
+**Učitali ste stariju verziju dokumenta!** Ukoliko je snimite - biti će kreirana nova verzija dokumenta.
+---- \ No newline at end of file
diff --git a/inc/lang/hr/index.txt b/inc/lang/hr/index.txt
new file mode 100644
index 000000000..9c30a805c
--- /dev/null
+++ b/inc/lang/hr/index.txt
@@ -0,0 +1 @@
+====== Indeks ======
diff --git a/inc/lang/hr/lang.php b/inc/lang/hr/lang.php
new file mode 100644
index 000000000..79a6cc3b0
--- /dev/null
+++ b/inc/lang/hr/lang.php
@@ -0,0 +1,268 @@
+<?php
+/**
+ * croatian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Tomo Krajina <aaa@puzz.info>
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Izmijeni dokument';
+$lang['btn_source'] = 'Prikaži kod dokumenta';
+$lang['btn_show'] = 'Prikaži dokument';
+$lang['btn_create'] = 'Novi dokument';
+$lang['btn_search'] = 'Pretraži';
+$lang['btn_save'] = 'Spremi';
+$lang['btn_preview'] = 'Prikaži';
+$lang['btn_top'] = 'Na vrh';
+$lang['btn_newer'] = '<< noviji';
+$lang['btn_older'] = 'stariji >>';
+$lang['btn_revs'] = 'Stare inačice';
+$lang['btn_recent'] = 'Nedavne izmjene';
+$lang['btn_upload'] = 'Postavi';
+$lang['btn_cancel'] = 'Odustani';
+$lang['btn_index'] = 'Indeks';
+$lang['btn_secedit'] = 'Izmjeni';
+$lang['btn_login'] = 'Prijavi se';
+$lang['btn_logout'] = 'Odjavi se';
+$lang['btn_admin'] = 'Administriranje';
+$lang['btn_update'] = 'Ažuriraj';
+$lang['btn_delete'] = 'Obriši';
+$lang['btn_back'] = 'Povratak';
+$lang['btn_backlink'] = 'Povratni linkovi';
+$lang['btn_backtomedia'] = 'Povratak na Mediafile izbornik';
+$lang['btn_subscribe'] = 'Pretplati se na promjene dokumenta';
+$lang['btn_profile'] = 'Ažuriraj profil';
+$lang['btn_reset'] = 'Poništi promjene';
+$lang['btn_resendpwd'] = 'Pošalji novu lozinku';
+$lang['btn_draft'] = 'Uredi nacrt dokumenta';
+$lang['btn_recover'] = 'Vrati prijašnji nacrt dokumenta';
+$lang['btn_draftdel'] = 'Obriši nacrt dokumenta';
+$lang['btn_revert'] = 'Vrati';
+$lang['btn_register'] = 'Registracija';
+$lang['loggedinas'] = 'Prijavljen kao';
+$lang['user'] = 'Korisničko ime';
+$lang['pass'] = 'Lozinka';
+$lang['newpass'] = 'Nova lozinka';
+$lang['oldpass'] = 'Potvrdi trenutnu lozinku';
+$lang['passchk'] = 'Ponoviti';
+$lang['remember'] = 'Zapamti me';
+$lang['fullname'] = 'Ime i prezime';
+$lang['email'] = 'Email';
+$lang['profile'] = 'Korisnički profil';
+$lang['badlogin'] = 'Ne ispravno korisničko ime ili lozinka.';
+$lang['minoredit'] = 'Manje izmjene';
+$lang['draftdate'] = 'Nacrt dokumenta je automatski spremljen u ';
+$lang['nosecedit'] = 'Stranica se u međuvremenu promijenila. Informacija o odjeljku je ostarila pa je učitana kompletna stranica.';
+$lang['regmissing'] = 'Morate popuniti sva polja.';
+$lang['reguexists'] = 'Korisnik s tim korisničkim imenom već postoji.';
+$lang['regsuccess'] = 'Korisnik je uspješno stvoren i poslana je lozinka emailom.';
+$lang['regsuccess2'] = 'Korisnik je uspješno stvoren.';
+$lang['regmailfail'] = 'Pojavila se greška prilikom slanja lozinke emailom. Kontaktirajte administratora!';
+$lang['regbadmail'] = 'Email adresa nije ispravna, ukoliko ovo smatrate greškom, kontaktirajte administratora.';
+$lang['regbadpass'] = 'Unesene lozinke nisu jednake, pokušajte ponovno.';
+$lang['regpwmail'] = 'Vaša DokuWiki lozinka';
+$lang['reghere'] = 'Još uvijek nemate korisnički račun? Registrirajte se.';
+$lang['profna'] = 'Ovaj wiki ne dopušta izmjene korisničkog profila.';
+$lang['profnochange'] = 'Nema izmjena.';
+$lang['profnoempty'] = 'Prazno korisničko ime ili email nisu dopušteni.';
+$lang['profchanged'] = 'Korisnički profil je uspješno izmijenjen.';
+$lang['pwdforget'] = 'Izgubili ste lozinku? Zatražite novu';
+$lang['resendna'] = 'Ovaj wiki ne podržava ponovno slanje lozinke emailom.';
+$lang['resendpwd'] = 'Poslati novu lozinku za';
+$lang['resendpwdmissing'] = 'Ispunite sva polja.';
+$lang['resendpwdnouser'] = 'Nije moguće pronaći korisnika.';
+$lang['resendpwdbadauth'] = 'Neispravan autorizacijski kod. Provjerite da li ste koristili potpun potvrdni link.';
+$lang['resendpwdconfirm'] = 'Potvrdni link je poslan emailom.';
+$lang['resendpwdsuccess'] = 'Nova lozinka je poslana emailom.';
+$lang['license'] = 'Osim na mjestima gdje je naznačeno drugačije, sadržaj ovog wikija je licenciran sljedećom licencom:';
+$lang['licenseok'] = 'Pažnja: promjenom ovog dokumenta pristajete licencirati sadržaj sljedećom licencom: ';
+$lang['searchmedia'] = 'Traži naziv datoteke:';
+$lang['searchmedia_in'] = 'Traži u %s';
+$lang['txt_upload'] = 'Odaberite datoteku za postavljanje';
+$lang['txt_filename'] = 'Postaviti kao (nije obavezno)';
+$lang['txt_overwrt'] = 'Prepiši postojeću datoteku';
+$lang['lockedby'] = 'Zaključao';
+$lang['lockexpire'] = 'Zaključano do';
+$lang['js']['willexpire'] = 'Dokument kojeg mijenjate će biti zaključan još 1 minutu.\n Ukoliko želite i dalje raditi izmjene na dokumentu - kliknite na "Pregled".';
+$lang['js']['notsavedyet'] = 'Vaše izmjene će se izgubiti.
+Želite li nastaviti?';
+$lang['js']['searchmedia'] = 'Traži datoteke';
+$lang['js']['keepopen'] = 'Ostavi prozor otvoren nakon izbora';
+$lang['js']['hidedetails'] = 'Sakrij detalje';
+$lang['js']['mediatitle'] = 'Postavke poveznice';
+$lang['js']['mediadisplay'] = 'Vrsta poveznice';
+$lang['js']['mediaalign'] = 'Poravnanje';
+$lang['js']['mediasize'] = 'Veličina slike';
+$lang['js']['mediatarget'] = 'Cilj poveznice';
+$lang['js']['mediaclose'] = 'Zatvori';
+$lang['js']['mediainsert'] = 'Umetni';
+$lang['js']['mediadisplayimg'] = 'Prikaži sliku.';
+$lang['js']['mediadisplaylnk'] = 'Prikaži samo poveznicu.';
+$lang['js']['mediasmall'] = 'Mala verzija.';
+$lang['js']['mediamedium'] = 'Srednja verzija.';
+$lang['js']['medialarge'] = 'Velika verzija.';
+$lang['js']['mediaoriginal'] = 'Originalna verzija.';
+$lang['js']['medialnk'] = 'Poveznica na stranicu s detaljima';
+$lang['js']['mediadirect'] = 'Direktna poveznica na original';
+$lang['js']['medianolnk'] = 'Bez poveznice';
+$lang['js']['medianolink'] = 'Nemoj povezati sliku';
+$lang['js']['medialeft'] = 'Poravnaj sliku lijevo.';
+$lang['js']['mediaright'] = 'Poravnaj sliku desno.';
+$lang['js']['mediacenter'] = 'Poravnaj sliku u sredinu.';
+$lang['js']['medianoalign'] = 'Bez poravnanja.';
+$lang['js']['nosmblinks'] = 'Linkovi na dijeljene Windows mape rade samo s Internet Explorerom. Link je još uvijek moguće kopirati i zalijepiti.';
+$lang['js']['linkwiz'] = 'Čarobnjak za poveznice';
+$lang['js']['linkto'] = 'Poveznica na:';
+$lang['js']['del_confirm'] = 'Zbilja želite obrisati odabrane stavke?';
+$lang['rssfailed'] = 'Došlo je do greške prilikom preuzimanja feed-a: ';
+$lang['nothingfound'] = 'Traženi dokumetni nisu pronađeni.';
+$lang['mediaselect'] = 'Mediafile datoteke';
+$lang['fileupload'] = 'Mediafile postavljanje';
+$lang['uploadsucc'] = 'Postavljanje uspješno';
+$lang['uploadfail'] = 'Neuspješno postavljanje. Možda dozvole na poslužitelju nisu ispravne?';
+$lang['uploadwrong'] = 'Postavljanje nije dopušteno. Nastavak datoteke je zabranjen!';
+$lang['uploadexist'] = 'Datoteka već postoji.';
+$lang['uploadbadcontent'] = 'Postavljeni sadržaj ne odgovara ekstenziji %s datoteke.';
+$lang['uploadspam'] = 'Postavljanje je blokirano spam crnom listom.';
+$lang['uploadxss'] = 'Postavljanje je blokirano zbog mogućeg zlonamjernog sadržaja.';
+$lang['uploadsize'] = 'Postavljena datoteka je prevelika (max. %s)';
+$lang['deletesucc'] = 'Datoteka "%s" je obrisana.';
+$lang['deletefail'] = '"%s" se ne može obrisati - provjerite dozvole na poslužitelju.';
+$lang['mediainuse'] = 'Datoteka "%s" nije obrisana - još uvijek se koristi.';
+$lang['namespaces'] = 'Imenski prostori';
+$lang['mediafiles'] = 'Datoteke u';
+$lang['accessdenied'] = 'Nemate potrebne dozvole za pregled ove stranice.';
+$lang['mediausage'] = 'Koristi sljedeću sintaksu za referenciranje ove datoteke:';
+$lang['mediaview'] = 'Pregledaj originalnu datoteku';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Postavi datoteku u odabrani imenski prostor. Podimenski prostori se stvaraju dodavanjem istih kao prefiks naziva datoteke u "Postavi kao" polju, tako da se odvoje dvotočkama.';
+$lang['mediaextchange'] = 'Ekstenzija datoteke promijenjena iz .%s u .%s!';
+$lang['reference'] = 'Reference za';
+$lang['ref_inuse'] = 'Datoteka se ne može obrisati jer se još uvijek koristi u sljedećim dokumentima:';
+$lang['ref_hidden'] = 'Neke reference se nalaze na dokumentima koje nemate dozvolu čitati';
+$lang['hits'] = 'Pronađeno';
+$lang['quickhits'] = 'Pronađeno po nazivima dokumenata';
+$lang['toc'] = 'Sadržaj';
+$lang['current'] = 'trenutno';
+$lang['yours'] = 'Vaša inačica';
+$lang['diff'] = 'Prikaži razlike u odnosu na trenutnu inačicu';
+$lang['diff2'] = 'Pokaži razlike između odabranih inačica';
+$lang['difflink'] = 'Poveznica na ovaj prikaz usporedbe';
+$lang['diff_type'] = 'Razlike u prikazu:';
+$lang['diff_inline'] = 'U istoj razini';
+$lang['diff_side'] = 'Usporedo';
+$lang['line'] = 'Redak';
+$lang['breadcrumb'] = 'Putanja';
+$lang['youarehere'] = 'Vi ste ovdje';
+$lang['lastmod'] = 'Zadnja izmjena';
+$lang['by'] = 'od';
+$lang['deleted'] = 'obrisano';
+$lang['created'] = 'stvoreno';
+$lang['restored'] = 'vraćena prijašnja inačica';
+$lang['external_edit'] = 'vanjsko uređivanje';
+$lang['summary'] = 'Sažetak izmjena';
+$lang['noflash'] = 'Za prikazivanje ovog sadržaja potreban je <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>';
+$lang['download'] = 'Preuzmi isječak';
+$lang['mail_newpage'] = 'stranica dodana:';
+$lang['mail_changed'] = 'stranica izmjenjena:';
+$lang['mail_subscribe_list'] = 'stranice promijenjene u imenskom prostoru:';
+$lang['mail_new_user'] = 'novi korisnik:';
+$lang['mail_upload'] = 'datoteka postavljena:';
+$lang['qb_bold'] = 'Podebljani tekst';
+$lang['qb_italic'] = 'Ukošeni tekst';
+$lang['qb_underl'] = 'Podcrtani tekst';
+$lang['qb_code'] = 'Kod';
+$lang['qb_strike'] = 'Precrtani tekst';
+$lang['qb_h1'] = 'Naslov - razina 1';
+$lang['qb_h2'] = 'Naslov - razina 2';
+$lang['qb_h3'] = 'Naslov - razina 3';
+$lang['qb_h4'] = 'Naslov - razina 4';
+$lang['qb_h5'] = 'Naslov - razina 5';
+$lang['qb_h'] = 'Naslov';
+$lang['qb_hs'] = 'Odaberite naslov';
+$lang['qb_hplus'] = 'Naslov više razine';
+$lang['qb_hminus'] = 'Naslov niže razine';
+$lang['qb_hequal'] = 'Naslov iste razine';
+$lang['qb_link'] = 'Interni link';
+$lang['qb_extlink'] = 'Vanjski link';
+$lang['qb_hr'] = 'Vodoravna crta';
+$lang['qb_ol'] = 'Pobrojana lista';
+$lang['qb_ul'] = 'Lista';
+$lang['qb_media'] = 'Dodaj slike i ostale datoteke';
+$lang['qb_sig'] = 'Potpis';
+$lang['qb_smileys'] = 'Smiješkići';
+$lang['qb_chars'] = 'Posebni znakovi';
+$lang['upperns'] = 'Skoči u nadređeni imenski prostor';
+$lang['admin_register'] = 'Dodaj novog korisnika';
+$lang['metaedit'] = 'Uredi metapodatake';
+$lang['metasaveerr'] = 'Neuspješno zapisivanje metapodataka';
+$lang['metasaveok'] = 'Spremljeni metapdaci';
+$lang['img_backto'] = 'Povratak na';
+$lang['img_title'] = 'Naziv';
+$lang['img_caption'] = 'Naslov';
+$lang['img_date'] = 'Datum';
+$lang['img_fname'] = 'Ime datoteke';
+$lang['img_fsize'] = 'Veličina';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Autorsko pravo';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Ključne riječi';
+$lang['subscr_subscribe_success'] = 'Dodan %s u listu pretplatnika za %s';
+$lang['subscr_subscribe_error'] = 'Greška kod dodavanja %s u listu pretplatnika za %s';
+$lang['subscr_subscribe_noaddress'] = 'Ne postoji adresa povezana sa vašim podacima za prijavu, stoga ne možete biti dodani u listu pretplatnika';
+$lang['subscr_unsubscribe_success'] = 'Uklonjen %s iz liste pretplatnika za %s';
+$lang['subscr_unsubscribe_error'] = 'Greška prilikom uklanjanja %s iz liste pretplatnika za %s';
+$lang['subscr_already_subscribed'] = '%s je već pretplaćen na %s';
+$lang['subscr_not_subscribed'] = '%s nije pretplaćen na %s';
+$lang['subscr_m_not_subscribed'] = 'Trenutno niste pretplaćeni na trenutnu stranicu ili imenski prostor.';
+$lang['subscr_m_new_header'] = 'Dodaj pretplatu';
+$lang['subscr_m_current_header'] = 'Trenutne pretplate';
+$lang['subscr_m_unsubscribe'] = 'Odjavi pretplatu';
+$lang['subscr_m_subscribe'] = 'Pretplati se';
+$lang['subscr_m_receive'] = 'Primaj';
+$lang['subscr_style_every'] = 'email za svaku promjenu';
+$lang['subscr_style_digest'] = 'email s kratakim prikazom promjena za svaku stranicu (svaka %.2f dana)';
+$lang['subscr_style_list'] = 'listu promijenjenih stranica od zadnjeg primljenog email-a (svaka %.2f dana)';
+$lang['authmodfailed'] = 'Greška u konfiguraciji korisničke autentifikacije. Molimo Vas da kontaktirate administratora.';
+$lang['authtempfail'] = 'Autentifikacija korisnika je privremeno nedostupna. Molimo Vas da kontaktirate administratora.';
+$lang['i_chooselang'] = 'Izaberite vaš jezik';
+$lang['i_installer'] = 'DokuWiki instalacija';
+$lang['i_wikiname'] = 'Naziv Wikija';
+$lang['i_enableacl'] = 'Omogući ACL (preporučeno)';
+$lang['i_superuser'] = 'Superkorisnik';
+$lang['i_problems'] = 'Instalacija je pronašla probleme koji su naznačeni ispod. Nije moguće nastaviti dok se ti problemi ne riješe.';
+$lang['i_modified'] = 'Zbog sigurnosnih razlog, ova skripta ce raditi samo sa novim i nepromijenjenim instalacijama dokuWikija. Preporucujemo da ili re-ekstraktirate fajlove iz downloadovanog paketa ili konsultujete pune a href="http://dokuwiki.org/install">Instrukcije za instalaciju Dokuwikija</a>';
+$lang['i_funcna'] = 'PHP funkcija <code>%s</code> nije dostupna. Možda ju je vaš pružatelj hostinga onemogućio iz nekog razloga?';
+$lang['i_phpver'] = 'Vaša PHP verzija <code>%s</code> je niža od potrebne <code>%s</code>. Trebate nadograditi vašu PHP instalaciju.';
+$lang['i_permfail'] = '<code>%s</code> nema dozvolu pisanja od strane DokuWiki. Trebate podesiti dozvole pristupa tom direktoriju.';
+$lang['i_confexists'] = '<code>%s</code> već postoji';
+$lang['i_writeerr'] = 'Ne može se kreirati <code>%s</code>. Trebate provjeriti dozvole direktorija/datoteke i kreirati dokument ručno.';
+$lang['i_badhash'] = 'neprepoznat ili promijenjen dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - nedozvoljena ili prazna vrijednost';
+$lang['i_success'] = 'Konfiguracija je uspješno završena. Sada možete obrisati install.php datoteku. Nastavite na <a href="doku.php">vaš novi DokuWiki</a>.';
+$lang['i_failure'] = 'Pojavile su se neke greške prilikom pisanja konfiguracijskih datoteka. Morati ćete ih ručno ispraviti da bi mogli koristiti <a href="doku.php">vaš novi DokuWiki</a>.';
+$lang['i_policy'] = 'Inicijalna ACL politika';
+$lang['i_pol0'] = 'Otvoreni Wiki (čitanje, pisanje, učitavanje za sve)';
+$lang['i_pol1'] = 'Javni Wiki (čitanje za sve, pisanje i učitavanje za registrirane korisnike)';
+$lang['i_pol2'] = 'Zatvoreni Wiki (čitanje, pisanje, učitavanje samo za registrirane korisnike)';
+$lang['i_retry'] = 'Pokušaj ponovo';
+$lang['i_license'] = 'Molim odaberite licencu pod kojom želite postavljati vaš sadržaj:';
+$lang['recent_global'] = 'Trenutno gledate promjene unutar <b>%s</b> imenskog prostora. Također možete <a href="%s">vidjeti zadnje promjene cijelog wiki-a</a>';
+$lang['years'] = '%d godina prije';
+$lang['months'] = '%d mjeseci prije';
+$lang['weeks'] = '%d tjedana prije';
+$lang['days'] = '%d dana prije';
+$lang['hours'] = '%d sati prije';
+$lang['minutes'] = '%d minuta prije';
+$lang['seconds'] = '%d sekundi prije';
+$lang['wordblock'] = 'Vaša promjena nije spremljena jer sadrži blokirani tekst (spam).';
diff --git a/inc/lang/hr/locked.txt b/inc/lang/hr/locked.txt
new file mode 100644
index 000000000..ff081aad8
--- /dev/null
+++ b/inc/lang/hr/locked.txt
@@ -0,0 +1,3 @@
+====== Dokument zaključan ======
+
+Mijenjanje ovog dokumenta je trenutno onemogućeno jer je otvoren od strane nekog drugog korisnika. Morate pričekati da on završi sa svojim izmjenama.
diff --git a/inc/lang/hr/login.txt b/inc/lang/hr/login.txt
new file mode 100644
index 000000000..216af130d
--- /dev/null
+++ b/inc/lang/hr/login.txt
@@ -0,0 +1,3 @@
+====== Prijava ======
+
+Upišite korisničko ime i lozinku da biste se prijavili.
diff --git a/inc/lang/hr/mailtext.txt b/inc/lang/hr/mailtext.txt
new file mode 100644
index 000000000..911f8eade
--- /dev/null
+++ b/inc/lang/hr/mailtext.txt
@@ -0,0 +1,16 @@
+Dokument na Vašem wiki-ju je promijenjen ili dodan:
+
+Datum : @DATE@
+Preglednik : @BROWSER@
+IP-Adresa : @IPADDRESS@
+Host : @HOSTNAME@
+Prijašnja verzija : @OLDPAGE@
+Nova verzija : @NEWPAGE@
+Opis izmjene : @SUMMARY@
+Korisnik : @USER@
+
+@DIFF@
+
+
+--
+Ovaj email je poslan na: @DOKUWIKIURL@
diff --git a/inc/lang/hr/newpage.txt b/inc/lang/hr/newpage.txt
new file mode 100644
index 000000000..39346580f
--- /dev/null
+++ b/inc/lang/hr/newpage.txt
@@ -0,0 +1,3 @@
+====== Dokument ne postoji ======
+
+Traženi dokument (još) ne postoji. Ukoliko ga želite otvoriti kliknite na ''Novi dokument''.
diff --git a/inc/lang/hr/norev.txt b/inc/lang/hr/norev.txt
new file mode 100644
index 000000000..231fb5edf
--- /dev/null
+++ b/inc/lang/hr/norev.txt
@@ -0,0 +1,3 @@
+====== Nepostojeća verzija ======
+
+Tražena verzija dokumenta ne postoji.
diff --git a/inc/lang/hr/password.txt b/inc/lang/hr/password.txt
new file mode 100644
index 000000000..bb156c290
--- /dev/null
+++ b/inc/lang/hr/password.txt
@@ -0,0 +1,9 @@
+Pozdrav @FULLNAME@!
+
+Slijede podaci za @TITLE@ sa @DOKUWIKIURL@
+
+Korisničko ime : @LOGIN@
+Lozinka : @PASSWORD@
+
+--
+@DOKUWIKIURL@
diff --git a/inc/lang/hr/preview.txt b/inc/lang/hr/preview.txt
new file mode 100644
index 000000000..89ae86a71
--- /dev/null
+++ b/inc/lang/hr/preview.txt
@@ -0,0 +1,3 @@
+====== Pregled ======
+
+Ovo je pregled kako će izgledati Vaš dokument nakon što se snimi.
diff --git a/inc/lang/hr/read.txt b/inc/lang/hr/read.txt
new file mode 100644
index 000000000..221f1b200
--- /dev/null
+++ b/inc/lang/hr/read.txt
@@ -0,0 +1 @@
+Ova stranica se može samo čitati. Možete vidjeti kod, ali ga ne možete mijenjati. Javite se vašem administratoru ako se s tim ne slažete. \ No newline at end of file
diff --git a/inc/lang/hr/recent.txt b/inc/lang/hr/recent.txt
new file mode 100644
index 000000000..4145ca1c5
--- /dev/null
+++ b/inc/lang/hr/recent.txt
@@ -0,0 +1,3 @@
+====== Nedavne izmjene ======
+
+Stranice koje su nedavno promijenjene.
diff --git a/inc/lang/hr/register.txt b/inc/lang/hr/register.txt
new file mode 100644
index 000000000..32a5489fb
--- /dev/null
+++ b/inc/lang/hr/register.txt
@@ -0,0 +1,3 @@
+====== Prijava novog korisnika ======
+
+Ispunite potrebne podatke da biste dobili korisnički račun na wikiju. Posebno obratite pažnju da ste unijeli valjani email.
diff --git a/inc/lang/hr/resendpwd.txt b/inc/lang/hr/resendpwd.txt
new file mode 100644
index 000000000..ed25f985c
--- /dev/null
+++ b/inc/lang/hr/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Slanje nove lozinke ======
+
+Ispunite potrebne podatke da biste dobili novu lozinku za Vaš korisnički račun. Link za potvrdu biti će poslan na Vašu email adresu.
diff --git a/inc/lang/hr/revisions.txt b/inc/lang/hr/revisions.txt
new file mode 100644
index 000000000..d224a56f3
--- /dev/null
+++ b/inc/lang/hr/revisions.txt
@@ -0,0 +1,3 @@
+====== Stare verzije ======
+
+Slijedi spisak starih verzija za traženi dokument.
diff --git a/inc/lang/hr/searchpage.txt b/inc/lang/hr/searchpage.txt
new file mode 100644
index 000000000..91d9f9c0a
--- /dev/null
+++ b/inc/lang/hr/searchpage.txt
@@ -0,0 +1 @@
+====== Rezultati pretraživanja ======
diff --git a/inc/lang/hr/showrev.txt b/inc/lang/hr/showrev.txt
new file mode 100644
index 000000000..aba2c0db0
--- /dev/null
+++ b/inc/lang/hr/showrev.txt
@@ -0,0 +1,2 @@
+**Ovo je stara verzija dokumenta!**
+----
diff --git a/inc/lang/hr/stopwords.txt b/inc/lang/hr/stopwords.txt
new file mode 100644
index 000000000..bc6eb48ae
--- /dev/null
+++ b/inc/lang/hr/stopwords.txt
@@ -0,0 +1,29 @@
+# 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
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/hr/updateprofile.txt b/inc/lang/hr/updateprofile.txt
new file mode 100644
index 000000000..8eab906d2
--- /dev/null
+++ b/inc/lang/hr/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Izmjena korisničkog profila ======
+
+Ispunite samo polja koja želite mijenjati. Ne može se mijenjati korisničko ime.
diff --git a/inc/lang/hu/admin.txt b/inc/lang/hu/admin.txt
new file mode 100644
index 000000000..03d29243c
--- /dev/null
+++ b/inc/lang/hu/admin.txt
@@ -0,0 +1,3 @@
+===== Adminisztrálás =====
+
+Itt találod a DokuWiki adminisztrálási lehetőségeit.
diff --git a/inc/lang/hu/adminplugins.txt b/inc/lang/hu/adminplugins.txt
new file mode 100644
index 000000000..89fe3738a
--- /dev/null
+++ b/inc/lang/hu/adminplugins.txt
@@ -0,0 +1 @@
+===== További modulok ===== \ No newline at end of file
diff --git a/inc/lang/hu/backlinks.txt b/inc/lang/hu/backlinks.txt
new file mode 100644
index 000000000..d457ab769
--- /dev/null
+++ b/inc/lang/hu/backlinks.txt
@@ -0,0 +1,5 @@
+====== Hivatkozások ======
+
+Ez azoknak az oldalaknak a listája, amelyek erre az oldalra "visszamutatnak" (hivatkoznak).
+
+
diff --git a/inc/lang/hu/conflict.txt b/inc/lang/hu/conflict.txt
new file mode 100644
index 000000000..b823465b3
--- /dev/null
+++ b/inc/lang/hu/conflict.txt
@@ -0,0 +1,7 @@
+====== Újabb változat létezik ======
+
+Az általad szerkesztett dokumentumnak egy újabb változata létezik. Ez akkor történik, ha egy másik felhasználó megváltoztatta a dokumentumot, amíg szerkesztetted.
+
+Nézd át gondosan a lenti eltéréseket, aztán dönts arról, melyik változatot tartod meg. Ha ''Mentés'' gombot választod, akkor a Te változatod kerül mentésre. Nyomj ''Mégsem'' gombot a jelenlegi változat megtartásához.
+
+
diff --git a/inc/lang/hu/denied.txt b/inc/lang/hu/denied.txt
new file mode 100644
index 000000000..0b06724df
--- /dev/null
+++ b/inc/lang/hu/denied.txt
@@ -0,0 +1,4 @@
+====== Hozzáférés megtagadva ======
+
+Sajnáljuk, nincs jogod a folytatáshoz. Esetleg elfelejtettél bejelentkezni?
+
diff --git a/inc/lang/hu/diff.txt b/inc/lang/hu/diff.txt
new file mode 100644
index 000000000..6a09cdea2
--- /dev/null
+++ b/inc/lang/hu/diff.txt
@@ -0,0 +1,4 @@
+====== Különbségek ======
+
+A kiválasztott változat és az aktuális verzió közötti különbséget mutatjuk.
+
diff --git a/inc/lang/hu/draft.txt b/inc/lang/hu/draft.txt
new file mode 100644
index 000000000..4d12e2e0c
--- /dev/null
+++ b/inc/lang/hu/draft.txt
@@ -0,0 +1,5 @@
+===== Piszkozatot találtunk =====
+
+Az oldal utolsó szerkesztését nem fejezted be rendesen. A DokuWiki elmentette piszkozatként, így most folytathatod a szerkesztést. Lent látható, amit az utolsó szerkesztésből elmentettünk.
+
+Válassz a //helyreállítás// vagy a //törlés// opciók közül a piszkozat sorsát illetően. \ No newline at end of file
diff --git a/inc/lang/hu/edit.txt b/inc/lang/hu/edit.txt
new file mode 100644
index 000000000..898387cf2
--- /dev/null
+++ b/inc/lang/hu/edit.txt
@@ -0,0 +1 @@
+Szerkeszd az oldalt majd üsd le a ''Mentés'' gombot. Lásd a [[wiki:syntax|nyelvtan]] oldalt a formázási lehetőségekért. Kérünk, hogy csak akkor szerkeszd az oldalt ha **jobbítani** tudod. Ha ki akarsz próbálni dolgokat akkor az első lépéseid a [[playground:playground|játszótéren]] (playground) tedd.
diff --git a/inc/lang/hu/editrev.txt b/inc/lang/hu/editrev.txt
new file mode 100644
index 000000000..e17662e60
--- /dev/null
+++ b/inc/lang/hu/editrev.txt
@@ -0,0 +1,2 @@
+**Egy korábbi változatot töltöttél be!** Ha elmented, akkor egy újabb aktuális verzió jön létre ezzel a tartalommal.
+----
diff --git a/inc/lang/hu/index.txt b/inc/lang/hu/index.txt
new file mode 100644
index 000000000..ebf15148d
--- /dev/null
+++ b/inc/lang/hu/index.txt
@@ -0,0 +1,4 @@
+====== Áttekintő (index) ======
+
+Az összes elérhető oldal áttekintése [[doku>namespaces|névterek]] szerint rendezve.
+
diff --git a/inc/lang/hu/install.html b/inc/lang/hu/install.html
new file mode 100644
index 000000000..1676e9364
--- /dev/null
+++ b/inc/lang/hu/install.html
@@ -0,0 +1,26 @@
+<p>Ez az oldal segít a <a href="http://dokuwiki.org">DokuWiki</a> kezdeti
+beállításában és a konfigurálásban. További információ
+<a href="http://dokuwiki.org/installer">ezen az oldalon</a>
+található.</p>
+
+<p>A DokuWiki hagyományos fájlokat használ a wiki oldalak és a hozzájuk
+kapcsolódó információk (pl. képek, keresési indexek, korábbi változatok stb.)
+tárolásához. Emiatt a sikeres működés érdekében a DokuWikinek írási joggal
+<strong>kell</strong> rendelkeznie azokon a könyvtárakon, ahová ezek a
+fájlok kerülnek. Ez a Beállító Varázsló nem képes beállítani a könyvtárakhoz
+a szükséges jogosultságokat, azokat közvetlenül parancssorból kell megtenni,
+illetve tárhelyszolgáltatás igénybevétele esetén FTP kliens segítségével,
+vagy a tárhelyszolgáltató által rendelkezésre bocsátott beállítóeszköz
+(pl. cPanel) segítségével.</p>
+
+<p>A Beállító Varázsló felkészíti ezt a DokuWikit a hozzáférési listák
+(<acronym title="access control list">ACL</acronym>-ek) használatára. Így
+a Wiki-gazda felhasználóval hozzáférünk az admin menühöz, mellyel
+bővítményeket telepíthetünk, felhasználókat és hozzáférési jogokat
+kezelhetünk, valamint változtathatunk a konfigurációs beállításokon.
+Ez tulajdonképpen nem szükséges a DokuWiki működéséhez, de megkönnyíti
+az adminisztrációt.</p>
+
+<p>Szakértők illetve speciális beállítást igénylő felhasználók további információkat
+találnak a következő oldalakon <a href="http://dokuwiki.org/install">telepítéssel</a>
+és <a href="http://dokuwiki.org/config">konfigurálási lehetőségekkel</a> kapcsolatban.</p>
diff --git a/inc/lang/hu/lang.php b/inc/lang/hu/lang.php
new file mode 100644
index 000000000..a44fd9317
--- /dev/null
+++ b/inc/lang/hu/lang.php
@@ -0,0 +1,273 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Ziegler Gábor <gziegler@freemail.hu>
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Oldal szerkesztése';
+$lang['btn_source'] = 'Oldalforrás megtekintése';
+$lang['btn_show'] = 'Oldal megtekintése';
+$lang['btn_create'] = 'Oldal létrehozása';
+$lang['btn_search'] = 'Keresés';
+$lang['btn_save'] = 'Mentés';
+$lang['btn_preview'] = 'Előnézet';
+$lang['btn_top'] = 'Vissza a tetejére';
+$lang['btn_newer'] = '<< Újabb változat';
+$lang['btn_older'] = 'Régebbi változat >>';
+$lang['btn_revs'] = 'Korábbi változatok';
+$lang['btn_recent'] = 'Legfrissebb változások';
+$lang['btn_upload'] = 'Feltöltés';
+$lang['btn_cancel'] = 'Mégsem';
+$lang['btn_index'] = 'Áttekintő';
+$lang['btn_secedit'] = 'Szerkesztés';
+$lang['btn_login'] = 'Bejelentkezés';
+$lang['btn_logout'] = 'Kijelentkezés';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Frissítés';
+$lang['btn_delete'] = 'Törlés';
+$lang['btn_back'] = 'Vissza';
+$lang['btn_backlink'] = 'Hivatkozások';
+$lang['btn_backtomedia'] = 'Vissza a médiafájlok kezeléséhez';
+$lang['btn_subscribe'] = 'Oldalváltozások-hírlevél feliratkozás';
+$lang['btn_profile'] = 'Személyes beállítások';
+$lang['btn_reset'] = 'Alaphelyzet';
+$lang['btn_resendpwd'] = 'Új jelszó küldése';
+$lang['btn_draft'] = 'Piszkozat szerkesztése';
+$lang['btn_recover'] = 'Piszkozat folytatása';
+$lang['btn_draftdel'] = 'Piszkozat törlése';
+$lang['btn_revert'] = 'Helyreállítás';
+$lang['btn_register'] = 'Regisztráció';
+$lang['loggedinas'] = 'Belépett felhasználó: ';
+$lang['user'] = 'Azonosító';
+$lang['pass'] = 'Jelszó';
+$lang['newpass'] = 'Új jelszó';
+$lang['oldpass'] = 'Régi jelszó';
+$lang['passchk'] = 'még egyszer';
+$lang['remember'] = 'Emlékezz rám';
+$lang['fullname'] = 'Teljes név';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'Személyes beállítások';
+$lang['badlogin'] = 'Sajnáljuk, az azonosító, vagy a jelszó nem jó.';
+$lang['minoredit'] = 'Apróbb változások';
+$lang['draftdate'] = 'Piszkozat elmentve:';
+$lang['nosecedit'] = 'Időközben megváltozott az oldal, emiatt a szakasz nem friss. Töltse újra az egész oldalt!';
+$lang['regmissing'] = 'Sajnáljuk, az összes mezőt ki kell töltened.';
+$lang['reguexists'] = 'Sajnáljuk, ilyen azonosítójú felhasználónk már van.';
+$lang['regsuccess'] = 'A felhasználói azonosítót létrehoztuk. A jelszót postáztuk.';
+$lang['regsuccess2'] = 'A felhasználói azonosítót létrehoztuk.';
+$lang['regmailfail'] = 'Úgy tűnik hiba történt a jelszó postázása során. Kérjük lépj kapcsolatba a Wiki-gazdával!!';
+$lang['regbadmail'] = 'A megadott e-mail cím érvénytelennek tűnik. Ha úgy gondolod ez hiba, lépj kapcsolatba Wiki-gazdával!';
+$lang['regbadpass'] = 'A két megadott jelszó nem egyezik, próbáld újra!';
+$lang['regpwmail'] = 'A DokuWiki jelszavad';
+$lang['reghere'] = 'Még nincs azonosítód? Itt kérhetsz';
+$lang['profna'] = 'Ez a wiki nem támogatja a személyes beállítások módosítását.';
+$lang['profnochange'] = 'Nem történt változás.';
+$lang['profnoempty'] = 'A név és e-mail mező nem maradhat üresen!';
+$lang['profchanged'] = 'A személyes beállítások változtatása megtörtént.';
+$lang['pwdforget'] = 'Elfelejtetted a jelszavad? Itt kérhetsz újat';
+$lang['resendna'] = 'Ez a wiki nem támogatja a jelszó újraküldést.';
+$lang['resendpwd'] = 'Új jelszó kiküldése ennek a felhasználónak';
+$lang['resendpwdmissing'] = 'Sajnáljuk, az összes mezőt ki kell töltened.';
+$lang['resendpwdnouser'] = 'Sajnáljuk, ilyen azonosítójú felhasználónk nem létezik.';
+$lang['resendpwdbadauth'] = 'Sajnáljuk, ez a megerősítő kód nem helyes. Biztos, hogy a teljes megerősítés linket beírtad pontosan?';
+$lang['resendpwdconfirm'] = 'A megerősítés linket e-mailben elküldtük.';
+$lang['resendpwdsuccess'] = 'Az új jelszavadat elküldtük e-mailben.';
+$lang['license'] = 'Hacsak máshol nincs egyéb rendelkezés, ezen wiki tartalma a következő licenc alatt érhető el:';
+$lang['licenseok'] = 'Megjegyzés: az oldal szerkesztésével elfogadja, hogy a tartalom a következő licenc alatt lesz elérhető:';
+$lang['searchmedia'] = 'Keresett fájl neve:';
+$lang['searchmedia_in'] = 'Keresés a következőben: %s';
+$lang['txt_upload'] = 'Válaszd ki a feltöltendő fájlt';
+$lang['txt_filename'] = 'feltöltési név (elhagyható)';
+$lang['txt_overwrt'] = 'Létező fájl felülírása';
+$lang['lockedby'] = 'Jelenleg zárolta:';
+$lang['lockexpire'] = 'A zárolás lejár:';
+$lang['js']['willexpire'] = 'Az oldalszerkesztési zárolásod körülbelül egy percen belül lejár.\nAz ütközések elkerülése végett használd az előnézet gombot a zárolási időzítés frissítéséhez.';
+$lang['js']['notsavedyet'] = 'Elmentetlen változások vannak, amelyek el fognak veszni.
+Tényleg ezt akarod?';
+$lang['js']['searchmedia'] = 'Fájlok keresése';
+$lang['js']['keepopen'] = 'Tartsd nyitva ezt az ablakot a kijelöléshez!';
+$lang['js']['hidedetails'] = 'Részletek elrejtése';
+$lang['js']['mediatitle'] = 'Link beállítások';
+$lang['js']['mediadisplay'] = 'Link típusa';
+$lang['js']['mediaalign'] = 'Igazítás';
+$lang['js']['mediasize'] = 'Képméret';
+$lang['js']['mediatarget'] = 'Link';
+$lang['js']['mediaclose'] = 'Bezárás';
+$lang['js']['mediainsert'] = 'Beillesztés';
+$lang['js']['mediadisplayimg'] = 'Kép megtekintése.';
+$lang['js']['mediadisplaylnk'] = 'Link megtekintése.';
+$lang['js']['mediasmall'] = 'Kisebb méret';
+$lang['js']['mediamedium'] = 'Közepes méret';
+$lang['js']['medialarge'] = 'Nagyobb méret';
+$lang['js']['mediaoriginal'] = 'Eredeti';
+$lang['js']['medialnk'] = 'Link a részletekre';
+$lang['js']['mediadirect'] = 'Közvetlen link az eredetire';
+$lang['js']['medianolnk'] = 'Nincsen link';
+$lang['js']['medianolink'] = 'Ne linkelje a képet';
+$lang['js']['medialeft'] = 'Kép igazítása balra.';
+$lang['js']['mediaright'] = 'Kép igazítása jobbra.';
+$lang['js']['mediacenter'] = 'Kép igazítása középre.';
+$lang['js']['medianoalign'] = 'Nem legyen igazítás.';
+$lang['js']['nosmblinks'] = 'A Windows megosztott könyvtárak kereszthivatkozása csak Microsoft Internet Explorerben működik közvetlenül.
+A hivatkozást másolni és beszúrni ettől fügetlenül mndig tudod.';
+$lang['js']['linkwiz'] = 'Hivatkozás varázsló';
+$lang['js']['linkto'] = 'Hivatkozás erre:';
+$lang['js']['del_confirm'] = 'Valóban törölni akarod a kiválasztott elem(ek)et?';
+$lang['rssfailed'] = 'Hiba történt ennek a betöltésekor: ';
+$lang['nothingfound'] = 'Semmit sem találtam.';
+$lang['mediaselect'] = 'Médiafájl kiválasztása';
+$lang['fileupload'] = 'Médiafájl feltöltése';
+$lang['uploadsucc'] = 'A feltöltés sikerült';
+$lang['uploadfail'] = 'A feltöltés nem sikerült. Talán rosszak a jogosultságok?';
+$lang['uploadwrong'] = 'A feltöltés megtagadva. Ez a fájl kiterjesztés tiltott.';
+$lang['uploadexist'] = 'A fájl már létezik, nem történt semmi.';
+$lang['uploadbadcontent'] = 'A feltöltött tartalom nem egyezik a %s fájl kiterjesztéssel.';
+$lang['uploadspam'] = 'A feltöltést visszautasítottuk spam-gyanú miatt.';
+$lang['uploadxss'] = 'A feltöltést visszautasítottuk, mert lehetséges, hogy kártékony kódot tartalmaz.';
+$lang['uploadsize'] = 'A feltöltött fájl túl nagy. (max. %s)';
+$lang['deletesucc'] = 'A "%s" fájlt töröltük.';
+$lang['deletefail'] = 'A "%s" fájl nem törölhető. - Ellenőrizd a jogosultságokat!';
+$lang['mediainuse'] = 'A "%s" fájl nem törlődött - még használat alatt van.';
+$lang['namespaces'] = 'Névtér';
+$lang['mediafiles'] = 'Elérhető fájlok itt:';
+$lang['accessdenied'] = 'Nincsen jogod az oldal megtekintésére.';
+$lang['mediausage'] = 'A következő formában hivatkozhatsz erre az állományra:';
+$lang['mediaview'] = 'Eredeti állomány megtekintése';
+$lang['mediaroot'] = 'kiindulási hely';
+$lang['mediaupload'] = 'Itt tölthetsz fel állományt az aktuális névtérbe. Al-névtér létrehozásához a "Feltöltési név" mezőben kell kettősponttal elválasztva megadnod azt.';
+$lang['mediaextchange'] = 'Az állomány kiterjesztése erről: .%s erre: .%s változott!';
+$lang['reference'] = 'Hivatkozások';
+$lang['ref_inuse'] = 'A fájl nem törölhető, mert a következő oldalakon használják:';
+$lang['ref_hidden'] = 'Van néhány hivatkozás az oldalakon, amelyekhez nincs olvasási jogosultságod';
+$lang['hits'] = 'Találatok';
+$lang['quickhits'] = 'Illeszkedő oldalnevek';
+$lang['toc'] = 'Tartalomjegyzék';
+$lang['current'] = 'aktuális';
+$lang['yours'] = 'A te változatod';
+$lang['diff'] = 'a különbségeket mutatja az aktuális változathoz képest';
+$lang['diff2'] = 'a különbségeket mutatja a kiválasztott változatok között';
+$lang['difflink'] = 'Összehasonlító nézet linkje';
+$lang['diff_type'] = 'Összehasonlítás módja:';
+$lang['diff_inline'] = 'Sorok között';
+$lang['diff_side'] = 'Kétoldalas';
+$lang['line'] = 'sorszám';
+$lang['breadcrumb'] = 'Nyomvonal';
+$lang['youarehere'] = 'Itt vagy';
+$lang['lastmod'] = 'Utolsó módosítás';
+$lang['by'] = 'szerkesztette:';
+$lang['deleted'] = 'eltávolítva';
+$lang['created'] = 'létrehozva';
+$lang['restored'] = 'az előző változat helyreállítva';
+$lang['external_edit'] = 'külső szerkesztés';
+$lang['summary'] = 'A változások összefoglalása';
+$lang['noflash'] = 'Ennek a tartalomnak a megtekintéséhez <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> szükséges.';
+$lang['download'] = 'Kódrészlet letöltése';
+$lang['mail_newpage'] = 'új oldal jött létre:';
+$lang['mail_changed'] = 'oldal megváltozott:';
+$lang['mail_subscribe_list'] = 'oldalak megváltoztak ebben a névtérben:';
+$lang['mail_new_user'] = 'Új felhasználó:';
+$lang['mail_upload'] = 'állományt töltöttek fel:';
+$lang['qb_bold'] = 'Félkövér szöveg';
+$lang['qb_italic'] = 'Dőlt szöveg';
+$lang['qb_underl'] = 'Aláhúzott szöveg';
+$lang['qb_code'] = 'Forráskód szöveg';
+$lang['qb_strike'] = 'Áthúzott szöveg';
+$lang['qb_h1'] = '1. szintű címsor';
+$lang['qb_h2'] = '2. szintű címsor';
+$lang['qb_h3'] = '3. szintű címsor';
+$lang['qb_h4'] = '4. szintű címsor';
+$lang['qb_h5'] = '5. szintű címsor';
+$lang['qb_h'] = 'Címsor';
+$lang['qb_hs'] = 'Címsor kiválasztása';
+$lang['qb_hplus'] = 'Nagyobb címsor';
+$lang['qb_hminus'] = 'Kisebb címsor';
+$lang['qb_hequal'] = 'Azonos szintű címsor';
+$lang['qb_link'] = 'Belső hivatkozás';
+$lang['qb_extlink'] = 'Külső hivatkozás';
+$lang['qb_hr'] = 'Vízszintes elválasztó vonal';
+$lang['qb_ol'] = 'Sorszámozott lista elem';
+$lang['qb_ul'] = 'Felsorolás lista elem';
+$lang['qb_media'] = 'Képek és más fájlok hozzáadása';
+$lang['qb_sig'] = 'Aláírás beszúrása';
+$lang['qb_smileys'] = 'Szmájlik';
+$lang['qb_chars'] = 'Speciális karakterek';
+$lang['upperns'] = 'Ugrás a szülő névtérhez';
+$lang['admin_register'] = 'Új felhasználó';
+$lang['metaedit'] = 'Meta-adatok szerkesztése';
+$lang['metasaveerr'] = 'A meta-adatok írása meghiúsult ';
+$lang['metasaveok'] = 'Meta-adatok elmentve';
+$lang['img_backto'] = 'Vissza';
+$lang['img_title'] = 'Cím';
+$lang['img_caption'] = 'Képaláírás';
+$lang['img_date'] = 'Dátum';
+$lang['img_fname'] = 'Fájlnév';
+$lang['img_fsize'] = 'Méret';
+$lang['img_artist'] = 'Készítette';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Formátum';
+$lang['img_camera'] = 'Fényképező típusa';
+$lang['img_keywords'] = 'Kulcsszavak';
+$lang['subscr_subscribe_success'] = '%s hozzáadva az értesítési listához: %s';
+$lang['subscr_subscribe_error'] = 'Hiba történt %s hozzáadásakor az értesítési listához: %s';
+$lang['subscr_subscribe_noaddress'] = 'Nincsen e-mail cím megadva az adataidnál, így a rendszer nem tudott hozzáadni az értesítési listához';
+$lang['subscr_unsubscribe_success'] = '%s eltávolítva az értesítési listából: %s';
+$lang['subscr_unsubscribe_error'] = 'Hiba történt %s eltávolításakor az értesítési listából: %s';
+$lang['subscr_already_subscribed'] = '%s már feliratkozott erre: %s';
+$lang['subscr_not_subscribed'] = '%s nincsen feliratkozva erre: %s';
+$lang['subscr_m_not_subscribed'] = 'Jelenleg nem vagy feliratkozva erre az oldalra vagy névtérre';
+$lang['subscr_m_new_header'] = 'Feliratkozás hozzáadása';
+$lang['subscr_m_current_header'] = 'Feliratkozások';
+$lang['subscr_m_unsubscribe'] = 'Leiratkozás';
+$lang['subscr_m_subscribe'] = 'Feliratkozás';
+$lang['subscr_m_receive'] = 'Küldj';
+$lang['subscr_style_every'] = 'e-mailt minden változásról';
+$lang['subscr_style_digest'] = 'összefoglaló e-mailt oldalanként (minden %.2f nap)';
+$lang['subscr_style_list'] = 'egy listát a módosított oldalakról a legutóbbi e-mail óta (minden %.2f nap)';
+$lang['authmodfailed'] = 'Hibás felhasználó-aznosítási módszer van beállítva. Légy szíves értesítsd a Wiki-gazdát!';
+$lang['authtempfail'] = 'A felhasználó azonosítás átmenetileg nem működik. Ha sokáig így lenne, légy szíves értesítsd a Wiki-gazdát!';
+$lang['i_chooselang'] = 'Válassz nyelvet';
+$lang['i_installer'] = 'DokuWiki Beállító Varázsló';
+$lang['i_wikiname'] = 'A Wiki neve';
+$lang['i_enableacl'] = 'Hozzáférési listák engedélyezése (ajánlott)';
+$lang['i_superuser'] = 'Wiki-gazda';
+$lang['i_problems'] = 'A Beállító Varázsló a következő problémák miatt megakadt. Nem tudjuk folytatni, amíg ezek nincsenek elhárítva!';
+$lang['i_modified'] = 'Biztonsági okokból ez a Varázsló csak új és módosítatlan DokuWiki változaton működik.
+Csomagold ki újra a fájlokat a letöltött csomagból, vagy nézd meg a teljes <a href="http://dokuwiki.org/install">Dokuwiki telepítési útmutatót</a>.';
+$lang['i_funcna'] = 'A <code>%s</code> PHP funkció nem elérhető. Esetleg a tárhelyszolgáltató letiltotta biztonsági okok miatt?';
+$lang['i_phpver'] = 'A PHP <code>%s</code> verziója alacsonyabb, mint ami szükséges lenne: <code>%s</code>. Frissítsd a PHP-det újabb verzióra!';
+$lang['i_permfail'] = 'A DokiWiki nem tudja írni a <code>%s</code> könyvtárat. Be kell állítanod ehhez a könyvtárhoz a megfelelő jogosultságokat!';
+$lang['i_confexists'] = '<code>%s</code> már létezik.';
+$lang['i_writeerr'] = 'Nem tudom ezt létrehozni: <code>%s</code>. Ellenőrizd a könyvtár/fájl jogosultságokat, és hozd létre az állományt kézzel.';
+$lang['i_badhash'] = 'A dokuwiki.php nem felismerhető vagy módosított (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - nem helyes vagy üres érték';
+$lang['i_success'] = 'A beállítás sikeresen befejeződött. Most már letörölhető az install.php fájl. Látogasd meg az <a href="doku.php">új DokuWikidet</a>!';
+$lang['i_failure'] = 'Hiba lépett fel a konfigurációs állományok írásakor. Ki kell javítanod kézzel, mielőtt használni kezded az <a href="doku.php">új DokuWikidet</a>.';
+$lang['i_policy'] = 'Kezdeti hozzáférési politika';
+$lang['i_pol0'] = 'Nyitott Wiki (mindenki olvashatja, írhatja, és fájlokat tölthet fel)';
+$lang['i_pol1'] = 'Publikus Wiki (mindenki olvashatja, de csak regisztrált felhasználók írhatják, és tölthetnek fel fájlokat)';
+$lang['i_pol2'] = 'Zárt Wiki (csak regisztrált felhasználók olvashatják, írhatják és tölthetnek fel fájlokat)';
+$lang['i_retry'] = 'Újra';
+$lang['i_license'] = 'Kérlek válassz licenszt a feltöltött tartalomhoz:';
+$lang['recent_global'] = 'Jelenleg csak a <b>%s</b> névtér friss változásai látszanak. Megtekinthetők <a href="%s">a teljes wiki friss változásai</a> is.';
+$lang['years'] = '%d évvel ezelőtt';
+$lang['months'] = '%d hónappal ezelőtt';
+$lang['weeks'] = '%d héttel ezelőtt';
+$lang['days'] = '%d nappal ezelőtt';
+$lang['hours'] = '%d órával ezelőtt';
+$lang['minutes'] = '%d perccel ezelőtt';
+$lang['seconds'] = '%d másodperccel ezelőtt';
+$lang['wordblock'] = 'A változásokat nem sikerült menteni, mert tiltott tartalom van benne (spam)';
diff --git a/inc/lang/hu/locked.txt b/inc/lang/hu/locked.txt
new file mode 100644
index 000000000..229141674
--- /dev/null
+++ b/inc/lang/hu/locked.txt
@@ -0,0 +1,4 @@
+====== Az oldal zárolva ======
+
+Ezt az oldalt épp szerkeszti egy másik felhasználó. Várnod kell, amíg a másik felhasználó befejezi, vagy amíg a zárolási időzítő le nem jár.
+
diff --git a/inc/lang/hu/login.txt b/inc/lang/hu/login.txt
new file mode 100644
index 000000000..3f7e62e72
--- /dev/null
+++ b/inc/lang/hu/login.txt
@@ -0,0 +1,5 @@
+====== Belépés ======
+
+Nem vagy bejelentkezve! Add meg az azonosítási adataid a belépéshez lentebb! A böngésződben engedélyezned kell a sütik (cookies) fogadását a belépéshez.
+
+
diff --git a/inc/lang/hu/mailtext.txt b/inc/lang/hu/mailtext.txt
new file mode 100644
index 000000000..9b0c2921e
--- /dev/null
+++ b/inc/lang/hu/mailtext.txt
@@ -0,0 +1,16 @@
+A DokuWikidben egy oldalt létrejött, vagy megváltozott. A részletek:
+
+Dátum: @DATE@
+Böngésző: @BROWSER@
+IP-cím: @IPADDRESS@
+Gép neve: @HOSTNAME@
+Előző változat: @OLDPAGE@
+Új változat: @NEWPAGE@
+Összefoglaló: @SUMMARY@
+Felhasználó: @USER@
+
+@DIFF@
+
+
+--
+Ezt a levelet a @DOKUWIKIURL@ DokuWiki generálta.
diff --git a/inc/lang/hu/newpage.txt b/inc/lang/hu/newpage.txt
new file mode 100644
index 000000000..de5a34d8e
--- /dev/null
+++ b/inc/lang/hu/newpage.txt
@@ -0,0 +1,3 @@
+====== Ilyen oldal még nem létezik ======
+
+Egy nem létező oldalra tévedtél. Létrehozhatod az ''Oldal létrehozása'' gombra kattintva. \ No newline at end of file
diff --git a/inc/lang/hu/norev.txt b/inc/lang/hu/norev.txt
new file mode 100644
index 000000000..4dd408459
--- /dev/null
+++ b/inc/lang/hu/norev.txt
@@ -0,0 +1,5 @@
+====== Nincs ilyen változat ======
+
+A megadott változat nem létezik. Használd az ''Előző változatok'' nyomógombot az előzmények listájának megtekintéséhez.
+
+
diff --git a/inc/lang/hu/password.txt b/inc/lang/hu/password.txt
new file mode 100644
index 000000000..db24b9009
--- /dev/null
+++ b/inc/lang/hu/password.txt
@@ -0,0 +1,10 @@
+Kedves @FULLNAME@!
+
+A felhasználói adataid a @TITLE@ wikihez, a következő helyen: @DOKUWIKIURL@
+
+Azonosító: @LOGIN@
+Jelszó: @PASSWORD@
+
+--
+Ezt a levelet @DOKUWIKIURL@ DokuWiki generálta.
+
diff --git a/inc/lang/hu/preview.txt b/inc/lang/hu/preview.txt
new file mode 100644
index 000000000..ad7f7d4b0
--- /dev/null
+++ b/inc/lang/hu/preview.txt
@@ -0,0 +1,4 @@
+====== Előnézet ======
+
+Ez a szöveged előnézete, így fog kinézni. Figyelj jól: ez **még nincs elmentve**!
+
diff --git a/inc/lang/hu/pwconfirm.txt b/inc/lang/hu/pwconfirm.txt
new file mode 100644
index 000000000..617419ee8
--- /dev/null
+++ b/inc/lang/hu/pwconfirm.txt
@@ -0,0 +1,14 @@
+Szia @FULLNAME@!
+
+Te vagy más valaki kért egy új jelszót a @DOKUWIKIURL@
+címen lévő @TITLE@ wiki felhasználódhoz.
+
+Ha nem kértél ilyet, hagyd figyelmen kívül ezt a levelet.
+
+Ha Te voltál, az új jelszó kérelmed megerősítéséhez a
+következő linkre kattints, vagy másold a böngésződbe:
+
+@CONFIRM@
+
+--
+Ezt a levelet a @DOKUWIKIURL@ címen lévő DokuWiki generálta.
diff --git a/inc/lang/hu/read.txt b/inc/lang/hu/read.txt
new file mode 100644
index 000000000..89ac96338
--- /dev/null
+++ b/inc/lang/hu/read.txt
@@ -0,0 +1,2 @@
+Ez az oldal csak olvasható. Megtekintheted a forrását, de nem változtathatod meg. Ha úgy gondolod, hogy ez helytelen, kérdezd a Wiki-gazdát.
+
diff --git a/inc/lang/hu/recent.txt b/inc/lang/hu/recent.txt
new file mode 100644
index 000000000..4e0c1ec06
--- /dev/null
+++ b/inc/lang/hu/recent.txt
@@ -0,0 +1,5 @@
+====== Legutóbbi változások ======
+
+Az alábbi oldalak változtak legutoljára.
+
+
diff --git a/inc/lang/hu/register.txt b/inc/lang/hu/register.txt
new file mode 100644
index 000000000..2745c4d77
--- /dev/null
+++ b/inc/lang/hu/register.txt
@@ -0,0 +1,4 @@
+====== Új felhasználó regisztrálása ======
+
+Töltsd ki az összes alábbi adatot az új Wiki felhasználói azonosítód létrehozásához. Győződj meg róla, hogy **érvényes e-mail címet** adtál meg -- az új jelszavad erre a címre küldjük el. Az azonosítód érvényes [[doku>pagename|oldalnév]] kell legyen.
+
diff --git a/inc/lang/hu/registermail.txt b/inc/lang/hu/registermail.txt
new file mode 100644
index 000000000..d45ef0d38
--- /dev/null
+++ b/inc/lang/hu/registermail.txt
@@ -0,0 +1,13 @@
+Egy új felhasználó regisztrált a következő adatokkal:
+
+Felhasználói név: @NEWUSER@
+Teljes név: @NEWNAME@
+E-mail: @NEWEMAIL@
+
+Dátum: @DATE@
+Böngésző: @BROWSER@
+IP-cím : @IPADDRESS@
+Gép neve: @HOSTNAME@
+
+--
+Ezt a levelet @DOKUWIKIURL@ DokuWiki generálta. \ No newline at end of file
diff --git a/inc/lang/hu/resendpwd.txt b/inc/lang/hu/resendpwd.txt
new file mode 100644
index 000000000..24931a7ed
--- /dev/null
+++ b/inc/lang/hu/resendpwd.txt
@@ -0,0 +1,3 @@
+===== Új jelszó kérése =====
+
+Kérlek add meg a felhasználó neved az új jelszó elküldéséhez. A jelszó cseréjéhez szükséges megerősítő linket a regisztrált e-mail címedre küldjük. \ No newline at end of file
diff --git a/inc/lang/hu/revisions.txt b/inc/lang/hu/revisions.txt
new file mode 100644
index 000000000..3537fd653
--- /dev/null
+++ b/inc/lang/hu/revisions.txt
@@ -0,0 +1,3 @@
+====== Előző változatok ======
+
+Ezek az előző változatai az aktuális dokumentumnak. Egy előző változathoz való visszatéréshez nyomd meg az ''Oldal szerkesztése'' gombot, majd mentsd el.
diff --git a/inc/lang/hu/searchpage.txt b/inc/lang/hu/searchpage.txt
new file mode 100644
index 000000000..b1defed84
--- /dev/null
+++ b/inc/lang/hu/searchpage.txt
@@ -0,0 +1,5 @@
+====== Keresés ======
+
+A keresés eredményét lentebb láthatod. Ha nem találtad meg amit kerestél, akkor létrehozhatsz egy új oldalt a keresésed alapján ''Az oldal szerkesztése'' gombbal.
+
+===== Eredmény(ek) ===== \ No newline at end of file
diff --git a/inc/lang/hu/showrev.txt b/inc/lang/hu/showrev.txt
new file mode 100644
index 000000000..2131b4dc0
--- /dev/null
+++ b/inc/lang/hu/showrev.txt
@@ -0,0 +1,2 @@
+**Ez a dokumentum egy előző változata!**
+----
diff --git a/inc/lang/hu/stopwords.txt b/inc/lang/hu/stopwords.txt
new file mode 100644
index 000000000..a8bd35c7d
--- /dev/null
+++ b/inc/lang/hu/stopwords.txt
@@ -0,0 +1,39 @@
+# Ez egy szó-lista (soronként egy szóval), amelyeket az index készítésekor nem veszünk figyelembe.
+# Ha szerkeszted ezt a fájlt, győződj meg arról, hogy UNIX sorvég-jeleket használj! (csak NL karakter)
+# Nincs szükség 3 karakternél rövidebb szavak felsorolására, ezeket egyébként sem vesszük figyelembe.
+# Ez a lista a http://www.ranks.nl/stopwords/ oldalon szereplő alapján készült
+a
+az
+egy
+be
+ki
+le
+fel
+meg
+el
+át
+rá
+ide
+oda
+szét
+össze
+vissza
+de
+hát
+és
+vagy
+hogy
+van
+lesz
+volt
+csak
+nem
+igen
+mint
+én
+te
+mi
+ti
+ők
+ön
diff --git a/inc/lang/hu/subscr_digest.txt b/inc/lang/hu/subscr_digest.txt
new file mode 100644
index 000000000..62e777faf
--- /dev/null
+++ b/inc/lang/hu/subscr_digest.txt
@@ -0,0 +1,17 @@
+Szia,
+
+A @PAGE@ oldal a @TITLE wikiben megváltozott.
+Itt vannak az eltérések:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Régi verzió: @OLDPAGE@
+Új verzió: @NEWPAGE@
+
+Ha nem szeretnél értesítéseket kapni, jelentkezz be a wiki-be itt: @DOKUWIKIURL@, majd ezen az oldalon tudsz leiratkozni: @SUBSCRIBE@.
+
+--
+Ezt a levelet a DokuWiki generálta
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/hu/subscr_form.txt b/inc/lang/hu/subscr_form.txt
new file mode 100644
index 000000000..22fa94015
--- /dev/null
+++ b/inc/lang/hu/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Feliratkozás kezelés ======
+
+Ezen az oldalon van lehetőséged kezelni a feliratkozásaidat az adott oldalra vagy névtérre. \ No newline at end of file
diff --git a/inc/lang/hu/subscr_list.txt b/inc/lang/hu/subscr_list.txt
new file mode 100644
index 000000000..f68e6fc0a
--- /dev/null
+++ b/inc/lang/hu/subscr_list.txt
@@ -0,0 +1,14 @@
+Szia,
+
+A @PAGE@ névtérhez tartozó oldalak megváltoztak a @TITLE wikiben.
+Itt vannak a módosított oldalak:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Ha nem szeretnél értesítéseket kapni, jelentkezz be a wiki-be itt: @DOKUWIKIURL@, majd ezen az oldalon tudsz leiratkozni: @SUBSCRIBE@.
+
+--
+Ezt a levelet a DokuWiki generálta
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/hu/subscr_single.txt b/inc/lang/hu/subscr_single.txt
new file mode 100644
index 000000000..a17a98cfd
--- /dev/null
+++ b/inc/lang/hu/subscr_single.txt
@@ -0,0 +1,20 @@
+Szia,
+
+A @PAGE@ oldal a @TITLE wikiben megváltozott.
+Itt vannak az eltérések:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Dátum: @DATE@
+Felhasználó: @USER@
+Összefoglaló: @SUMMARY@
+Régi verzió: @OLDPAGE@
+Új verzió: @NEWPAGE@
+
+Ha nem szeretnél értesítéseket kapni, jelentkezz be a wiki-be itt: @DOKUWIKIURL@, majd ezen az oldalon tudsz leiratkozni: @NEWPAGE@.
+
+--
+Ezt a levelet a DokuWiki generálta
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/hu/updateprofile.txt b/inc/lang/hu/updateprofile.txt
new file mode 100644
index 000000000..50df15384
--- /dev/null
+++ b/inc/lang/hu/updateprofile.txt
@@ -0,0 +1,3 @@
+===== Felhasználói adatok megváltoztatása =====
+
+Csak azt a mezőt kell kitöltened, amit változtatni szeretnél. A felhasználói nevet nem lehet megváltoztatni.
diff --git a/inc/lang/hu/uploadmail.txt b/inc/lang/hu/uploadmail.txt
new file mode 100644
index 000000000..c772ab220
--- /dev/null
+++ b/inc/lang/hu/uploadmail.txt
@@ -0,0 +1,13 @@
+Fájlfeltöltés történt a DokuWikidben. Részletek:
+
+Állomány: @MEDIA@
+Dátum: @DATE@
+Böngésző: @BROWSER@
+IP-cím: @IPADDRESS@
+Gépnév: @HOSTNAME@
+Méret: @SIZE@
+MIME-típus: @MIME@
+Felhasználó: @USER@
+
+--
+Ezt a levelet @DOKUWIKIURL@ DokuWiki generálta. \ No newline at end of file
diff --git a/inc/lang/ia/admin.txt b/inc/lang/ia/admin.txt
new file mode 100644
index 000000000..f81ff3170
--- /dev/null
+++ b/inc/lang/ia/admin.txt
@@ -0,0 +1,3 @@
+====== Administration ======
+
+Hic infra se trova un lista de cargas administrative disponibile in DokuWiki.
diff --git a/inc/lang/ia/adminplugins.txt b/inc/lang/ia/adminplugins.txt
new file mode 100644
index 000000000..ad8f794b0
--- /dev/null
+++ b/inc/lang/ia/adminplugins.txt
@@ -0,0 +1 @@
+===== Plug-ins additional ===== \ No newline at end of file
diff --git a/inc/lang/ia/backlinks.txt b/inc/lang/ia/backlinks.txt
new file mode 100644
index 000000000..de5d2ac56
--- /dev/null
+++ b/inc/lang/ia/backlinks.txt
@@ -0,0 +1,3 @@
+====== Retroligamines ======
+
+Isto es un lista de paginas que contine ligamines de retorno al pagina actual. \ No newline at end of file
diff --git a/inc/lang/ia/conflict.txt b/inc/lang/ia/conflict.txt
new file mode 100644
index 000000000..576cb7e3f
--- /dev/null
+++ b/inc/lang/ia/conflict.txt
@@ -0,0 +1,5 @@
+====== Un version plus nove existe ======
+
+Existe un version plus nove del documento que tu ha modificate. Isto occurre si un altere usator cambia le documento durante que tu lo modifica.
+
+Examina minutiosemente le differentias monstrate hic infra, postea decide qual version debe esser conservate. Si tu selige ''salveguardar'', tu version essera salveguardate. Preme ''cancellar'' pro conservar le version actual.
diff --git a/inc/lang/ia/denied.txt b/inc/lang/ia/denied.txt
new file mode 100644
index 000000000..044e1532d
--- /dev/null
+++ b/inc/lang/ia/denied.txt
@@ -0,0 +1,3 @@
+====== Permission refusate ======
+
+Pardono, tu non ha le derectos requisite pro continuar. Pote esser que tu ha oblidate de aperir un session. \ No newline at end of file
diff --git a/inc/lang/ia/diff.txt b/inc/lang/ia/diff.txt
new file mode 100644
index 000000000..dbfa70f13
--- /dev/null
+++ b/inc/lang/ia/diff.txt
@@ -0,0 +1,3 @@
+====== Differentias ======
+
+Isto te monstra le differentias inter duo versiones del pagina. \ No newline at end of file
diff --git a/inc/lang/ia/draft.txt b/inc/lang/ia/draft.txt
new file mode 100644
index 000000000..ae8de13f4
--- /dev/null
+++ b/inc/lang/ia/draft.txt
@@ -0,0 +1,5 @@
+====== Version provisori trovate ======
+
+Tu ultime session de modification in iste pagina non ha essite concludite correctemente. DokuWiki ha automaticamente salveguardate un version provisori durante tu labor. Ora tu pote usar iste version provisori pro continuar le modification. Hic infra tu vide le datos salveguardate de tu ultime session.
+
+Per favor decide si tu vole //recuperar// le session de modification perdite, //deler// le version provisori o //cancellar// le processo de modification. \ No newline at end of file
diff --git a/inc/lang/ia/edit.txt b/inc/lang/ia/edit.txt
new file mode 100644
index 000000000..5bc58362a
--- /dev/null
+++ b/inc/lang/ia/edit.txt
@@ -0,0 +1 @@
+Modifica le pagina e preme "Salveguardar". Vide [[wiki:syntax]] pro le syntaxe wiki. Per favor modifica le paginas solmente si tu pote **meliorar** lo. Si tu vole testar alcun cosas, apprende facer tu prime passos in le [[playground:playground|parco de jocos]]. \ No newline at end of file
diff --git a/inc/lang/ia/editrev.txt b/inc/lang/ia/editrev.txt
new file mode 100644
index 000000000..192381f8c
--- /dev/null
+++ b/inc/lang/ia/editrev.txt
@@ -0,0 +1,2 @@
+**Tu ha cargate un version ancian del documento!** Si tu lo salveguarda, tu crea un nove version con iste datos.
+---- \ No newline at end of file
diff --git a/inc/lang/ia/index.txt b/inc/lang/ia/index.txt
new file mode 100644
index 000000000..5957cc2ab
--- /dev/null
+++ b/inc/lang/ia/index.txt
@@ -0,0 +1,3 @@
+====== Indice ======
+
+Isto es un indice super tote le paginas disponibile, ordinate per [[doku>namespaces|spatio de nomines]].
diff --git a/inc/lang/ia/install.html b/inc/lang/ia/install.html
new file mode 100644
index 000000000..01b6f43b5
--- /dev/null
+++ b/inc/lang/ia/install.html
@@ -0,0 +1,13 @@
+<p>Iste pagina te assiste in le prime installation e configuration de
+<a href="http://dokuwiki.org">Dokuwiki</a>. Ulterior informationes super iste installator es disponibile in le
+<a href="http://dokuwiki.org/installer">pagina de documentation</a> de illo.</p>
+
+<p>DokuWiki usa files ordinari pro le immagazinage de paginas wiki e altere informationes associate con iste paginas (p.ex. imagines, indices de recerca, versiones ancian, etc). Pro poter functionar, DokuWiki
+<strong>debe</strong> haber accesso de scriptura al directorios que contine iste files. Iste installator non es capabile de configurar le permissiones de directorios. Isto normalmente debe esser facite directemente con le linea de commandos, o si tu usa un albergo web, via FTP o via le pannello de controlo de tu albergo (p.ex. cPanel).</p>
+
+<p>Iste installator configurara tu installation de DokuWiki pro
+<acronym title="listas de controlo de accesso">ACL</acronym>, lo que permitte crear contos administrator, e forni accesso al menu administrative de DokuWiki pro installar plug-ins, gerer usatores, gerer accesso a paginas wiki e alterar configurationes. Isto non es necessari pro le functionamento de DokuWiki, nonobstante, illo rendera DokuWiki plus facile de administrar.</p>
+
+<p>Le usatores experte o con exigentias special pro le installation deberea usar iste ligamines pro detalios concernente le
+<a href="http://dokuwiki.org/install">instructiones de installation</a>
+e <a href="http://dokuwiki.org/config">configurationes</a>.</p>
diff --git a/inc/lang/ia/lang.php b/inc/lang/ia/lang.php
new file mode 100644
index 000000000..c336d8541
--- /dev/null
+++ b/inc/lang/ia/lang.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * ia language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesIa.php?view=co
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Modificar iste pagina';
+$lang['btn_source'] = 'Monstrar codice-fonte';
+$lang['btn_show'] = 'Monstrar pagina';
+$lang['btn_create'] = 'Crear iste pagina';
+$lang['btn_search'] = 'Cercar';
+$lang['btn_save'] = 'Salveguardar';
+$lang['btn_preview'] = 'Previsualisar';
+$lang['btn_top'] = 'Retornar al initio';
+$lang['btn_newer'] = '<< plus recente';
+$lang['btn_older'] = 'minus recente >>';
+$lang['btn_revs'] = 'Versiones ancian';
+$lang['btn_recent'] = 'Modificationes recente';
+$lang['btn_upload'] = 'Incargar';
+$lang['btn_cancel'] = 'Cancellar';
+$lang['btn_index'] = 'Indice';
+$lang['btn_secedit'] = 'Modificar';
+$lang['btn_login'] = 'Aperir session';
+$lang['btn_logout'] = 'Clauder session';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Actualisar';
+$lang['btn_delete'] = 'Deler';
+$lang['btn_back'] = 'Retornar';
+$lang['btn_backlink'] = 'Retroligamines';
+$lang['btn_backtomedia'] = 'Retornar al selection de files multimedia';
+$lang['btn_subscribe'] = 'Gerer subscriptiones';
+$lang['btn_profile'] = 'Actualisar profilo';
+$lang['btn_reset'] = 'Reinitialisar';
+$lang['btn_resendpwd'] = 'Inviar nove contrasigno';
+$lang['btn_draft'] = 'Modificar version provisori';
+$lang['btn_recover'] = 'Recuperar version provisori';
+$lang['btn_draftdel'] = 'Deler version provisori';
+$lang['btn_revert'] = 'Restaurar';
+$lang['btn_register'] = 'Crear conto';
+$lang['loggedinas'] = 'Session aperite como';
+$lang['user'] = 'Nomine de usator';
+$lang['pass'] = 'Contrasigno';
+$lang['newpass'] = 'Nove contrasigno';
+$lang['oldpass'] = 'Confirmar contrasigno actual';
+$lang['passchk'] = 'un altere vice';
+$lang['remember'] = 'Memorar me';
+$lang['fullname'] = 'Nomine real';
+$lang['email'] = 'E-mail';
+$lang['profile'] = 'Profilo de usator';
+$lang['badlogin'] = 'Le nomine de usator o le contrasigno es incorrecte.';
+$lang['minoredit'] = 'Modificationes minor';
+$lang['draftdate'] = 'Version provisori automaticamente salveguardate le';
+$lang['nosecedit'] = 'Le pagina ha essite modificate intertanto. Le informationes del section es ora obsolete, dunque le pagina complete ha essite cargate in su loco.';
+$lang['regmissing'] = 'Es necessari completar tote le campos.';
+$lang['reguexists'] = 'Regrettabilemente, un usator con iste nomine ja existe.';
+$lang['regsuccess'] = 'Le conto ha essite create e le contrasigno ha essite inviate per e-mail.';
+$lang['regsuccess2'] = 'Le conto ha essite create.';
+$lang['regmailfail'] = 'Il pare que un error occurreva durante le invio del message con le contrasigno. Per favor contacta le administrator!';
+$lang['regbadmail'] = 'Le adresse de e-mail date pare esser invalide. Si tu pensa que isto es un error, contacta le administrator.';
+$lang['regbadpass'] = 'Le duo contrasignos date non es identic. Per favor reproba.';
+$lang['regpwmail'] = 'Tu contrasigno de DokuWiki';
+$lang['reghere'] = 'Tu non ha ancora un conto? Crea un, simplemente.';
+$lang['profna'] = 'Iste wiki non supporta le modification de profilos.';
+$lang['profnochange'] = 'Nulle modification, nihil a facer.';
+$lang['profnoempty'] = 'Un nomine o adresse de e-mail vacue non es permittite.';
+$lang['profchanged'] = 'Actualisation del profilo de usator succedite.';
+$lang['pwdforget'] = 'Contrasigno oblidate? Obtene un altere';
+$lang['resendna'] = 'Iste wiki non supporta le invio de un nove contrasigno.';
+$lang['resendpwd'] = 'Inviar nove contrasigno pro';
+$lang['resendpwdmissing'] = 'Es necessari completar tote le campos.';
+$lang['resendpwdnouser'] = 'Iste usator non ha essite trovate in le base de datos.';
+$lang['resendpwdbadauth'] = 'Iste codice de authentication non es valide. Assecura te que tu ha usate le ligamine de confirmation complete.';
+$lang['resendpwdconfirm'] = 'Un ligamine de confirmation ha essite inviate per e-mail.';
+$lang['resendpwdsuccess'] = 'Tu nove contrasigno ha essite inviate per e-mail.';
+$lang['license'] = 'Excepte ubi indicate alteremente, le contento in iste wiki es disponibile sub le licentia sequente:';
+$lang['licenseok'] = 'Nota ben! Per modificar iste pagina tu accepta que tu contento essera publicate sub le conditiones del licentia sequente:';
+$lang['searchmedia'] = 'Cercar file con nomine:';
+$lang['searchmedia_in'] = 'Cercar in %s';
+$lang['txt_upload'] = 'Selige le file a incargar';
+$lang['txt_filename'] = 'Incargar como (optional)';
+$lang['txt_overwrt'] = 'Reimplaciar le file existente';
+$lang['lockedby'] = 'Actualmente serrate per';
+$lang['lockexpire'] = 'Serratura expira le';
+$lang['js']['willexpire'] = 'Tu serratura super le modification de iste pagina expirara post un minuta.\nPro evitar conflictos, usa le button Previsualisar pro reinitialisar le timer del serratura.';
+$lang['js']['notsavedyet'] = "Le modificationes non salveguardate essera perdite.\nRealmente continuar?";
+$lang['rssfailed'] = 'Un error occurreva durante le obtention de iste syndication:';
+$lang['nothingfound'] = 'Nihil ha essite trovate.';
+$lang['mediaselect'] = 'Files multimedia';
+$lang['fileupload'] = 'Incargar file multimedia';
+$lang['uploadsucc'] = 'Incargamento succedite';
+$lang['uploadfail'] = 'Incargamento fallite. Pote esser que le permissiones es incorrecte.';
+$lang['uploadwrong'] = 'Incargamento refusate. Iste typo de file es prohibite!';
+$lang['uploadexist'] = 'File ja existe. Nihil facite.';
+$lang['uploadbadcontent'] = 'Le typo del contento incargate non corresponde al extension del nomine de file "%s".';
+$lang['uploadspam'] = 'Le incargamento ha essite blocate per le lista nigre anti-spam.';
+$lang['uploadxss'] = 'Le incargamento ha essite blocate a causa de contento possibilemente malitiose.';
+$lang['uploadsize'] = 'Le file incargate es troppo grande. (Max. %s)';
+$lang['deletesucc'] = 'Le file "%s" ha essite delite.';
+$lang['deletefail'] = '"%s" non poteva esser delite. Verifica le permissiones.';
+$lang['mediainuse'] = 'Le file "%s" non ha essite delite proque illo es ancora in uso.';
+$lang['namespaces'] = 'Spatios de nomines';
+$lang['mediafiles'] = 'Files disponibile in';
+$lang['js']['searchmedia'] = 'Cercar files';
+$lang['js']['keepopen'] = 'Mantener fenestra aperte post selection';
+$lang['js']['hidedetails'] = 'Celar detalios';
+$lang['js']['mediatitle'] = 'Configuration del ligamine';
+$lang['js']['mediadisplay'] = 'Typo de ligamine';
+$lang['js']['mediaalign'] = 'Alineamento';
+$lang['js']['mediasize'] = 'Dimension del imagine';
+$lang['js']['mediatarget'] = 'Destination del ligamine';
+$lang['js']['mediaclose'] = 'Clauder';
+$lang['js']['mediainsert'] = 'Inserer';
+$lang['js']['mediadisplayimg'] = 'Monstrar le imagine.';
+$lang['js']['mediadisplaylnk'] = 'Monstrar solmente le imagine.';
+$lang['js']['mediasmall'] = 'Version parve';
+$lang['js']['mediamedium'] = 'Version medie';
+$lang['js']['medialarge'] = 'Version grande';
+$lang['js']['mediaoriginal'] = 'Version original';
+$lang['js']['medialnk'] = 'Ligamine al pagina de detalios';
+$lang['js']['mediadirect'] = 'Ligamine directe verso le original';
+$lang['js']['medianolnk'] = 'Nulle ligamine';
+$lang['js']['medianolink'] = 'Non ligar verso le imagine';
+$lang['js']['medialeft'] = 'Alinear le imagine verso le sinistra.';
+$lang['js']['mediaright'] = 'Alinear le imagine verso le dextra.';
+$lang['js']['mediacenter'] = 'Alinear le imagine in le medio.';
+$lang['js']['medianoalign'] = 'Non alinear.';
+$lang['js']['nosmblinks'] = 'Le ligamines a ressources de Windows functiona solmente in Microsoft Internet Explorer.
+Tu pote nonobstante copiar e collar le ligamine.';
+$lang['js']['linkwiz'] = 'Assistente pro ligamines';
+$lang['js']['linkto'] = 'Ligar verso:';
+$lang['js']['del_confirm'] = 'Realmente deler le entrata(s) seligite?';
+$lang['mediausage'] = 'Usa le syntaxe sequente pro referer a iste file:';
+$lang['mediaview'] = 'Vider file original';
+$lang['mediaroot'] = 'radice';
+$lang['mediaupload'] = 'Incarga hic un file in le spatio de nomines actual. Pro crear subspatios de nomines, antepone los al nomine de file "Incargar como", separate per signos de duo punctos (":").';
+$lang['mediaextchange'] = 'Extension del file cambiate de .%s a .%s!';
+$lang['reference'] = 'Referentias pro';
+$lang['ref_inuse'] = 'Le file non pote esser delite proque illo es ancora in uso per le sequente paginas:';
+$lang['ref_hidden'] = 'Alcun referentias es in paginas pro le quales tu non ha le permission de lectura';
+$lang['hits'] = 'Resultatos';
+$lang['quickhits'] = 'Nomines de pagina correspondente';
+$lang['toc'] = 'Tabula de contento';
+$lang['current'] = 'actual';
+$lang['yours'] = 'Tu version';
+$lang['diff'] = 'Monstrar differentias con versiones actual';
+$lang['diff2'] = 'Monstrar differentias inter le versiones seligite';
+$lang['line'] = 'Linea';
+$lang['breadcrumb'] = 'Tracia';
+$lang['youarehere'] = 'Tu es hic';
+$lang['lastmod'] = 'Ultime modification';
+$lang['by'] = 'per';
+$lang['deleted'] = 'removite';
+$lang['created'] = 'create';
+$lang['restored'] = 'ancian version restaurate';
+$lang['external_edit'] = 'modification externe';
+$lang['summary'] = 'Modificar summario';
+$lang['noflash'] = 'Le <a href="http://www.adobe.com/products/flashplayer/">plug-in Flash de Adobe</a> es necessari pro monstrar iste contento.';
+$lang['download'] = 'Discargar fragmento';
+$lang['mail_newpage'] = 'pagina addite:';
+$lang['mail_changed'] = 'pagina modificate:';
+$lang['mail_subscribe_list'] = 'paginas modificate in spatio de nomines:';
+$lang['mail_new_user'] = 'nove usator:';
+$lang['mail_upload'] = 'file incargate:';
+$lang['qb_bold'] = 'Texto grasse';
+$lang['qb_italic'] = 'Texto italic';
+$lang['qb_underl'] = 'Texto sublineate';
+$lang['qb_code'] = 'Texto de codice';
+$lang['qb_strike'] = 'Texto cancellate';
+$lang['qb_h1'] = 'Titulo a nivello 1';
+$lang['qb_h2'] = 'Titulo a nivello 2';
+$lang['qb_h3'] = 'Titulo a nivello 3';
+$lang['qb_h4'] = 'Titulo a nivello 4';
+$lang['qb_h5'] = 'Titulo a nivello 5';
+$lang['qb_h'] = 'Titulo';
+$lang['qb_hs'] = 'Seliger titulo';
+$lang['qb_hplus'] = 'Titulo superior';
+$lang['qb_hminus'] = 'Titulo inferior';
+$lang['qb_hequal'] = 'Titulo al mesme nivello';
+$lang['qb_link'] = 'Ligamine interne';
+$lang['qb_extlink'] = 'Ligamine externe';
+$lang['qb_hr'] = 'Linea horizontal';
+$lang['qb_ol'] = 'Elemento de lista ordinate';
+$lang['qb_ul'] = 'Elemento de lista non ordinate';
+$lang['qb_media'] = 'Adder imagines e altere files';
+$lang['qb_sig'] = 'Inserer signatura';
+$lang['qb_smileys'] = 'Emoticones ';
+$lang['qb_chars'] = 'Characteres special';
+$lang['upperns'] = 'Saltar al spatio de nomines superior';
+$lang['admin_register'] = 'Adder nove usator';
+$lang['metaedit'] = 'Modificar metadatos';
+$lang['metasaveerr'] = 'Scriptura de metadatos fallite';
+$lang['metasaveok'] = 'Metadatos salveguardate';
+$lang['img_backto'] = 'Retornar a';
+$lang['img_title'] = 'Titulo';
+$lang['img_caption'] = 'Legenda';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Nomine de file';
+$lang['img_fsize'] = 'Dimension';
+$lang['img_artist'] = 'Photographo';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Formato';
+$lang['img_camera'] = 'Camera';
+$lang['img_keywords'] = 'Parolas-clave';
+$lang['subscr_subscribe_success'] = '%s addite al lista de subscription de %s';
+$lang['subscr_subscribe_error'] = 'Error durante le addition de %s al lista de subscription de %s';
+$lang['subscr_subscribe_noaddress'] = 'Il non ha un adresse associate con tu conto. Tu non pote esser addite al lista de subscription.';
+$lang['subscr_unsubscribe_success'] = '%s removite del lista de subscription de %s';
+$lang['subscr_unsubscribe_error'] = 'Error durante le remotion de %s del lista de subscription de %s';
+$lang['subscr_already_subscribed'] = '%s es ja subscribite a %s';
+$lang['subscr_not_subscribed'] = '%s non es subscribite a %s';
+$lang['subscr_m_not_subscribed'] = 'Tu non es actualmente subscribite al pagina o spatio de nomines actual.';
+$lang['subscr_m_new_header'] = 'Adder subscription';
+$lang['subscr_m_current_header'] = 'Subscriptiones actual';
+$lang['subscr_m_unsubscribe'] = 'Cancellar subscription';
+$lang['subscr_m_subscribe'] = 'Subscriber';
+$lang['subscr_m_receive'] = 'Reciper';
+$lang['subscr_style_every'] = 'un message pro cata modification';
+$lang['subscr_style_digest'] = 'un digesto de modificationes pro cata pagina';
+$lang['subscr_style_list'] = 'lista de paginas modificate depost le ultime e-mail';
+$lang['authmodfailed'] = 'Configuration incorrecte de authentication de usator. Per favor informa le administrator de tu wiki.';
+$lang['authtempfail'] = 'Le authentication de usator temporarimente non es disponibile. Si iste situation persiste, per favor informa le administrator de tu wiki.';
+$lang['i_chooselang'] = 'Selige tu lingua';
+$lang['i_installer'] = 'Installator de DokuWiki';
+$lang['i_wikiname'] = 'Nomine del wiki';
+$lang['i_enableacl'] = 'Activar ACL (recommendate)';
+$lang['i_superuser'] = 'Superusator';
+$lang['i_problems'] = 'Le installator ha trovate alcun problemas, indicate hic infra. Tu debe resolver iste problemas pro poter continuar.';
+$lang['i_modified'] = 'Pro motivos de securitate, iste script functiona solmente con un installation de DokuWiki nove e non modificate.
+Tu debe re-extraher le files del pacchetto discargate, o consultar le <a href="http://dokuwiki.org/install">instructiones de installation</a> complete pro altere optiones.';
+$lang['i_funcna'] = 'Le function PHP <code>%s</code> non es disponibile. Pote esser que tu albergo web lo ha disactivate pro un ration o altere.';
+$lang['i_phpver'] = 'Le version de PHP <code>%s</code> es plus ancian que le version requisite <code>%s</code>. Es necessari actualisar le installation de PHP.';
+$lang['i_permfail'] = '<code>%s</code> non permitte le accesso de scriptura a DokuWiki. Tu debe reparar le permissiones de iste directorio!';
+$lang['i_confexists'] = '<code>%s</code> ja existe';
+$lang['i_writeerr'] = 'Impossibile crear <code>%s</code>. Tu debe verificar le permissiones de directorios/files e crear iste file manualmente.';
+$lang['i_badhash'] = 'dokuwiki.php non recognoscite o modificate (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - valor vacue o invalide';
+$lang['i_success'] = 'Le configuration ha succedite. Tu pote ora deler le file install.php. Continua a
+<a href="doku.php">tu nove DokuWiki</a>.';
+$lang['i_failure'] = 'Alcun errores occurreva durante le scriptura del files de configuration. Es possibile que tu debe remediar iste errores manualmente ante que
+tu pote usar <a href="doku.php">tu nove DokuWiki</a>.';
+$lang['i_policy'] = 'Politica de ACL interne';
+$lang['i_pol0'] = 'Wiki aperte (lectura, scriptura, incargamento pro omnes)';
+$lang['i_pol1'] = 'Wiki public (lectura pro omnes, scriptura e incargamento pro usatores registrate)';
+$lang['i_pol2'] = 'Wiki claudite (lectura, scriptura e incargamento solmente pro usatores registrate)';
+$lang['i_retry'] = 'Reprobar';
+$lang['recent_global'] = 'Tu observa actualmente le modificationes intra le spatio de nomines <b>%s</b>. Tu pote etiam <a href="%s">vider le modificationes recente de tote le wiki</a>.';
+$lang['years'] = '%d annos retro';
+$lang['months'] = '%d menses retro';
+$lang['weeks'] = '%d septimanas retro';
+$lang['days'] = '%d dies retro';
+$lang['hours'] = '%d horas retro';
+$lang['minutes'] = '%d minutas retro';
+$lang['seconds'] = '%d secundas retro';
diff --git a/inc/lang/ia/locked.txt b/inc/lang/ia/locked.txt
new file mode 100644
index 000000000..726aabb34
--- /dev/null
+++ b/inc/lang/ia/locked.txt
@@ -0,0 +1,3 @@
+====== Pagina serrate ======
+
+Iste pagina es actualmente serrate proque un altere usator lo modifica in iste momento. Tu debe attender usque iste usator fini le modification o usque al expiration del serratura. \ No newline at end of file
diff --git a/inc/lang/ia/login.txt b/inc/lang/ia/login.txt
new file mode 100644
index 000000000..4c428f358
--- /dev/null
+++ b/inc/lang/ia/login.txt
@@ -0,0 +1,3 @@
+====== Aperir session ======
+
+Tu non es identificate! Entra tu credentiales de authentication pro aperir un session. Tu debe haber activate le cookies pro aperir un session. \ No newline at end of file
diff --git a/inc/lang/ia/mailtext.txt b/inc/lang/ia/mailtext.txt
new file mode 100644
index 000000000..14c1a3a60
--- /dev/null
+++ b/inc/lang/ia/mailtext.txt
@@ -0,0 +1,17 @@
+Un pagina in tu DokuWiki ha essite addite o modificate. Ecce le detalios:
+
+Data : @DATE@
+Navigator : @BROWSER@
+Adresse IP : @IPADDRESS@
+Nomine host : @HOSTNAME@
+Version ancian: @OLDPAGE@
+Version nove: @NEWPAGE@
+Summario: @SUMMARY@
+Usator : @USER@
+
+@DIFF@
+
+
+--
+Iste e-mail ha essite generate per DokuWiki a
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ia/newpage.txt b/inc/lang/ia/newpage.txt
new file mode 100644
index 000000000..8db7aa797
--- /dev/null
+++ b/inc/lang/ia/newpage.txt
@@ -0,0 +1,3 @@
+====== Iste topico non existe ancora ======
+
+Tu ha sequite un ligamine verso un topico que non existe ancora. Si tu ha le permission requisite, tu pote crear lo con le button "Crear iste pagina". \ No newline at end of file
diff --git a/inc/lang/ia/norev.txt b/inc/lang/ia/norev.txt
new file mode 100644
index 000000000..75e44b969
--- /dev/null
+++ b/inc/lang/ia/norev.txt
@@ -0,0 +1,3 @@
+====== Version non existe ======
+
+Le version specificate non existe. Usa le button "Versiones ancian" pro un lista de versiones ancian de iste documento. \ No newline at end of file
diff --git a/inc/lang/ia/password.txt b/inc/lang/ia/password.txt
new file mode 100644
index 000000000..9ad93d6ed
--- /dev/null
+++ b/inc/lang/ia/password.txt
@@ -0,0 +1,10 @@
+Salute @FULLNAME@!
+
+Ecce tu datos de usator pro @TITLE@ a @DOKUWIKIURL@
+
+Nomine de usator : @LOGIN@
+Contrasigno : @PASSWORD@
+
+--
+Iste message ha essite generate per DokuWiki a
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ia/preview.txt b/inc/lang/ia/preview.txt
new file mode 100644
index 000000000..22b958baf
--- /dev/null
+++ b/inc/lang/ia/preview.txt
@@ -0,0 +1,3 @@
+====== Previsualisation ======
+
+Isto es un previsualisation de tu texto. Memora: le pagina **non** ha ancora essite salveguardate! \ No newline at end of file
diff --git a/inc/lang/ia/pwconfirm.txt b/inc/lang/ia/pwconfirm.txt
new file mode 100644
index 000000000..a490f7929
--- /dev/null
+++ b/inc/lang/ia/pwconfirm.txt
@@ -0,0 +1,14 @@
+Salute @FULLNAME@!
+
+Alcuno ha requestate un nove contrasigno pro tu conto de @TITLE@
+a @DOKUWIKIURL@
+
+Si tu non ha requestate un nove contrasigno, alora simplemente ignora iste message.
+
+Pro confirmar que le requesta realmente ha essite inviate per te, per favor usa le ligamine sequente.
+
+@CONFIRM@
+
+--
+Iste message ha essite generate per DokuWiki a
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ia/read.txt b/inc/lang/ia/read.txt
new file mode 100644
index 000000000..e7e80dbfc
--- /dev/null
+++ b/inc/lang/ia/read.txt
@@ -0,0 +1 @@
+Iste pagina es pro lectura solmente. Tu pote vider le codice-fonte, ma non modificar lo. Contacta tu administrator si tu pensa que isto es errate. \ No newline at end of file
diff --git a/inc/lang/ia/recent.txt b/inc/lang/ia/recent.txt
new file mode 100644
index 000000000..ba39c3ff5
--- /dev/null
+++ b/inc/lang/ia/recent.txt
@@ -0,0 +1,3 @@
+====== Modificationes recente ======
+
+Le sequente paginas ha essite modificate recentemente. \ No newline at end of file
diff --git a/inc/lang/ia/register.txt b/inc/lang/ia/register.txt
new file mode 100644
index 000000000..22c4e4ada
--- /dev/null
+++ b/inc/lang/ia/register.txt
@@ -0,0 +1,3 @@
+====== Crear un nove conto de usator ======
+
+Completa tote le informationes hic infra pro crear un nove conto in iste wiki. Assecura te de fornir un **adresse de e-mail valide!** Si le systema non te demanda de entrar un contrasigno hic, un nove contrasigno essera inviate a iste adresse. Le nomine de usator debe esser un [[doku>pagename|nomine de pagina]] valide.
diff --git a/inc/lang/ia/registermail.txt b/inc/lang/ia/registermail.txt
new file mode 100644
index 000000000..c4e9d56bc
--- /dev/null
+++ b/inc/lang/ia/registermail.txt
@@ -0,0 +1,14 @@
+Un nove conto de usator ha essite create. Ecce le detalios:
+
+Nomine de usator : @NEWUSER@
+Nomine complete : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Data : @DATE@
+Navigator : @BROWSER@
+Adresse IP : @IPADDRESS@
+Nomine host : @HOSTNAME@
+
+--
+Iste message ha essite generate per DokuWiki a
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ia/resendpwd.txt b/inc/lang/ia/resendpwd.txt
new file mode 100644
index 000000000..97bcac02a
--- /dev/null
+++ b/inc/lang/ia/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Inviar nove contrasigno ======
+
+Per favor entra tu nomine de usator in le formulario hic infra pro requestar un nove contrasigno pro tu conto in iste wiki. Un ligamine de confirmation essera inviate a tu adresse de e-mail registrate. \ No newline at end of file
diff --git a/inc/lang/ia/revisions.txt b/inc/lang/ia/revisions.txt
new file mode 100644
index 000000000..e914edb61
--- /dev/null
+++ b/inc/lang/ia/revisions.txt
@@ -0,0 +1,3 @@
+====== Versiones ancian ======
+
+Ecce le versiones ancian del documento presente. Pro reverter lo a un version ancian, selige un version del lista in basso, clicca "Modificar iste pagina" e salveguarda lo. \ No newline at end of file
diff --git a/inc/lang/ia/searchpage.txt b/inc/lang/ia/searchpage.txt
new file mode 100644
index 000000000..c53683371
--- /dev/null
+++ b/inc/lang/ia/searchpage.txt
@@ -0,0 +1,5 @@
+====== Recerca ======
+
+Le resultatos de tu recerca se trova hic infra. Si tu non ha trovate lo que tu cerca, tu pote crear o modificar le pagina nominate secundo tu consulta con le button appropriate.
+
+===== Resultatos ===== \ No newline at end of file
diff --git a/inc/lang/ia/showrev.txt b/inc/lang/ia/showrev.txt
new file mode 100644
index 000000000..60ee2a7f6
--- /dev/null
+++ b/inc/lang/ia/showrev.txt
@@ -0,0 +1,2 @@
+**Isto es un version ancian del documento!**
+---- \ No newline at end of file
diff --git a/inc/lang/ia/stopwords.txt b/inc/lang/ia/stopwords.txt
new file mode 100644
index 000000000..e3e513509
--- /dev/null
+++ b/inc/lang/ia/stopwords.txt
@@ -0,0 +1,38 @@
+# Isto es un lista de parolas que le generator de indices ignora, un parola per linea.
+# Si tu modifica iste file, assecura te de usar le fines de linea UNIX (newline singule).
+# Non es necessari includer parolas plus curte que 3 characteres - istes es ignorate in omne caso.
+a
+ab
+circa
+com
+como
+como
+con
+de
+e
+es
+essera
+esserea
+esseva
+essite
+ex
+illo
+in
+iste
+istes
+le
+le
+les
+lo
+lor
+o
+pro
+quando
+que
+qui
+super
+sur
+tu
+ubi
+un
+www
diff --git a/inc/lang/ia/subscr_digest.txt b/inc/lang/ia/subscr_digest.txt
new file mode 100644
index 000000000..ba7b92d8b
--- /dev/null
+++ b/inc/lang/ia/subscr_digest.txt
@@ -0,0 +1,20 @@
+Salute!
+
+Le pagina @PAGE@ in le wiki @TITLE@ ha cambiate.
+Ecce le modificationes:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Version ancian: @OLDPAGE@
+Version nove: @NEWPAGE@
+
+Pro cancellar le notificationes de paginas, aperi un session al wiki a
+@DOKUWIKIURL@ postea visita
+@SUBSCRIBE@
+e cancella tu subscription al modificationes in paginas e/o spatios de nomines.
+
+--
+Iste message ha essite generate per DokuWiki a
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ia/subscr_form.txt b/inc/lang/ia/subscr_form.txt
new file mode 100644
index 000000000..f63a30d4c
--- /dev/null
+++ b/inc/lang/ia/subscr_form.txt
@@ -0,0 +1,4 @@
+====== Gestion de subscriptiones ======
+
+Iste pagina permitte gerer tu subscriptiones pro le pagina e spatio de nomines actual.
+ \ No newline at end of file
diff --git a/inc/lang/ia/subscr_list.txt b/inc/lang/ia/subscr_list.txt
new file mode 100644
index 000000000..9f93db252
--- /dev/null
+++ b/inc/lang/ia/subscr_list.txt
@@ -0,0 +1,17 @@
+Salute!
+
+Alcun paginas in le spatio de nomines @PAGE@ del wiki @TITLE@ ha cambiate.
+Ecce le paginas con modiicationes:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Pro cancellar le notificationes de paginas, aperi un session al wiki a
+@DOKUWIKIURL@ postea visita
+@SUBSCRIBE@
+e cancella tu subscription al modificationes in paginas e/o spatios de nomines.
+
+--
+Iste message ha essite generate per DokuWiki a
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ia/subscr_single.txt b/inc/lang/ia/subscr_single.txt
new file mode 100644
index 000000000..3d6ef7103
--- /dev/null
+++ b/inc/lang/ia/subscr_single.txt
@@ -0,0 +1,26 @@
+Salute!
+
+Le pagina @PAGE@ in le wiki @TITLE@ ha cambiate.
+Ecce le modificationes:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Data : @DATE@
+Usator : @USER@
+Summario: @SUMMARY@
+Version ancian: @OLDPAGE@
+Version nove: @NEWPAGE@
+
+Pro cancellar le notificationes de paginas, aperi un session al wiki a
+@DOKUWIKIURL@ postea visita
+@NEWPAGE@
+e cancella tu subscription al modificationes in paginas e/o spatios de nomines.
+
+--
+Iste message ha essite generate per DokuWiki a
+@DOKUWIKIURL@
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ia/updateprofile.txt b/inc/lang/ia/updateprofile.txt
new file mode 100644
index 000000000..3968d3cde
--- /dev/null
+++ b/inc/lang/ia/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Actualisa le profilo de tu conto ======
+
+Solmente es necessari completar le campos que tu vole cambiar. Non es possibile cambiar tu nomine de usator. \ No newline at end of file
diff --git a/inc/lang/ia/uploadmail.txt b/inc/lang/ia/uploadmail.txt
new file mode 100644
index 000000000..8f120f25b
--- /dev/null
+++ b/inc/lang/ia/uploadmail.txt
@@ -0,0 +1,14 @@
+Un file ha essite incargate in tu DokuWiki. Ecce le detalios:
+
+File : @MEDIA@
+Data : @DATE@
+Navigator : @BROWSER@
+Adresse IP : @IPADDRESS@
+Nomine host: @HOSTNAME@
+Dimension : @SIZE@
+Typo MIME : @MIME@
+Usator : @USER@
+
+--
+Iste message ha essite generate per DokuWiki a
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/id-ni/lang.php b/inc/lang/id-ni/lang.php
new file mode 100644
index 000000000..9c04f0259
--- /dev/null
+++ b/inc/lang/id-ni/lang.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Haogö nga\'örö da\'a';
+$lang['btn_source'] = 'Oroma\'ö nga\'örö sindruhu';
+$lang['btn_show'] = 'Foroma\'ö nga\'örö';
+$lang['btn_create'] = 'Fazökhi nga\'öro';
+$lang['btn_search'] = 'Alui';
+$lang['btn_save'] = 'Irö\'ö';
+$lang['btn_preview'] = 'Foroma\'ö zikhala';
+$lang['btn_top'] = 'Angawuli ba mböröta';
+$lang['btn_newer'] = '<< sibohou';
+$lang['btn_older'] = 'si no ara >>';
+$lang['btn_revs'] = 'nifawu\'a si\'oföna';
+$lang['btn_recent'] = 'Lahe nibohouni';
+$lang['btn_upload'] = 'Fa\'oeh\'ö';
+$lang['btn_cancel'] = 'Lö alua';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit'] = 'Ehaogö';
+$lang['btn_login'] = 'Felalö bakha';
+$lang['btn_logout'] = 'Möi baero';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Bohouni';
+$lang['btn_delete'] = 'Heta';
+$lang['btn_back'] = 'Fulifuri';
+$lang['btn_backlink'] = 'Link fangawuli';
+$lang['btn_backtomedia'] = 'Angawuli ba filianö Mediafile';
+$lang['btn_profile'] = 'Famohouni pörofile';
+$lang['btn_reset'] = 'Fawu\'a';
+$lang['btn_resendpwd'] = 'Fa\'ohe\'ö kode sibohou';
+$lang['btn_draft'] = 'Fawu\'a wanura';
+$lang['btn_draftdel'] = 'Heta zura';
+$lang['btn_register'] = 'Fasura\'ö';
+$lang['loggedinas'] = 'Möi bakha zotöi';
+$lang['user'] = 'Töi';
+$lang['pass'] = 'Kode';
+$lang['newpass'] = 'Kode sibohou';
+$lang['oldpass'] = 'Faduhu\'ö kode';
+$lang['passchk'] = 'Sura sakalitö';
+$lang['remember'] = 'Töngöni ndra\'o';
+$lang['fullname'] = 'Töi safönu';
+$lang['email'] = 'Imele';
+$lang['profile'] = 'Töi pörofile';
+$lang['badlogin'] = 'Bologö dödöu, fasala döi faoma kode.';
+$lang['minoredit'] = 'Famawu\'a ma\'ifu';
+$lang['regmissing'] = 'Bologö dödöu, si lö tola lö\'ö öfo\'ösi fefu nahia si tohöna.';
+$lang['reguexists'] = 'Bologö dödöu, no so zangoguna\'ö töi da\'a.';
+$lang['regsuccess'] = 'No tefazökhi akunö ba tefa\'ohe\'ö kode ba imele.';
+$lang['regsuccess2'] = 'No tefazökhi akunö';
+$lang['regmailfail'] = 'Oroma wa so ma\'ifu zifawuka ba wama\'ohe\'ö imele kode. Fuli sofu khö admin!';
+$lang['regbadmail'] = 'Imele nibe\'emö lö atulö - na ö\'ila wa fasala da\'a, sofu khö admin';
+$lang['regbadpass'] = 'Dombuadombua kode nibe\'emö lö fagölö, fuli sura.';
+$lang['regpwmail'] = 'Kode DokuWiki';
+$lang['reghere'] = 'Hadia no so akunömö? Na lö\'ö, fazökhi sambua.';
+$lang['profna'] = 'Lö tetehegö ba wiki da\'a ba wamawu\'a pörofile';
+$lang['profnochange'] = 'Lö hadöi nifawu\'ö, lö hadöi ni\'ohalöwögöi';
+$lang['profnoempty'] = 'Lö tetehegö na lö hadöi töi ma imele.';
+$lang['profchanged'] = 'Pörofile zangoguna\'ö no tebohouni.';
+$lang['pwdforget'] = 'Hadia olifu\'ö kode? Fuli halö kode';
+$lang['resendna'] = 'Lö tetehegi ba wiki da\'a wama\'ohe\'ö kode dua kali.';
+$lang['resendpwd'] = 'Tefa\'ohe\'ö kode sibahou khö';
+$lang['resendpwdmissing'] = 'Bologö dödöu, si lö tola lö\'ö öfo\'ösi fefu nahia si tohöna.';
+$lang['resendpwdnouser'] = 'Bologö dödöu, lö masöndra zangoguna da\'a ba database.';
+$lang['resendpwdconfirm'] = 'No tefaohe\'ö link famaduhu\'ö ba imele.';
+$lang['resendpwdsuccess'] = 'No tefa\'ohe\'ö kode sibohou ba imele.';
+$lang['txt_upload'] = 'Fili file ni fa\'ohe\'ö';
+$lang['js']['notsavedyet'] = "Famawu\'a si lö mu\'irö\'ö taya. \nSinduhu ötohugö?";
+$lang['mediaselect'] = 'Media file';
diff --git a/inc/lang/id/admin.txt b/inc/lang/id/admin.txt
new file mode 100644
index 000000000..8cb25edb6
--- /dev/null
+++ b/inc/lang/id/admin.txt
@@ -0,0 +1,4 @@
+====== Administrasi ======
+
+Berikut ini adalah daftar pekerjaan administratif yang dapat Anda temukan di DokuWiki.
+
diff --git a/inc/lang/id/backlinks.txt b/inc/lang/id/backlinks.txt
new file mode 100644
index 000000000..79c70f30b
--- /dev/null
+++ b/inc/lang/id/backlinks.txt
@@ -0,0 +1,3 @@
+====== Backlinks ======
+
+Daftar dibawah ini adalah halaman-halaman (lain) yang terhubung ke halaman ini.
diff --git a/inc/lang/id/conflict.txt b/inc/lang/id/conflict.txt
new file mode 100644
index 000000000..236e8b6e9
--- /dev/null
+++ b/inc/lang/id/conflict.txt
@@ -0,0 +1,6 @@
+====== Versi terbaru telah Ada ======
+
+Versi terbaru dari dokumen yang baru saja Anda Edit telah ada. Ini terjadi ketika user lain telah selesai mengubah halaman, saat Anda sedang meng-edit.
+
+Pertimbangkan perbedaan yang ditampilkan dibawah ini, kemudian putuskan versi mana yang harus disimpan. Jika Anda memilih "Simpan", versi (tulisan terbaru) Andalah yang akan disimpan. Tekan "Batal" to menggunakan versi tulisan yang telah ada.
+
diff --git a/inc/lang/id/denied.txt b/inc/lang/id/denied.txt
new file mode 100644
index 000000000..bad8f24a6
--- /dev/null
+++ b/inc/lang/id/denied.txt
@@ -0,0 +1,4 @@
+====== Akses Ditolak ======
+
+Maaf, Anda tidak mempunyai hak akses untuk melanjutkan. Apakah Anda belum login?
+
diff --git a/inc/lang/id/diff.txt b/inc/lang/id/diff.txt
new file mode 100644
index 000000000..eee1e5a58
--- /dev/null
+++ b/inc/lang/id/diff.txt
@@ -0,0 +1,4 @@
+====== Perbedaan ======
+
+Ini menunjukkan perbedaan antara versi yang terpilih dengan versi yang sedang aktif.
+
diff --git a/inc/lang/id/draft.txt b/inc/lang/id/draft.txt
new file mode 100644
index 000000000..d7de1458b
--- /dev/null
+++ b/inc/lang/id/draft.txt
@@ -0,0 +1,5 @@
+====== File Draft ditemukan ======
+
+Proses pengeditan Anda sebelumnya tidak selesai dengan sempurna. DokuWiki secara otomatis meyimpan draft yang dapat Anda pakai untuk melanjutkan pengeditan. Dibawah ini Anda dapat melihat data yang disimpan pada sesi sebelumnya.
+
+Silahkan pilih jika Anda ingin //recover// sesi pengeditan terakhir atau //hapus// draft, atau //batalkan// proses pengeditan.
diff --git a/inc/lang/id/edit.txt b/inc/lang/id/edit.txt
new file mode 100644
index 000000000..a32803c44
--- /dev/null
+++ b/inc/lang/id/edit.txt
@@ -0,0 +1,2 @@
+Ubah isi halaman kemudian tekan "Simpan". Lihat [[wiki:syntax]] untuk sintaks-sintaks Wiki. Mohon edit/ubah halaman sesuai dengan judul halamannya. Bila Anda masih ragu untuk menulis di halaman ini, silahkan bermain-main di [[playground:playground|tamanbermain]].
+
diff --git a/inc/lang/id/editrev.txt b/inc/lang/id/editrev.txt
new file mode 100644
index 000000000..e6d247c7a
--- /dev/null
+++ b/inc/lang/id/editrev.txt
@@ -0,0 +1,2 @@
+**Anda telah membuka dokumen versi lama!** Jika menyimpannya, berarti Anda akan membuat versi baru dari data ini.
+---- \ No newline at end of file
diff --git a/inc/lang/id/index.txt b/inc/lang/id/index.txt
new file mode 100644
index 000000000..88bbb12e4
--- /dev/null
+++ b/inc/lang/id/index.txt
@@ -0,0 +1,4 @@
+====== Index ======
+
+Berikut ini adalah index dari keseluruhan halaman yang ada, diurutkan berdasar [[doku>namespaces|namespaces]].
+
diff --git a/inc/lang/id/install.html b/inc/lang/id/install.html
new file mode 100644
index 000000000..9a9a8f1e9
--- /dev/null
+++ b/inc/lang/id/install.html
@@ -0,0 +1,25 @@
+<p>Halaman ini membatu Anda dalam proses instalasi dan konfigurasi pertama kali
+untuk <a href="http://dokuwiki.org">Dokuwiki</a>. Informasi lebih lanjut
+tentang alat instalasi ini tersedia dalam
+<a href="http://dokuwiki.org/installer">halaman dokumentasi</a> sendiri.</p>
+
+<p>DokuWIki menggunakan berkas biasa sebagai media penyimpanan halaman wiki
+dan informasi lainnya yang berhubungan dengan halaman tersebut (contoh: gambar,
+indeks pencarian, revisi lama, dll). Agar bisa menggunakannya DokuWiki
+<strong>harus</strong> memiliki hak akses tulis pada direktori yang menyimpan
+berkas-berkas tersebut. Alat instalasi ini tidak dapat melakukan perubahan
+konfigurasi hak akses pada direktori. Biasanya harus menggunakan command shell
+atau jika Anda pengguna layanan hosting, melalui FTP atau control panel layanan
+hosting Anda (misalnya: cPanel). </p>
+
+<p>Alat instalasi ini akan mengatur konfigurasi DokuWiki Anda untuk
+<acronym title="access control list">ACL</acronym>, yang selanjutnya akan
+memperbolehkan administrator untuk login dan mengakses menu Admin DokuWiki
+untuk menginstal plugin, mengatur pengguna (user), mengatur hak akses ke
+halaman wiki dan perubahan konfigurasi. Ini tidak diawajibkan dalam pengoperasian
+DokuWiki, tetapi dapat membuat DokuWiki lebih mudah untuk dipelihara.</p>
+
+<p>Pengguna berpengalaman atau pengguna dengan kebutuhan instalasi khusus silahkan
+melihat link <a href="http://dokuwiki.org/install">Panduan Instalasi</a>
+and <a href="http://dokuwiki.org/config">Konfigurasi WIki</a>.
+untuk hal-hal yang berhubungan dengan instalasi dan konfigurasi.</p>
diff --git a/inc/lang/id/lang.php b/inc/lang/id/lang.php
new file mode 100644
index 000000000..9df252225
--- /dev/null
+++ b/inc/lang/id/lang.php
@@ -0,0 +1,199 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author mubaidillah <mubaidillah@gmail.com>
+ * @author Irwan Butar Butar <irwansah.putra@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '"';
+$lang['doublequoteclosing'] = '"';
+$lang['singlequoteopening'] = '\'';
+$lang['singlequoteclosing'] = '\'';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Edit halaman ini';
+$lang['btn_source'] = 'Lihat sumber halaman';
+$lang['btn_show'] = 'Tampilkan halaman';
+$lang['btn_create'] = 'Buat halaman baru';
+$lang['btn_search'] = 'Cari';
+$lang['btn_save'] = 'Simpan';
+$lang['btn_preview'] = 'Preview';
+$lang['btn_top'] = 'kembali ke atas';
+$lang['btn_newer'] = '<< lebih lanjut';
+$lang['btn_older'] = 'sebelumnya >>';
+$lang['btn_revs'] = 'Revisi-revisi lama';
+$lang['btn_recent'] = 'Perubahan terbaru';
+$lang['btn_upload'] = 'Upload';
+$lang['btn_cancel'] = 'Batal';
+$lang['btn_index'] = 'Indeks';
+$lang['btn_secedit'] = 'Edit';
+$lang['btn_login'] = 'Login';
+$lang['btn_logout'] = 'Keluar';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Ubah';
+$lang['btn_delete'] = 'Hapus';
+$lang['btn_back'] = 'Kembali';
+$lang['btn_backlink'] = 'Backlinks';
+$lang['btn_backtomedia'] = 'Kembali ke Pilihan Mediafile';
+$lang['btn_subscribe'] = 'Ikuti Perubahan';
+$lang['btn_unsubscribe'] = 'Berhenti Ikuti Perubahan';
+$lang['btn_profile'] = 'Ubah Profil';
+$lang['btn_reset'] = 'Reset';
+$lang['btn_resendpwd'] = 'Kirim password baru';
+$lang['btn_draft'] = 'Edit draft';
+$lang['btn_draftdel'] = 'Hapus draft';
+$lang['btn_register'] = 'Daftar';
+$lang['loggedinas'] = 'Login sebagai ';
+$lang['user'] = 'Username';
+$lang['pass'] = 'Password';
+$lang['newpass'] = 'Password baru';
+$lang['oldpass'] = 'Konfirmasi password';
+$lang['passchk'] = 'sekali lagi';
+$lang['remember'] = 'Ingat saya';
+$lang['fullname'] = 'Nama lengkap';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'Profil User';
+$lang['badlogin'] = 'Maaf, username atau password salah.';
+$lang['minoredit'] = 'Perubahan Minor';
+$lang['draftdate'] = 'Simpan draft secara otomatis';
+$lang['regmissing'] = 'Maaf, Anda harus mengisi semua field.';
+$lang['reguexists'] = 'Maaf, user dengan user login ini telah ada.';
+$lang['regsuccess'] = 'User telah didaftarkan dan password telah dikirim ke email Anda.';
+$lang['regsuccess2'] = 'User telah dibuatkan.';
+$lang['regmailfail'] = 'Kami menemukan kesalahan saat mengirimkan password ke alamat email Anda. Mohon hubungi administrator.';
+$lang['regbadmail'] = 'Alamat email yang Anda masukkan tidak valid - jika menurut Anda hal ini adalah kesalahan sistem, mohon hubungi admin.';
+$lang['regbadpass'] = 'Passwod yang dimasukkan tidak sama. Silahkan ulangi lagi.';
+$lang['regpwmail'] = 'Password DokuWiki Anda';
+$lang['reghere'] = 'Anda belum mempunyai account? silahkan ';
+$lang['profna'] = 'Wiki ini tidak mengijinkan perubahan profil.';
+$lang['profnochange'] = 'Tidak ada perubahan.';
+$lang['profnoempty'] = 'Mohon mengisikan nama atau alamat email.';
+$lang['profchanged'] = 'Profil User berhasil diubah.';
+$lang['pwdforget'] = 'Lupa Password? Dapatkan yang baru';
+$lang['resendna'] = 'Wiki ini tidak mendukung pengiriman ulang password.';
+$lang['resendpwd'] = 'Kirim password baru untuk';
+$lang['resendpwdmissing'] = 'Maaf, Anda harus mengisikan semua field.';
+$lang['resendpwdnouser'] = 'Maaf, user ini tidak ditemukan.';
+$lang['resendpwdbadauth'] = 'Maaf, kode autentikasi tidak valid. Pastikan Anda menggunakan keseluruhan link konfirmasi.';
+$lang['resendpwdconfirm'] = 'Link konfirmasi telah dikirim melalui email.';
+$lang['resendpwdsuccess'] = 'Password baru Anda telah dikirim melalui email.';
+$lang['txt_upload'] = 'File yang akan diupload';
+$lang['txt_filename'] = 'Masukkan nama wiki (opsional)';
+$lang['txt_overwrt'] = 'File yang telah ada akan ditindih';
+$lang['lockedby'] = 'Sedang dikunci oleh';
+$lang['lockexpire'] = 'Penguncian artikel sampai dengan';
+$lang['js']['willexpire'] = 'Halaman yang sedang Anda kunci akan berakhir dalam waktu kurang lebih satu menit.\nUntuk menghindari konflik, gunakan tombol Preview untuk me-reset timer pengunci.';
+$lang['js']['notsavedyet'] = "Perubahan yang belum disimpan akan hilang.\nYakin akan dilanjutkan?";
+$lang['rssfailed'] = 'Error terjadi saat mengambil feed: ';
+$lang['nothingfound'] = 'Tidak menemukan samasekali.';
+$lang['mediaselect'] = 'Pilihan Mediafile';
+$lang['fileupload'] = 'Mediafile Upload';
+$lang['uploadsucc'] = 'Upload sukses';
+$lang['uploadfail'] = 'Upload gagal. Apakah hak ijinnya salah?';
+$lang['uploadwrong'] = 'Upload ditolak. Ekstensi file ini tidak diperbolehkan!';
+$lang['uploadexist'] = 'File telah ada. Tidak mengerjakan apa-apa.';
+$lang['uploadbadcontent'] = 'Isi file yang diupload tidak cocok dengan ekstensi file %s.';
+$lang['uploadspam'] = 'File yang diupload diblok oleh spam blacklist.';
+$lang['uploadxss'] = 'File yang diupload diblok karena kemungkinan isi yang berbahaya.';
+$lang['deletesucc'] = 'File "%s" telah dihapus.';
+$lang['deletefail'] = '"%s" tidak dapat dihapus - cek hak aksesnya.';
+$lang['mediainuse'] = 'File "%s" belum dihapus - file ini sedang digunakan.';
+$lang['namespaces'] = 'Namespaces';
+$lang['mediafiles'] = 'File tersedia didalam';
+$lang['js']['keepopen'] = 'Biarkan window terbuka dalam pemilihan';
+$lang['js']['hidedetails'] = 'Sembunyikan detil';
+$lang['mediausage'] = 'Gunakan sintaks berikut untuk me-refer ke file ini';
+$lang['mediaview'] = 'Tampilkan file asli';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Upload file ke namespace ini. Untuk menbuat namespace baru, tambahkan namanya didepanpada nama file "Upload as" dipisahkan dengan titik dua (:).';
+$lang['mediaextchange'] = 'Ektensi file berubah dari .%s ke .%s';
+$lang['reference'] = 'Referensi untuk';
+$lang['ref_inuse'] = 'File tidak dapat dihapus karena sedang digunakan oleh halaman:';
+$lang['ref_hidden'] = 'Beberapa referensi ada didalam halaman yang tidak diijinkan untuk Anda baca.';
+$lang['hits'] = 'Hits';
+$lang['quickhits'] = 'Matching pagenames';
+$lang['toc'] = 'Daftar isi';
+$lang['current'] = 'sekarang';
+$lang['yours'] = 'Versi Anda';
+$lang['diff'] = 'Tampilkan perbedaan dengan versi sekarang';
+$lang['diff2'] = 'Tampilkan perbedaan diantara revisi terpilih';
+$lang['line'] = 'Baris';
+$lang['breadcrumb'] = 'Jejak';
+$lang['youarehere'] = 'Anda disini';
+$lang['lastmod'] = 'Terakhir diubah';
+$lang['by'] = 'oleh';
+$lang['deleted'] = 'terhapus';
+$lang['created'] = 'dibuat';
+$lang['restored'] = 'revisi lama ditampilkan kembali';
+$lang['external_edit'] = 'Perubahan eksternal';
+$lang['summary'] = 'Edit summary';
+$lang['mail_newpage'] = 'Halaman ditambahkan:';
+$lang['mail_changed'] = 'Halaman diubah:';
+$lang['mail_new_user'] = 'User baru:';
+$lang['mail_upload'] = 'Berkas di-upload:';
+$lang['js']['nosmblinks'] = "Link ke share Windows hanya bekerja di Microsoft Internet Explorer.\nAnda masih dapat mengcopy and paste linknya.";
+$lang['qb_bold'] = 'Tebal';
+$lang['qb_italic'] = 'Miring';
+$lang['qb_underl'] = 'Garis Bawah';
+$lang['qb_code'] = 'Kode';
+$lang['qb_strike'] = 'Text Tercoret';
+$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_link'] = 'Link Internal';
+$lang['qb_extlink'] = 'Link External';
+$lang['qb_hr'] = 'Garis Horisontal';
+$lang['qb_ol'] = 'Item Berurutan';
+$lang['qb_ul'] = 'Item Tidak Berurutan';
+$lang['qb_media'] = 'Tambahkan gambar atau file lain';
+$lang['qb_sig'] = 'Sisipkan tanda tangan';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Karakter Khusus';
+$lang['js']['del_confirm'] = 'Hapus tulisan ini?';
+$lang['admin_register'] = 'Tambah user baru';
+$lang['metaedit'] = 'Edit Metadata';
+$lang['metasaveerr'] = 'Gagal menulis metadata';
+$lang['metasaveok'] = 'Metadata tersimpan';
+$lang['img_backto'] = 'Kembali ke';
+$lang['img_title'] = 'Judul';
+$lang['img_caption'] = 'Label';
+$lang['img_date'] = 'Tanggal';
+$lang['img_fname'] = 'Nama file';
+$lang['img_fsize'] = 'Ukuran';
+$lang['img_artist'] = 'Tukang foto';
+$lang['img_copyr'] = 'Hakcipta';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Katakunci';
+$lang['subscribe_success'] = 'Penambahan %s ke data subsripsi untuk %s';
+$lang['subscribe_error'] = 'Gagal menambahkan %s ke data subsripsi untuk %s';
+$lang['subscribe_noaddress'] = 'Tidak ditemukan alamat yang berhubungan dengan login Anda, Anda tidak dapat menambahkan daftar subscription';
+$lang['unsubscribe_success'] = 'Menghapus %s dari daftar subscription untuk %s';
+$lang['unsubscribe_error'] = 'Gagal menghapus %s dari daftar subscription untuk %s';
+$lang['authmodfailed'] = 'Konfigurasi autentikasi user tidak valid. Harap informasikan admin Wiki Anda.';
+$lang['authtempfail'] = 'Autentikasi user saat ini sedang tidak dapat digunakan. Jika kejadian ini berlanjut, Harap informasikan admin Wiki Anda.';
+$lang['i_chooselang'] = 'Pilih bahasa';
+$lang['i_installer'] = 'Instalasi DokuWiki';
+$lang['i_wikiname'] = 'Nama Wiki';
+$lang['i_enableacl'] = 'Aktifkan ACL (disarankan)';
+$lang['i_problems'] = 'Terdapat beberapa kesalahan seperti berikut. Anda tidak dapat melanjutkan sampai kesalahan tersebut diperbaiki.';
+$lang['i_modified'] = 'Untuk alasan keamanan, skrip ini hanya dapat dijalankan pada instalasi DikuWiki baru dan belum di modifikasi. Silahkan meng-ekstrak kembali berkasi dari halaman dowload, atau lihat <a href="http://dokuwiki.org/install">Dokuwiki installation instructions</a> ';
+$lang['i_funcna'] = 'Fungsi PHP <code>%s</code> tidak tersedia. Mungkin dinonaktifkan oleh layanan hosting Anda?';
+$lang['i_phpver'] = 'Versi PHP Anda <code>%s</code> lebih rendah dari yang dibutuhkan <code>%s</code>. Mohon melakukan upgrade.';
+$lang['i_permfail'] = '<code>%s</code> tidak dapat ditulis oleh DokuWiki. Anda harus memperbaiki konfigurasi hak akses untuk direktori tersebut.';
+$lang['i_confexists'] = '<code>%s</code> sudah ada';
+$lang['i_writeerr'] = 'Tidak dapat membuat <code>%s</code>. Anda harus memeriksa konfigurasi hak akses direktori/berkas dan membuatnya secara manual.';
+$lang['i_badhash'] = 'dokuwiki.php tidak dikenal atau sudah diubah (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - tidak valid atau belum diisi';
+$lang['i_success'] = 'Konfigurasi telah berhasil. Anda boleh menghapus berkas install.php sekarang. Lanjutkan ke <a href="doku.php">DokuWiki baru Anda</a>.';
+$lang['i_failure'] = 'Terdapat beberapa kesalahan dalam menulis berkas konfigurasi. Anda harus memperbaikinnya sendiri sebelum dapat menggunakan <a href="doku.php">DokuWiki baru Anda</a>.';
+$lang['i_policy'] = 'Policy ACL awal';
+$lang['i_pol0'] = 'Wiki Terbuka (baca, tulis, upload untuk semua orang)';
+$lang['i_pol1'] = 'Wiki Publik (baca untuk semua orang, tulis dan upload untuk pengguna terdaftar)';
+$lang['i_pol2'] = 'Wiki Privat (baca, tulis dan upload hanya untuk pengguna terdaftar)';
+$lang['i_retry'] = 'Coba Lagi';
diff --git a/inc/lang/id/locked.txt b/inc/lang/id/locked.txt
new file mode 100644
index 000000000..8147717fd
--- /dev/null
+++ b/inc/lang/id/locked.txt
@@ -0,0 +1,3 @@
+====== Halaman Terkunci ======
+
+Halaman ini tertutup (terkunci) untuk diedit oleh user lain. Anda harus menunggu sampai user ini menyelesaikan pengeditan, atau masa berlaku penguncian telah berakhir.
diff --git a/inc/lang/id/login.txt b/inc/lang/id/login.txt
new file mode 100644
index 000000000..f736e882b
--- /dev/null
+++ b/inc/lang/id/login.txt
@@ -0,0 +1,4 @@
+====== Login ======
+
+Anda belum login! Masukkan data autentifikasi dibawah ini untuk masuk log (login). Cookies harus diaktifkan agar bisa login.
+
diff --git a/inc/lang/id/mailtext.txt b/inc/lang/id/mailtext.txt
new file mode 100644
index 000000000..7eede9b3c
--- /dev/null
+++ b/inc/lang/id/mailtext.txt
@@ -0,0 +1,17 @@
+Halaman di DokuWiki Anda telah bertamah atau berubah, dengan detil sebagai berikut:
+
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+Old Revision: @OLDPAGE@
+New Revision: @NEWPAGE@
+Edit Summary: @SUMMARY@
+User : @USER@
+
+@DIFF@
+
+
+--
+Email ini digenerate oleh DokuWiki di
+@DOKUWIKIURL@
diff --git a/inc/lang/id/newpage.txt b/inc/lang/id/newpage.txt
new file mode 100644
index 000000000..8d3f99d72
--- /dev/null
+++ b/inc/lang/id/newpage.txt
@@ -0,0 +1,3 @@
+====== Topik ini belum tersedia ======
+
+Belum ada artikel di halaman ini. Anda dapat membuat tulisan-tulisan baru di halaman ini dengan menekan tombol "Buat Halaman Baru" (lihat dibagian bawah...!)
diff --git a/inc/lang/id/norev.txt b/inc/lang/id/norev.txt
new file mode 100644
index 000000000..5244f8303
--- /dev/null
+++ b/inc/lang/id/norev.txt
@@ -0,0 +1,4 @@
+====== Revisi tidak tersedia ======
+
+Revisi yang diinginkan tidak ada. Gunakan tombol ''Revisi Lama'' untuk menampilkan daftar revisi lama dari dokumen ini.
+
diff --git a/inc/lang/id/password.txt b/inc/lang/id/password.txt
new file mode 100644
index 000000000..2e64b8dc3
--- /dev/null
+++ b/inc/lang/id/password.txt
@@ -0,0 +1,10 @@
+Hi @FULLNAME@!
+
+Berikut data Anda untuk @TITLE@ di @DOKUWIKIURL@
+
+Login : @LOGIN@
+Password : @PASSWORD@
+
+--
+Email ini dibuat otomatis oleh DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/id/preview.txt b/inc/lang/id/preview.txt
new file mode 100644
index 000000000..1621946b1
--- /dev/null
+++ b/inc/lang/id/preview.txt
@@ -0,0 +1,4 @@
+====== Preview ======
+
+Ini adalah preview tentang bagimana tulisan Anda akan ditampilkan. Ingat: tulisan ini **belum disimpan**!
+
diff --git a/inc/lang/id/pwconfirm.txt b/inc/lang/id/pwconfirm.txt
new file mode 100644
index 000000000..19131ee47
--- /dev/null
+++ b/inc/lang/id/pwconfirm.txt
@@ -0,0 +1,13 @@
+Hai @FULLNAME@!
+
+Seseorang telah meminta password baru untuk @TITLE@ Anda login ke @DOKUWIKIURL@
+
+Jika Anda tidak meminta password baru, mohon mengacuhkan email ini.
+
+Untuk mengkonfirmasi bahwa permintaan tersebut adalah benar dari Anda, silahkan gunakan link dibawah.
+
+@CONFIRM@
+
+--
+Email ini dibuat otomatis oleh DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/id/read.txt b/inc/lang/id/read.txt
new file mode 100644
index 000000000..f78c0eb9d
--- /dev/null
+++ b/inc/lang/id/read.txt
@@ -0,0 +1,2 @@
+Halaman ini hanya bisa dibaca. Anda bisa melihat sumbernya, tetapi tidak diperkenankan untuk mengubah. Hubungi administrator jika menemukan kesalahan pada halaman ini.
+
diff --git a/inc/lang/id/recent.txt b/inc/lang/id/recent.txt
new file mode 100644
index 000000000..f7cf24443
--- /dev/null
+++ b/inc/lang/id/recent.txt
@@ -0,0 +1,5 @@
+====== Perubahan ======
+
+Berikut ini adalah halaman-halaman yang baru saja diubah.
+
+
diff --git a/inc/lang/id/register.txt b/inc/lang/id/register.txt
new file mode 100644
index 000000000..dd8c578f0
--- /dev/null
+++ b/inc/lang/id/register.txt
@@ -0,0 +1,4 @@
+====== Mendaftar sebagai anggota baru ======
+
+Isikan semua informasi dibawah ini untuk membuat account baru di wiki ini. Pastikan Anda telah mengisikan **alamat email yang valid**, karena password akan dikirim melalui email ini. Nama login harus sesuai dengan aturan [[doku>pagename|pagename]].
+
diff --git a/inc/lang/id/registermail.txt b/inc/lang/id/registermail.txt
new file mode 100644
index 000000000..ed8c97ca3
--- /dev/null
+++ b/inc/lang/id/registermail.txt
@@ -0,0 +1,14 @@
+User baru telah mendaftar. Berikut detailnya:
+
+User name : @NEWUSER@
+Full name : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+
+--
+Email ini dibuat otomatis oleh DokuWIki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/id/resendpwd.txt b/inc/lang/id/resendpwd.txt
new file mode 100644
index 000000000..276b2928f
--- /dev/null
+++ b/inc/lang/id/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Kirim Password Baru ======
+
+Masukkan nama user Anda pada form dibawah untuk permintaan perubahan password account Anda di Wiki ini. Link konfirmasi akan dikirimkan melalui alamat email Anda sewaktu registrasi.
diff --git a/inc/lang/id/revisions.txt b/inc/lang/id/revisions.txt
new file mode 100644
index 000000000..d82b2735f
--- /dev/null
+++ b/inc/lang/id/revisions.txt
@@ -0,0 +1,4 @@
+====== Revisi Lama ======
+
+Ini adalah revisi-revisi lama dari dokumen ini. Untuk mengaktifkan kembali revisi lama, pilih dokumen revisi, kemudikan tekan "Edit halaman ini" lalu Simpan.
+
diff --git a/inc/lang/id/searchpage.txt b/inc/lang/id/searchpage.txt
new file mode 100644
index 000000000..c47bed7dc
--- /dev/null
+++ b/inc/lang/id/searchpage.txt
@@ -0,0 +1,5 @@
+====== Pencarian ======
+
+Anda dapat menemukan hasil pencarian dibawah ini. Jika Anda tidak menemukan apa yang diinginkan, Anda dapat membuat halaman baru, dengan nama sesuai "text pencarian" Anda. Gunakan tombol "Edit halaman ini".
+
+===== Hasil Pencarian ===== \ No newline at end of file
diff --git a/inc/lang/id/showrev.txt b/inc/lang/id/showrev.txt
new file mode 100644
index 000000000..27f0c6421
--- /dev/null
+++ b/inc/lang/id/showrev.txt
@@ -0,0 +1,2 @@
+**Ini adalah dokumen versi lama!**
+----
diff --git a/inc/lang/id/stopwords.txt b/inc/lang/id/stopwords.txt
new file mode 100644
index 000000000..73713c838
--- /dev/null
+++ b/inc/lang/id/stopwords.txt
@@ -0,0 +1,37 @@
+# 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
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
+yang
+dan
+adalah
+untuk
+lalu
+maka
+kemudian
+jika
diff --git a/inc/lang/id/updateprofile.txt b/inc/lang/id/updateprofile.txt
new file mode 100644
index 000000000..b7f71a198
--- /dev/null
+++ b/inc/lang/id/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Ubah Profil Account Anda ======
+
+Anda hanya perlu mengisikan field yang ingin Anda ubah. Anda tidak dapat mengubah username Anda.
diff --git a/inc/lang/id/uploadmail.txt b/inc/lang/id/uploadmail.txt
new file mode 100644
index 000000000..dc628fc11
--- /dev/null
+++ b/inc/lang/id/uploadmail.txt
@@ -0,0 +1,14 @@
+Sebuah file telah diupload di DokuWiki Anda. Berikut detailnya:
+
+File : @MEDIA@
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+Size : @SIZE@
+MIME Type : @MIME@
+User : @USER@
+
+--
+Email ini dibuat otomatis oleh DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/is/adminplugins.txt b/inc/lang/is/adminplugins.txt
new file mode 100644
index 000000000..ce7b9d390
--- /dev/null
+++ b/inc/lang/is/adminplugins.txt
@@ -0,0 +1 @@
+===== Aðrar viðbætur ===== \ No newline at end of file
diff --git a/inc/lang/is/diff.txt b/inc/lang/is/diff.txt
new file mode 100644
index 000000000..a6d246ad7
--- /dev/null
+++ b/inc/lang/is/diff.txt
@@ -0,0 +1,3 @@
+===== Breytingar =====
+
+Hér sést hvað hefur breyst á milli útgáfna. \ No newline at end of file
diff --git a/inc/lang/is/lang.php b/inc/lang/is/lang.php
new file mode 100644
index 000000000..caf098ee6
--- /dev/null
+++ b/inc/lang/is/lang.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * is language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesIs.php?view=co
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Breyta þessari síðu';
+$lang['btn_source'] = 'Skoða wikikóða';
+$lang['btn_show'] = 'Sýna síðu';
+$lang['btn_create'] = 'Búa til þessa síðu';
+$lang['btn_search'] = 'Leit';
+$lang['btn_save'] = 'Vista';
+$lang['btn_preview'] = 'Forskoða';
+$lang['btn_top'] = 'Efst á síðu';
+$lang['btn_newer'] = '<< nýrra';
+$lang['btn_older'] = 'eldra >>';
+$lang['btn_revs'] = 'breytingaskrá';
+$lang['btn_recent'] = 'Nýlegar breytingar';
+$lang['btn_upload'] = 'Hlaða upp';
+$lang['btn_cancel'] = 'Hætta við';
+$lang['btn_index'] = 'Atriðaskrá';
+$lang['btn_secedit'] = 'Breyta';
+$lang['btn_login'] = 'Innskrá';
+$lang['btn_logout'] = 'Útskrá';
+$lang['btn_admin'] = 'Stjórnandi';
+$lang['btn_update'] = 'Uppfæra';
+$lang['btn_delete'] = 'Eyða';
+$lang['btn_back'] = 'Til baka';
+$lang['btn_backlink'] = 'Hvað tengist hingað';
+$lang['btn_backtomedia'] = 'Aftur til miðlaskrá';
+$lang['btn_subscribe'] = 'Vakta';
+$lang['btn_unsubscribe'] = 'Afvakta';
+$lang['btn_profile'] = 'Uppfæra notanda';
+$lang['btn_reset'] = 'Endurstilla';
+$lang['btn_resendpwd'] = 'Senda nýtt aðgangsorð með tölvupósti';
+$lang['btn_draft'] = 'Breyta uppkasti';
+$lang['btn_recover'] = 'Endurheimta uppkast';
+$lang['btn_draftdel'] = 'Eyða uppkasti';
+$lang['btn_revert'] = 'Endurheimta';
+$lang['btn_register'] = 'Skráning';
+$lang['loggedinas'] = 'Innskráning sem';
+$lang['user'] = 'Notendanafn';
+$lang['pass'] = 'Aðgangsorð';
+$lang['newpass'] = 'Nýtt aðgangsorð';
+$lang['oldpass'] = 'Staðfesta núverandi (gamla) aðgangsorðið';
+$lang['passchk'] = 'Aðgangsorð (aftur)';
+$lang['remember'] = 'Muna.';
+$lang['fullname'] = 'Fullt nafn þitt*';
+$lang['email'] = 'Tölvupóstfangið þitt*';
+$lang['profile'] = 'Notendastillingar';
+$lang['badlogin'] = 'Því miður, notandanafn eða aðgangsorð var rangur.';
+$lang['minoredit'] = 'Minniháttar breyting';
+$lang['draftdate'] = 'Uppkast vistað sjálfkrafa';
+$lang['nosecedit'] = 'Síðunni var breytt á meðan, upplýsingar um svæðið voru úreltar og öll síðan því endurhlaðin.';
+$lang['regmissing'] = 'Afsakið, en þú verður að fylla út í allar eyður.';
+$lang['reguexists'] = 'Afsakið, notandi með þessu nafni er þegar skráður inn.';
+$lang['regsuccess'] = 'Notandi hefur verið búinn til og aðgangsorð sent í tölvupósti.';
+$lang['regsuccess2'] = 'Notandi hefur verið búinn til.';
+$lang['regmailfail'] = 'Það lítur út fyrir villu við sendingu aðgangsorðs. Vinsamlegast hafðu samband við stjórnanda.';
+$lang['regbadmail'] = 'Uppgefinn tölvupóstur virðist ógildur - teljir þú þetta vera villu, hafðu þá samband við stjórnanda.';
+$lang['regbadpass'] = 'Aðgangsorðin tvö eru ekki eins, vinsamlegast reyndu aftur.';
+$lang['regpwmail'] = 'DokuWiki aðgangsorðið þitt';
+$lang['reghere'] = 'Ertu ekki með reikning? Skráðu þig';
+$lang['profna'] = 'Þessi wiki leyfir ekki breytingar á notendaupplýsingum';
+$lang['profnochange'] = 'Enga breytingar vistaðar';
+$lang['profnoempty'] = 'Það er ekki leyfilegt að skilja nafn og póstfang eftir óútfyllt';
+$lang['profchanged'] = 'Notendaupplýsingum breytt';
+$lang['pwdforget'] = 'Gleymt aðgangsorð? Fáðu nýtt';
+$lang['resendna'] = 'Þessi wiki styður ekki endursendingar aðgangsorðs';
+$lang['resendpwd'] = 'Senda nýtt aðgangsorð fyrir';
+$lang['resendpwdmissing'] = 'Afsakið, þú verður að út eyðublaðið allt';
+$lang['resendpwdnouser'] = 'Afsakið, notandi finnst ekki.';
+$lang['resendpwdbadauth'] = 'Afsakið, þessi sannvottunorð er ekki gild. Gakktu úr skugga um að þú notaðir að ljúka staðfesting hlekkur.';
+$lang['resendpwdconfirm'] = 'Staðfesting hlekkur hefur verið send með tölvupósti.';
+$lang['resendpwdsuccess'] = 'Nýja aðgangsorðið hefur verið sent með tölvupósti.';
+$lang['license'] = 'Nema annað sé tekið fram, efni á þessari wiki er leyfð undir eftirfarandi leyfi:';
+$lang['licenseok'] = 'Athugið: Með því að breyta þessari síðu samþykkir þú að leyfisveitandi efni undir eftirfarandi leyfi:';
+$lang['searchmedia'] = 'Leit skrárheiti:';
+$lang['searchmedia_in'] = 'Leit í %s';
+$lang['txt_upload'] = 'Veldu skrá til innhleðslu';
+$lang['txt_filename'] = 'Innhlaða sem (valfrjálst)';
+$lang['txt_overwrt'] = 'Skrifa yfir skrá sem þegar er til';
+$lang['lockedby'] = 'Læstur af';
+$lang['lockexpire'] = 'Læsing rennur út eftir';
+$lang['nothingfound'] = 'Ekkert fannst';
+$lang['mediaselect'] = 'Miðlaskrá';
+$lang['fileupload'] = 'Hlaða inn miðlaskrá';
+$lang['uploadsucc'] = 'Innhlaðning tókst';
+$lang['uploadfail'] = 'Villa í innhlaðningu';
+$lang['uploadwrong'] = 'Innhleðslu neitað. Skrár með þessari endingu eru ekki leyfðar.';
+$lang['uploadexist'] = 'Skrá var þegar til staðar.';
+$lang['uploadbadcontent'] = 'Innhlaðið efni var ekki við að %s skrárendingu.';
+$lang['uploadspam'] = 'Þessi innhlaðning er útilokuð vegna ruslpósts svarturlisti.';
+$lang['uploadxss'] = 'Þessi innhlaðning er útilokuð vegna hugsanlega skaðlegum efni.';
+$lang['uploadsize'] = 'Innhlaðið skrá var of stór. (Hámark eru %s)';
+$lang['deletesucc'] = 'Skrá %s hefur verið eytt.';
+$lang['namespaces'] = 'Nafnrýmar';
+$lang['mediafiles'] = 'Tiltækar skrár í';
+$lang['js']['searchmedia'] = 'Leita að skrám';
+$lang['js']['hidedetails'] = 'Fela upplýsingar';
+$lang['js']['linkwiz'] = 'Tengill-leiðsagnarforrit';
+$lang['js']['linkto'] = 'Tengja';
+$lang['js']['del_confirm'] = 'Á örugglega að eyða valdar skrár?';
+$lang['mediaview'] = 'Sjá upprunalega skrá';
+$lang['mediaroot'] = 'rót';
+$lang['mediaextchange'] = 'Skrárending var breytt úr .%s til .%s!';
+$lang['reference'] = 'Tilvísanir til';
+$lang['ref_inuse'] = 'Ekki hægt að eyða skráin, því það er enn notað af eftirfarandi síðum:';
+$lang['ref_hidden'] = 'Sumar tilvísanir eru að síður sem þú hefur ekki leyfi til að lesa';
+$lang['hits'] = 'Samsvör';
+$lang['quickhits'] = 'Samsvörun síðunöfn';
+$lang['toc'] = 'Efnisyfirlit';
+$lang['current'] = 'nú';
+$lang['yours'] = 'Þín útgáfa';
+$lang['diff'] = 'Sýna ágreiningur til núverandi endurskoðun';
+$lang['diff2'] = 'Sýna ágreiningur meðal valið endurskoðun';
+$lang['line'] = 'Lína';
+$lang['breadcrumb'] = 'Snefill';
+$lang['youarehere'] = 'Þú ert hér';
+$lang['lastmod'] = 'Síðast breytt';
+$lang['by'] = 'af';
+$lang['deleted'] = 'eytt';
+$lang['created'] = 'myndað';
+$lang['restored'] = 'Breytt aftur til fyrri útgáfu';
+$lang['external_edit'] = 'utanaðkomandi breyta';
+$lang['summary'] = 'Forskoða';
+$lang['noflash'] = 'Það þarf <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash viðbót</a> til að sýna sumt efnið á þessari síðu';
+$lang['download'] = 'Hlaða niður til kóðabút';
+$lang['mail_newpage'] = 'síðu bætt við:';
+$lang['mail_changed'] = 'síðu breytt:';
+$lang['mail_new_user'] = 'nýr notandi:';
+$lang['mail_upload'] = 'Innhlaðið skrá:';
+$lang['qb_bold'] = 'Feitletraður texti';
+$lang['qb_italic'] = 'Skáletraður texti';
+$lang['qb_underl'] = 'Undirstrikaður texti';
+$lang['qb_code'] = 'Kóðatraður texti';
+$lang['qb_strike'] = 'Yfirstrikaður texti';
+$lang['qb_h1'] = 'Fyrsta stigs fyrirsögn';
+$lang['qb_h2'] = 'Annars stigs fyrirsögn';
+$lang['qb_h3'] = 'Þriðja stigs fyrirsögn';
+$lang['qb_h4'] = 'Fjórða stigs fyrirsögn';
+$lang['qb_h5'] = 'Fimmta stigs fyrirsögn';
+$lang['qb_h'] = 'Fyrirsögn';
+$lang['qb_hs'] = 'Veldu fyrirsögn';
+$lang['qb_hplus'] = 'Hærra stigs fyrirsögn';
+$lang['qb_hminus'] = 'Lægri stigs fyrirsögn';
+$lang['qb_hequal'] = 'Sama stigs fyrirsögn';
+$lang['qb_link'] = 'Innri tengill';
+$lang['qb_extlink'] = 'Ytri tengill (muna að setja http:// á undan)';
+$lang['qb_hr'] = 'Lárétt lína (notist sparlega)';
+$lang['qb_ol'] = 'Númeraðaðan listatriði';
+$lang['qb_ul'] = 'Ónúmeraðaðan listatriði';
+$lang['qb_media'] = 'Bæta inn myndum og öðrum skrám';
+$lang['qb_sig'] = 'Undirskrift þín auk tímasetningu';
+$lang['qb_smileys'] = 'Broskallar';
+$lang['qb_chars'] = 'Sértækir stafir';
+$lang['admin_register'] = 'Setja nýjan notenda inn';
+$lang['metaedit'] = 'Breyta lýsigögnum';
+$lang['metasaveerr'] = 'Vistun lýsigagna mistókst';
+$lang['metasaveok'] = 'Lýsigögn vistuð';
+$lang['img_backto'] = 'Aftur til';
+$lang['img_title'] = 'Heiti';
+$lang['img_caption'] = 'Skýringartexti';
+$lang['img_date'] = 'Dagsetning';
+$lang['img_fname'] = 'Skrárheiti';
+$lang['img_fsize'] = 'Stærð';
+$lang['img_artist'] = 'Myndsmiður';
+$lang['img_copyr'] = 'Útgáfuréttur';
+$lang['img_format'] = 'Forsnið';
+$lang['img_camera'] = 'Myndavél';
+$lang['img_keywords'] = 'Lykilorðir';
+$lang['i_retry'] = 'Reyna aftur';
diff --git a/inc/lang/is/login.txt b/inc/lang/is/login.txt
new file mode 100644
index 000000000..81e7e5e32
--- /dev/null
+++ b/inc/lang/is/login.txt
@@ -0,0 +1,3 @@
+===== Innskráning =====
+
+Þú ert ekki skráður inn! Skráuðu þig inn hér að neðan. Athugaðu að vafrinn sem að þú notar verður að styðja móttöku smákaka. \ No newline at end of file
diff --git a/inc/lang/is/recent.txt b/inc/lang/is/recent.txt
new file mode 100644
index 000000000..7d3cf5720
--- /dev/null
+++ b/inc/lang/is/recent.txt
@@ -0,0 +1,3 @@
+===== Nýlegar Breytingar =====
+
+Eftirfarandi síðum hefur nýlega verið breytt. \ No newline at end of file
diff --git a/inc/lang/is/resendpwd.txt b/inc/lang/is/resendpwd.txt
new file mode 100644
index 000000000..b847b1d4d
--- /dev/null
+++ b/inc/lang/is/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Senda nýtt aðgangsorð ======
+
+Vinsamlegast sláðu inn notendanafn þitt í formið hér fyrir neðan til að biðja um nýtt aðgangsorð fyrir reikninginn þinn í þessu wiki. A staðfesting hlekkur verður sendast á skráð netfang. \ No newline at end of file
diff --git a/inc/lang/it/admin.txt b/inc/lang/it/admin.txt
new file mode 100644
index 000000000..95a611edc
--- /dev/null
+++ b/inc/lang/it/admin.txt
@@ -0,0 +1,4 @@
+====== Amministrazione ======
+
+Qui sotto puoi trovare una lista delle possibili azioni amministrative attualmente disponibili in Dokuwiki.
+
diff --git a/inc/lang/it/adminplugins.txt b/inc/lang/it/adminplugins.txt
new file mode 100644
index 000000000..4f17d6da4
--- /dev/null
+++ b/inc/lang/it/adminplugins.txt
@@ -0,0 +1 @@
+===== Plugin aggiuntivi ===== \ No newline at end of file
diff --git a/inc/lang/it/backlinks.txt b/inc/lang/it/backlinks.txt
new file mode 100644
index 000000000..ad5a9c23b
--- /dev/null
+++ b/inc/lang/it/backlinks.txt
@@ -0,0 +1,4 @@
+====== Puntano qui ======
+
+Questa è una lista delle pagine che sembrano avere un collegamento alla pagina attuale.
+
diff --git a/inc/lang/it/conflict.txt b/inc/lang/it/conflict.txt
new file mode 100644
index 000000000..bcb90d28d
--- /dev/null
+++ b/inc/lang/it/conflict.txt
@@ -0,0 +1,6 @@
+====== Esiste una versione più recente ======
+
+Esiste una versione più recente del documento che hai modificato. Questo può accadere quando un altro utente ha già modificato il documento durante le tue modifiche.
+
+Esamina le differenze mostrate di seguito, quindi decidi quale versione mantenere. Se scegli ''Salva'', la tua versione verrà salvata. Clicca su ''Annulla'' per mantenere la versione attuale.
+
diff --git a/inc/lang/it/denied.txt b/inc/lang/it/denied.txt
new file mode 100644
index 000000000..d21956a5b
--- /dev/null
+++ b/inc/lang/it/denied.txt
@@ -0,0 +1,5 @@
+====== Accesso negato ======
+
+Non hai i diritti per continuare. Forse hai dimenticato di effettuare l'accesso?
+
+
diff --git a/inc/lang/it/diff.txt b/inc/lang/it/diff.txt
new file mode 100644
index 000000000..5a41eaaec
--- /dev/null
+++ b/inc/lang/it/diff.txt
@@ -0,0 +1,4 @@
+====== Differenze ======
+
+Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.
+
diff --git a/inc/lang/it/draft.txt b/inc/lang/it/draft.txt
new file mode 100644
index 000000000..479d0fafc
--- /dev/null
+++ b/inc/lang/it/draft.txt
@@ -0,0 +1,6 @@
+====== Trovata Bozza ======
+
+La tua ultima sessione di modifica su questa pagina non è stata completata correttamente. DokuWiki ha salvato in automatico una bozza durante il tuo lavoro, che puoi ora utilizzare per continuare le tue modifiche. Di seguito puoi trovare i dati che sono stati salvati dalla tua ultima sessione.
+
+Decidi se vuoi //recuperare// la sessione di modifica, //eliminare// la bozza salavata in automatico oppure //annullare// le modifiche.
+
diff --git a/inc/lang/it/edit.txt b/inc/lang/it/edit.txt
new file mode 100644
index 000000000..8f2ba973a
--- /dev/null
+++ b/inc/lang/it/edit.txt
@@ -0,0 +1,2 @@
+Modifica la pagina e clicca su ''Salva''. Vedi [[wiki:syntax]] per la sintassi riconosciuta dal Wiki. Modifica questa pagina solo se puoi **apportare dei miglioramenti**. Se vuoi solo fare degli esperimenti ed imparare come fare i primi passi usa [[playground:playground]].
+
diff --git a/inc/lang/it/editrev.txt b/inc/lang/it/editrev.txt
new file mode 100644
index 000000000..502320083
--- /dev/null
+++ b/inc/lang/it/editrev.txt
@@ -0,0 +1,2 @@
+**Hai caricato una revisione precedente del documento!** Se salvi questa pagina creerai una nuova versione con questi dati.
+---- \ No newline at end of file
diff --git a/inc/lang/it/index.txt b/inc/lang/it/index.txt
new file mode 100644
index 000000000..52c6fbc5d
--- /dev/null
+++ b/inc/lang/it/index.txt
@@ -0,0 +1,4 @@
+====== Indice ======
+
+Questo è un indice di tutte le pagine disponibili ordinate per [[doku>namespaces|categorie]].
+
diff --git a/inc/lang/it/install.html b/inc/lang/it/install.html
new file mode 100644
index 000000000..3454fbc3e
--- /dev/null
+++ b/inc/lang/it/install.html
@@ -0,0 +1,24 @@
+<p>Questa pagina ti assisterà durante l'installazione e la prima configurazione di
+<a href="http://dokuwiki.org">Dokuwiki</a>. Ulteriori informazioni sulla
+procedura di installazione sono reperibili nella
+<a href="http://dokuwiki.org/installer">pagina di documentazione</a>.</p>
+
+<p>DokuWiki utilizza dei normali file per la memorizzazione delle pagine del wiki e
+delle altre informazioni associate a tali pagine (es. immagini, indici per la ricerca, vecchie
+revisioni, ecc.). Per poter operare correttamente DokuWiki
+<strong>deve</strong> accedere in scrittura alle directory che contengono tali
+file. La procedura di installazione non è in grado di impostare i permessi sulle directory. Questo
+deve normalmente essere fatto direttamente da linea di comando oppure, se stai usando un servizio di hosting,
+attraverso FTP o dal pannello di controllo del servizio di hosting (es. cPanel).</p>
+
+<p>Questa procedura di installazione imposterà la configurazione di DokuWiki per l'uso di
+<acronym title="lista controllo accessi">ACL</acronym>, che consente all'amministratore di
+collegarsi e accedere al menu di amministrazione di DokuWiki per installare plugin, gestire
+utenti, gestire gli accessi alle pagine wiki e modificare le impostazioni del wiki.
+Non è necessario per il funzionamento di DokuWiki, ma renderà Dokuwiki più facile
+da amministrare.</p>
+
+<p>Gli utenti esperti o con particolari esigenze di installazione dovrebbero far riferimento ai
+seguenti link per dettagli sulle
+<a href="http://dokuwiki.org/install">istruzioni per l'installazione</a>
+e sui <a href="http://dokuwiki.org/config">parametri di configurazione</a>.</p>
diff --git a/inc/lang/it/lang.php b/inc/lang/it/lang.php
new file mode 100644
index 000000000..dfe7818e9
--- /dev/null
+++ b/inc/lang/it/lang.php
@@ -0,0 +1,273 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Giorgio Vecchiocattivi <giorgio@vecchio.it>
+ * @author Roberto Bolli [http://www.rbnet.it/]
+ * @author Silvia Sargentoni <polinnia@tin.it>
+ * @author Diego Pierotto <ita.translations@tiscali.it>
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Matteo Carnevali <rekstorm@gmail.com>
+ * @author Osman Tekin <osman.tekin93@hotmail.it>
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Modifica questa pagina';
+$lang['btn_source'] = 'Mostra sorgente';
+$lang['btn_show'] = 'Mostra pagina';
+$lang['btn_create'] = 'Crea questa pagina';
+$lang['btn_search'] = 'Cerca';
+$lang['btn_save'] = 'Salva';
+$lang['btn_preview'] = 'Anteprima';
+$lang['btn_top'] = 'Torna su';
+$lang['btn_newer'] = '<< più recenti';
+$lang['btn_older'] = 'meno recenti >>';
+$lang['btn_revs'] = 'Revisioni precedenti';
+$lang['btn_recent'] = 'Ultime modifiche';
+$lang['btn_upload'] = 'Invia file';
+$lang['btn_cancel'] = 'Annulla';
+$lang['btn_index'] = 'Indice';
+$lang['btn_secedit'] = 'Modifica';
+$lang['btn_login'] = 'Entra';
+$lang['btn_logout'] = 'Esci';
+$lang['btn_admin'] = 'Amministrazione';
+$lang['btn_update'] = 'Aggiorna';
+$lang['btn_delete'] = 'Elimina';
+$lang['btn_back'] = 'Indietro';
+$lang['btn_backlink'] = 'Puntano qui';
+$lang['btn_backtomedia'] = 'Torna alla selezione file';
+$lang['btn_subscribe'] = 'Sottoscrivi modifiche';
+$lang['btn_profile'] = 'Aggiorna profilo';
+$lang['btn_reset'] = 'Annulla';
+$lang['btn_resendpwd'] = 'Invia nuova password';
+$lang['btn_draft'] = 'Modifica bozza';
+$lang['btn_recover'] = 'Ripristina bozza';
+$lang['btn_draftdel'] = 'Elimina bozza';
+$lang['btn_revert'] = 'Ripristina';
+$lang['btn_register'] = 'Registrazione';
+$lang['loggedinas'] = 'Collegato come';
+$lang['user'] = 'Nome utente';
+$lang['pass'] = 'Password';
+$lang['newpass'] = 'Nuova password';
+$lang['oldpass'] = 'Conferma password attuale';
+$lang['passchk'] = 'Ripeti password';
+$lang['remember'] = 'Memorizza nome utente e password';
+$lang['fullname'] = 'Nome completo';
+$lang['email'] = 'Email';
+$lang['profile'] = 'Profilo utente';
+$lang['badlogin'] = 'Il nome utente o la password non sono validi.';
+$lang['minoredit'] = 'Modifiche minori';
+$lang['draftdate'] = 'Bozza salvata in automatico il';
+$lang['nosecedit'] = 'La pagina è stata modificata nel frattempo; è impossibile modificare solo la sezione scelta, quindi è stata caricata la pagina intera.';
+$lang['regmissing'] = 'Devi riempire tutti i campi.';
+$lang['reguexists'] = 'Il nome utente inserito esiste già.';
+$lang['regsuccess'] = 'L\'utente è stato creato. La password è stata spedita via email.';
+$lang['regsuccess2'] = 'L\'utente è stato creato.';
+$lang['regmailfail'] = 'Sembra che ci sia stato un errore nell\'invio della email. Contatta l\'amministratore!';
+$lang['regbadmail'] = 'L\'indirizzo email fornito sembra essere non valido - se pensi che ci sia un errore contatta l\'amministratore';
+$lang['regbadpass'] = 'Le due password inserite non coincidono, prova di nuovo.';
+$lang['regpwmail'] = 'La tua password per DokuWiki';
+$lang['reghere'] = 'Non sei ancora registrato? Registrati qui.';
+$lang['profna'] = 'Questo wiki non supporta modifiche al profilo';
+$lang['profnochange'] = 'Nessuna modifica, niente da aggiornare.';
+$lang['profnoempty'] = 'Nome o indirizzo email vuoti non sono consentiti.';
+$lang['profchanged'] = 'Aggiornamento del profilo utente riuscito.';
+$lang['pwdforget'] = 'Hai dimenticato la password? Richiedine una nuova';
+$lang['resendna'] = 'Questo wiki non supporta l\'invio di nuove password.';
+$lang['resendpwd'] = 'Invia nuova password per';
+$lang['resendpwdmissing'] = 'Devi riempire tutti i campi.';
+$lang['resendpwdnouser'] = 'Impossibile trovare questo utente nel database.';
+$lang['resendpwdbadauth'] = 'Spiacenti, questo codice di autorizzazione non è valido. Assicurati di aver usato il link completo di conferma.';
+$lang['resendpwdconfirm'] = 'Un link di conferma è stato spedito via email.';
+$lang['resendpwdsuccess'] = 'La nuova password è stata spedita via email.';
+$lang['license'] = 'Ad eccezione da dove è diversamente indicato, il contenuto di questo wiki è soggetto alla seguente licenza:';
+$lang['licenseok'] = 'Nota: modificando questa pagina accetti di rilasciare il contenuto sotto la seguente licenza:';
+$lang['searchmedia'] = 'Cerca file di nome:';
+$lang['searchmedia_in'] = 'Cerca in %s';
+$lang['txt_upload'] = 'Seleziona un file da caricare';
+$lang['txt_filename'] = 'Carica come (opzionale)';
+$lang['txt_overwrt'] = 'Sovrascrivi file esistente';
+$lang['lockedby'] = 'Attualmente bloccato da';
+$lang['lockexpire'] = 'Il blocco scade alle';
+$lang['js']['willexpire'] = 'Il tuo blocco su questa pagina scadrà tra circa un minuto.\nPer evitare incongruenze usa il pulsante di anteprima per prolungare il periodo di blocco.';
+$lang['js']['notsavedyet'] = 'Le modifiche non salvate andranno perse.';
+$lang['js']['searchmedia'] = 'Cerca file';
+$lang['js']['keepopen'] = 'Tieni la finestra aperta durante la selezione';
+$lang['js']['hidedetails'] = 'Nascondi Dettagli';
+$lang['js']['mediatitle'] = 'Impostazioni link';
+$lang['js']['mediadisplay'] = 'Tipo link';
+$lang['js']['mediaalign'] = 'Allineamento';
+$lang['js']['mediasize'] = 'Dimensioni immagine';
+$lang['js']['mediatarget'] = 'Target del link';
+$lang['js']['mediaclose'] = 'Chiudi';
+$lang['js']['mediainsert'] = 'Inserisci';
+$lang['js']['mediadisplayimg'] = 'Mostra l\'immagine.';
+$lang['js']['mediadisplaylnk'] = 'Mostra solo il link.';
+$lang['js']['mediasmall'] = 'Versione piccola';
+$lang['js']['mediamedium'] = 'Versione media';
+$lang['js']['medialarge'] = 'Versione grande';
+$lang['js']['mediaoriginal'] = 'Versione originale';
+$lang['js']['medialnk'] = 'Link alla pagina dei dettagli';
+$lang['js']['mediadirect'] = 'Link all\'originale';
+$lang['js']['medianolnk'] = 'No link';
+$lang['js']['medianolink'] = 'Non linkare l\'immagine.';
+$lang['js']['medialeft'] = 'Allinea l\'immagine a sinistra.';
+$lang['js']['mediaright'] = 'Allinea l\'immagine a destra.';
+$lang['js']['mediacenter'] = 'Allinea l\'immagine al centro.';
+$lang['js']['medianoalign'] = 'Non allineare.';
+$lang['js']['nosmblinks'] = 'I collegamenti con le risorse condivise di Windows funzionano solo con Microsoft Internet Explorer.
+È comunque possibile copiare e incollare il collegamento.';
+$lang['js']['linkwiz'] = 'Collegamento guidato';
+$lang['js']['linkto'] = 'Collega a:';
+$lang['js']['del_confirm'] = 'Eliminare veramente questa voce?';
+$lang['rssfailed'] = 'Si è verificato un errore cercando questo feed: ';
+$lang['nothingfound'] = 'Nessun risultato trovato.';
+$lang['mediaselect'] = 'Selezione dei file';
+$lang['fileupload'] = 'File caricato';
+$lang['uploadsucc'] = 'Invio riuscito';
+$lang['uploadfail'] = 'Invio fallito. È possibile che si tratti di un problema di permessi.';
+$lang['uploadwrong'] = 'Invio rifiutato. Questa estensione di file non è ammessa';
+$lang['uploadexist'] = 'Il file esiste già. Invio annullato.';
+$lang['uploadbadcontent'] = 'Il tipo di contenuto caricato non corrisponde all\'estensione del file %s.';
+$lang['uploadspam'] = 'Il caricamento è stato bloccato come spam perché presente nella lista nera.';
+$lang['uploadxss'] = 'Il caricamento è stato bloccato perchè il contenuto potrebbe essere un virus o presentare problemi di sicurezza.';
+$lang['uploadsize'] = 'Il file caricato è troppo grande. (massimo %s)';
+$lang['deletesucc'] = 'Il file "%s" è stato eliminato.';
+$lang['deletefail'] = '"%s" non può essere eliminato - verifica i permessi.';
+$lang['mediainuse'] = 'Il file "%s" non è stato eliminato - è ancora in uso.';
+$lang['namespaces'] = 'Categorie';
+$lang['mediafiles'] = 'File disponibili in';
+$lang['accessdenied'] = 'Non sei autorizzato a vedere questa pagina.';
+$lang['mediausage'] = 'Usa la seguente sintassi per riferirti a questo file:';
+$lang['mediaview'] = 'Mostra file originale';
+$lang['mediaroot'] = 'directory principale';
+$lang['mediaupload'] = 'Carica un file nella categoria attuale. Per creare sottocategorie, falle precedere dal nome del file nella casella "Carica come", separandole da due punti (:).';
+$lang['mediaextchange'] = 'Estensione del file modificata da .%s a .%s!';
+$lang['reference'] = 'Riferimenti a';
+$lang['ref_inuse'] = 'Il file non può essere eliminato in quanto è ancora utilizzato dalle seguenti pagine:';
+$lang['ref_hidden'] = 'Sono presenti alcuni riferimenti a pagine per le quali non hai i permessi di lettura';
+$lang['hits'] = 'Occorrenze trovate';
+$lang['quickhits'] = 'Pagine trovate';
+$lang['toc'] = 'Indice';
+$lang['current'] = 'versione attuale';
+$lang['yours'] = 'la tua versione';
+$lang['diff'] = 'differenze con la versione attuale';
+$lang['diff2'] = 'differenze tra le versioni selezionate';
+$lang['difflink'] = 'Link a questa pagina di confronto';
+$lang['line'] = 'Linea';
+$lang['breadcrumb'] = 'Traccia';
+$lang['youarehere'] = 'Ti trovi qui';
+$lang['lastmod'] = 'Ultima modifica';
+$lang['by'] = 'da';
+$lang['deleted'] = 'eliminata';
+$lang['created'] = 'creata';
+$lang['restored'] = 'versione precedente ripristinata';
+$lang['external_edit'] = 'modifica esterna';
+$lang['summary'] = 'Oggetto della modifica';
+$lang['noflash'] = 'E\' necessario <a href="http://www.adobe.com/products/flashplayer/">il plugin Adobe Flash</a> per visualizzare questo contenuto.';
+$lang['download'] = 'Scarica lo "snippet"';
+$lang['mail_newpage'] = 'pagina aggiunta:';
+$lang['mail_changed'] = 'pagina modificata:';
+$lang['mail_subscribe_list'] = 'pagine modificate nella categoria:';
+$lang['mail_new_user'] = 'nuovo utente:';
+$lang['mail_upload'] = 'file caricato:';
+$lang['qb_bold'] = 'Grassetto';
+$lang['qb_italic'] = 'Corsivo';
+$lang['qb_underl'] = 'Sottolineato';
+$lang['qb_code'] = 'Codice';
+$lang['qb_strike'] = 'Barrato';
+$lang['qb_h1'] = 'Intestazione di livello 1';
+$lang['qb_h2'] = 'Intestazione di livello 2';
+$lang['qb_h3'] = 'Intestazione di livello 3';
+$lang['qb_h4'] = 'Intestazione di livello 4';
+$lang['qb_h5'] = 'Intestazione di livello 5';
+$lang['qb_h'] = 'Titolo';
+$lang['qb_hs'] = 'Seleziona il titolo';
+$lang['qb_hplus'] = 'Titolo superiore';
+$lang['qb_hminus'] = 'Titolo inferiore';
+$lang['qb_hequal'] = 'Titolo dello stesso livello';
+$lang['qb_link'] = 'Collegamento interno';
+$lang['qb_extlink'] = 'Collegamento esterno';
+$lang['qb_hr'] = 'Riga orizzontale';
+$lang['qb_ol'] = 'Elenco numerato';
+$lang['qb_ul'] = 'Elenco puntato';
+$lang['qb_media'] = 'Inserisci immagini o altri file';
+$lang['qb_sig'] = 'Inserisci la firma';
+$lang['qb_smileys'] = 'Smiley';
+$lang['qb_chars'] = 'Caratteri speciali';
+$lang['upperns'] = 'vai alla categoria principale';
+$lang['admin_register'] = 'Aggiungi un nuovo utente';
+$lang['metaedit'] = 'Modifica metadati';
+$lang['metasaveerr'] = 'Scrittura metadati fallita';
+$lang['metasaveok'] = 'Metadati salvati';
+$lang['img_backto'] = 'Torna a';
+$lang['img_title'] = 'Titolo';
+$lang['img_caption'] = 'Descrizione';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Nome File';
+$lang['img_fsize'] = 'Dimensione';
+$lang['img_artist'] = 'Autore';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Formato';
+$lang['img_camera'] = 'Camera';
+$lang['img_keywords'] = 'Parole chiave';
+$lang['subscr_subscribe_success'] = 'Aggiunto %s alla lista di sottoscrizioni %s';
+$lang['subscr_subscribe_error'] = 'Impossibile aggiungere %s alla lista di sottoscrizioni %s';
+$lang['subscr_subscribe_noaddress'] = 'Non esiste alcun indirizzo associato al tuo account, non puoi essere aggiunto alla lista di sottoscrizioni';
+$lang['subscr_unsubscribe_success'] = 'Rimosso %s dalla lista di sottoscrizioni %s';
+$lang['subscr_unsubscribe_error'] = 'Impossibile rimuovere %s dalla lista di sottoscrizioni %s';
+$lang['subscr_already_subscribed'] = '%s è già iscritto a %s';
+$lang['subscr_not_subscribed'] = '%s non è iscritto a %s';
+$lang['subscr_m_not_subscribed'] = 'Attualmente non sei iscritto alla pagina o categoria corrente';
+$lang['subscr_m_new_header'] = 'Aggiungi sottoscrizione';
+$lang['subscr_m_current_header'] = 'Sottoscrizioni attuali';
+$lang['subscr_m_unsubscribe'] = 'Rimuovi sottoscrizione';
+$lang['subscr_m_subscribe'] = 'Sottoscrivi';
+$lang['subscr_m_receive'] = 'Ricevi';
+$lang['subscr_style_every'] = 'email per ogni modifica';
+$lang['subscr_style_digest'] = 'email riassuntiva delle modifiche di ogni pagina';
+$lang['subscr_style_list'] = 'elenco delle pagine modificate dall\'ultima email';
+$lang['authmodfailed'] = 'La configurazione dell\'autenticazione non è corretta. Informa l\'amministratore di questo wiki.';
+$lang['authtempfail'] = 'L\'autenticazione è temporaneamente non disponibile. Se questa situazione persiste, informa l\'amministratore di questo wiki.';
+$lang['i_chooselang'] = 'Scegli la lingua';
+$lang['i_installer'] = 'Installazione di DokuWiki';
+$lang['i_wikiname'] = 'Nome Wiki';
+$lang['i_enableacl'] = 'Abilita ACL (consigliato)';
+$lang['i_superuser'] = 'Amministratore';
+$lang['i_problems'] = 'Si sono verificati problemi durante l\'installazione, indicati di seguito. Non è possibile continuare finché non saranno risolti.';
+$lang['i_modified'] = 'Per motivi di sicurezza questa procedura funziona solamente con un\'installazione Dokuwiki nuova e non modificata.
+Prova a estrarre di nuovo i file dal pacchetto scaricato oppure consulta le
+<a href="http://dokuwiki.org/install">istruzioni per l\'installazione di Dokuwiki</a>';
+$lang['i_funcna'] = 'La funzione PHP <code>%s</code> non è disponibile. Forse è stata disabilitata dal tuo provider per qualche motivo?';
+$lang['i_phpver'] = 'La versione di PHP <code>%s</code> è inferiore a quella richiesta <code>%s</code>. Devi aggiornare l\'installazione di PHP.';
+$lang['i_permfail'] = 'DokuWiki non può scrivere <code>%s</code>. E\' necessario correggere i permessi per questa directory!';
+$lang['i_confexists'] = '<code>%s</code> esiste già';
+$lang['i_writeerr'] = 'Impossibile creare <code>%s</code>. E\' necessario verificare i permessi della directory o del file oppure creare il file manualmente.';
+$lang['i_badhash'] = 'dokuwiki.php (hash=<code>%s</code>) non riconosciuto o modificato';
+$lang['i_badval'] = '<code>%s</code> - valore vuoto o non valido';
+$lang['i_success'] = 'La configurazione è stata completata correttamente. Ora è possibile eliminare il file install.php. Poi, visita <a href="doku.php">il tuo nuovo DokuWiki</a>.';
+$lang['i_failure'] = 'Si sono verificati errori durante la scrittura dei file di configurazione. Potrebbe essere necessario correggerli manualmente prima di poter utilizzare <a href="doku.php">il tuo nuovo DokuWiki</a>.';
+$lang['i_policy'] = 'Regole di accesso iniziali';
+$lang['i_pol0'] = 'Wiki Aperto (lettura, scrittura, caricamento file per tutti)';
+$lang['i_pol1'] = 'Wiki Pubblico (lettura per tutti, scrittura e caricamento file per gli utenti registrati)';
+$lang['i_pol2'] = 'Wiki Chiuso (lettura, scrittura, caricamento file solamente per gli utenti registrati)';
+$lang['i_retry'] = 'Riprova';
+$lang['i_license'] = 'Per favore scegli la licenza sotto cui vuoi rilasciare il contenuto:';
+$lang['recent_global'] = 'Stai attualmente vedendo le modifiche effettuate nell\'area <b>%s</b>. Puoi anche <a href="%s">vedere le modifiche recenti dell\'intero wiki</a>.';
+$lang['years'] = '%d anni fa';
+$lang['months'] = '%d mesi fa';
+$lang['weeks'] = '%d settimane fa';
+$lang['days'] = '%d giorni fa';
+$lang['hours'] = '%d ore fa';
+$lang['minutes'] = '%d minuti fa';
+$lang['seconds'] = '%d secondi fa';
+$lang['wordblock'] = 'La modifica non è stata salvata perché contiene testo bloccato (spam).';
diff --git a/inc/lang/it/locked.txt b/inc/lang/it/locked.txt
new file mode 100644
index 000000000..a655ffcd3
--- /dev/null
+++ b/inc/lang/it/locked.txt
@@ -0,0 +1,3 @@
+====== Pagina bloccata ======
+
+Questa pagina è attualmente bloccata poiché un altro utente sta effettuando delle modifiche. Devi attendere che l'utente concluda le modifiche o che il blocco scada.
diff --git a/inc/lang/it/login.txt b/inc/lang/it/login.txt
new file mode 100644
index 000000000..c6fd97b6f
--- /dev/null
+++ b/inc/lang/it/login.txt
@@ -0,0 +1,4 @@
+====== Accesso ======
+
+Non sei ancora collegato! Inserisci il tuo nome utente e la tua password per autenticarti. E' necessario che il tuo browser abbia i cookie abilitati.
+
diff --git a/inc/lang/it/mailtext.txt b/inc/lang/it/mailtext.txt
new file mode 100644
index 000000000..3a326961e
--- /dev/null
+++ b/inc/lang/it/mailtext.txt
@@ -0,0 +1,17 @@
+Una pagina su DokuWiki è stata aggiunta o modificata. Questi sono i dettagli:
+
+Data : @DATE@
+Browser : @BROWSER@
+Indirizzo IP : @IPADDRESS@
+Nome host : @HOSTNAME@
+Vecchia revisione : @OLDPAGE@
+Nuova revisione : @NEWPAGE@
+Oggetto della modifica : @SUMMARY@
+Utente : @USER@
+
+@DIFF@
+
+
+--
+Questa email è stata generata dal DokuWiki all'indirizzo
+@DOKUWIKIURL@
diff --git a/inc/lang/it/newpage.txt b/inc/lang/it/newpage.txt
new file mode 100644
index 000000000..d41601cfb
--- /dev/null
+++ b/inc/lang/it/newpage.txt
@@ -0,0 +1,3 @@
+====== Questo argomento non esiste ancora ======
+
+Hai seguito un collegamento ad un argomento che non è ancora stato creato. Se vuoi puoi crearlo tu stesso usando il pulsante ''Crea questa pagina''.
diff --git a/inc/lang/it/norev.txt b/inc/lang/it/norev.txt
new file mode 100644
index 000000000..91ef751f9
--- /dev/null
+++ b/inc/lang/it/norev.txt
@@ -0,0 +1,3 @@
+====== Revisione inesistente ======
+
+La revisione richiesta non esiste. Usa il pulsante ''Revisioni precedenti'' per ottenere una lista di revisioni precedenti di questo documento.
diff --git a/inc/lang/it/password.txt b/inc/lang/it/password.txt
new file mode 100644
index 000000000..670d5ae44
--- /dev/null
+++ b/inc/lang/it/password.txt
@@ -0,0 +1,10 @@
+Ciao @FULLNAME@!
+
+Questi sono i tuoi dati di accesso per @TITLE@ su @DOKUWIKIURL@
+
+Nome utente : @LOGIN@
+Password : @PASSWORD@
+
+--
+Questa email è stata generata dal DokuWiki all'indirizzo
+@DOKUWIKIURL@
diff --git a/inc/lang/it/preview.txt b/inc/lang/it/preview.txt
new file mode 100644
index 000000000..c3cf35246
--- /dev/null
+++ b/inc/lang/it/preview.txt
@@ -0,0 +1,5 @@
+====== Anteprima ======
+
+Questa è un'anteprima di come apparirà il tuo testo. Attenzione: **la pagina non è ancora stata salvata**!.
+
+
diff --git a/inc/lang/it/pwconfirm.txt b/inc/lang/it/pwconfirm.txt
new file mode 100644
index 000000000..8a594ded8
--- /dev/null
+++ b/inc/lang/it/pwconfirm.txt
@@ -0,0 +1,15 @@
+Ciao @FULLNAME@!
+
+Qualcuno ha richiesto una nuova password per il tuo accesso
+@TITLE@ a @DOKUWIKIURL@
+
+Se non hai richiesto tu la nuova password ignora questa email.
+
+Per confermare che la richiesta è stata realmente inviata da te usa il
+seguente collegamento.
+
+@CONFIRM@
+
+--
+Questa email è stata generata dal DokuWiki all'indirizzo
+@DOKUWIKIURL@
diff --git a/inc/lang/it/read.txt b/inc/lang/it/read.txt
new file mode 100644
index 000000000..0a7245404
--- /dev/null
+++ b/inc/lang/it/read.txt
@@ -0,0 +1 @@
+Questa pagina è in sola lettura. Puoi visualizzare il sorgente, ma non puoi modificarlo. Contatta l'amministratore se pensi che ci sia un errore.
diff --git a/inc/lang/it/recent.txt b/inc/lang/it/recent.txt
new file mode 100644
index 000000000..4c29a9d52
--- /dev/null
+++ b/inc/lang/it/recent.txt
@@ -0,0 +1,4 @@
+====== Ultime modifiche ======
+
+Queste sono le ultime pagine modificate.
+
diff --git a/inc/lang/it/register.txt b/inc/lang/it/register.txt
new file mode 100644
index 000000000..5a336a971
--- /dev/null
+++ b/inc/lang/it/register.txt
@@ -0,0 +1,3 @@
+====== Registrazione nuovo utente ======
+
+Riempi tutte le informazioni seguenti per creare un nuovo account in questo wiki. Assicurati di inserire un **indirizzo email valido** - a meno che tu non l'abbia già inserita qui, la password ti sarà inviata con un messaggio di posta elettronica. Il nome utente deve soddisfare i criteri per i [[doku>pagename|nomi delle pagine]]. \ No newline at end of file
diff --git a/inc/lang/it/registermail.txt b/inc/lang/it/registermail.txt
new file mode 100644
index 000000000..30a6fed48
--- /dev/null
+++ b/inc/lang/it/registermail.txt
@@ -0,0 +1,14 @@
+Un nuovo utente è stato registrato. Ecco i dettagli:
+
+Nome utente : @NEWUSER@
+Nome completo : @NEWNAME@
+EMail : @NEWEMAIL@
+
+Data : @DATE@
+Browser : @BROWSER@
+Indirizzo IP : @IPADDRESS@
+Nome host : @HOSTNAME@
+
+--
+Questa email è stata generata dal DokuWiki all'indirizzo
+@DOKUWIKIURL@
diff --git a/inc/lang/it/resendpwd.txt b/inc/lang/it/resendpwd.txt
new file mode 100644
index 000000000..54604d7f3
--- /dev/null
+++ b/inc/lang/it/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Invia nuova password ======
+
+Inserisci tutte le informazioni per ottenere una nuova password per il tuo account su questo wiki. La nuova password sarà inviata al tuo indirizzo di posta elettronica registrato. Il nome utente deve essere il tuo nome utente in questo wiki.
diff --git a/inc/lang/it/revisions.txt b/inc/lang/it/revisions.txt
new file mode 100644
index 000000000..19c501b07
--- /dev/null
+++ b/inc/lang/it/revisions.txt
@@ -0,0 +1,3 @@
+====== Versione precedente ======
+
+Queste sono le versioni precedenti del documento attuale. Per ripristinare una versione precedente, seleziona la versione, modificala usando il pulsante ''Modifica questa pagina'' e salvala.
diff --git a/inc/lang/it/searchpage.txt b/inc/lang/it/searchpage.txt
new file mode 100644
index 000000000..60a019c3e
--- /dev/null
+++ b/inc/lang/it/searchpage.txt
@@ -0,0 +1,5 @@
+====== Cerca ======
+
+Questi sono i risultati della ricerca. Se non hai trovato quello che cercavi, puoi creare una nuova pagina con questo titolo usando il pulsante ''Crea questa pagina''.
+
+===== Risultati =====
diff --git a/inc/lang/it/showrev.txt b/inc/lang/it/showrev.txt
new file mode 100644
index 000000000..7c184f206
--- /dev/null
+++ b/inc/lang/it/showrev.txt
@@ -0,0 +1,2 @@
+**Questa è una vecchia versione del documento!**
+----
diff --git a/inc/lang/it/stopwords.txt b/inc/lang/it/stopwords.txt
new file mode 100644
index 000000000..e91aa3b55
--- /dev/null
+++ b/inc/lang/it/stopwords.txt
@@ -0,0 +1,119 @@
+# Questo è un elenco di parole che l'indicizzatore ignora, una parola per riga
+# Quando modifichi questo file fai attenzione ad usare la chiusura della riga in stile UNIX (nuova linea singola)
+# Non è necessario includere parole più brevi di 3 caratteri - queste vengono in ogni caso ignorate
+# Questo elenco è basato su quello trovato in http://www.ranks.nl/stopwords/
+adesso
+alla
+allo
+allora
+altre
+altri
+altro
+anche
+ancora
+avere
+aveva
+avevano
+ben
+buono
+che
+chi
+cinque
+comprare
+con
+consecutivi
+consecutivo
+cosa
+cui
+del
+della
+dello
+dentro
+deve
+devo
+doppio
+due
+ecco
+fare
+fine
+fino
+fra
+gente
+giu
+hai
+hanno
+indietro
+invece
+lavoro
+lei
+loro
+lui
+lungo
+meglio
+molta
+molti
+molto
+nei
+nella
+noi
+nome
+nostro
+nove
+nuovi
+nuovo
+oltre
+ora
+otto
+peggio
+pero
+persone
+piu
+poco
+primo
+promesso
+qua
+quarto
+quasi
+quattro
+quello
+questo
+qui
+quindi
+quinto
+rispetto
+sara
+secondo
+sei
+sembra
+sembrava
+senza
+sette
+sia
+siamo
+siete
+solo
+sono
+sopra
+soprattutto
+sotto
+stati
+stato
+stesso
+su
+subito
+sul
+sulla
+tanto
+tempo
+terzo
+tra
+tre
+triplo
+ultimo
+una
+uno
+va
+vai
+voi
+volte
+vostro
diff --git a/inc/lang/it/subscr_digest.txt b/inc/lang/it/subscr_digest.txt
new file mode 100644
index 000000000..a19128702
--- /dev/null
+++ b/inc/lang/it/subscr_digest.txt
@@ -0,0 +1,20 @@
+Ciao!
+
+La pagina @PAGE@ nel wiki @TITLE@ è cambiata.
+Queste sono le modifiche:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Vecchia revisione: @OLDPAGE@
+Nuova revisione: @NEWPAGE@
+
+Per non ricevere più queste notifiche collegati al
+wiki @DOKUWIKIURL@ e poi visita @SUBSCRIBE@
+e rimuovi la sottoscrizione alle modifiche delle
+pagine e/o categorie.
+
+--
+Questa email è stata generata dal DokuWiki all'indirizzo
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/it/subscr_form.txt b/inc/lang/it/subscr_form.txt
new file mode 100644
index 000000000..54f66e44a
--- /dev/null
+++ b/inc/lang/it/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Gestione iscrizioni ======
+
+Questa pagina permette di gestire le tue iscrizioni alla pagina e catogoria attuale. \ No newline at end of file
diff --git a/inc/lang/it/subscr_list.txt b/inc/lang/it/subscr_list.txt
new file mode 100644
index 000000000..8eb7acd3c
--- /dev/null
+++ b/inc/lang/it/subscr_list.txt
@@ -0,0 +1,18 @@
+Ciao!
+
+Le pagine nella categoria @PAGE@ del wiki @TITLE@ sono
+cambiate.
+Queste sono le pagine modificate:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Per non ricevere più queste notifiche collegati al
+wiki @DOKUWIKIURL@ e poi visita @SUBSCRIBE@
+e rimuovi la sottoscrizione alle modifiche delle
+pagine e/o categorie.
+
+--
+Questa email è stata generata dal DokuWiki all'indirizzo
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/it/subscr_single.txt b/inc/lang/it/subscr_single.txt
new file mode 100644
index 000000000..8cde8ea0f
--- /dev/null
+++ b/inc/lang/it/subscr_single.txt
@@ -0,0 +1,24 @@
+Ciao!
+
+La pagina @PAGE@ nel wiki @TITLE@ è cambiata.
+Queste sono le modifiche:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Data : @DATE@
+Utente : @USER@
+Sommario modifica: @SUMMARY@
+Vecchia revisione: @OLDPAGE@
+Nuova revisione: @NEWPAGE@
+
+Per non ricevere più queste notifiche, collegati al
+wiki all'indirizzo @DOKUWIKIURL@ e poi visita
+@NEWPAGE@
+e rimuovi la sottoscrizione alle modifiche della
+pagina o categoria.
+
+--
+Questa email è stata generata dal DokuWiki all'indirizzo
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/it/updateprofile.txt b/inc/lang/it/updateprofile.txt
new file mode 100644
index 000000000..71157a2ed
--- /dev/null
+++ b/inc/lang/it/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Aggiorna il profilo del tuo account ======
+
+E' necessario compilare solo i campi che desideri modificare. Non puoi cambiare il tuo nome utente.
diff --git a/inc/lang/it/uploadmail.txt b/inc/lang/it/uploadmail.txt
new file mode 100644
index 000000000..da3dacd36
--- /dev/null
+++ b/inc/lang/it/uploadmail.txt
@@ -0,0 +1,14 @@
+Un file è stato caricato sul tuo DokuWiki. Seguono i dettagli:
+
+File : @MEDIA@
+Data : @DATE@
+Browser : @BROWSER@
+Indirizzo IP : @IPADDRESS@
+Hostname : @HOSTNAME@
+Dimensione : @SIZE@
+Tipo MIME : @MIME@
+Utente : @USER@
+
+--
+Questa email è stata generata dal DokuWiki all'indirizzo
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ja/admin.txt b/inc/lang/ja/admin.txt
new file mode 100644
index 000000000..b0c6d34ab
--- /dev/null
+++ b/inc/lang/ja/admin.txt
@@ -0,0 +1,4 @@
+====== 管理者メニュー ======
+
+DokuWikiで管理できるタスクの一覧です
+
diff --git a/inc/lang/ja/adminplugins.txt b/inc/lang/ja/adminplugins.txt
new file mode 100644
index 000000000..1708bbb3c
--- /dev/null
+++ b/inc/lang/ja/adminplugins.txt
@@ -0,0 +1 @@
+===== 追加プラグイン ===== \ No newline at end of file
diff --git a/inc/lang/ja/backlinks.txt b/inc/lang/ja/backlinks.txt
new file mode 100644
index 000000000..69644b79d
--- /dev/null
+++ b/inc/lang/ja/backlinks.txt
@@ -0,0 +1,4 @@
+====== バックリンク ======
+
+先ほどの文書にリンクしている文書のリストです。
+
diff --git a/inc/lang/ja/conflict.txt b/inc/lang/ja/conflict.txt
new file mode 100644
index 000000000..099b5989a
--- /dev/null
+++ b/inc/lang/ja/conflict.txt
@@ -0,0 +1,6 @@
+====== 新しいバージョンが存在します ======
+
+編集中に他のユーザーがこの文書を更新したため、新しいバージョンの文書が存在します。
+
+以下に文書間の差分を表示するので、どちらかの文書を選択してください。''保存'' を選択すると現在編集中の文書が保存されます。''キャンセル'' は編集中の文書が破棄されます。
+
diff --git a/inc/lang/ja/denied.txt b/inc/lang/ja/denied.txt
new file mode 100644
index 000000000..d170aebe4
--- /dev/null
+++ b/inc/lang/ja/denied.txt
@@ -0,0 +1,4 @@
+====== アクセスが拒否されました ======
+
+実行する権限がありません。ログインされているか確認してください。
+
diff --git a/inc/lang/ja/diff.txt b/inc/lang/ja/diff.txt
new file mode 100644
index 000000000..fe5f6b165
--- /dev/null
+++ b/inc/lang/ja/diff.txt
@@ -0,0 +1,4 @@
+====== 差分 ======
+
+この文書の現在のバージョンと選択したバージョンの差分を表示します。
+
diff --git a/inc/lang/ja/draft.txt b/inc/lang/ja/draft.txt
new file mode 100644
index 000000000..af3160b8c
--- /dev/null
+++ b/inc/lang/ja/draft.txt
@@ -0,0 +1,6 @@
+====== ドラフトファイルが存在します ======
+
+このページに対する最後の編集は正しく終了されませんでした。 その編集作業を引き続き行えるよう、以下に示す内容が自動的に保存されています。
+
+この自動的に保存された編集内容に対して、//復元する//、//削除する//、 もしくはこのページの編集を//キャンセル//して下さい。
+
diff --git a/inc/lang/ja/edit.txt b/inc/lang/ja/edit.txt
new file mode 100644
index 000000000..e7a8f9720
--- /dev/null
+++ b/inc/lang/ja/edit.txt
@@ -0,0 +1,4 @@
+編集して''保存''をクリックしてください。Wikiの構文については [[wiki:syntax]] を参考にしてください
+
+当然のことですが、この文書の質を **向上** させる場合のみ編集してください。もし編集方法や構文を練習したいのであれば [[playground:playground]] を利用してください。
+
diff --git a/inc/lang/ja/editrev.txt b/inc/lang/ja/editrev.txt
new file mode 100644
index 000000000..7c984131c
--- /dev/null
+++ b/inc/lang/ja/editrev.txt
@@ -0,0 +1,2 @@
+**古いリビジョンの文書を開いています** もしこのまま保存すると、この文書が最新となります。
+----
diff --git a/inc/lang/ja/index.txt b/inc/lang/ja/index.txt
new file mode 100644
index 000000000..b0447899d
--- /dev/null
+++ b/inc/lang/ja/index.txt
@@ -0,0 +1,4 @@
+====== サイトマップ ======
+
+[[doku>namespaces|名前空間]] に基づく、全ての文書の索引です。
+
diff --git a/inc/lang/ja/install.html b/inc/lang/ja/install.html
new file mode 100644
index 000000000..7439d27e1
--- /dev/null
+++ b/inc/lang/ja/install.html
@@ -0,0 +1,14 @@
+<p>このページは、<a href="http://dokuwiki.org">Dokuwiki</a>のインストールと初期設定をサポートします。
+このインストーラーに関する詳細は <a href="http://dokuwiki.org/installer">documentation page</a> を参考にしてください。</p>
+
+<p>DokuWikiは、通常のファイルにWikiページの内容と関連する情報(例えば、画像、検索インデックス、古いリビジョンなど)を保存します。
+そのため、DokuWikiを使用するためには、それらのファイルを保存するディレクトリに書き込みの権限が<strong>必ず</strong>必要となります。
+このインストーラーではディレクトリの権限の変更は行えないため、コマンドシェルで権限の変更を直接行うか、
+ホスティングサービスを利用している場合はそのコントロールパネルもしくはFTPを通して、権限の変更を行ってください。</p>
+
+<p>DokuWikiは、プラグイン、ユーザー、Wikiページへのアクセス制限、設定の変更を管理する機能を有しており、
+その機能を有効にするために必要な <acronym title="access control list">ACL</acronym> の設定が、このインストーラーによって行われます。
+この管理機能は、DokuWikiを使用する上で必要ではありませんが、DokuWikiの管理を簡単にしてくれます。</p>
+
+<p>従来のバージョンを使用しているユーザーや特別なセットアップが必要な場合は、次のリンク先を参考にして下さい
+(<a href="http://dokuwiki.org/install">installation instructions</a>, <a href="http://dokuwiki.org/config">configuration settings</a>)。</p>
diff --git a/inc/lang/ja/lang.php b/inc/lang/ja/lang.php
new file mode 100644
index 000000000..0c428ad64
--- /dev/null
+++ b/inc/lang/ja/lang.php
@@ -0,0 +1,314 @@
+<?php
+/**
+ * japanese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = '文書の編集';
+$lang['btn_source'] = 'ソースの表示';
+$lang['btn_show'] = '文書の表示';
+$lang['btn_create'] = '文書の作成';
+$lang['btn_search'] = '検索';
+$lang['btn_save'] = '保存';
+$lang['btn_preview'] = 'プレビュー';
+$lang['btn_top'] = '文書の先頭へ';
+$lang['btn_newer'] = '<< より新しい';
+$lang['btn_older'] = 'より古い >>';
+$lang['btn_revs'] = '以前のリビジョン';
+$lang['btn_recent'] = '最近の変更';
+$lang['btn_upload'] = 'アップロード';
+$lang['btn_cancel'] = 'キャンセル';
+$lang['btn_index'] = 'サイトマップ';
+$lang['btn_secedit'] = '編集';
+$lang['btn_login'] = 'ログイン';
+$lang['btn_logout'] = 'ログアウト';
+$lang['btn_admin'] = '管理';
+$lang['btn_update'] = '更新';
+$lang['btn_delete'] = '削除';
+$lang['btn_back'] = '戻る';
+$lang['btn_backlink'] = 'バックリンク';
+$lang['btn_backtomedia'] = 'メディアファイル選択に戻る';
+$lang['btn_subscribe'] = '変更履歴配信の登録';
+$lang['btn_profile'] = 'ユーザー情報の更新';
+$lang['btn_reset'] = 'リセット';
+$lang['btn_resendpwd'] = 'パスワード再発行';
+$lang['btn_draft'] = 'ドラフトを編集';
+$lang['btn_recover'] = 'ドラフトを復元';
+$lang['btn_draftdel'] = 'ドラフトを削除';
+$lang['btn_revert'] = '元に戻す';
+$lang['btn_register'] = 'ユーザー登録';
+$lang['btn_apply'] = '適用';
+$lang['btn_media'] = 'メディアマネージャー';
+$lang['loggedinas'] = 'ようこそ';
+$lang['user'] = 'ユーザー名';
+$lang['pass'] = 'パスワード';
+$lang['newpass'] = '新しいパスワード';
+$lang['oldpass'] = '現在のパスワード';
+$lang['passchk'] = '確認';
+$lang['remember'] = 'ユーザー名とパスワードを記憶する';
+$lang['fullname'] = 'フルネーム';
+$lang['email'] = 'メールアドレス';
+$lang['profile'] = 'ユーザー情報';
+$lang['badlogin'] = 'ユーザー名かパスワードが違います。';
+$lang['minoredit'] = '小変更';
+$lang['draftdate'] = 'ドラフト保存日時:';
+$lang['nosecedit'] = 'ページ内容が変更されていますがセクション情報が古いため、代わりにページ全体をロードしました。';
+$lang['regmissing'] = '全ての項目を入力してください。';
+$lang['reguexists'] = 'このユーザー名は既に存在しています。';
+$lang['regsuccess'] = '新しいユーザーが作成されました。パスワードは登録したメールアドレス宛てに送付されます。';
+$lang['regsuccess2'] = '新しいユーザーが作成されました。';
+$lang['regmailfail'] = 'パスワードのメール送信に失敗しました。お手数ですが管理者まで連絡をお願いします。';
+$lang['regbadmail'] = 'メールアドレスが有効ではありません。';
+$lang['regbadpass'] = '確認用のパスワードが正しくありません。';
+$lang['regpwmail'] = 'あなたの DokuWiki パスワード';
+$lang['reghere'] = 'ご自分用のアカウントを取ってみては如何ですか?';
+$lang['profna'] = 'ユーザー情報の変更は出来ません';
+$lang['profnochange'] = '変更点はありませんでした。';
+$lang['profnoempty'] = 'ユーザー名とメールアドレスを入力して下さい。';
+$lang['profchanged'] = 'ユーザー情報は更新されました。';
+$lang['pwdforget'] = 'パスワードをお忘れですか?パスワード再発行';
+$lang['resendna'] = 'パスワードの再発行は出来ません。';
+$lang['resendpwd'] = '新しいパスワードを送信します:';
+$lang['resendpwdmissing'] = '全ての項目を入力して下さい。';
+$lang['resendpwdnouser'] = '入力されたユーザーが見つかりませんでした。';
+$lang['resendpwdbadauth'] = '申し訳ありません。この確認コードは有効ではありません。メール内に記載されたリンクを確認してください。';
+$lang['resendpwdconfirm'] = '確認用のリンクを含んだメールを送信しました。';
+$lang['resendpwdsuccess'] = '新しいパスワードがメールで送信されました。';
+$lang['license'] = '特に明示されていない限り、本Wikiの内容は次のライセンスに従います:';
+$lang['licenseok'] = '注意: 本ページを編集することは、あなたの編集した内容が次のライセンスに従うことに同意したものとみなします:';
+$lang['searchmedia'] = '検索ファイル名:';
+$lang['searchmedia_in'] = '%s 内を検索';
+$lang['txt_upload'] = 'アップロードするファイルを選んでください。';
+$lang['txt_filename'] = '名前を変更してアップロード(オプション)';
+$lang['txt_overwrt'] = '既存のファイルを上書き';
+$lang['lockedby'] = 'この文書は次のユーザによってロックされています';
+$lang['lockexpire'] = 'ロック期限:';
+$lang['js']['willexpire'] = '編集中の文書はロック期限を過ぎようとしています。このままロックする場合は、一度文書の確認を行って期限をリセットしてください。';
+$lang['js']['notsavedyet'] = '変更は保存されません。このまま処理を続けてよろしいですか?';
+$lang['js']['searchmedia'] = 'ファイル検索';
+$lang['js']['keepopen'] = '選択中はウィンドウを閉じない';
+$lang['js']['hidedetails'] = '詳細を非表示';
+$lang['js']['mediatitle'] = 'リンク設定';
+$lang['js']['mediadisplay'] = 'リンクタイプ';
+$lang['js']['mediaalign'] = '位置';
+$lang['js']['mediasize'] = 'イメージサイズ';
+$lang['js']['mediatarget'] = 'リンク先';
+$lang['js']['mediaclose'] = '閉じる';
+$lang['js']['mediainsert'] = '挿入';
+$lang['js']['mediadisplayimg'] = 'イメージを表示';
+$lang['js']['mediadisplaylnk'] = 'リンクのみ表示';
+$lang['js']['mediasmall'] = '小さいサイズ';
+$lang['js']['mediamedium'] = '通常サイズ';
+$lang['js']['medialarge'] = '大きいサイズ';
+$lang['js']['mediaoriginal'] = 'オリジナルのサイズ';
+$lang['js']['medialnk'] = '詳細ページへのリンク';
+$lang['js']['mediadirect'] = 'オリジナルへの直リンク';
+$lang['js']['medianolnk'] = 'リンク無し';
+$lang['js']['medianolink'] = 'イメージをリンクしない';
+$lang['js']['medialeft'] = 'イメージを左に寄せる';
+$lang['js']['mediaright'] = 'イメージを右に寄せる';
+$lang['js']['mediacenter'] = 'イメージを中央に寄せる';
+$lang['js']['medianoalign'] = '位置を設定しない';
+$lang['js']['nosmblinks'] = 'ウィンドウズの共有フォルダへリンクは Microsoft Internet Explorer でのみ可能となります。
+当然、カットアンドペーストが使用できます。';
+$lang['js']['linkwiz'] = 'リンクウィザード';
+$lang['js']['linkto'] = 'リンク先:';
+$lang['js']['del_confirm'] = '選択した項目を本当に削除しますか?';
+$lang['js']['restore_confirm'] = '本当にこのバージョンを復元しますか?';
+$lang['js']['media_diff'] = '差分の表示方法:';
+$lang['js']['media_diff_both'] = '並べて表示';
+$lang['js']['media_diff_opacity'] = '重ねて透過表示';
+$lang['js']['media_diff_portions'] = '重ねて切替表示';
+$lang['js']['media_select'] = 'ファイルを選択...';
+$lang['js']['media_upload_btn'] = 'アップロード';
+$lang['js']['media_done_btn'] = '完了';
+$lang['js']['media_drop'] = 'ここにファイルをドロップするとアップロードします';
+$lang['js']['media_cancel'] = '削除';
+$lang['js']['media_overwrt'] = '既存のファイルを上書きする';
+$lang['rssfailed'] = 'RSSの取得に失敗しました:';
+$lang['nothingfound'] = '該当文書はありませんでした。';
+$lang['mediaselect'] = 'メディアファイル';
+$lang['fileupload'] = 'メディアファイルをアップロード';
+$lang['uploadsucc'] = 'アップロード完了';
+$lang['uploadfail'] = 'アップロードに失敗しました。権限がありません。';
+$lang['uploadwrong'] = 'アップロードは拒否されました。この拡張子は許可されていません。';
+$lang['uploadexist'] = '同名のファイルが存在するため、アップロードできません。';
+$lang['uploadbadcontent'] = 'アップロードされたファイルの内容は、拡張子 %s と一致しません。';
+$lang['uploadspam'] = 'スパムブラックリストによりアップロードが遮断されました。';
+$lang['uploadxss'] = '悪意のある内容である可能性により、アップロードが遮断されました。';
+$lang['uploadsize'] = 'アップロードしようとしたファイルは大きすぎます(最大 %s)。';
+$lang['deletesucc'] = 'ファイル "%s" は削除されました。';
+$lang['deletefail'] = 'ファイル "%s" が削除できません。権限を確認して下さい。';
+$lang['mediainuse'] = 'ファイル "%s" は使用中のため、削除されませんでした。';
+$lang['namespaces'] = '名前空間';
+$lang['mediafiles'] = '有効なファイル:';
+$lang['accessdenied'] = 'このページを閲覧する権限がありません。';
+$lang['mediausage'] = 'このファイルを使用するためには次の文法を使用する:';
+$lang['mediaview'] = 'オリジナルファイルを閲覧';
+$lang['mediaroot'] = 'ルート';
+$lang['mediaupload'] = 'ファイルを現在の名前空間にアップロードします。副名前空間を使用する場合には、ファイル名の前にコロンで区切って追加してください。';
+$lang['mediaextchange'] = '拡張子が .%s から .%s へ変更されました。';
+$lang['reference'] = '参照先';
+$lang['ref_inuse'] = 'このファイルは、次のページで使用中のため削除できません。';
+$lang['ref_hidden'] = 'このページに存在するいくつかの参照先は、権限が無いため読むことができません。';
+$lang['hits'] = 'ヒット';
+$lang['quickhits'] = 'マッチした文書名';
+$lang['toc'] = '目次';
+$lang['current'] = '現在';
+$lang['yours'] = 'あなたのバージョン';
+$lang['diff'] = '現在のリビジョンとの差分を表示';
+$lang['diff2'] = '選択したリビジョン間の差分を表示';
+$lang['difflink'] = 'この比較画面にリンクする';
+$lang['diff_type'] = '差分の表示方法:';
+$lang['diff_inline'] = 'インライン';
+$lang['diff_side'] = '横に並べる';
+$lang['line'] = 'ライン';
+$lang['breadcrumb'] = 'トレース';
+$lang['youarehere'] = '現在位置';
+$lang['lastmod'] = '最終更新';
+$lang['by'] = 'by';
+$lang['deleted'] = '削除';
+$lang['created'] = '作成';
+$lang['restored'] = '以前のバージョンを復元';
+$lang['external_edit'] = '外部編集';
+$lang['summary'] = '編集の概要';
+$lang['noflash'] = 'この内容を表示するためには <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> が必要です。';
+$lang['download'] = 'この部分をダウンロード';
+$lang['mail_newpage'] = '文書の追加:';
+$lang['mail_changed'] = '文書の変更:';
+$lang['mail_subscribe_list'] = '名前空間内でページが変更:';
+$lang['mail_new_user'] = '新規ユーザー:';
+$lang['mail_upload'] = 'ファイルのアップロード:';
+$lang['changes_type'] = '表示する変更のタイプ:';
+$lang['pages_changes'] = 'ページの変更';
+$lang['media_changes'] = 'メディアファイルの変更';
+$lang['both_changes'] = 'ページとメディアファイルの変更';
+$lang['qb_bold'] = '太字';
+$lang['qb_italic'] = '斜体';
+$lang['qb_underl'] = '下線';
+$lang['qb_code'] = 'コード';
+$lang['qb_strike'] = '打消線';
+$lang['qb_h1'] = '第一見出し';
+$lang['qb_h2'] = '第二見出し';
+$lang['qb_h3'] = '第三見出し';
+$lang['qb_h4'] = '第四見出し';
+$lang['qb_h5'] = '第五見出し';
+$lang['qb_h'] = '見出し';
+$lang['qb_hs'] = '見出し選択';
+$lang['qb_hplus'] = '上の階層の見出し';
+$lang['qb_hminus'] = '下の階層の見出し';
+$lang['qb_hequal'] = '同じ階層の見出し';
+$lang['qb_link'] = '内部リンク';
+$lang['qb_extlink'] = '外部リンク';
+$lang['qb_hr'] = '横罫線';
+$lang['qb_ol'] = '記号付きリスト';
+$lang['qb_ul'] = '記号なしリスト';
+$lang['qb_media'] = 'イメージやファイルの追加';
+$lang['qb_sig'] = '署名の挿入';
+$lang['qb_smileys'] = 'スマイリー';
+$lang['qb_chars'] = '特殊文字';
+$lang['upperns'] = '上の階層の名前空間へ';
+$lang['admin_register'] = '新規ユーザー作成';
+$lang['metaedit'] = 'メタデータ編集';
+$lang['metasaveerr'] = 'メタデータの書き込みに失敗しました';
+$lang['metasaveok'] = 'メタデータは保存されました';
+$lang['img_backto'] = '戻る';
+$lang['img_title'] = 'タイトル';
+$lang['img_caption'] = '見出し';
+$lang['img_date'] = '日付';
+$lang['img_fname'] = 'ファイル名';
+$lang['img_fsize'] = 'サイズ';
+$lang['img_artist'] = '作成者';
+$lang['img_copyr'] = '著作権';
+$lang['img_format'] = 'フォーマット';
+$lang['img_camera'] = '使用カメラ';
+$lang['img_keywords'] = 'キーワード';
+$lang['img_width'] = '幅';
+$lang['img_height'] = '高さ';
+$lang['img_manager'] = 'メディアマネージャーで閲覧';
+$lang['subscr_subscribe_success'] = '%sが%sの購読リストに登録されました。';
+$lang['subscr_subscribe_error'] = '%sを%sの購読リストへの追加に失敗しました。';
+$lang['subscr_subscribe_noaddress'] = 'あなたのログインに対応するアドレスがないため、購読リストへ追加することができません。';
+$lang['subscr_unsubscribe_success'] = '%sを%sの購読リストから削除しました。';
+$lang['subscr_unsubscribe_error'] = '%sを%sの購読リストからの削除に失敗しました。';
+$lang['subscr_already_subscribed'] = '%sは既に%sに登録されています。';
+$lang['subscr_not_subscribed'] = '%sは%sに登録されていません。';
+$lang['subscr_m_not_subscribed'] = '現在のページ、もしくは名前空間にあなたは登録されていません。';
+$lang['subscr_m_new_header'] = '購読を追加';
+$lang['subscr_m_current_header'] = '現在の購読リスト';
+$lang['subscr_m_unsubscribe'] = '購読を解除';
+$lang['subscr_m_subscribe'] = '購読';
+$lang['subscr_m_receive'] = '受信';
+$lang['subscr_style_every'] = '全ての変更にメールを送信';
+$lang['subscr_style_digest'] = 'それぞれのページへの変更の要約をメールする(%.2f 日毎)';
+$lang['subscr_style_list'] = '前回のメールから変更されたページをリスト(%.2f 日毎)';
+$lang['authmodfailed'] = 'ユーザー認証の設定が正しくありません。Wikiの管理者に連絡して下さい。';
+$lang['authtempfail'] = 'ユーザー認証が一時的に使用できなくなっています。この状態が続いているようであれば、Wikiの管理者に連絡して下さい。';
+$lang['i_chooselang'] = '使用言語を選択してください';
+$lang['i_installer'] = 'DokuWiki インストーラー';
+$lang['i_wikiname'] = 'Wiki名';
+$lang['i_enableacl'] = 'ACL(アクセス管理)を使用する(推奨)';
+$lang['i_superuser'] = 'スーパーユーザー';
+$lang['i_problems'] = '問題が発見されました。以下に示す問題を解決するまで、インストールを続行できません。';
+$lang['i_modified'] = 'セキュリティの理由から、新規もしくはカスタマイズしていない DokuWiki に対してのみ、このスクリプトは有効です。
+ ダウンロードしたパッケージを再解凍して使用するか、
+ <a href="http://dokuwiki.org/install">Dokuwiki インストールガイド</a>を参考にしてインストールしてください。';
+$lang['i_funcna'] = 'PHPの関数 <code>%s</code> が使用できません。ホスティング会社が何らかの理由で無効にしている恐れがあります。';
+$lang['i_phpver'] = 'PHPのバージョン <code>%s</code> が必要なバージョン <code>%s</code> より以前のものです。PHPのアップグレードが必要です。';
+$lang['i_permfail'] = '<code>%s</code> に書き込みできません。このディレクトリの権限を確認して下さい。';
+$lang['i_confexists'] = '<code>%s</code> は既に存在します';
+$lang['i_writeerr'] = '<code>%s</code> を作成できません。ディレクトリとファイルの権限を確認し、それらを手動で作成する必要があります。';
+$lang['i_badhash'] = 'dokuwiki.php が認識できないか、編集されています(hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - 正しくない、もしくは値が空です';
+$lang['i_success'] = '設定ファイルは正しく作成されました。<a href="doku.php">作成した DokuWiki</a>を使用するには install.php を削除してください。';
+$lang['i_failure'] = '設定ファイルの作成中にエラーが発生しました。<a href="doku.php">作成した DokuWiki</a>を使用する前に、それらの問題を手動で修正する必要があります。';
+$lang['i_policy'] = 'ACL初期設定';
+$lang['i_pol0'] = 'オープン Wiki(全ての人に、閲覧・書き込み・アップロードを許可)';
+$lang['i_pol1'] = 'パブリック Wiki(閲覧は全ての人が可能、書き込み・アップロードは登録ユーザーのみ)';
+$lang['i_pol2'] = 'クローズド Wiki (登録ユーザーにのみ使用を許可)';
+$lang['i_retry'] = '再試行';
+$lang['i_license'] = 'あなたが作成したコンテンツが属するライセンスを選択してください:';
+$lang['recent_global'] = '現在、<b>%s</b> 名前空間内の変更点を閲覧中です。<a href="%s">Wiki全体の最近の変更点を確認する</a>ことも可能です。';
+$lang['years'] = '%d年前';
+$lang['months'] = '%dカ月前';
+$lang['weeks'] = '%d週間前';
+$lang['days'] = '%d日前';
+$lang['hours'] = '%d時間前';
+$lang['minutes'] = '%d分前';
+$lang['seconds'] = '%d秒前';
+$lang['wordblock'] = 'スパムと認識されるテキストが含まれているため、変更は保存されませんでした。';
+$lang['media_uploadtab'] = 'アップロード';
+$lang['media_searchtab'] = '検索';
+$lang['media_file'] = 'ファイル';
+$lang['media_viewtab'] = '詳細';
+$lang['media_edittab'] = '編集';
+$lang['media_historytab'] = '履歴';
+$lang['media_list_thumbs'] = 'サムネイル';
+$lang['media_list_rows'] = '行';
+$lang['media_sort_name'] = '名前';
+$lang['media_sort_date'] = '日付';
+$lang['media_namespaces'] = '名前空間を選択';
+$lang['media_files'] = '%s 内のファイル';
+$lang['media_upload'] = '%s にアップロード';
+$lang['media_search'] = '%s 内で検索';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s at %s';
+$lang['media_edit'] = '%s を編集';
+$lang['media_history'] = '%s の履歴';
+$lang['media_meta_edited'] = 'メタデータが編集されました';
+$lang['media_perm_read'] = 'ファイルを閲覧する権限がありません。';
+$lang['media_perm_upload'] = 'ファイルをアップロードする権限がありません。';
+$lang['media_update'] = '新しいバージョンをアップロード';
+$lang['media_restore'] = 'このバージョンを復元';
+$lang['plugin_install_err'] = 'プラグインが正しくインストールされませんでした。プラグインのディレクトリ名を \'%s\' から \'%s\' に変更してください。';
diff --git a/inc/lang/ja/locked.txt b/inc/lang/ja/locked.txt
new file mode 100644
index 000000000..1c37c93d1
--- /dev/null
+++ b/inc/lang/ja/locked.txt
@@ -0,0 +1,3 @@
+====== 文書ロック中 ======
+
+この文書は他のユーザーによってロックされています。編集が完了するか、ロックの期限が切れるのを待って下さい。
diff --git a/inc/lang/ja/login.txt b/inc/lang/ja/login.txt
new file mode 100644
index 000000000..ef18d378e
--- /dev/null
+++ b/inc/lang/ja/login.txt
@@ -0,0 +1,4 @@
+====== ログイン ======
+
+ユーザー名とパスワードを入力してログインしてください(クッキーを有効にする必要があります)。
+
diff --git a/inc/lang/ja/mailtext.txt b/inc/lang/ja/mailtext.txt
new file mode 100644
index 000000000..09688cbb7
--- /dev/null
+++ b/inc/lang/ja/mailtext.txt
@@ -0,0 +1,17 @@
+DokuWiki 内の文書が追加もしくは変更されました。詳細は以下の通りです。
+
+日付 : @DATE@
+ブラウザ : @BROWSER@
+IPアドレス : @IPADDRESS@
+ホスト名 : @HOSTNAME@
+前リビジョン: @OLDPAGE@
+新リビジョン: @NEWPAGE@
+編集のサマリ: @SUMMARY@
+ユーザー名 : @USER@
+
+@DIFF@
+
+
+--
+このメールは次のDokuWikiより自動的に送信されています。
+@DOKUWIKIURL@
diff --git a/inc/lang/ja/newpage.txt b/inc/lang/ja/newpage.txt
new file mode 100644
index 000000000..d03169f8a
--- /dev/null
+++ b/inc/lang/ja/newpage.txt
@@ -0,0 +1,4 @@
+====== このトピックには文書が存在しません ======
+
+このトピックに文書が作成されていません。 もし、文書作成の権限がある場合は、''文書の作成''をクリックして 最初の文書を作成することができます。
+
diff --git a/inc/lang/ja/norev.txt b/inc/lang/ja/norev.txt
new file mode 100644
index 000000000..48ccde700
--- /dev/null
+++ b/inc/lang/ja/norev.txt
@@ -0,0 +1,4 @@
+====== リビジョンが存在しません ======
+
+指定されたリビジョン存在しません。''以前のリビジョン''をクリックして確認してください。
+
diff --git a/inc/lang/ja/password.txt b/inc/lang/ja/password.txt
new file mode 100644
index 000000000..c00fe0bc2
--- /dev/null
+++ b/inc/lang/ja/password.txt
@@ -0,0 +1,10 @@
+こんにちは @FULLNAME@! さん
+
+@TITLE@(@DOKUWIKIURL@)に登録されたユーザー情報は以下の通りです。
+
+ユーザー名 : @LOGIN@
+パスワード : @PASSWORD@
+
+--
+このメールは次のDokuWikiより自動的に送信されています。
+@DOKUWIKIURL@
diff --git a/inc/lang/ja/preview.txt b/inc/lang/ja/preview.txt
new file mode 100644
index 000000000..ee839cd06
--- /dev/null
+++ b/inc/lang/ja/preview.txt
@@ -0,0 +1,4 @@
+====== プレビュー ======
+
+編集中の文書のプレビューです。確認用なので**保存されていない**ことに注意してください。
+
diff --git a/inc/lang/ja/pwconfirm.txt b/inc/lang/ja/pwconfirm.txt
new file mode 100644
index 000000000..98ccfcdea
--- /dev/null
+++ b/inc/lang/ja/pwconfirm.txt
@@ -0,0 +1,13 @@
+こんにちは @FULLNAME@ さん
+
+@TITLE@(@DOKUWIKIURL@)に新規パスワード発行のリクエストがありました。
+
+もしこのリクエストに覚えが無ければ、このメールは無視してください。
+
+このリクエストを行った本人であれば、以下のリンクから作業を完了させてください。
+
+@CONFIRM@
+
+--
+このメールは次のDokuWikiより自動的に送信されています。
+@DOKUWIKIURL@
diff --git a/inc/lang/ja/read.txt b/inc/lang/ja/read.txt
new file mode 100644
index 000000000..14137cc14
--- /dev/null
+++ b/inc/lang/ja/read.txt
@@ -0,0 +1,2 @@
+この文書は読取専用です。文書のソースを閲覧することは可能ですが、変更はできません。もし変更したい場合は管理者に連絡してください。
+
diff --git a/inc/lang/ja/recent.txt b/inc/lang/ja/recent.txt
new file mode 100644
index 000000000..d18fd1bc2
--- /dev/null
+++ b/inc/lang/ja/recent.txt
@@ -0,0 +1,5 @@
+====== 最近の変更 ======
+
+以下の文書は最近更新されたものです。
+
+
diff --git a/inc/lang/ja/register.txt b/inc/lang/ja/register.txt
new file mode 100644
index 000000000..b242d1e88
--- /dev/null
+++ b/inc/lang/ja/register.txt
@@ -0,0 +1,4 @@
+====== 新規ユーザー登録 ======
+
+このWikiのユーザー登録を行うためには、以下の情報を全て入力して下さい。 もし以下の項目にパスワードが存在しない場合、パスワードはメールにて送信されますので、 必ず**有効な**メールアドレスを入力してください。 また、ログイン名は [[doku>pagename|pagename]] に準拠していなければなりません。
+
diff --git a/inc/lang/ja/registermail.txt b/inc/lang/ja/registermail.txt
new file mode 100644
index 000000000..2b272de40
--- /dev/null
+++ b/inc/lang/ja/registermail.txt
@@ -0,0 +1,14 @@
+新しいユーザーが登録されました。ユーザー情報は以下の通りです。
+
+ユーザー名 : @NEWUSER@
+フルネーム : @NEWNAME@
+メールアドレス : @NEWEMAIL@
+
+登録日 : @DATE@
+ブラウザ : @BROWSER@
+IPアドレス : @IPADDRESS@
+ホスト名 : @HOSTNAME@
+
+--
+このメールは次のDokuWikiより自動的に送信されています。
+@DOKUWIKIURL@
diff --git a/inc/lang/ja/resendpwd.txt b/inc/lang/ja/resendpwd.txt
new file mode 100644
index 000000000..23dd6ff1f
--- /dev/null
+++ b/inc/lang/ja/resendpwd.txt
@@ -0,0 +1,4 @@
+====== パスワード再発行 ======
+
+このWikiで使用する新しいパスワードをリクエストするために、ユーザー名を入力して下さい。 新パスワード発行リクエストの確認メールが、登録されているメールアドレスに送信されます。
+
diff --git a/inc/lang/ja/revisions.txt b/inc/lang/ja/revisions.txt
new file mode 100644
index 000000000..e43731ccd
--- /dev/null
+++ b/inc/lang/ja/revisions.txt
@@ -0,0 +1,4 @@
+====== 以前のリビジョン ======
+
+以下はこの文書の以前のリビジョンです。復元するには''文書の編集''をクリック、その後保存してください。
+
diff --git a/inc/lang/ja/searchpage.txt b/inc/lang/ja/searchpage.txt
new file mode 100644
index 000000000..af312728b
--- /dev/null
+++ b/inc/lang/ja/searchpage.txt
@@ -0,0 +1,5 @@
+====== 検索 ======
+
+以下に検索結果を表示します。もし、探しているものが見つからない場合、 検索キーワードにちなんだ名前の文書を作成もしくは編集を行ってください。
+
+===== 結果 =====
diff --git a/inc/lang/ja/showrev.txt b/inc/lang/ja/showrev.txt
new file mode 100644
index 000000000..d8ce4784e
--- /dev/null
+++ b/inc/lang/ja/showrev.txt
@@ -0,0 +1,2 @@
+**以前のリビジョンの文書です**
+----
diff --git a/inc/lang/ja/stopwords.txt b/inc/lang/ja/stopwords.txt
new file mode 100644
index 000000000..628e46ebe
--- /dev/null
+++ b/inc/lang/ja/stopwords.txt
@@ -0,0 +1,29 @@
+# 以下は、インデックス作成時に無視する語句のリストです。一行に一単語ずつ記入してください。
+# UNIXで用いられる改行コード(LF)を使用してください
+# 3文字より短い語句は自動的に無視されるので、リストに加える必要はありません。
+# このリストは次のサイトをもとに作成されています(http://www.ranks.nl/stopwords/)
+about
+are
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/ja/subscr_digest.txt b/inc/lang/ja/subscr_digest.txt
new file mode 100644
index 000000000..ff5fc8d47
--- /dev/null
+++ b/inc/lang/ja/subscr_digest.txt
@@ -0,0 +1,21 @@
+こんにちは。
+
+@TITLE@ 内のページ @PAGE@ は変更されました。
+変更点は以下の通りです:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+古いリビジョン: @OLDPAGE@
+新しいリビジョン: @NEWPAGE@
+
+この通知を解除するには次のウィキへログインし
+@DOKUWIKIURL@
+その後、
+@SUBSCRIBE@
+ページと名前空間の変更に対する購読を解除してください。
+
+--
+このメールは次の DokuWiki によって生成されました:
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ja/subscr_form.txt b/inc/lang/ja/subscr_form.txt
new file mode 100644
index 000000000..5767189fd
--- /dev/null
+++ b/inc/lang/ja/subscr_form.txt
@@ -0,0 +1,3 @@
+====== 購読管理 ======
+
+このページで、現在のページと名前空間に対する購読を管理することができます。 \ No newline at end of file
diff --git a/inc/lang/ja/subscr_list.txt b/inc/lang/ja/subscr_list.txt
new file mode 100644
index 000000000..0d225af58
--- /dev/null
+++ b/inc/lang/ja/subscr_list.txt
@@ -0,0 +1,19 @@
+こんにちは。
+
+@TITLE@ の 名前空間 @PAGE@ にあるページが変更されました。
+変更点は以下の通りです:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+
+この通知を解除するには次のウィキへログインし
+@DOKUWIKIURL@
+その後、
+@SUBSCRIBE@
+ページと名前空間の変更に対する購読を解除してください。
+
+--
+このメールは次の DokuWiki によって生成されました:
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ja/subscr_single.txt b/inc/lang/ja/subscr_single.txt
new file mode 100644
index 000000000..b02352238
--- /dev/null
+++ b/inc/lang/ja/subscr_single.txt
@@ -0,0 +1,24 @@
+こんにちは。
+
+@TITLE@ のウィキにあるページ @PAGE@ が変更されました。
+変更点は以下の通りです:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+日付 : @DATE@
+ユーザー : @USER@
+変更概要: @SUMMARY@
+古いリビジョン: @OLDPAGE@
+新しいリビジョン: @NEWPAGE@
+
+この通知を解除するには次のウィキへログインし
+@DOKUWIKIURL@
+その後、
+@SUBSCRIBE@
+ページと名前空間の変更に対する購読を解除してください。
+
+--
+このメールは次の DokuWiki によって生成されました:
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ja/updateprofile.txt b/inc/lang/ja/updateprofile.txt
new file mode 100644
index 000000000..e83d92965
--- /dev/null
+++ b/inc/lang/ja/updateprofile.txt
@@ -0,0 +1,5 @@
+====== アカウント情報更新 ======
+
+変更したい項目を入力して下さい。ユーザー名は変更できません。
+
+
diff --git a/inc/lang/ja/uploadmail.txt b/inc/lang/ja/uploadmail.txt
new file mode 100644
index 000000000..53f30db61
--- /dev/null
+++ b/inc/lang/ja/uploadmail.txt
@@ -0,0 +1,14 @@
+お使いのDokuWikiにファイルがアップロードされました。詳細は以下の通りです。
+
+ファイル : @MEDIA@
+日付 : @DATE@
+ブラウザ : @BROWSER@
+IPアドレス : @IPADDRESS@
+ホスト名 : @HOSTNAME@
+サイズ : @SIZE@
+MIMEタイプ : @MIME@
+ユーザー名 : @USER@
+
+--
+このメールは次のDokuWikiより自動的に送信されています。
+@DOKUWIKIURL@
diff --git a/inc/lang/kk/lang.php b/inc/lang/kk/lang.php
new file mode 100644
index 000000000..9738ae51c
--- /dev/null
+++ b/inc/lang/kk/lang.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '"';
+$lang['doublequoteclosing'] = '"';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Бұл мақаланы өңдеү';
+$lang['btn_source'] = 'Бастапқы мәтінді көрсету';
+$lang['btn_show'] = 'Бетті көрсету';
+$lang['btn_create'] = 'Бұл бетті жасау';
+$lang['btn_search'] = 'Іздеу';
+$lang['btn_save'] = 'Сақтау';
+$lang['btn_preview'] = 'Қарап шығу';
+$lang['btn_top'] = 'Жоғары';
+$lang['btn_newer'] = '<<жаңарақ';
+$lang['btn_older'] = 'ескірек>>';
+$lang['btn_revs'] = 'Қайта қараулары';
+$lang['btn_recent'] = 'Жуырдағы өзгерістер';
+$lang['btn_upload'] = 'Еңгізу';
+$lang['btn_cancel'] = 'Болдырмау';
+$lang['btn_index'] = 'Барлық беттері';
+$lang['btn_secedit'] = 'Өңдеу';
+$lang['btn_login'] = 'Кіру';
+$lang['btn_logout'] = 'Шығу';
+$lang['btn_admin'] = 'Басқару';
+$lang['btn_update'] = 'Жаңарту';
+$lang['btn_delete'] = 'Жою';
+$lang['btn_back'] = 'Артқа';
+$lang['btn_backlink'] = 'Кері сілтемелері';
+$lang['btn_backtomedia'] = 'Медиафайлды таңдауға қайту';
+$lang['btn_subscribe'] = 'Жазылуларды басқару';
+$lang['btn_profile'] = 'Профильді жаңарту';
+$lang['btn_reset'] = 'Түсіру';
+$lang['btn_resendpwd'] = 'Жаңа құпиясөзді жіберу';
+$lang['btn_draft'] = 'Шимайды өңдеу';
+$lang['btn_recover'] = 'Шимайды қайтару';
+$lang['btn_draftdel'] = 'Шимайды өшіру';
+$lang['btn_revert'] = 'Қалпына келтіру';
+$lang['btn_register'] = 'Тіркеу';
+$lang['loggedinas'] = 'түпнұсқамен кірген';
+$lang['user'] = 'Түпнұсқа';
+$lang['pass'] = 'Құпиясөз';
+$lang['newpass'] = 'Жаңа құпиясөз';
+$lang['oldpass'] = 'Ағымдағы құпиясөзді растау';
+$lang['passchk'] = 'Тағы бір рет';
+$lang['remember'] = 'Мені сақтау';
+$lang['fullname'] = 'Шын аты';
+$lang['email'] = 'Е-пошта';
+$lang['profile'] = 'Пайдаланушының профилі';
+$lang['badlogin'] = 'Кешріңіз, түпнұсқа әлде құпиясөз дұрыс емес';
+$lang['minoredit'] = 'Шағын өзгерістер';
+$lang['draftdate'] = 'Шимай сақталғаны';
+$lang['nosecedit'] = 'Бет өзгерді де бөлік тұралы ақпарат ескірді. Толық нұсқасы ашылды.';
+$lang['regmissing'] = 'Кешіріңіз, барлық тармақтары толтыруыңыз керек.';
+$lang['reguexists'] = 'Кешіріңіз, бұл түпнұскамен де пайдаланушы бар.';
+$lang['regsuccess'] = 'Пайдаланушы қосылды әрі құпиясөзін электрондық поштаға жіберді.';
+$lang['regsuccess2'] = 'Пайдаланушы қосылды.';
+$lang['regmailfail'] = 'Құпиясөз хатты жіберуде қате болған сияқты. Мархабат, әкімшімен хабарласыңыз.';
+$lang['regbadmail'] = 'Берілген электрондық пошта бұрыс деп көрінеді - егер бұл қателікті деп ойласаңыз, әкімшіге хабарлаңыз.';
+$lang['regbadpass'] = 'Берілген екі құпиясөз бірдей емес, мархабат. қайтадан көріңіз.';
+$lang['regpwmail'] = 'Сіздің DokuWiki құпиясөзіңіз';
+$lang['reghere'] = 'Есебіңіз әлі жоқ па? Біреуін оңай ашыңыз';
+$lang['profna'] = 'Бұл wiki профиль өзертуді қолдамайды';
+$lang['profnochange'] = 'Өзгеріс жоқ, істейтін ештеңе жоқ.';
+$lang['profnoempty'] = 'Бос есім не email рұқсат етілмейді.';
+$lang['profchanged'] = 'Пайдаланушы профилі сәтті жаңартылған.';
+$lang['pwdforget'] = 'Құпиясөзіңізді ұмыттыңызба? Жаңадан біреуін алыңыз';
+$lang['resendna'] = 'Бұл wiki құпиясөзді қайта жіберуді қолдамайды.';
+$lang['resendpwd'] = 'Келесіге жаңа құпиясөзді жіберу ';
+$lang['resendpwdmissing'] = 'Кешіріңіз, барлық тармақтары толтыруыңыз керек.';
+$lang['resendpwdnouser'] = 'Кешіріңіз, бұл пайдаланушыны дерекқорымызда тапқан жоқпыз.';
+$lang['resendpwdbadauth'] = 'Кешіріңіз, бұл түпнұсқалық коды бұрыс. Толық растау сілтемені пайдалануыңызды тексеріңіз.';
+$lang['resendpwdconfirm'] = 'Растау сілтеме email арқылы жіберілді.';
+$lang['resendpwdsuccess'] = 'Сіздің жаңа құпиясөзіңіз email арқылы жіберілді.';
+$lang['license'] = 'Басқаша көрсетілген болмаса, бұл wiki-дің мазмұны келесі лицензия бойынша беріледі:';
+$lang['licenseok'] = 'Ескерту: бұл бетті өңдеуіңізбен мазмұныңыз келесі лицензия бойынша беруге келесесіз:';
+$lang['searchmedia'] = 'Іздеу файлдың атауы:';
+$lang['searchmedia_in'] = '%s-мен іздеу:';
+$lang['txt_upload'] = 'Еңгізетін файлды таңдау';
+$lang['txt_filename'] = 'Келесідей еңгізу (қалауынша)';
+$lang['txt_overwrt'] = 'Бар файлды қайта жазу';
+$lang['lockedby'] = 'Осы уақытта тойтарылған';
+$lang['lockexpire'] = 'Тойтару келесі уақытта бітеді';
+$lang['js']['willexpire'] = 'Бұл бетті түзеу тойтаруыңыз бір минутта бітеді. Қақтығыс болмау және тойтару таймерді түсіру үшін қарап шығу пернені басыңыз.';
+$lang['js']['notsavedyet'] = 'Сақталмаған өзгерістер жоғалатын болады.';
+$lang['js']['searchmedia'] = 'Файлдарды іздеу';
+$lang['js']['keepopen'] = 'Таңдаған соң терезе жаппаңыз';
+$lang['js']['hidedetails'] = 'Ұсақтарды жасыру';
+$lang['js']['mediatitle'] = 'Султеме теңшелімдері';
+$lang['js']['mediadisplay'] = 'Сілтеме түрі';
+$lang['js']['mediaalign'] = 'Тегістеуі';
+$lang['js']['mediasize'] = 'Сүреттің өлшемі';
+$lang['js']['mediatarget'] = 'Сілтеме нысанасы';
+$lang['js']['mediaclose'] = 'Жабу';
+$lang['js']['mediainsert'] = 'Еңгізу';
+$lang['js']['mediadisplayimg'] = 'Бұл сүретті көрсету';
+$lang['js']['mediadisplaylnk'] = 'Бұл сілтемені ғана көрсету,';
+$lang['js']['mediasmall'] = 'Шағын нұсқасы';
+$lang['js']['mediamedium'] = 'Орташа нұсқасы';
+$lang['js']['medialarge'] = 'Үлкен нұсқасы';
+$lang['js']['mediaoriginal'] = 'Түпнұсқалық нұсқасы';
+$lang['js']['medialnk'] = 'Толық бетке сілтеме';
+$lang['js']['mediadirect'] = 'Түпнұсқалыққа тұра сілтемесі';
+$lang['js']['medianolnk'] = 'Сілтеме жоқ';
+$lang['js']['medianolink'] = 'Суретті сілтетпеу';
+$lang['js']['medialeft'] = 'Сүретті сол жаққа тегістеу';
+$lang['js']['mediaright'] = 'Сүретті оң жаққа тегістеу';
+$lang['js']['mediacenter'] = 'Сүретті ортаға тегістеу';
+$lang['js']['medianoalign'] = 'Тегістеусіз';
diff --git a/inc/lang/km/admin.txt b/inc/lang/km/admin.txt
new file mode 100644
index 000000000..29338b2e7
--- /dev/null
+++ b/inc/lang/km/admin.txt
@@ -0,0 +1,3 @@
+====== អ្នកគ្រោង ======
+ខាងក្រោមជាប្រដបប្រដារបស់អ្នកគ្រោង ឌោគូវីគី។
+
diff --git a/inc/lang/km/backlinks.txt b/inc/lang/km/backlinks.txt
new file mode 100644
index 000000000..f28068a58
--- /dev/null
+++ b/inc/lang/km/backlinks.txt
@@ -0,0 +1,5 @@
+====== ខ្សែដំណរក្រោយ ======
+នេះជាទំព័រដែលមានដំណរបណ្តពីទំព័រឥឡូវ។
+====== Backlinks ======
+This is a list of pages that seem to link back to the current page.
+
diff --git a/inc/lang/km/conflict.txt b/inc/lang/km/conflict.txt
new file mode 100644
index 000000000..7b95fda65
--- /dev/null
+++ b/inc/lang/km/conflict.txt
@@ -0,0 +1,3 @@
+====== មានបុនរាព្រឹត្តិថ្មីៗ ======
+មានបុនរាព្រឹត្តិថ្មី
+
diff --git a/inc/lang/km/denied.txt b/inc/lang/km/denied.txt
new file mode 100644
index 000000000..58b10ee86
--- /dev/null
+++ b/inc/lang/km/denied.txt
@@ -0,0 +1,3 @@
+====== បដិសេធអនុញ្ញាត ======
+សូមទុស អ្នកគ្មានអនុញ្ញាតទៅបណ្តទេ។
+
diff --git a/inc/lang/km/edit.txt b/inc/lang/km/edit.txt
new file mode 100644
index 000000000..516ea3779
--- /dev/null
+++ b/inc/lang/km/edit.txt
@@ -0,0 +1,3 @@
+កែតម្រូវទំព័រនេះហើយ ចុច«រក្សាតុក»។ មើល [[wiki:syntax|វាក្យ​សម្ពន្ធ]] ជាកម្នូវីគី។
+សំកែសម្រួលបើអ្នកអាច**ច្នៃចរើន**វា។ បើអ្នកចង់សាកពិសោតអ្វីមួយ សំរៀននៅក្នុង
+[[playground:playground|playground]]។
diff --git a/inc/lang/km/editrev.txt b/inc/lang/km/editrev.txt
new file mode 100644
index 000000000..097c1dae1
--- /dev/null
+++ b/inc/lang/km/editrev.txt
@@ -0,0 +1,2 @@
+**អ្នក ឯក្សារចាស់!** បើអ្នករក្សាវា អ្នកគុង់តែបង្កើត ថ្មីជាមួយទិន្នន័យនេះ។
+----
diff --git a/inc/lang/km/index.txt b/inc/lang/km/index.txt
new file mode 100644
index 000000000..350050837
--- /dev/null
+++ b/inc/lang/km/index.txt
@@ -0,0 +1,2 @@
+====== លិបិក្រម ======
+នេះជាលិបិក្រមទំព័រទាំងឡាយបញ្ជាដោយ [[doku>wiki:namespaces|នាមថាន]]។
diff --git a/inc/lang/km/lang.php b/inc/lang/km/lang.php
new file mode 100644
index 000000000..68587e90f
--- /dev/null
+++ b/inc/lang/km/lang.php
@@ -0,0 +1,227 @@
+<?php
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Ratana Lim <aerorat@yahoo.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '«';
+$lang['doublequoteclosing'] = '»';
+$lang['singlequoteopening'] = '‘';//&lsquo;
+$lang['singlequoteclosing'] = '’';//&rsquo;
+$lang['apostrophe'] = '’';//&rsquo;
+
+$lang['btn_edit'] = 'កែទំព័រនេះ';
+$lang['btn_source'] = 'បង្ហាងប្រភពទំព័រ';
+$lang['btn_show'] = 'បង្ហាងទំព័រ';
+$lang['btn_create'] = 'បង្កើតទំព័រនេះ';
+$lang['btn_search'] = 'ស្វែងរក';
+$lang['btn_save'] = 'រក្សាទុក';
+$lang['btn_preview']= 'បង្ហាញ';
+$lang['btn_top'] = 'ទៅលើ';
+$lang['btn_newer'] = '<<ទំព័រទំនើប';
+$lang['btn_older'] = 'ទំព័រថ្មែសម័យ>>';
+$lang['btn_revs'] = 'ទំព័រចាស់ៗ';
+$lang['btn_recent'] = 'ទំព័រថ្មីៗ';
+$lang['btn_upload'] = 'ដាកលើង';
+$lang['btn_cancel'] = 'បោះបង់';
+$lang['btn_index'] = 'លិបិក្រម';
+$lang['btn_secedit']= 'កែ';
+$lang['btn_login'] = 'កត់ចូល';
+$lang['btn_logout'] = 'កត់ចេញ';
+$lang['btn_admin'] = 'អ្នកគ្រប់គ្រង';
+$lang['btn_update'] = 'កែឡើង';
+$lang['btn_delete'] = 'លុបចោល';
+$lang['btn_back'] = 'ត្រឡប់';
+$lang['btn_backlink'] = 'ខ្សែចំណងក្រោយ';
+$lang['btn_backtomedia'] = 'ទៅប្រព័នឯកសាវិញ';
+$lang['btn_subscribe'] = 'ដាក់ដំណឹងផ្លស់ប្តូរ';
+$lang['btn_unsubscribe'] = 'ដកដំណឹងផ្លស់ប្តូរ';
+$lang['btn_profile'] = 'កែប្រវត្តិរូប';
+$lang['btn_reset'] = 'កមណត់ឡើងរិញ';
+$lang['btn_resendpwd'] = 'ផ្ញើពាក្សសម្ងាត់';
+$lang['btn_draft'] = 'កែគំរោង';
+$lang['btn_recover'] = 'ស្រោះគំរោងឡើង';
+$lang['btn_draftdel'] = 'លុបគំរោង';
+$lang['btn_register'] = 'ចុះឈ្មោះ';//'Register';
+
+$lang['loggedinas'] = 'អ្នកប្រើ';
+$lang['user'] = 'នាមបម្រើ';
+$lang['pass'] = 'ពាក្សសម្ងត់';
+$lang['newpass'] = 'ពាក្សសម្ងាត់ថ្មី';
+$lang['oldpass'] = 'បន្ជាកពាក្សសម្ងាត់';
+$lang['passchk'] = 'ម្ដងទាត';
+$lang['remember'] = 'ចំណាំខ្ញុំ';
+$lang['fullname'] = 'នាមត្រគោល';
+$lang['email'] = 'អ៊ីមែល';
+$lang['profile'] = 'ប្រវត្តិរូប';// 'User Profile';
+$lang['badlogin'] = 'សុំអាទោស​ នាមបំរើ ឬ ពាក្សសម្ងាតមិនត្រវទេ។';
+$lang['minoredit'] = 'កែបបណ្តិចបណ្តួច';// 'Minor Changes';
+$lang['draftdate'] = 'គំរោង កត់ស្វ័យប្រវត្ត';
+
+$lang['regmissing'] = 'សុំអាទោស​ អ្នកត្រវបំពេញក្របវាល។';
+$lang['reguexists'] = 'សុំអាទោស​ នាមប្រើនេះមានរួចហើ។';
+$lang['regsuccess'] = 'អ្នកប្រើបានបង្កើតហើយ និងពាក្សសម្ងាតក៏បានផ្ញើទៀត។';
+$lang['regsuccess2']= 'អ្នកប្រើបានបង្កើតហើយ។';
+$lang['regmailfail']= 'មើលទៅដុចជាមានកំហុសក្នុង....សុំទាកទងអ្នកក្របក្រង';
+$lang['regbadmail'] = 'អ៊ីមេលអ្នកសាសេមិនត្រូវបញ្ជរ&mdash;បើអ្នកកិតថានេះជាកំហុសបដិបត្តិ សុំទាកទងអ្នកក្របគ្រោង។';
+$lang['regbadpass'] = 'គូពាក្សសម្ងាតមិនដូចគ្នាទេ សមសាកទៀត។';
+$lang['regpwmail'] = 'ពាក្សសម្ងាតអ្នក';
+$lang['reghere'] = 'អ្នកឥតមានបញ្ជីនាមបម្រើទេ? សុំចល់ចុះឈ្មោះធ្វើគណនីសម្របប្រើប្រស';
+
+$lang['profna'] = 'មិនអាចកែ';
+$lang['profnochange'] = 'ឥតផ្លាស់ប្ដូរ ក្មានអ្វីធ្វើទេ។';
+$lang['profnoempty'] = 'នាមេឬអីមេលទទេ';
+$lang['profchanged'] = 'ប្រវត្តិរូបអ្នកប្រើបាន ។';
+
+$lang['pwdforget'] = 'ភ្លិចពាក្សសម្ងាត់ យកមួយទាត។';
+$lang['resendna'] = 'វីគីនេះមិនឧបរំផ្ញើពាក្សសម្ងាតម្ដងទៀតទេ។';
+$lang['resendpwd'] = 'ផ្ញើពាក្សសម្ងាតឲ្យ';
+$lang['resendpwdmissing'] = 'សុំអាទោស​ អ្នកត្រវបំពេញវាល។';
+$lang['resendpwdnouser'] = 'សុំអាទោស​ យាងរកអ្នកប្រើមិនឃើងទេ។';
+$lang['resendpwdbadauth'] = 'សុំអាទោស​ រហស្សលេខអនុញ្ញាតពំអាចប្រើបានទេ។ ខ្សែបន្ត';
+$lang['resendpwdconfirm'] ='ខ្សែបន្ត';
+$lang['resendpwdsuccess'] = 'ពាក្សសម្ងាតអ្នកបានផ្ញើហើយ។';
+
+$lang['txt_upload'] = 'ជ្រើសឯកសារដែលរុញ​ឡើង';
+$lang['txt_filename'] = 'រុញឡើងជា (ស្រេច​ចិត្ត)';
+$lang['txt_overwrt'] = 'កត់ពីលើ';//'Overwrite existing file';
+$lang['lockedby'] = 'ឥឡូវនេះចកជាប់​';
+$lang['lockexpire'] = 'សោជាប់ផុត​កំណត់ម៉ោង';
+$lang['js']['willexpire'] = 'សោអ្នកចំពោះកែតម្រូវទំព័រនេះ ហួសពែលក្នុងមួយនាទី។\nកុំឲ្យមានជម្លោះ ប្រើ «បង្ហាញ»​ ទៅកំណត់​ឡើង​វិញ។';
+
+$lang['js']['notsavedyet'] = "កម្រែមិនទានរុក្សាទកត្រូវបោះបង់។\nបន្តទៅទាឬទេ?";
+$lang['rssfailed'] = 'មានកំហុសពេលទៅ​ប្រមូល​យកមតិ​ព័ត៌មាន៖ ';
+$lang['nothingfound']= 'រកមិនឃើញអ្វីទេ។';
+
+$lang['mediaselect'] = 'ឯកសារមីឌៀ';
+$lang['fileupload'] = 'រុញឯកសារមីឌៀឡើង';
+$lang['uploadsucc'] = 'រុញចូលមានជ័យ';
+$lang['uploadfail'] = 'រុញឡើងបរាជ័យ។ ប្រហែលខុសសិទ្ឋានុញ្ញាត?';
+$lang['uploadwrong'] = 'រុញឡើងត្រូវ​បាន​បដិសេធ។ ឯកសារ';
+$lang['uploadexist'] = 'ឯកសារមានហើយ។ ឥតមានធ្វើអ្វីទេ។';
+$lang['uploadbadcontent'] = 'ធាតុចំរុញឡើងមិនត្រូវកន្ទុយឯកសារ %s ទេ។';
+$lang['uploadspam'] = 'ចំរុញឡើង បង្ខាំង ដៅយ ';
+$lang['uploadxss'] = 'ចំរុញឡើង បង្ខាំង ';
+$lang['deletesucc'] = 'ឯកសារ «%s» បានលុបហើយ។';
+$lang['deletefail'] = '«%s» មិនអាចលុបទេ&mdashមើល';
+$lang['mediainuse'] = 'ឯកសារ «%s» ឥតទានលុបទេ&mdashមានគេកំភងទេជាប់ប្រើ។';
+$lang['namespaces'] = 'នាមដ្ឋាន';
+$lang['mediafiles'] = 'ឯកសារទំនេនៅក្នុង';
+
+$lang['js']['keepopen'] = 'ទុកបង្អួចបើក ពេលការជម្រើស';
+$lang['js']['hidedetails'] = 'បាំង';
+$lang['mediausage'] = 'ប្រើ';
+$lang['mediaview'] = 'មើលឯកសារដើម';
+$lang['mediaroot'] = 'ឫស';
+$lang['mediaupload'] = 'រុញឯកសារឡើងទៅនាមដ្ឋាននេះ។ នាមដ្ឋាន «រុញឡើង»';
+$lang['mediaextchange'] = 'កន្ទុយឯកសារផ្លាសពី «%s» ទៅ «%s»!';
+
+$lang['reference'] = 'អនុសាសនចំពោះ';
+$lang['ref_inuse'] = 'ឯកសារមិនអាចលុបពីព្រោះវានៅចាប់ប្រើដៅទំព័រ៖';
+$lang['ref_hidden'] = 'អនុសាសនខ្លះនៅលើទំព័រអ្នកគ្មានសេធអនុញ្ញាត';
+
+$lang['hits'] = 'ត្រូវ';
+$lang['quickhits'] = 'ឈ្មោះទំព័រប្រៀបដូច';
+$lang['toc'] = 'មាតិកា';
+$lang['current'] = 'ឥឡៅវ';
+$lang['yours'] = 'តំណែអ្នាក';
+$lang['diff'] = 'បង្ហាងអសទិសភាពជាមួយតំណែឥឡូវ ';
+$lang['line'] = 'ខ្សែ';
+$lang['breadcrumb'] = 'ដាន';
+$lang['youarehere'] = 'ដាន';
+$lang['lastmod'] = 'ពេលកែចុងក្រោយ';
+$lang['by'] = 'និពន្ឋដោយ';
+$lang['deleted'] = 'យកចេញ';
+$lang['created'] = 'បង្កើត';
+$lang['restored'] = 'ស្ដារបុនរាព្រឹតចាស់';
+$lang['external_edit'] = 'កំរេពីក្រៅ';
+$lang['summary'] = 'កែតម្រា';
+
+$lang['mail_newpage'] = 'ថែមទំព័រ';
+$lang['mail_changed'] = 'ទំព័រប្រែប្រួល';
+$lang['mail_new_user'] = 'អ្នកប្រើថ្មី';
+$lang['mail_upload'] = 'រុញអក្សាលើង';
+
+$lang['nosmblinks'] = 'ខ្សែបន្តទៅ «Windows share» ប្រើបានក្នុង «Microsoft IE»។ អ្នកអាច កាត់ឬបិត ខ្សែនេះ។';
+
+$lang['qb_bold'] = 'ឃ្វាមក្រស';
+$lang['qb_italic'] = 'ឃ្វាមជ្រៀង';
+$lang['qb_underl'] = 'ឃ្វាម';
+$lang['qb_code'] = 'ឃ្វាមក្បួន';
+$lang['qb_strike'] = 'ឃ្វាម';
+$lang['qb_h1'] = 'និវេទន៍ទី១';
+$lang['qb_h2'] = 'និវេទន៍ទី២';
+$lang['qb_h3'] = 'និវេទន៍ទី៣';
+$lang['qb_h4'] = 'និវេទន៍ទី៤';
+$lang['qb_h5'] = 'និវេទន៍ទី៥';
+$lang['qb_link'] = 'ខ្សែបន្តក្នុង';
+$lang['qb_extlink'] = 'ខ្សែបន្តក្រៅ';
+$lang['qb_hr'] = 'បន្ទាផ្ដេក';
+$lang['qb_ol'] = 'តារាងត្រៀប';
+$lang['qb_ul'] = 'តារាងអត្រៀប';
+$lang['qb_media'] = 'បន្ថែមរូនឹងឯកសារឥទៀត';
+$lang['qb_sig'] = 'ស៊កហត្ថលេខា';
+$lang['qb_smileys'] = 'សញ្ញាអារម្មណ៍';
+$lang['qb_chars'] = 'អក្ខរៈពិសេស';
+
+$lang['js']['del_confirm']= 'លុប';
+$lang['admin_register']= 'តែមអ្នកប្រើ';//'Add new user';
+
+$lang['spell_start'] = 'ពិនិត្យអក្ខរាវិរុទ្ធ';//'Check Spelling';
+$lang['spell_stop'] = 'បណ្តកំរែ'; 'Resume Editing';
+$lang['spell_wait'] = 'សូមចាំ';//'Please wait...';
+$lang['spell_noerr'] = 'ឥតមានខុះទេ';
+$lang['spell_nosug'] = 'ឥតមានយោបល់';
+$lang['spell_change']= 'ដូរជំនួស';//'Change';
+
+$lang['metaedit'] = 'កែទិន្នន័យអរូប';//'Edit Metadata';
+$lang['metasaveerr'] = 'ពំអាចកត់រទិន្នន័យអរូប';//'Writing metadata failed';
+$lang['metasaveok'] = 'ទិន្នន័យអរូប';
+$lang['img_backto'] = 'ថយក្រោយ';
+$lang['img_title'] = 'អភិធេយ្យ';
+$lang['img_caption'] = 'ចំណងជើង';
+$lang['img_date'] = 'ថ្ងៃខែ';//'Date';
+$lang['img_fname'] = 'ឈ្មោះឯកសារ';
+$lang['img_fsize'] = 'ទំហំ';//'Size';
+$lang['img_artist'] = 'អ្នកថតរូប';
+$lang['img_copyr'] = 'រក្សា​សិទ្ធិ';
+$lang['img_format'] = 'ធុនប្រភេទ';
+$lang['img_camera'] = 'គ្រឿងថត';
+$lang['img_keywords']= 'មេពាក្ស';//'Keywords';
+
+$lang['subscribe_success'] = ' ដកថែម %s ចូលបញ្ជីបរិវិសកមចំពោះ %s';
+$lang['subscribe_error'] = 'មានកំហុសពេលបន្ថែម %s ចូលបញ្ជីបរិវិសកមចំពោះ %s';
+$lang['subscribe_noaddress']= 'ឥតមានអាសយដ្ឋាន អ្នកមិនអាចកត់ចុល';
+$lang['unsubscribe_success']= 'ដក %s ចេញពីបញ្ជីបរិវិសកមចំពោះ %s';
+$lang['unsubscribe_error'] = 'មានកំហុសពេលដក %s​ ចេញពីបញ្ជីបរិវិសកមចំពោះ %s';
+
+/* auth.class language support */
+$lang['authmodfailed'] = 'និនផ្ទៀងផ្ទាត់​ភាព​​ត្រឹមត្រូវបានទេ។ សុំទាកទងអ្នកក្របគ្រោង។';
+$lang['authtempfail'] = 'ការផ្ទៀងផ្ទាត់​ភាព​​ត្រឹមត្រូវឥតដំនេ។ ប្រើ ....';
+
+/* installer strings */
+$lang['i_chooselang'] = 'រើសពាស្សាអ្នក';
+$lang['i_installer'] = 'ដំឡើងឌោគូវីគី';
+$lang['i_wikiname'] = 'នាមវីគី';
+$lang['i_enableacl'] = 'បើកប្រើ (អនុសាស)';
+$lang['i_superuser'] = 'អ្នកកំពូល';
+$lang['i_problems'] = 'កម្មវិធី​ដំឡើងបានប៉ះឧបសគ្គ។ អ្នកមិនអាចបន្តទៅទៀត ដល់អ្នកជួសជុលវា។';
+$lang['i_modified'] = '';
+$lang['i_funcna'] = '<code>%s</code> ';
+$lang['i_phpver'] = 'PHP ប្រវត់លេខ<code>%s</code> ជា';
+$lang['i_permfail'] = '<code>%s</code> មិនអាចសាស';
+$lang['i_confexists'] = '<code>%s</code> មានហាយ';
+$lang['i_writeerr'] = 'មិនអាចបណ្កើ<code>%s</code>។ អ្នកត្រវការពិនិត្យអធិក្រឹតិរបស់ថតនឹងឯកសារ។';
+$lang['i_badhash'] = '(hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code>&mdash;';
+$lang['i_success'] = '';
+$lang['i_failure'] = 'ពលសាសារ';
+$lang['i_policy'] = 'បញ្ជីអនុញ្ញតផ្ដើម';
+$lang['i_pol0'] = 'វីគីបើកចំហ';
+$lang['i_pol1'] = 'វីគីសធារណៈ';
+$lang['i_pol2'] = 'វីគីបិទជិត';
+
+$lang['i_retry'] = 'ម្តងទៀត';
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/lang/km/login.txt b/inc/lang/km/login.txt
new file mode 100644
index 000000000..2149d9c32
--- /dev/null
+++ b/inc/lang/km/login.txt
@@ -0,0 +1,5 @@
+====== កត់ចូល ======
+
+អ្នកមិនទាន់។
+អ្នកត្រូវការអនុញ្ញាឲ្យកត់តនំបានចូល។
+
diff --git a/inc/lang/km/newpage.txt b/inc/lang/km/newpage.txt
new file mode 100644
index 000000000..4b2b4e2d8
--- /dev/null
+++ b/inc/lang/km/newpage.txt
@@ -0,0 +1,4 @@
+====== ឥតទានមានទេ ======
+អ្នកតាមត្រសៃខ្សែដែលគ្មានទំព័រ។
+បើ
+
diff --git a/inc/lang/km/norev.txt b/inc/lang/km/norev.txt
new file mode 100644
index 000000000..7ca11893e
--- /dev/null
+++ b/inc/lang/km/norev.txt
@@ -0,0 +1,2 @@
+====== ឥតមានបុនរាព្រឹត្តិទេ ======
+បុនរាព្រឹត្តិពុំមានទេ។ សុំប្រើ «ទំព័រចាស់ៗ» ទៅមើលបញ្ជីប្រវត្តទំព័រចាស់រូបស់អត្ថបទនេះ។
diff --git a/inc/lang/km/password.txt b/inc/lang/km/password.txt
new file mode 100644
index 000000000..a3495e7ae
--- /dev/null
+++ b/inc/lang/km/password.txt
@@ -0,0 +1,10 @@
+សួរស្ដី @FULLNAME@!
+
+នេះជាបញ្ជីប្រើប្រះរុបស @TITLE@ នៅ @DOKUWIKIURL@
+
+នាមបង្រើ៖ @LOGIN@
+ពាក្សសម្ងាត៖ @PASSWORD@
+
+--
+អ៊ីមេលនេះបន្ចេអពីឌោគូវីគីនៅ
+@DOKUWIKIURL@
diff --git a/inc/lang/km/pwconfirm.txt b/inc/lang/km/pwconfirm.txt
new file mode 100644
index 000000000..7c6a3ac97
--- /dev/null
+++ b/inc/lang/km/pwconfirm.txt
@@ -0,0 +1,13 @@
+សួស្ដី @FULLNAME@!
+
+មានគេសុមស្នើពាក្យ​សម្ងាត់​រុបសឲ្យ@TITLE@ នៅ @DOKUWIKIURL@។
+បើអ្នកមិនជាអ្នកសុមពាក្យ​សម្ងាត់ទេ សុំបស់ចល់អ៊ីមេលនេះ។
+
+
+សុំអះអាងដែលសំណើនេះដោយទៅតាមខ្សែ
+
+@CONFIRM@
+
+--
+អ៊ីមេលនេះបង្កើតពីឌក្គូវីគីនៅ
+@DOKUWIKIURL@
diff --git a/inc/lang/km/recent.txt b/inc/lang/km/recent.txt
new file mode 100644
index 000000000..14449ea49
--- /dev/null
+++ b/inc/lang/km/recent.txt
@@ -0,0 +1,3 @@
+====== ប្រវត្តិទំព័របច្ចុប្បន្ន ======
+ទំព័រទាំងនេះគឺទំព័រកែប្រែ
+
diff --git a/inc/lang/km/register.txt b/inc/lang/km/register.txt
new file mode 100644
index 000000000..b850c2ec3
--- /dev/null
+++ b/inc/lang/km/register.txt
@@ -0,0 +1,7 @@
+====== អ្នកប្រើថ្មី ======
+
+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>wiki:pagename|pagename]].
+
diff --git a/inc/lang/km/revisions.txt b/inc/lang/km/revisions.txt
new file mode 100644
index 000000000..a15186df8
--- /dev/null
+++ b/inc/lang/km/revisions.txt
@@ -0,0 +1,4 @@
+====== ប្រវត្តិទំព័រចាស់ ======
+ទាំងនេះគឺប្រវត្តិទំព័រចាស់រុបសអត្ថបទនេះ។
+ជ្រើសខ្សែទំព័រពីខាងក្រោមហើយ ចុត «កែទំព័រនេះ» រួចហើយរក្សាវាទុក។
+
diff --git a/inc/lang/ko/admin.txt b/inc/lang/ko/admin.txt
new file mode 100644
index 000000000..7dd0f58b3
--- /dev/null
+++ b/inc/lang/ko/admin.txt
@@ -0,0 +1,4 @@
+====== 관리 작업 ======
+
+DokuWiki에서 사용가능한 관리 작업 목록을 아래에서 찾을 수 있습니다.
+
diff --git a/inc/lang/ko/adminplugins.txt b/inc/lang/ko/adminplugins.txt
new file mode 100644
index 000000000..5312cf357
--- /dev/null
+++ b/inc/lang/ko/adminplugins.txt
@@ -0,0 +1 @@
+===== 부가적인 플러그인 ===== \ No newline at end of file
diff --git a/inc/lang/ko/backlinks.txt b/inc/lang/ko/backlinks.txt
new file mode 100644
index 000000000..1711945e4
--- /dev/null
+++ b/inc/lang/ko/backlinks.txt
@@ -0,0 +1,4 @@
+====== 백링크 ======
+
+현재 페이지로 백링크되는 페이지 목록입니다.
+
diff --git a/inc/lang/ko/conflict.txt b/inc/lang/ko/conflict.txt
new file mode 100644
index 000000000..529296359
--- /dev/null
+++ b/inc/lang/ko/conflict.txt
@@ -0,0 +1,6 @@
+====== 새 버전 있음 ======
+
+편집하신 문서의 새 버전이 있습니다. 당신이 편집하고 있는 동안 다른 사람이 동일한 파일을 편집하였을 경우 이런 일이 생길 수 있습니다.
+
+아래의 차이점을 면밀히 검토하시고, 어떤 버전을 저장하실지 결정하십시오. **저장**을 선택하시면, 당신의 버전이 저장됩니다. **취소** 를 선택하시면 현재 버전이 유지됩니다.
+
diff --git a/inc/lang/ko/denied.txt b/inc/lang/ko/denied.txt
new file mode 100644
index 000000000..316a660c0
--- /dev/null
+++ b/inc/lang/ko/denied.txt
@@ -0,0 +1,4 @@
+====== 권한 거절 ======
+
+계속할 수 있는 권한이 없습니다. 로그인하십시오.
+
diff --git a/inc/lang/ko/diff.txt b/inc/lang/ko/diff.txt
new file mode 100644
index 000000000..8cfb1da43
--- /dev/null
+++ b/inc/lang/ko/diff.txt
@@ -0,0 +1,5 @@
+====== 차이점 ======
+
+이 페이지의 선택한 이전 버전과 현재 버전 사이의 차이점을 보여줍니다.
+
+
diff --git a/inc/lang/ko/draft.txt b/inc/lang/ko/draft.txt
new file mode 100644
index 000000000..3df8a5e86
--- /dev/null
+++ b/inc/lang/ko/draft.txt
@@ -0,0 +1,6 @@
+====== 문서 초안이 있습니다. ======
+
+이 페이지의 마지막 편집 세션은 정상적으로 끝나지 않았습니다. DokuWiki는 작업 도중 자동으로 저장된 문서 초안을 사용하여 편집을 계속 할 수 있습니다. 마지막 세션동안 저장된 문서 초안을 아래에서 볼 수 있습니다.
+
+확실하게 비정상적으로 종료된 세션을 //복구//할지 여부를 결정하고, 자동으로 저장되었던 초안을 //삭제//하거나 편집 과정을 취소하기 바랍니다.
+
diff --git a/inc/lang/ko/edit.txt b/inc/lang/ko/edit.txt
new file mode 100644
index 000000000..9b59524f7
--- /dev/null
+++ b/inc/lang/ko/edit.txt
@@ -0,0 +1,2 @@
+페이지를 편집하고 **저장**을 누르십시오. 위키 구문은 [[wiki:syntax]] 혹은 [[wiki:ko_syntax|(한글) 구문]]을 참고하십시오. 이 페이지를 **더 낫게 만들 자신이 있을** 때에만 편집하십시오. 실험을 하고 싶을 때에는, 먼저 [[playground:playground|연습장]] 에 가서 연습해 보십시오.
+
diff --git a/inc/lang/ko/editrev.txt b/inc/lang/ko/editrev.txt
new file mode 100644
index 000000000..2715448d3
--- /dev/null
+++ b/inc/lang/ko/editrev.txt
@@ -0,0 +1,2 @@
+**문서의 이전 버전을 선택하였습니다!** 저장할 경우 이 자료의 새 버전을 만듭니다.
+---- \ No newline at end of file
diff --git a/inc/lang/ko/index.txt b/inc/lang/ko/index.txt
new file mode 100644
index 000000000..7ca9488e0
--- /dev/null
+++ b/inc/lang/ko/index.txt
@@ -0,0 +1,4 @@
+====== Index ======
+
+이 페이지는 [[doku>namespaces|네임스페이스]] 에서 정렬한 모든 페이지의 목록입니다.
+
diff --git a/inc/lang/ko/install.html b/inc/lang/ko/install.html
new file mode 100644
index 000000000..6b1bfaf75
--- /dev/null
+++ b/inc/lang/ko/install.html
@@ -0,0 +1,17 @@
+<p>이 페이지는 <a href="http://dokuwiki.org">Dokuwiki</a> 설치와 환경 설정을 도와줍니다.
+. 설치 과정에 대한 더 자세한 정보는 <a href="http://dokuwiki.org/ko:install">한글 설치문서</a>와
+<a href="http://dokuwiki.org/install">영문 설치문서</a>를 참고하기 바랍니다.
+</p>
+
+<p>DokuWiki는 위키 페이지와 페이지와 관련된 정보(그림,색인, 이전 버전 문서 등등)를 저장하기 위해 일반적인 텍스트 파일들을 사용합니다. 정상적으로 DokuWiki를 사용하려면 이 파일들을 담고 있는 디렉토리들에 대한 쓰기 권한을 가지고 있어야 합니다.
+현재 설치 과정 중에는 디렉토리 권한 설정이 불가능합니다. 보통 직접 쉘 명령어를 사용하거나, 호스팅을 사용한다면 FTP나 호스팅 제어판(예. CPanel)을 사용해서 설정해야 합니다.</p>
+
+<p>현재 설치 과정중에 관리자로 로그인 후 DokuWiki의 관리 메뉴(플러그인 설치, 사용자 관리, 위키 페이지 접근 권한 관리, 옵션 설정)를 가능하게 <acronym title="접근 제어 목록">ACL</acronym>에 대한 환경 설정을 수행합니다.
+이 것은 DokuWiki가 동작하는데 필요한 사항은 아니지만, 어찌되었든 더 쉽게 관리자가 관리할 수 있도록 해줍니다.</p>
+
+<p>숙련된 사용자들이나 특별한 설치 과정이 필요한 경우에 다음 링크들을 참조하기 바랍니다:
+<a href="http://dokuwiki.org/ko:install">설치 과정(한글)</a>
+과 <a href="http://dokuwiki.org/ko:config">환경 설정(한글),</a>
+<a href="http://dokuwiki.org/install">설치 과정(영문)</a>
+과 <a href="http://dokuwiki.org/config">환경 설정(영문)</a>
+</p>
diff --git a/inc/lang/ko/lang.php b/inc/lang/ko/lang.php
new file mode 100644
index 000000000..b0664e7f4
--- /dev/null
+++ b/inc/lang/ko/lang.php
@@ -0,0 +1,273 @@
+<?php
+/**
+ * korean language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Hyun Kim <lawfully@gmail.com>
+ * @author jk Lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = '페이지 편집';
+$lang['btn_source'] = '소스 보기';
+$lang['btn_show'] = '페이지 보기';
+$lang['btn_create'] = '페이지 만들기';
+$lang['btn_search'] = '찾기';
+$lang['btn_save'] = '저장';
+$lang['btn_preview'] = '미리보기';
+$lang['btn_top'] = '맨위로';
+$lang['btn_newer'] = '<< 최근';
+$lang['btn_older'] = '이전 >>';
+$lang['btn_revs'] = '이전 버전들';
+$lang['btn_recent'] = '최근 변경 목록';
+$lang['btn_upload'] = '업로드';
+$lang['btn_cancel'] = '취소';
+$lang['btn_index'] = '색인';
+$lang['btn_secedit'] = '편집';
+$lang['btn_login'] = '로그인';
+$lang['btn_logout'] = '로그아웃';
+$lang['btn_admin'] = '관리';
+$lang['btn_update'] = '변경';
+$lang['btn_delete'] = '삭제';
+$lang['btn_back'] = '뒤로';
+$lang['btn_backlink'] = '이전 링크';
+$lang['btn_backtomedia'] = '미디어 파일 선택으로 돌아가기';
+$lang['btn_subscribe'] = '구독 신청';
+$lang['btn_profile'] = '개인정보 변경';
+$lang['btn_reset'] = '초기화';
+$lang['btn_resendpwd'] = '새 패스워드 보내기';
+$lang['btn_draft'] = '문서초안 편집';
+$lang['btn_recover'] = '문서초안 복구';
+$lang['btn_draftdel'] = '문서초안 삭제';
+$lang['btn_revert'] = '복원';
+$lang['btn_register'] = '등록';
+$lang['loggedinas'] = '다음 사용자로 로그인';
+$lang['user'] = '사용자';
+$lang['pass'] = '패스워드';
+$lang['newpass'] = '새로운 패스워드';
+$lang['oldpass'] = '현재 패스워드 확인';
+$lang['passchk'] = '패스워드 다시 확인';
+$lang['remember'] = '기억하기';
+$lang['fullname'] = '실제 이름';
+$lang['email'] = '이메일';
+$lang['profile'] = '개인 정보';
+$lang['badlogin'] = '잘못된 사용자 이름이거나 패스워드입니다.';
+$lang['minoredit'] = '일부 내용 변경';
+$lang['draftdate'] = '문서 초안 자동저장 시간';
+$lang['nosecedit'] = '페이지가 수정되어 섹션정보가 달라져 페이지 전부를 다시 읽습니다.';
+$lang['regmissing'] = '모든 항목을 입력해야 합니다.';
+$lang['reguexists'] = '같은 이름을 사용하는 사용자가 있습니다.';
+$lang['regsuccess'] = '사용자를 만들었습니다. 패스워드는 이메일로 보냈습니다.';
+$lang['regsuccess2'] = '사용자를 만들었습니다.';
+$lang['regmailfail'] = '패스워드를 이메일로 전송할 때 오류가 발생했습니다. 관리자에게 문의하기 바랍니다!';
+$lang['regbadmail'] = '이메일 주소가 틀렸습니다. - 오류라고 생각되면 관리자에게 문의하기 바랍니다.';
+$lang['regbadpass'] = '새로운 패스워드들이 일치하지 않습니다. 다시 입력하기 바랍니다.';
+$lang['regpwmail'] = 'DokuWiki 패스워드';
+$lang['reghere'] = '아직 등록하지 않았다면 등록하기 바랍니다.';
+$lang['profna'] = '이 위키는 개인 정보 수정을 허용하지 않습니다.';
+$lang['profnochange'] = '변경사항이 없습니다.';
+$lang['profnoempty'] = '이름이나 이메일 주소가 비었습니다.';
+$lang['profchanged'] = '개인정보 변경이 성공했습니다.';
+$lang['pwdforget'] = '패스워드를 잊어버린 경우 새로 발급받을 수 있습니다.';
+$lang['resendna'] = '이 위키는 패스워드 재발급을 지원하지 않습니다.';
+$lang['resendpwd'] = '새로운 패스워드를 보냅니다.';
+$lang['resendpwdmissing'] = '새로운 패스워드를 입력해야햡니다.';
+$lang['resendpwdnouser'] = '등록된 사용자가 아닙니다. 다시 확인 바랍니다.';
+$lang['resendpwdbadauth'] = '인증 코드가 틀립니다. 잘못된 링크인지 확인 바랍니다.';
+$lang['resendpwdconfirm'] = '확인 링크를 이메일로 보냈습니다.';
+$lang['resendpwdsuccess'] = '새로운 패스워드는 이메일로 보내드립니다.';
+$lang['license'] = '이 위키의 내용은 다음의 라이센스에 따릅니다 :';
+$lang['licenseok'] = '주의 : 이 페이지를 수정한다는 다음의 라이센스에 동의함을 의미합니다 :';
+$lang['searchmedia'] = '파일이름 찾기:';
+$lang['searchmedia_in'] = ' %s에서 검색';
+$lang['txt_upload'] = '업로드 파일을 선택합니다.';
+$lang['txt_filename'] = '업로드 파일 이름을 입력합니다.(선택 사항)';
+$lang['txt_overwrt'] = '새로운 파일로 이전 파일을 교체합니다.';
+$lang['lockedby'] = '현재 잠금 사용자';
+$lang['lockexpire'] = '잠금 해제 시간';
+$lang['js']['willexpire'] = '잠시 후 편집 잠금이 해제됩니다.\n편집 충돌을 피하려면 미리보기를 눌러 잠금 시간을 다시 설정하기 바랍니다.';
+$lang['js']['notsavedyet'] = '저장하지 않은 변경은 지워집니다.
+계속하시겠습니까?';
+$lang['js']['searchmedia'] = '파일 찾기';
+$lang['js']['keepopen'] = '선택할 때 윈도우를 열어놓으시기 바랍니다.';
+$lang['js']['hidedetails'] = '자세한 정보 감추기';
+$lang['js']['mediatitle'] = '링크 설정';
+$lang['js']['mediadisplay'] = '링크 형태';
+$lang['js']['mediaalign'] = '배치';
+$lang['js']['mediasize'] = '그림 크기';
+$lang['js']['mediatarget'] = '링크 목표';
+$lang['js']['mediaclose'] = '닫기';
+$lang['js']['mediainsert'] = '삽입';
+$lang['js']['mediadisplayimg'] = '그림보기';
+$lang['js']['mediadisplaylnk'] = '링크만 보여줍니다.';
+$lang['js']['mediasmall'] = '작게';
+$lang['js']['mediamedium'] = '중간';
+$lang['js']['medialarge'] = '크게';
+$lang['js']['mediaoriginal'] = '원본';
+$lang['js']['medialnk'] = '세부정보페이지로 링크';
+$lang['js']['mediadirect'] = '원본으로 직접 링크';
+$lang['js']['medianolnk'] = '링크 없슴';
+$lang['js']['medianolink'] = '그림을 링크하지 않음';
+$lang['js']['medialeft'] = '왼쪽 배치';
+$lang['js']['mediaright'] = '오른쪽 배치';
+$lang['js']['mediacenter'] = '중앙 배치';
+$lang['js']['medianoalign'] = '배치 없슴';
+$lang['js']['nosmblinks'] = '윈도우 공유 파일과의 연결은 MS 인터넷 익스플로러에서만 동작합니다.
+그러나 링크를 복사하거나 붙여넣기를 할 수 있습니다.';
+$lang['js']['linkwiz'] = '링크 마법사';
+$lang['js']['linkto'] = '다음으로 연결:';
+$lang['js']['del_confirm'] = '정말로 선택된 항목(들)을 삭제하시겠습니까?';
+$lang['rssfailed'] = 'feed 가져오기 실패: ';
+$lang['nothingfound'] = '아무 것도 없습니다.';
+$lang['mediaselect'] = '미디어 파일 선택';
+$lang['fileupload'] = '미디어 파일 업로드';
+$lang['uploadsucc'] = '업로드 성공';
+$lang['uploadfail'] = '업로드 실패. 잘못된 권한 때문일지도 모릅니다.';
+$lang['uploadwrong'] = '업로드 거부. 금지된 확장자입니다!';
+$lang['uploadexist'] = '이미 파일이 존재합니다.';
+$lang['uploadbadcontent'] = '업로드된 파일이 파일 확장자 %s와 일치하지 않습니다.';
+$lang['uploadspam'] = '스팸 차단기가 업로드를 취소하였습니다.';
+$lang['uploadxss'] = '악성 코드의 가능성이 있어 업로드를 취소하였습니다.';
+$lang['uploadsize'] = '업로드한 파일이 너무 큽니다. (최대 %s)';
+$lang['deletesucc'] = '"%s" 파일이 삭제되었습니다.';
+$lang['deletefail'] = '"%s" 파일을 삭제할 수 없습니다. - 삭제 권한이 있는지 확인하기 바랍니다.';
+$lang['mediainuse'] = '"%s" 파일을 삭제할 수 없습니다. - 아직 사용 중입니다.';
+$lang['namespaces'] = '네임스페이스';
+$lang['mediafiles'] = '사용 가능한 파일 목록';
+$lang['accessdenied'] = '이 페이지를 볼 권한이 없습니다.';
+$lang['mediausage'] = '이 파일을 참조하려면 다음 문법을 사용하기 바랍니다:';
+$lang['mediaview'] = '원본 파일 보기';
+$lang['mediaroot'] = '루트(root)';
+$lang['mediaupload'] = '파일을 현재 네임스페이스로 업로드합니다. 하위 네임스페이스를 만들려면 파일 이름 앞에 콜론(:)으로 구분되는 이름을 붙이면 됩니다.';
+$lang['mediaextchange'] = '파일 확장자가 .%s에서 .%s으로 변경됐습니다!';
+$lang['reference'] = '참조';
+$lang['ref_inuse'] = '다음 페이지들에서 아직 사용 중이므로 파일을 삭제할 수 없습니다:';
+$lang['ref_hidden'] = '페이지들의 몇몇 참조는 읽을 수 있는 권한이 없습니다.';
+$lang['hits'] = '히트 수';
+$lang['quickhits'] = '일치하는 페이지 이름';
+$lang['toc'] = '목차';
+$lang['current'] = '현재';
+$lang['yours'] = '버전';
+$lang['diff'] = '현재 버전과의 차이 보기';
+$lang['diff2'] = '선택된 버전들 간 차이 보기';
+$lang['difflink'] = '차이 보기로 연결';
+$lang['diff_type'] = '버전간 차이 표시:';
+$lang['diff_inline'] = '인라인 방식';
+$lang['diff_side'] = '다중창 방식';
+$lang['line'] = '줄';
+$lang['breadcrumb'] = '추적';
+$lang['youarehere'] = '현재 위치';
+$lang['lastmod'] = '마지막 수정';
+$lang['by'] = '작성자';
+$lang['deleted'] = '삭제';
+$lang['created'] = '새로 만듦';
+$lang['restored'] = '옛 버전 복구';
+$lang['external_edit'] = '외부 편집기';
+$lang['summary'] = '편집 요약';
+$lang['noflash'] = '이 컨텐츠를 표시하기 위해서 <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>이 필요합니다.';
+$lang['download'] = '조각 다운로드';
+$lang['mail_newpage'] = '페이지 추가:';
+$lang['mail_changed'] = '페이지 변경:';
+$lang['mail_subscribe_list'] = '네임스페이스에서 변경된 페이지:';
+$lang['mail_new_user'] = '새로운 사용자:';
+$lang['mail_upload'] = '파일 첨부:';
+$lang['qb_bold'] = '굵은 글';
+$lang['qb_italic'] = '이탤릭체 글';
+$lang['qb_underl'] = '밑줄 그어진 글';
+$lang['qb_code'] = '코드로 표시된 글';
+$lang['qb_strike'] = '취소 표시된 글';
+$lang['qb_h1'] = '1단계 헤드라인';
+$lang['qb_h2'] = '2단계 헤드라인';
+$lang['qb_h3'] = '3단계 헤드라인';
+$lang['qb_h4'] = '4단계 헤드라인';
+$lang['qb_h5'] = '5단계 헤드라인';
+$lang['qb_h'] = '표제';
+$lang['qb_hs'] = '표제 선택';
+$lang['qb_hplus'] = '상위 표제';
+$lang['qb_hminus'] = '하위 표제';
+$lang['qb_hequal'] = '동급 표제';
+$lang['qb_link'] = '내부 링크';
+$lang['qb_extlink'] = '외부 링크';
+$lang['qb_hr'] = '수평선';
+$lang['qb_ol'] = '숫자 목록';
+$lang['qb_ul'] = '목록';
+$lang['qb_media'] = '이미지와 기타 파일 추가';
+$lang['qb_sig'] = '서명 추가';
+$lang['qb_smileys'] = '이모티콘';
+$lang['qb_chars'] = '특수문자';
+$lang['upperns'] = '상위 네임스페이스로 이동';
+$lang['admin_register'] = '새로운 사용자 추가';
+$lang['metaedit'] = '메타 데이타를 편집합니다.';
+$lang['metasaveerr'] = '메타 데이타 쓰기가 실패했습니다.';
+$lang['metasaveok'] = '메타 데이타가 저장되었습니다.';
+$lang['img_backto'] = '뒤로';
+$lang['img_title'] = '이름';
+$lang['img_caption'] = '설명';
+$lang['img_date'] = '날짜';
+$lang['img_fname'] = '파일 이름';
+$lang['img_fsize'] = '크기';
+$lang['img_artist'] = '만든이';
+$lang['img_copyr'] = '저작권';
+$lang['img_format'] = '포맷';
+$lang['img_camera'] = '카메라';
+$lang['img_keywords'] = '키워드';
+$lang['subscr_subscribe_success'] = '%s을(를) 구독목록 %s에 추가하였습니다';
+$lang['subscr_subscribe_error'] = '%s을(를) 구독목록 %s에 추가하는데 실패했습니다';
+$lang['subscr_subscribe_noaddress'] = '등록된 주소가 없기 때문에 구독목록에 등록되지 않았습니다';
+$lang['subscr_unsubscribe_success'] = '%s을(를) 구독목록 %s에서 제거하였습니다';
+$lang['subscr_unsubscribe_error'] = '%s을(를) 구독목록 %s에서 제거하는데 실패했습니다';
+$lang['subscr_already_subscribed'] = '%s은(는) 이미 %s에 구독되고 있습니다';
+$lang['subscr_not_subscribed'] = '%s은(는) 이미 %s에 구독되어 있지 않습니다';
+$lang['subscr_m_not_subscribed'] = '현재의 페이지나 네임스페이스에 구독등록이 되어있지 않습니다.';
+$lang['subscr_m_new_header'] = '구독 추가';
+$lang['subscr_m_current_header'] = '현재 구독중인 것들';
+$lang['subscr_m_unsubscribe'] = '구독 취소';
+$lang['subscr_m_subscribe'] = '구독';
+$lang['subscr_m_receive'] = '받기';
+$lang['subscr_style_every'] = '모든 변화를 이메일로 받기';
+$lang['subscr_style_digest'] = '각 페이지의 변화를 요약 (매 %.2f 일 마다)';
+$lang['subscr_style_list'] = '마지막 이메일 이후 변화된 페이지의 목록 (매 %.2f 일 마다)';
+$lang['authmodfailed'] = '잘못된 사용자 인증 설정입니다. 관리자에게 문의하기 바랍니다.';
+$lang['authtempfail'] = '사용자 인증이 일시적으로 불가능합니다. 만일 계속해서 문제가 발생하면 관리자에게 문의하기 바랍니다.';
+$lang['i_chooselang'] = '사용하는 언어를 선택합니다.';
+$lang['i_installer'] = 'DokuWiki 설치';
+$lang['i_wikiname'] = '위키 이름';
+$lang['i_enableacl'] = 'ACL기능 사용(권장 사항)';
+$lang['i_superuser'] = '슈퍼 유저';
+$lang['i_problems'] = '설치 중 아래와 같은 문제가 발생했습니다. 문제를 해결한 후 설치를 계속하기 바랍니다.';
+$lang['i_modified'] = '보안 상의 이유로 아래 스크립트는 수정되지 않은 새 Dokuwiki설치에서만 동작됩니다.
+다운로드된 압축 패키지를 다시 설치하거나 <a href="http://dokuwiki.org/install"> DokuWiki 설치 과정</a>을 참고해서 설치하기 바랍니다.';
+$lang['i_funcna'] = 'PHP함수 <code>%s</code> 사용이 불가능합니다. 호스트 제공자가 어떤 이유에서인지 막아 놓았을지 모릅니다.';
+$lang['i_phpver'] = 'PHP <code>%s</code>버전은 필요한 <code>%s</code>버전보다 오래되었습니다.PHP를 업그레이드할 필요가 있습니다.';
+$lang['i_permfail'] = 'DokuWiki는 <code>%s</code>에 쓰기 가능 권한이 없습니다. 먼저 이 디렉토리에 쓰기 권한이 설정되어야 합니다!';
+$lang['i_confexists'] = '<code>%s</code>는 이미 존재합니다.';
+$lang['i_writeerr'] = '<code>%s</code>을 만들 수 없습니다. 먼저 디렉토리/파일 권한을 확인하고 파일을 수동으로 만들기 바랍니다.';
+$lang['i_badhash'] = 'dokuwiki.php를 인식할 수 없거나 원본 파일이 아닙니다. (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - 유효하지 않거나 빈 값입니다.';
+$lang['i_success'] = '환경 설정이 성공적으로 끝났습니다. install.php를 지워도 상관없습니다.
+ <a href="doku.php">새로운 DokuWiki</a>.';
+$lang['i_failure'] = '환경 설정 파일에 쓰는 도중 에러가 발생했습니다.
+새로운 <a href="doku.php"> DokuWiki</a>를 사용하기 전에 수동으로 문제를 해결할 필요가 있습니다.';
+$lang['i_policy'] = '초기 ACL 정책';
+$lang['i_pol0'] = '개방형 위키 (누구나 읽기/쓰기/업로드가 가능합니다.)';
+$lang['i_pol1'] = '공개형 위키 (누구나 읽을 수 있지만, 등록된 사용자만 쓰기/업로드가 가능합니다.)';
+$lang['i_pol2'] = '폐쇄형 위키 (등록된 사용자만 읽기/쓰기/업로드가 가능합니다.)';
+$lang['i_retry'] = '다시 시도';
+$lang['i_license'] = '내용의 배포를 위한 라이센스를 선택하세요.';
+$lang['recent_global'] = '<b>%s</b> 네임스페이스를 구독중입니다. <a href="%s">전체위키 변경사항 </a>도 보실수 있습니다.';
+$lang['years'] = '%d 년 전';
+$lang['months'] = '%d 개월 전';
+$lang['weeks'] = '%d 주 전';
+$lang['days'] = '%d 일 전';
+$lang['hours'] = '%d 시간 전';
+$lang['minutes'] = '%d 분 전';
+$lang['seconds'] = '%d 초 전';
+$lang['wordblock'] = '스팸 문구를 포함하고 있어서 저장되지 않았습니다.';
diff --git a/inc/lang/ko/locked.txt b/inc/lang/ko/locked.txt
new file mode 100644
index 000000000..24525fc46
--- /dev/null
+++ b/inc/lang/ko/locked.txt
@@ -0,0 +1,3 @@
+====== 페이지 잠금 ======
+
+다른 사용자가 이 페이지 편집을 위해 잠금을 실행하였습니다. 해당 사용자가 편집을 끝내거나 잠금이 해제될 때까지 기다리십시오.
diff --git a/inc/lang/ko/login.txt b/inc/lang/ko/login.txt
new file mode 100644
index 000000000..1aae449df
--- /dev/null
+++ b/inc/lang/ko/login.txt
@@ -0,0 +1,4 @@
+====== 로그인 ======
+
+로그인하지 않았습니다! 아래에서 로그인하십시오. 로그인하려면 쿠키를 받도록 설정하여야 합니다.
+
diff --git a/inc/lang/ko/mailtext.txt b/inc/lang/ko/mailtext.txt
new file mode 100644
index 000000000..5c496435e
--- /dev/null
+++ b/inc/lang/ko/mailtext.txt
@@ -0,0 +1,17 @@
+DokuWiki 페이지가 수정 혹은 추가되었습니다. 상세한 정보는 다음과 같습니다.
+
+날짜 : @DATE@
+브라우저 : @BROWSER@
+IP 주소 : @IPADDRESS@
+호스트명 : @HOSTNAME@
+옛날버전 : @OLDPAGE@
+새버전 : @NEWPAGE@
+편집 요약 : @SUMMARY@
+사용자 : @USER@
+
+@DIFF@
+
+
+--
+이 메일은 @DOKUWIKIURL@ 의 DokuWiki 가 생성한
+이메일입니다.
diff --git a/inc/lang/ko/newpage.txt b/inc/lang/ko/newpage.txt
new file mode 100644
index 000000000..f8380bd84
--- /dev/null
+++ b/inc/lang/ko/newpage.txt
@@ -0,0 +1,3 @@
+====== 이 토픽은 아직 없습니다 ======
+
+아직 없는 토픽 링크를 따라오셨습니다. **페이지 만들기** 버튼을 이용하여 새로 만들 수 있습니다.
diff --git a/inc/lang/ko/norev.txt b/inc/lang/ko/norev.txt
new file mode 100644
index 000000000..e1b4093b4
--- /dev/null
+++ b/inc/lang/ko/norev.txt
@@ -0,0 +1,3 @@
+====== 지정한 버전 없음 ======
+
+지정한 버전이 없습니다. **과거 버전** 버튼을 사용하여 이 문서의 버전 목록을 보십시오.
diff --git a/inc/lang/ko/password.txt b/inc/lang/ko/password.txt
new file mode 100644
index 000000000..e0a22c59a
--- /dev/null
+++ b/inc/lang/ko/password.txt
@@ -0,0 +1,10 @@
+안녕하세요, @FULLNAME@!
+
+@DOKUWIKIURL@ 의 @TITLE@ 의 사용자 정보입니다.
+
+사용자명 : @LOGIN@
+패스워드 : @PASSWORD@
+
+--
+이 이메일은 @DOKUWIKIURL@ 의 DokuWiki 가
+생성한 것입니다.
diff --git a/inc/lang/ko/preview.txt b/inc/lang/ko/preview.txt
new file mode 100644
index 000000000..8bcc6a1eb
--- /dev/null
+++ b/inc/lang/ko/preview.txt
@@ -0,0 +1,4 @@
+====== 미리보기 ======
+
+이것은 입력하신 내용이 어떻게 보일지 미리보기하는 곳입니다. 아직은 **저장되지 않았다**는 점을 기억하십시오.
+
diff --git a/inc/lang/ko/pwconfirm.txt b/inc/lang/ko/pwconfirm.txt
new file mode 100644
index 000000000..c022a52a9
--- /dev/null
+++ b/inc/lang/ko/pwconfirm.txt
@@ -0,0 +1,11 @@
+안녕하세요. @FULLNAME@!
+
+@DOKUWIKIURL@에 작성하신 @TITLE@을 보려면 새 패스워드가 필요하다는 요청을 누군가 받았다고 합니다.
+
+새로운 패스워드를 요청한 적이 없다면 이 이메일을 무시해버리세요.
+
+@CONFIRM@에서 정말로 본인이 그런 요청을 했었는지 확인해 보기 바랍니다.
+
+--
+
+@DOKUWIKIURL@의 DokuWiki가 자동으로 만들어낸 메일입니다.
diff --git a/inc/lang/ko/read.txt b/inc/lang/ko/read.txt
new file mode 100644
index 000000000..6b5d7b3db
--- /dev/null
+++ b/inc/lang/ko/read.txt
@@ -0,0 +1,2 @@
+이 페이지는 읽기 전용입니다. 소스를 볼 수는 있지만, 수정할 수는 없습니다. 연습은 [[public:playground|연습장]]에서 하십시오. 문제가 있다고 생각하시면 관리자에게 문의하십시오.
+
diff --git a/inc/lang/ko/recent.txt b/inc/lang/ko/recent.txt
new file mode 100644
index 000000000..f693c4bf1
--- /dev/null
+++ b/inc/lang/ko/recent.txt
@@ -0,0 +1,5 @@
+====== 최근 변경 ======
+
+아래의 페이지는 최근에 변경된 것입니다.
+
+
diff --git a/inc/lang/ko/register.txt b/inc/lang/ko/register.txt
new file mode 100644
index 000000000..24105efeb
--- /dev/null
+++ b/inc/lang/ko/register.txt
@@ -0,0 +1,4 @@
+====== 새 사용자 등록 ======
+
+이 위키에 새 계정을 만들려면 아래의 모든 내용을 입력하세요. **제대로 된 이메일 주소**를 사용하세요. 암호를 입력하는 곳이 없다면 암호는 이 이메일로 보내집니다. 사용자명은 올바른 [[doku>pagename|pagename]] 이어야 합니다.
+
diff --git a/inc/lang/ko/registermail.txt b/inc/lang/ko/registermail.txt
new file mode 100644
index 000000000..4b1aa20a5
--- /dev/null
+++ b/inc/lang/ko/registermail.txt
@@ -0,0 +1,14 @@
+새로운 사용자가 등록되었습니다:
+
+사용자 이름 : @NEWUSER@
+사용자 실제 이름 : @NEWNAME@
+이메일 : @NEWEMAIL@
+
+날짜 : @DATE@
+브라우저 : @BROWSER@
+IP주소 : @IPADDRESS@
+호스트 이름 : @HOSTNAME@
+
+--
+
+@DOKUWIKIURL@의 DokuWiki가 자동으로 만들어낸 메일입니다.
diff --git a/inc/lang/ko/resendpwd.txt b/inc/lang/ko/resendpwd.txt
new file mode 100644
index 000000000..b06163e92
--- /dev/null
+++ b/inc/lang/ko/resendpwd.txt
@@ -0,0 +1,4 @@
+====== 새로운 패스워드 전송 ======
+
+이 위키 계정에 대한 새 패스워드를 요구하기 위해 아래 폼에서 사용자 이름을 입력하세요. 확인 링크는 새로 등록된 이메일 주소로 발송됩니다.
+
diff --git a/inc/lang/ko/revisions.txt b/inc/lang/ko/revisions.txt
new file mode 100644
index 000000000..12d11894d
--- /dev/null
+++ b/inc/lang/ko/revisions.txt
@@ -0,0 +1,4 @@
+====== 이전 버전 ======
+
+이 문서의 옛날 버전은 다음과 같습니다. 이전 버전으로 돌아가려면, 아래에서 선택한 다음, **페이지 편집**을 클릭한 아후 저장하십시오.
+
diff --git a/inc/lang/ko/searchpage.txt b/inc/lang/ko/searchpage.txt
new file mode 100644
index 000000000..198d9a428
--- /dev/null
+++ b/inc/lang/ko/searchpage.txt
@@ -0,0 +1,5 @@
+====== 찾기 ======
+
+찾기 결과를 아래에서 볼 수 있습니다. 만일 원하는 것을 찾지 못하였다면, **페이지 편집** 버튼을 이용하여 질의 내용과 같은 이름의 페이지를 만들 수 있습니다.
+
+===== 결과 =====
diff --git a/inc/lang/ko/showrev.txt b/inc/lang/ko/showrev.txt
new file mode 100644
index 000000000..084d82737
--- /dev/null
+++ b/inc/lang/ko/showrev.txt
@@ -0,0 +1,2 @@
+**이것은 문서의 이전 버전입니다!**
+----
diff --git a/inc/lang/ko/stopwords.txt b/inc/lang/ko/stopwords.txt
new file mode 100644
index 000000000..bdb41deba
--- /dev/null
+++ b/inc/lang/ko/stopwords.txt
@@ -0,0 +1,29 @@
+# 색인이 만들어 지지 않는 단어 목록입니다.(한줄에 한단어)
+# 이 파일을 편집한다면 UNIX줄 종료문자를 사용해야합니다.(단일 개행문자)
+# 3문자이하 단어는 자동으로 무시되므로 3문자보다 짧은 단어는 포함시킬 필요가 없습니다.
+# http://www.ranks.nl/stopwords/을 기준으로 만들어진 목록입니다.
+about
+are
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/ko/subscr_digest.txt b/inc/lang/ko/subscr_digest.txt
new file mode 100644
index 000000000..2e9c87848
--- /dev/null
+++ b/inc/lang/ko/subscr_digest.txt
@@ -0,0 +1,18 @@
+안녕하세요!
+
+@TITLE@ 라는 제목의 페이지 @PAGE@ 가 변경되었습니다.
+
+변경사항은 다음과 같습니다:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+옛날 것: @OLDPAGE@
+새 것: @NEWPAGE@
+
+이 페이지 변경알림의 설정을 바구려면, @DOKUWIKIURL@에 로그인한 뒤
+@SUBSCRIBE@ 를 방문하여 페이지나 이름공간의 구독을 취소하세요.
+
+--
+@DOKUWIKIURL@의 DokuWiki가 자동으로 만들어낸 메일입니다. \ No newline at end of file
diff --git a/inc/lang/ko/subscr_form.txt b/inc/lang/ko/subscr_form.txt
new file mode 100644
index 000000000..31470f372
--- /dev/null
+++ b/inc/lang/ko/subscr_form.txt
@@ -0,0 +1,3 @@
+====== 구독 관리 ======
+
+이 페이지는 현재의 페이지와 네임스페이스의 구독을 관리할 수있도록 해줍니다. \ No newline at end of file
diff --git a/inc/lang/ko/subscr_list.txt b/inc/lang/ko/subscr_list.txt
new file mode 100644
index 000000000..2661a6a15
--- /dev/null
+++ b/inc/lang/ko/subscr_list.txt
@@ -0,0 +1,15 @@
+안녕하세요!
+
+@TITLE@ 라는 제목의 페이지 @PAGE@ 가 변경되었습니다.
+
+변경사항은 다음과 같습니다:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+이 페이지 변경알림의 설정을 바구려면, @DOKUWIKIURL@에 로그인한 뒤
+@SUBSCRIBE@ 를 방문하여 페이지나 이름공간의 구독을 취소하세요.
+
+--
+@DOKUWIKIURL@의 DokuWiki가 자동으로 만들어낸 메일입니다. \ No newline at end of file
diff --git a/inc/lang/ko/subscr_single.txt b/inc/lang/ko/subscr_single.txt
new file mode 100644
index 000000000..1aa4d7efa
--- /dev/null
+++ b/inc/lang/ko/subscr_single.txt
@@ -0,0 +1,21 @@
+안녕하세요!
+
+@TITLE@ 라는 제목의 페이지 @PAGE@ 가 변경되었습니다.
+
+변경사항은 다음과 같습니다:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+날짜 : @DATE@
+사용자 : @USER@
+편집 요약 : @SUMMARY@
+구 버전 : @OLDPAGE@
+새 버전 : @NEWPAGE@
+
+이 페이지 변경알림의 설정을 바구려면, @DOKUWIKIURL@에 로그인한 뒤 t
+@NEWPAGE@ 를 방문하여 페이지나 이름공간의 구독을 취소하세요.
+
+--
+@DOKUWIKIURL@의 DokuWiki가 자동으로 만들어낸 메일입니다. \ No newline at end of file
diff --git a/inc/lang/ko/updateprofile.txt b/inc/lang/ko/updateprofile.txt
new file mode 100644
index 000000000..5ea331c05
--- /dev/null
+++ b/inc/lang/ko/updateprofile.txt
@@ -0,0 +1,5 @@
+====== 개인 정보 수정 ======
+
+변경하고 싶은 항목을 입력하기 바랍니다. 사용자 이름은 바꾸고 싶지 않겠지요?
+
+
diff --git a/inc/lang/ko/uploadmail.txt b/inc/lang/ko/uploadmail.txt
new file mode 100644
index 000000000..46c66a66b
--- /dev/null
+++ b/inc/lang/ko/uploadmail.txt
@@ -0,0 +1,15 @@
+DokuWiki가 파일을 업로드하였습니다.
+
+자세한 정보:
+
+파일 : @MEDIA@
+날짜 : @DATE@
+웹 브라우저 : @BROWSER@
+IP 주소 : @IPADDRESS@
+호스트명 : @HOSTNAME@
+크기 : @SIZE@
+파일 종류 : @MIME@
+사용자 : @USER@
+
+--
+이 메일은 @DOKUWIKIURL@의 DokuWiki가 생성한 메일입니다. \ No newline at end of file
diff --git a/inc/lang/ku/admin.txt b/inc/lang/ku/admin.txt
new file mode 100644
index 000000000..cfd21b217
--- /dev/null
+++ b/inc/lang/ku/admin.txt
@@ -0,0 +1,4 @@
+====== Administration ======
+
+Below you can find a list of administrative tasks available in DokuWiki.
+
diff --git a/inc/lang/ku/backlinks.txt b/inc/lang/ku/backlinks.txt
new file mode 100644
index 000000000..5fa2ddfda
--- /dev/null
+++ b/inc/lang/ku/backlinks.txt
@@ -0,0 +1,4 @@
+====== Girêdanên paş ======
+
+Di rûpelên di vê lîsteyê de girêdanên ji vê rûpelê re hene.
+
diff --git a/inc/lang/ku/conflict.txt b/inc/lang/ku/conflict.txt
new file mode 100644
index 000000000..e139dce26
--- /dev/null
+++ b/inc/lang/ku/conflict.txt
@@ -0,0 +1,6 @@
+====== Guhertoyeke nûtir heye ======
+
+Guhertoyeke nûtir a belgeya ku tu biguherînî heye. Sedema wê, bikarhênerkê/î din di hema demê de belge diguherîne.
+
+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/inc/lang/ku/denied.txt b/inc/lang/ku/denied.txt
new file mode 100644
index 000000000..3ac72820c
--- /dev/null
+++ b/inc/lang/ku/denied.txt
@@ -0,0 +1,4 @@
+====== Permission Denied ======
+
+Sorry, you don't have enough rights to continue. Perhaps you forgot to login?
+
diff --git a/inc/lang/ku/diff.txt b/inc/lang/ku/diff.txt
new file mode 100644
index 000000000..934ffb67e
--- /dev/null
+++ b/inc/lang/ku/diff.txt
@@ -0,0 +1,4 @@
+====== Cuyawazî ======
+
+Li vê derê cuyawaziyên nav revîziyona hilbijartî û verziyona aniha tên nîşan dan.
+
diff --git a/inc/lang/ku/edit.txt b/inc/lang/ku/edit.txt
new file mode 100644
index 000000000..3a259dcf7
--- /dev/null
+++ b/inc/lang/ku/edit.txt
@@ -0,0 +1,2 @@
+Rûpelê biguherîne û ''Tomar bike'' bitikîne. Ji bo sîntaksa wîkiyê binihêre [[wiki:syntax]]. Ji kerema xwe rûpelê bi tenê biguherîne, heke tû dikarî **baştir** bikî. Heke tu dixwazî çend tiştan biceribînî, biçe [[wiki:playground]]. Li vê derê tu dikarî her tiştî biceribînî.
+
diff --git a/inc/lang/ku/editrev.txt b/inc/lang/ku/editrev.txt
new file mode 100644
index 000000000..e6995713b
--- /dev/null
+++ b/inc/lang/ku/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.
+---- \ No newline at end of file
diff --git a/inc/lang/ku/index.txt b/inc/lang/ku/index.txt
new file mode 100644
index 000000000..401404484
--- /dev/null
+++ b/inc/lang/ku/index.txt
@@ -0,0 +1,3 @@
+====== Îndeks ======
+
+Ev îndeksa hemû rûpelên heyî ye. Rûpel li gora [[doku>namespaces|namespace]] hatin birêzkirin. \ No newline at end of file
diff --git a/inc/lang/ku/lang.php b/inc/lang/ku/lang.php
new file mode 100644
index 000000000..63ccafa35
--- /dev/null
+++ b/inc/lang/ku/lang.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * kurdish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @translator Erdal Ronahî <erdal.ronahi@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+
+$lang['btn_edit'] = 'Vê rûpelê biguherîne';
+$lang['btn_source'] = 'Çavkaniya rûpelê nîşan bide';
+$lang['btn_show'] = 'Rûpelê nîşan bide';
+$lang['btn_create'] = 'Vê rûpelê biafirîne';
+$lang['btn_search'] = 'Lêbigere';
+$lang['btn_save'] = 'Tomar bike';
+$lang['btn_preview']= 'Pêşdîtin';
+$lang['btn_top'] = 'Biçe ser';
+$lang['btn_newer'] = '<< nûtir';
+$lang['btn_older'] = 'kevntir >>';
+$lang['btn_revs'] = 'Revîziyonên kevn';
+$lang['btn_recent'] = 'Guherandinên dawî';
+$lang['btn_upload'] = 'Bar bike';
+$lang['btn_cancel'] = 'Betal';
+$lang['btn_index'] = 'Îndeks';
+$lang['btn_secedit']= 'Biguherîne';
+$lang['btn_login'] = 'Têkeve';
+$lang['btn_logout'] = 'Derkeve';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Rojanekirin';
+$lang['btn_delete'] = 'Jê bibe';
+$lang['btn_back'] = 'Paş';
+$lang['btn_backlink'] = "Girêdanên paş";
+$lang['btn_backtomedia'] = 'Back to Mediafile Selection';
+$lang['btn_subscribe'] = 'Subscribe Changes';
+$lang['btn_unsubscribe'] = 'Unsubscribe Changes';
+$lang['btn_register'] = 'Register';
+
+$lang['loggedinas'] = 'Logged in as';
+$lang['user'] = 'Username';
+$lang['pass'] = 'Password';
+$lang['passchk'] = 'once again';
+$lang['remember'] = 'Remember me';
+$lang['fullname'] = 'Full name';
+$lang['email'] = 'E-Mail';
+$lang['badlogin'] = 'Sorry, username or password was wrong.';
+
+$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['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 identically, please try again.';
+$lang['regpwmail'] = 'Your DokuWiki password';
+$lang['reghere'] = 'You don\'t have an account yet? Just get one';
+
+$lang['txt_upload'] = 'Select file to upload';
+$lang['txt_filename'] = 'Enter wikiname (optional)';
+$lang['txt_overwrt'] = 'Overwrite existing file';
+$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.\nReally continue?";
+
+$lang['rssfailed'] = 'An error occured while fetching this feed: ';
+$lang['nothingfound']= 'Tiştek nehat dîtin.';
+
+$lang['mediaselect'] = 'Mediafile Selection';
+$lang['fileupload'] = 'Mediafile Upload';
+$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['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'] = 'Namespace';
+$lang['mediafiles'] = 'Available files in';
+
+$lang['reference'] = 'Referansa';
+$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'] = 'Tabloya Navêrokê';
+$lang['current'] = 'current';
+$lang['yours'] = 'Your Version';
+$lang['diff'] = 'show differences to current version';
+$lang['line'] = 'Rêz';
+$lang['breadcrumb'] = 'Şop';
+$lang['lastmod'] = 'Guherandina dawî';
+$lang['by'] = 'by';
+$lang['deleted'] = 'hat jê birin';
+$lang['created'] = 'hat afirandin';
+$lang['restored'] = 'old revision restored';
+$lang['summary'] = 'Kurteya guhartinê';
+
+$lang['mail_newpage'] = 'page added:';
+$lang['mail_changed'] = 'page changed:';
+
+$lang['js']['nosmblinks'] = "Linking to Windows shares only works in Microsoft Internet Explorer.\nYou still can copy and paste the link.";
+
+$lang['qb_bold'] = 'Bold Text';
+$lang['qb_italic'] = 'Italic Text';
+$lang['qb_underl'] = 'Underlined Text';
+$lang['qb_code'] = 'Code 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_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';
+$lang['qb_sig'] = 'Insert Signature';
+
+$lang['js']['del_confirm']= 'Delete this entry?';
+
+$lang['admin_acl'] = 'Access Control List Management...';
+$lang['admin_register']= 'Add new user...';
+
+$lang['acl_group'] = 'Group';
+$lang['acl_user'] = 'User';
+$lang['acl_perms'] = 'Permissions for';
+$lang['page'] = 'Rûpel';
+$lang['namespace'] = 'Namespace';
+
+$lang['acl_perm1'] = 'Bixwîne';
+$lang['acl_perm2'] = 'Biguherîne';
+$lang['acl_perm4'] = 'Biafirîne';
+$lang['acl_perm8'] = 'Upload';
+$lang['acl_perm16'] = 'Jê bibe';
+$lang['acl_new'] = 'Add new Entry';
+
+$lang['metaedit'] = 'Edit Metadata';
+$lang['metasaveerr'] = 'Writing metadata failed';
+$lang['metasaveok'] = 'Metadata saved';
+$lang['img_backto'] = 'Back to';
+$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['subscribe_success'] = 'Added %s to subscription list for %s';
+$lang['subscribe_error'] = 'Error adding %s to subscription list for %s';
+$lang['subscribe_noaddress']= 'There is no address associated with your login, you cannot be added to the subscription list';
+$lang['unsubscribe_success']= 'Removed %s from subscription list for %s';
+$lang['unsubscribe_error'] = 'Error removing %s from subscription list for %s';
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/lang/ku/locked.txt b/inc/lang/ku/locked.txt
new file mode 100644
index 000000000..af6347a96
--- /dev/null
+++ b/inc/lang/ku/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/inc/lang/ku/login.txt b/inc/lang/ku/login.txt
new file mode 100644
index 000000000..2004ea198
--- /dev/null
+++ b/inc/lang/ku/login.txt
@@ -0,0 +1,4 @@
+====== 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/inc/lang/ku/mailtext.txt b/inc/lang/ku/mailtext.txt
new file mode 100644
index 000000000..44a3f6553
--- /dev/null
+++ b/inc/lang/ku/mailtext.txt
@@ -0,0 +1,17 @@
+A page in your DokuWiki was added or changed. Here are the details:
+
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+Old Revision: @OLDPAGE@
+New Revision: @NEWPAGE@
+Edit Summary: @SUMMARY@
+User : @USER@
+
+@DIFF@
+
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/ku/newpage.txt b/inc/lang/ku/newpage.txt
new file mode 100644
index 000000000..6d256f06e
--- /dev/null
+++ b/inc/lang/ku/newpage.txt
@@ -0,0 +1,3 @@
+====== Ev rûpel hîn nehat nivîsandin ======
+
+Rûpela tu hatî hîn nehat nivîsandin. Tu dikarî niha dest bi nivîsandina vê rûpelê bikî. Ji bo vê, ''Dest pê bike'' bitikîne.
diff --git a/inc/lang/ku/norev.txt b/inc/lang/ku/norev.txt
new file mode 100644
index 000000000..0b21bf3f0
--- /dev/null
+++ b/inc/lang/ku/norev.txt
@@ -0,0 +1,4 @@
+====== No such revision ======
+
+The specified revision doesn't exist. Use the ''Old revisions'' button for a list of old revisions of this document.
+
diff --git a/inc/lang/ku/password.txt b/inc/lang/ku/password.txt
new file mode 100644
index 000000000..6d5cbe678
--- /dev/null
+++ b/inc/lang/ku/password.txt
@@ -0,0 +1,10 @@
+Hi @FULLNAME@!
+
+Here is your userdata for @TITLE@ at @DOKUWIKIURL@
+
+Login : @LOGIN@
+Password : @PASSWORD@
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/ku/preview.txt b/inc/lang/ku/preview.txt
new file mode 100644
index 000000000..da8f4cb44
--- /dev/null
+++ b/inc/lang/ku/preview.txt
@@ -0,0 +1,3 @@
+====== Pêşdîtin ======
+
+Li vê derê tu dikarî bibîni ku nivîsa te dê çawa xuya bibe. Ji bîr neke: Hîn **nehat tomar kirin**! \ No newline at end of file
diff --git a/inc/lang/ku/read.txt b/inc/lang/ku/read.txt
new file mode 100644
index 000000000..9f56d81ad
--- /dev/null
+++ b/inc/lang/ku/read.txt
@@ -0,0 +1,2 @@
+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/inc/lang/ku/recent.txt b/inc/lang/ku/recent.txt
new file mode 100644
index 000000000..268c89ab2
--- /dev/null
+++ b/inc/lang/ku/recent.txt
@@ -0,0 +1,3 @@
+====== Guherandinên dawî ======
+
+Ev rûpel di dema nêzîk de hatin guherandin.
diff --git a/inc/lang/ku/register.txt b/inc/lang/ku/register.txt
new file mode 100644
index 000000000..b65683bc2
--- /dev/null
+++ b/inc/lang/ku/register.txt
@@ -0,0 +1,4 @@
+====== 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** - your new password will be sent to it. The login name should be a valid [[doku>pagename|pagename]].
+
diff --git a/inc/lang/ku/revisions.txt b/inc/lang/ku/revisions.txt
new file mode 100644
index 000000000..dd5f35b8e
--- /dev/null
+++ b/inc/lang/ku/revisions.txt
@@ -0,0 +1,4 @@
+====== 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/inc/lang/ku/searchpage.txt b/inc/lang/ku/searchpage.txt
new file mode 100644
index 000000000..6646228d5
--- /dev/null
+++ b/inc/lang/ku/searchpage.txt
@@ -0,0 +1,5 @@
+====== Lêbigere ======
+
+Jêr encamên lêgerandina te tên nîşan dan. Heke tiştek nehatibe dîtin, tu dikarî dest bi nivîsandina rûpelekê nû bikî. Ji bo vê, ''Vê rûpelê biguherîne'' bitikîne.
+
+===== Encam ===== \ No newline at end of file
diff --git a/inc/lang/ku/showrev.txt b/inc/lang/ku/showrev.txt
new file mode 100644
index 000000000..3608de36b
--- /dev/null
+++ b/inc/lang/ku/showrev.txt
@@ -0,0 +1,2 @@
+**This is an old revision of the document!**
+----
diff --git a/inc/lang/ku/stopwords.txt b/inc/lang/ku/stopwords.txt
new file mode 100644
index 000000000..bc6eb48ae
--- /dev/null
+++ b/inc/lang/ku/stopwords.txt
@@ -0,0 +1,29 @@
+# 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
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/la/admin.txt b/inc/lang/la/admin.txt
new file mode 100644
index 000000000..a8e380280
--- /dev/null
+++ b/inc/lang/la/admin.txt
@@ -0,0 +1,3 @@
+====== Administratio ======
+
+In hac pagina administratio uicis est. \ No newline at end of file
diff --git a/inc/lang/la/adminplugins.txt b/inc/lang/la/adminplugins.txt
new file mode 100644
index 000000000..9f2ec47aa
--- /dev/null
+++ b/inc/lang/la/adminplugins.txt
@@ -0,0 +1 @@
+===== Addenda alia ===== \ No newline at end of file
diff --git a/inc/lang/la/backlinks.txt b/inc/lang/la/backlinks.txt
new file mode 100644
index 000000000..b3c0d131c
--- /dev/null
+++ b/inc/lang/la/backlinks.txt
@@ -0,0 +1,3 @@
+====== Nexa ======
+
+Index paginarum, quae ad hanc paginam connexae sunt.
diff --git a/inc/lang/la/conflict.txt b/inc/lang/la/conflict.txt
new file mode 100644
index 000000000..aebc38b25
--- /dev/null
+++ b/inc/lang/la/conflict.txt
@@ -0,0 +1,5 @@
+====== Recentior forma est ======
+
+Recentior forma est: nam dum hanc paginam recensibas, aliquis paginam mutauit.
+
+Discrimina uides et formam seruandam eligis. Alia forma delebitur. \ No newline at end of file
diff --git a/inc/lang/la/denied.txt b/inc/lang/la/denied.txt
new file mode 100644
index 000000000..fdb62f53e
--- /dev/null
+++ b/inc/lang/la/denied.txt
@@ -0,0 +1,3 @@
+====== Ad hanc paginam accedere non potes ======
+
+Ad hanc paginam accedere non potes: antea in conuentum ineas, deinde rursum temptas \ No newline at end of file
diff --git a/inc/lang/la/diff.txt b/inc/lang/la/diff.txt
new file mode 100644
index 000000000..ead382715
--- /dev/null
+++ b/inc/lang/la/diff.txt
@@ -0,0 +1,3 @@
+====== Discrimina ======
+
+Discrimina inter duas paginas ostendere \ No newline at end of file
diff --git a/inc/lang/la/draft.txt b/inc/lang/la/draft.txt
new file mode 100644
index 000000000..23bb20fe2
--- /dev/null
+++ b/inc/lang/la/draft.txt
@@ -0,0 +1,5 @@
+====== Propositum inuentum ======
+
+Tua extrema recensio non perfecta est. Vicis propositum in itinere seruauit, sic his seruatis uteris.
+
+Statuas si //restituere// uis, //delere// seruata aut //delere// omnes. \ No newline at end of file
diff --git a/inc/lang/la/edit.txt b/inc/lang/la/edit.txt
new file mode 100644
index 000000000..342b30726
--- /dev/null
+++ b/inc/lang/la/edit.txt
@@ -0,0 +1 @@
+Paginam recensere et "Serua" premere. Vide [[wiki:syntax]] ut uicis stilus uidere possis. Hanc paginam recenses, solum si hanc auges. Prima uestigia apud hunc nexum [[playground:playground|playground]] uidere possis. \ No newline at end of file
diff --git a/inc/lang/la/editrev.txt b/inc/lang/la/editrev.txt
new file mode 100644
index 000000000..6a4d082cc
--- /dev/null
+++ b/inc/lang/la/editrev.txt
@@ -0,0 +1,2 @@
+**Vetus forma a te restituta est** Si hanc formam seruabis, nouam creabis.
+---- \ No newline at end of file
diff --git a/inc/lang/la/index.txt b/inc/lang/la/index.txt
new file mode 100644
index 000000000..cd65dbb59
--- /dev/null
+++ b/inc/lang/la/index.txt
@@ -0,0 +1,3 @@
+====== Forma Situs ======
+
+Haec forma situs ordinata [[doku>namespaces|generatim]]. \ No newline at end of file
diff --git a/inc/lang/la/install.html b/inc/lang/la/install.html
new file mode 100644
index 000000000..c06f3ac2c
--- /dev/null
+++ b/inc/lang/la/install.html
@@ -0,0 +1,8 @@
+<p>Haec pagina te adiuuat in <a href="http://dokuwiki.org">Dokuuiki</a> conformando. Maiores res in
+<a href="http://dokuwiki.org/installer">hac pagina</a> sunt.</p>
+
+<p>DokuWiki documenta ut omnes paginas uicis et omnia (ut imagines, indices, ueteres formas) quae ad easdem pertinent colligat. Vt bene operet DokuWiki omnes facultates scrini habere <strong>debes</strong>. Hoc instrumentum facultates eligere non potest, his facultatibus locatori spati interretis quaeras uel FTP intrumento uel aliis rebus (ut cPanel) uteraris.</p>
+
+<p>Hoc intrumentum optiones primae DokuWiki <acronym title="index custodiae ,aditus">ICA</acronym>, quos rectori situs inire et indicem, ut addenda optiones uicis et alia administrare possit uidere licet. Hoc instrumentum non necessarium DokuWiki ut feliciter operet, sed melius administrare adiuuat.</p>
+
+<p>Periti uel qui certa quaesita habet paginas <a href="http://dokuwiki.org/install">rationis conformandum uicem</a> et <a href="http://dokuwiki.org/config">optionum conformationis</a> uidere possunt.</p> \ No newline at end of file
diff --git a/inc/lang/la/lang.php b/inc/lang/la/lang.php
new file mode 100644
index 000000000..25102d583
--- /dev/null
+++ b/inc/lang/la/lang.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * la language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesLa.php?view=co
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '"';
+$lang['doublequoteclosing'] = '"';
+$lang['singlequoteopening'] = '`';
+$lang['singlequoteclosing'] = '\'';
+$lang['apostrophe'] = '´';
+$lang['btn_edit'] = 'Recensere hanc paginam';
+$lang['btn_source'] = 'Fontem uidere';
+$lang['btn_show'] = 'Ostendere paginam';
+$lang['btn_create'] = 'Creare paginam';
+$lang['btn_search'] = 'Quaerere';
+$lang['btn_save'] = 'Seruare';
+$lang['btn_preview'] = 'Praeuidere';
+$lang['btn_top'] = 'I ad summa';
+$lang['btn_newer'] = '<< recentiores';
+$lang['btn_older'] = 'minus recentiores >>';
+$lang['btn_revs'] = 'Veteres renouationes';
+$lang['btn_recent'] = 'Nuper mutata';
+$lang['btn_upload'] = 'Onerare';
+$lang['btn_cancel'] = 'Abrogare';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit'] = 'Recensere';
+$lang['btn_login'] = 'Conuentum aperire';
+$lang['btn_logout'] = 'Conuentum concludere';
+$lang['btn_admin'] = 'Rector';
+$lang['btn_update'] = 'Nouare';
+$lang['btn_delete'] = 'Delere';
+$lang['btn_back'] = 'Redire';
+$lang['btn_backlink'] = 'Nexus ad paginam';
+$lang['btn_backtomedia'] = 'Ad media redire';
+$lang['btn_subscribe'] = 'Custodire';
+$lang['btn_profile'] = 'Tabellam nouare';
+$lang['btn_reset'] = 'Abrogare';
+$lang['btn_resendpwd'] = 'Tesseram nouam cursu interretiali petere';
+$lang['btn_draft'] = 'Propositum recensere';
+$lang['btn_recover'] = 'Propositum reficere';
+$lang['btn_draftdel'] = 'Propositum delere';
+$lang['btn_revert'] = 'Reficere';
+$lang['btn_register'] = 'Te adscribere';
+$lang['loggedinas'] = 'Nomen sodalis:';
+$lang['user'] = 'Nomen sodalis:';
+$lang['pass'] = 'Tessera tua';
+$lang['newpass'] = 'Tessera noua';
+$lang['oldpass'] = 'Tessera uetus:';
+$lang['passchk'] = 'Tesseram tuam adfirmare';
+$lang['remember'] = 'Tesseram meam sodalitatis memento';
+$lang['fullname'] = 'Nomen tuom uerum:';
+$lang['email'] = 'Cursus interretialis:';
+$lang['profile'] = 'Tabella Sodalis';
+$lang['badlogin'] = 'Error in ineundo est, rectum nomen uel tessera cedo.';
+$lang['minoredit'] = 'Recensio minor';
+$lang['draftdate'] = 'Propositum seruatur die:';
+$lang['nosecedit'] = 'Pagina interea mutatur, pars rerum exiit, in loco eius tota pagina reclamata est.';
+$lang['regmissing'] = 'Omnes campi complendi sunt.';
+$lang['reguexists'] = 'Nomen Sodalis ab aliquo iam elegitur.';
+$lang['regsuccess'] = 'Adscriptio feliciter perficitur et tessera cursu interretiali mittitur';
+$lang['regsuccess2'] = 'Adscriptio perficitur';
+$lang['regmailfail'] = 'Error in litteras mittendo est. Rectorem conueni!';
+$lang['regbadmail'] = 'Cursus interretialis non legitimus: si errorem putes, Rectorem conueni.';
+$lang['regbadpass'] = 'Tesserae quas scripsisti inter se non congruont.';
+$lang['regpwmail'] = 'Tessera Dokuuicis tuam';
+$lang['reghere'] = 'Non iam adscriptus\a esne? Te adscribe';
+$lang['profna'] = 'Tabellam tuam mutare non potes.';
+$lang['profnochange'] = 'Si res non mutare uis, nihil agere';
+$lang['profnoempty'] = 'Omnes campi complendi sunt.';
+$lang['profchanged'] = 'Tabella Sodalis feliciter nouatur';
+$lang['pwdforget'] = 'Tesseram amisistine? Nouam petere';
+$lang['resendna'] = 'Tesseram non mutare potest.';
+$lang['resendpwd'] = 'Tesseram mitte';
+$lang['resendpwdmissing'] = 'Omnes campi complendi sunt.';
+$lang['resendpwdnouser'] = 'In tabellis Sodalium nomen non inuentum est.';
+$lang['resendpwdbadauth'] = 'Tesseram non legitima est.';
+$lang['resendpwdconfirm'] = 'Confirmatio cursu interretiali mittitur.';
+$lang['resendpwdsuccess'] = 'Tessera noua cursu interretiali mittitur.';
+$lang['license'] = 'Praeter ubi adnotatum, omnia scripta Corporis Gentis Latinae cum his facultatibus:';
+$lang['licenseok'] = 'Caue: si paginam recenseas, has facultates confirmas:';
+$lang['searchmedia'] = 'Quaere titulum:';
+$lang['searchmedia_in'] = 'Quaere "%s":';
+$lang['txt_upload'] = 'Eligere documenta oneranda:';
+$lang['txt_filename'] = 'Onerare (optio):';
+$lang['txt_overwrt'] = 'Documento ueteri imponere:';
+$lang['lockedby'] = 'Nunc hoc intercludit';
+$lang['lockexpire'] = 'Hoc apertum';
+$lang['js']['willexpire'] = 'Interclusio paginae recensendae uno minuto finita est.\nUt errores uites, \'praeuisio\' preme ut interclusionem ripristines.';
+$lang['js']['notsavedyet'] = 'Res non seruatae amissurae sunt.';
+$lang['js']['searchmedia'] = 'Quaere inter documenta';
+$lang['js']['keepopen'] = 'Fenestram apertam tene';
+$lang['js']['hidedetails'] = 'Singulas res abscondere';
+$lang['js']['mediatitle'] = 'Optiones nexorum';
+$lang['js']['mediadisplay'] = 'Genus nexi';
+$lang['js']['mediaalign'] = 'Collocatio';
+$lang['js']['mediasize'] = 'Amplitudo imaginis';
+$lang['js']['mediatarget'] = 'Cui nexum est';
+$lang['js']['mediaclose'] = 'Claudere';
+$lang['js']['mediainsert'] = 'Insere';
+$lang['js']['mediadisplayimg'] = 'Imaginem ostendere';
+$lang['js']['mediadisplaylnk'] = 'Solum nexum ostendere';
+$lang['js']['mediasmall'] = 'Forma minor';
+$lang['js']['mediamedium'] = 'Forma media';
+$lang['js']['medialarge'] = 'Forma maior';
+$lang['js']['mediaoriginal'] = 'Forma primigenia';
+$lang['js']['medialnk'] = 'Singulis rebus paginae nexum';
+$lang['js']['mediadirect'] = 'Primigeniae formae nexum';
+$lang['js']['medianolnk'] = 'Connectio deest';
+$lang['js']['medianolink'] = 'Imaginem non connectere';
+$lang['js']['medialeft'] = 'Imaginem ad sinistram collocare';
+$lang['js']['mediaright'] = 'Imaginem ad dextram collocare';
+$lang['js']['mediacenter'] = 'Imaginem in mediam collocare';
+$lang['js']['medianoalign'] = 'Collocationem remouere';
+$lang['js']['nosmblinks'] = 'Windows nexa solum cum Microsoft Internet Explorer ostendi possunt.
+Adhuc transcribere nexum potes.';
+$lang['js']['linkwiz'] = 'Connectendi ductor';
+$lang['js']['linkto'] = 'Nexum ad:';
+$lang['js']['del_confirm'] = 'Delere electas res uin?';
+$lang['rssfailed'] = 'Error in restituendo ';
+$lang['nothingfound'] = 'Nihil inuentum est.';
+$lang['mediaselect'] = 'Documenta uisiua:';
+$lang['fileupload'] = 'Documentum uisiuom onerare';
+$lang['uploadsucc'] = 'Oneratum perfectum';
+$lang['uploadfail'] = 'Error onerandi.';
+$lang['uploadwrong'] = 'Onerare non potest. Genus documenti non legitimum!';
+$lang['uploadexist'] = 'Documentum iam est.';
+$lang['uploadbadcontent'] = 'Documentum oneratum cum genere documenti non congruit.';
+$lang['uploadspam'] = 'Onerare non potest: nam in indice perscriptionis documentum est.';
+$lang['uploadxss'] = 'Onerare non potest: nam forsitan malum scriptum in documento est.';
+$lang['uploadsize'] = 'Documentum onerandum ponderosius est. (Maxime "%s")';
+$lang['deletesucc'] = 'Documentum "%s" deletum est.';
+$lang['deletefail'] = '"%s" non deletur: uide facultates.';
+$lang['mediainuse'] = 'documentum "%s" non deletur, nam aliquis hoc utitur.';
+$lang['namespaces'] = 'Genus';
+$lang['mediafiles'] = 'Documentum liberum in:';
+$lang['accessdenied'] = 'Non uidere documentum potes.';
+$lang['mediausage'] = 'Hac forma uteris ut documentum referas:';
+$lang['mediaview'] = 'Vide documentum primigenium';
+$lang['mediaroot'] = 'scrinium';
+$lang['mediaupload'] = 'Hic genus oneras. Si nouom genus creare uis, ante "Onerare ut" nomen documenti diuisum a duabus punctis ponas.';
+$lang['mediaextchange'] = 'Genus documenti mutatum a(b) ".%s" ad ".%s"!';
+$lang['reference'] = 'Referre:';
+$lang['ref_inuse'] = 'Documentum non deleri potest, nam in his paginis apertum est:';
+$lang['ref_hidden'] = 'Aliquae mentiones ad paginas, ad quas ire non potes, habent';
+$lang['hits'] = 'Ictus';
+$lang['quickhits'] = 'Spatium nominis conguens';
+$lang['toc'] = 'Index';
+$lang['current'] = 'nouos\a\um';
+$lang['yours'] = 'Tua forma';
+$lang['diff'] = 'Discrimina inter formas ostendere';
+$lang['diff2'] = 'Discrimina inter electas recensiones ostendere';
+$lang['difflink'] = 'Nexum ad comparandum';
+$lang['line'] = 'Linea';
+$lang['breadcrumb'] = 'Vestigium';
+$lang['youarehere'] = 'Hic es';
+$lang['lastmod'] = 'Extrema mutatio';
+$lang['by'] = 'a(b)';
+$lang['deleted'] = 'deletur';
+$lang['created'] = 'creatur';
+$lang['restored'] = 'Recensio uetus restituta';
+$lang['external_edit'] = 'Externe recensere';
+$lang['summary'] = 'Indicem recensere';
+$lang['noflash'] = '<a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> necessarium est.';
+$lang['download'] = 'Snippet capere';
+$lang['mail_newpage'] = 'Pagina addita:';
+$lang['mail_changed'] = 'Pagina mutata:';
+$lang['mail_subscribe_list'] = 'Paginae in genere mutatae:';
+$lang['mail_new_user'] = 'Nouos Sodalis:';
+$lang['mail_upload'] = 'Documentum oneratum:';
+$lang['qb_bold'] = 'Litterae pingues';
+$lang['qb_italic'] = 'Litterae italicae';
+$lang['qb_underl'] = 'Litterae sullineatae';
+$lang['qb_code'] = 'Codex scripti';
+$lang['qb_strike'] = 'Litterae illineatae';
+$lang['qb_h1'] = 'Caput I';
+$lang['qb_h2'] = 'Caput II';
+$lang['qb_h3'] = 'Caput III';
+$lang['qb_h4'] = 'Caput IV';
+$lang['qb_h5'] = 'Caput V';
+$lang['qb_h'] = 'Caput';
+$lang['qb_hs'] = 'Caput eligere';
+$lang['qb_hplus'] = 'Caput maius';
+$lang['qb_hminus'] = 'Caput minus';
+$lang['qb_hequal'] = 'Caput eiusdem gradus';
+$lang['qb_link'] = 'Nexus internus';
+$lang['qb_extlink'] = 'Nexus externus (memento praefigere http://)';
+$lang['qb_hr'] = 'Linea directa (noli saepe uti)';
+$lang['qb_ol'] = 'Index ordinatus rerum';
+$lang['qb_ul'] = 'Index non ordinatus rerum';
+$lang['qb_media'] = 'Imagines et documenta addere';
+$lang['qb_sig'] = 'Subscriptio tua cum indicatione temporis';
+$lang['qb_smileys'] = 'Pupuli';
+$lang['qb_chars'] = 'Signa singularia';
+$lang['upperns'] = 'I ad anterius genus';
+$lang['admin_register'] = 'Nouom Sodalem creare';
+$lang['metaedit'] = 'Res codicis mutare';
+$lang['metasaveerr'] = 'Res codicis non scribitur.';
+$lang['metasaveok'] = 'Res codicis seruatae.';
+$lang['img_backto'] = 'Redere ad';
+$lang['img_title'] = 'Titulus';
+$lang['img_caption'] = 'Descriptio';
+$lang['img_date'] = 'Dies';
+$lang['img_fname'] = 'Titulus documenti';
+$lang['img_fsize'] = 'Pondus';
+$lang['img_artist'] = 'Imaginum exprimitor\trix';
+$lang['img_copyr'] = 'Iura exemplarium';
+$lang['img_format'] = 'Forma';
+$lang['img_camera'] = 'Cella';
+$lang['img_keywords'] = 'Verba claues';
+$lang['subscr_subscribe_success'] = '%s additur indici subscriptionis quod %s';
+$lang['subscr_subscribe_error'] = '%s non additur indici subscriptionis quod %s';
+$lang['subscr_subscribe_noaddress'] = 'Cursus interretialis tuus deest, sic in indice subscriptionis non scribi potes';
+$lang['subscr_unsubscribe_success'] = 'A subscriptione %s deletur quod %s';
+$lang['subscr_unsubscribe_error'] = 'Error delendi %s a subscriptione quod %s';
+$lang['subscr_already_subscribed'] = '%s iam subscriptus\a est in %s';
+$lang['subscr_not_subscribed'] = '%s non subscriptus\a est in %s';
+$lang['subscr_m_not_subscribed'] = 'Non hanc paginam uel genus subscribere potes.';
+$lang['subscr_m_new_header'] = 'Subscriptionem addere';
+$lang['subscr_m_current_header'] = 'haec subscriptio:';
+$lang['subscr_m_unsubscribe'] = 'Delere';
+$lang['subscr_m_subscribe'] = 'Subscribere';
+$lang['subscr_m_receive'] = 'Accipere';
+$lang['subscr_style_every'] = 'Cursus mutationibus omnibus';
+$lang['subscr_style_digest'] = 'Accipere litteras in mutando paginam (%.2f dies)';
+$lang['subscr_style_list'] = 'Index mutatarum paginarum ab extremis litteris (%.2f dies)';
+$lang['authmodfailed'] = 'Confirmatio infeliciter facta est. Rectorem conuenis.';
+$lang['authtempfail'] = 'Confirmare non potes. Rectorem conuenis.';
+$lang['i_chooselang'] = 'Linguam eligere';
+$lang['i_installer'] = 'Docuuicis creator';
+$lang['i_wikiname'] = 'Nomen Vicis';
+$lang['i_enableacl'] = 'ICA aptum facias (consulatum est)';
+$lang['i_superuser'] = 'Magister\stra';
+$lang['i_problems'] = 'Creator hos errores habes. Continuare potes postquam omnia soluentur.';
+$lang['i_modified'] = 'Hoc scriptum solum cum noua forma Dokuuicis est. Hoc rursum capere in pagina, in qua haec machina capta est, potes aut i ad <a href="http://dokuwiki.org/install">Dokuuicis installation instructions</a>';
+$lang['i_funcna'] = 'PHP functio <code>%s</code> inepta est.';
+$lang['i_phpver'] = 'Forma tua PHP <code>%s</code> minor quam illa necessaria <code>%s</code>.';
+$lang['i_permfail'] = '<code>%s</code> non a uice scribitur. Facultates inspicere.';
+$lang['i_confexists'] = '<code>%s</code> iam est.';
+$lang['i_writeerr'] = '<code>%s</code> non creari potest. Manu illum creas.';
+$lang['i_badhash'] = 'Ignotum uel mutatum dokuwiki.php (<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> non legitimum uel uacuom';
+$lang['i_success'] = 'Administratio feliciter perficitur. Delere install.php documentum potes. I ad <a href="doku.php">hanc paginam</a> ut continues.';
+$lang['i_failure'] = 'Aliqui errores dum documenta administrantur sunt. Manu onerare omnes potes priusquam <a href="doku.php">tuo nouo uice</a> uteris.';
+$lang['i_policy'] = 'ICA ratio prima';
+$lang['i_pol0'] = 'Vicem aperire (omnes legere, scribere, onerare possunt)';
+$lang['i_pol1'] = 'Publicus uicis (omnes legere, Sodales scribere et onerare possunt)';
+$lang['i_pol2'] = 'Clausus uicis (Soli Sodales legere scribere et onerare poccunt)';
+$lang['i_retry'] = 'Rursum temptas';
+$lang['i_license'] = 'Elige facultatem sub qua tuus uicis est:';
+$lang['recent_global'] = 'Mutatione in hoc genere uides. Recentiores mutationes quoque uidere <a href="%s">potes</a>';
+$lang['years'] = 'ab annis %d';
+$lang['months'] = 'a mensibus %d';
+$lang['weeks'] = 'a septimanis %d';
+$lang['days'] = 'a diebus %d';
+$lang['hours'] = 'a horis %d';
+$lang['minutes'] = 'a minutis %d';
+$lang['seconds'] = 'a secundis %d';
+$lang['wordblock'] = 'Mutationes non seruantur, eo quod mala uerba contenit';
diff --git a/inc/lang/la/locked.txt b/inc/lang/la/locked.txt
new file mode 100644
index 000000000..65446df30
--- /dev/null
+++ b/inc/lang/la/locked.txt
@@ -0,0 +1,3 @@
+====== Pagina inclusa ======
+
+Haec pagina inclusa est: nullam mutationem facere potest. \ No newline at end of file
diff --git a/inc/lang/la/login.txt b/inc/lang/la/login.txt
new file mode 100644
index 000000000..25d4cd170
--- /dev/null
+++ b/inc/lang/la/login.txt
@@ -0,0 +1,3 @@
+====== Aditus ======
+
+Nomen Sodalis et tesseram scribere debes ut in conuentum inire uelis. \ No newline at end of file
diff --git a/inc/lang/la/mailtext.txt b/inc/lang/la/mailtext.txt
new file mode 100644
index 000000000..2d2504c8c
--- /dev/null
+++ b/inc/lang/la/mailtext.txt
@@ -0,0 +1,16 @@
+Pagina in uice addita uel mutata. Hae singulae res sunt:
+
+Dies : @DATE@
+IP-Numerus : @IPADDRESS@
+Hospes situs : @HOSTNAME@
+Vetus recensio: @OLDPAGE@
+Noua recensio: @NEWPAGE@
+Summa recensere: @SUMMARY@
+Sodalis : @USER@
+
+@DIFF@
+
+
+--
+Hic cursus generatus a(b)
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/la/newpage.txt b/inc/lang/la/newpage.txt
new file mode 100644
index 000000000..13cfff7d6
--- /dev/null
+++ b/inc/lang/la/newpage.txt
@@ -0,0 +1,3 @@
+====== Hoc argumentum deest ======
+
+Nexum, quod pressisti, ad argumentum nullum fert. Si facultatem habes, creare nouam paginam potes. \ No newline at end of file
diff --git a/inc/lang/la/norev.txt b/inc/lang/la/norev.txt
new file mode 100644
index 000000000..19b60fe15
--- /dev/null
+++ b/inc/lang/la/norev.txt
@@ -0,0 +1,3 @@
+====== Forma non reperta ======
+
+Haec forma non reperta est. Aliam formam quaeris. \ No newline at end of file
diff --git a/inc/lang/la/password.txt b/inc/lang/la/password.txt
new file mode 100644
index 000000000..f49f4b85d
--- /dev/null
+++ b/inc/lang/la/password.txt
@@ -0,0 +1,10 @@
+Aue @FULLNAME@!
+
+Hae res @TITLE@, i ad paginam: @DOKUWIKIURL@
+
+Sodalis nomen : @LOGIN@
+Tessera : @PASSWORD@
+
+--
+Hic cursus generatus a(b)
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/la/preview.txt b/inc/lang/la/preview.txt
new file mode 100644
index 000000000..7e5a1377e
--- /dev/null
+++ b/inc/lang/la/preview.txt
@@ -0,0 +1,3 @@
+====== Praeuisio ======
+
+In hac pagina scriptum praeuidere potes. Memento hunc non seruatum iam esse. \ No newline at end of file
diff --git a/inc/lang/la/pwconfirm.txt b/inc/lang/la/pwconfirm.txt
new file mode 100644
index 000000000..32e351a9c
--- /dev/null
+++ b/inc/lang/la/pwconfirm.txt
@@ -0,0 +1,14 @@
+Aue, @FULLNAME@!
+
+Aliquis tesseram nouam @TITLE@
+ut ineas in @DOKUWIKIURL@
+
+Si nouam tesseram non petiuisti, hoc nuntium ignorat.
+
+Ut hoc nuntium petiuisti, premendo hunc nexum confirmas.
+
+@CONFIRM@
+
+--
+Hic cursus generatus a
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/la/read.txt b/inc/lang/la/read.txt
new file mode 100644
index 000000000..b1710f2e6
--- /dev/null
+++ b/inc/lang/la/read.txt
@@ -0,0 +1 @@
+Hanc paginam solum legere potes. Fontem uidere, sed non mutare potes. \ No newline at end of file
diff --git a/inc/lang/la/recent.txt b/inc/lang/la/recent.txt
new file mode 100644
index 000000000..d8e721cbf
--- /dev/null
+++ b/inc/lang/la/recent.txt
@@ -0,0 +1,3 @@
+====== Recentes Mutationes ======
+
+Hae paginae mutatae sunt in recentibus temporibus \ No newline at end of file
diff --git a/inc/lang/la/register.txt b/inc/lang/la/register.txt
new file mode 100644
index 000000000..71ca8dd0f
--- /dev/null
+++ b/inc/lang/la/register.txt
@@ -0,0 +1,3 @@
+====== Nouom\am Sodalem Adscribere ======
+
+Nomen Sodalis legitimus esse debes: [[doku>pagename|pagename]]. \ No newline at end of file
diff --git a/inc/lang/la/registermail.txt b/inc/lang/la/registermail.txt
new file mode 100644
index 000000000..73901950e
--- /dev/null
+++ b/inc/lang/la/registermail.txt
@@ -0,0 +1,14 @@
+Nouos\a Sodalis est. Hae suae res:
+
+Sodalis nomen : @NEWUSER@
+Nomen uerum : @NEWNAME@
+Cursus interretialis : @NEWEMAIL@
+
+Dies : @DATE@
+Machina interretis : @BROWSER@
+IP-numerus : @IPADDRESS@
+Hostname : @HOSTNAME@
+
+--
+Hic cursus generatus a
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/la/resendpwd.txt b/inc/lang/la/resendpwd.txt
new file mode 100644
index 000000000..5a4972fca
--- /dev/null
+++ b/inc/lang/la/resendpwd.txt
@@ -0,0 +1,3 @@
+====== ouam Tesseram mittere ======
+
+Inserere nomen Sodalis priusquam tesseram petere. Confirmatio mittibitur. \ No newline at end of file
diff --git a/inc/lang/la/revisions.txt b/inc/lang/la/revisions.txt
new file mode 100644
index 000000000..38b9bae0e
--- /dev/null
+++ b/inc/lang/la/revisions.txt
@@ -0,0 +1,3 @@
+====== Veteres recensiones ======
+
+In hac pagina ueteres recensiones paginae sunt: ut unam ex his restituas, illam eligis et deinde "Recensere paginam" premis et serua. \ No newline at end of file
diff --git a/inc/lang/la/searchpage.txt b/inc/lang/la/searchpage.txt
new file mode 100644
index 000000000..8e929110d
--- /dev/null
+++ b/inc/lang/la/searchpage.txt
@@ -0,0 +1,5 @@
+====== Quaerere ======
+
+Responsiones in hac pagina uidere potes.
+
+===== Responsiones ===== \ No newline at end of file
diff --git a/inc/lang/la/showrev.txt b/inc/lang/la/showrev.txt
new file mode 100644
index 000000000..b95e68265
--- /dev/null
+++ b/inc/lang/la/showrev.txt
@@ -0,0 +1,2 @@
+**Haec uetus forma documenti est!**
+---- \ No newline at end of file
diff --git a/inc/lang/la/stopwords.txt b/inc/lang/la/stopwords.txt
new file mode 100644
index 000000000..f063ba775
--- /dev/null
+++ b/inc/lang/la/stopwords.txt
@@ -0,0 +1,37 @@
+apud
+sunt
+etsi
+atque
+et
+tu
+tuus
+eius
+eorum
+infra
+ad
+in
+inter
+si
+in
+a
+ab
+de
+ut
+super
+aut
+uel
+illud
+illa
+ille
+ad
+fuit
+quid
+quod
+ubi
+hoc
+ex
+e
+cum
+haec
+hic
+www \ No newline at end of file
diff --git a/inc/lang/la/subscr_digest.txt b/inc/lang/la/subscr_digest.txt
new file mode 100644
index 000000000..629213359
--- /dev/null
+++ b/inc/lang/la/subscr_digest.txt
@@ -0,0 +1,20 @@
+Aue!
+
+Pagina @PAGE@ in @TITLE@ uici mutata.
+Haec mutationes sunt:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Vetus recensio: @OLDPAGE@
+Noua recensio: @NEWPAGE@
+
+Ut paginae adnotationes deleas, in uicem ineas in
+@DOKUWIKIURL@, deinde uideas
+@NEWPAGE@
+et paginarum generum optiones mutes.
+
+--
+Hic cursus a uicis generatus
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/la/subscr_form.txt b/inc/lang/la/subscr_form.txt
new file mode 100644
index 000000000..23000b31e
--- /dev/null
+++ b/inc/lang/la/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Inscriptionis Administratio ======
+
+In hac pagina inscriptiones huius paginae et generis sunt. \ No newline at end of file
diff --git a/inc/lang/la/subscr_list.txt b/inc/lang/la/subscr_list.txt
new file mode 100644
index 000000000..e6ff8d89d
--- /dev/null
+++ b/inc/lang/la/subscr_list.txt
@@ -0,0 +1,17 @@
+Aue!
+
+Paginae in spatio nominis @PAGE@ @TITLE@ uicis mutatae.
+Hae mutationes sunt:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Ut adnotationes deleas, preme hic
+@DOKUWIKIURL@ then visit
+@SUBSCRIBE@
+et paginarum et\aut generum mutationes tollis.
+
+--
+Hic cursus generatus a(b)
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/la/subscr_single.txt b/inc/lang/la/subscr_single.txt
new file mode 100644
index 000000000..7839791ea
--- /dev/null
+++ b/inc/lang/la/subscr_single.txt
@@ -0,0 +1,23 @@
+Aue!
+
+Pagina "@PAGE@" in titulo "@TITlE@" mutata.
+Hae mutationes sunt:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Dies : @DATE@
+Sodalis : @USER@
+Summa recensita: @SUMMARY@
+Vetus recensio: @OLDPAGE@
+Noua recensio: @NEWPAGE@
+
+Ut paginae adnotationes deleas, in uicem ineas in
+@DOKUWIKIURL@, deinde uideas
+@NEWPAGE@
+et paginarum et\aut generum optiones mutasa.
+
+--
+Hic cursus a uicis generatus
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/la/updateprofile.txt b/inc/lang/la/updateprofile.txt
new file mode 100644
index 000000000..565f81a3e
--- /dev/null
+++ b/inc/lang/la/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Nouare Sodalis tabellas ======
+
+Solum in campis, quos mutare uis, scribis. Nomen Sodalis non mutare potes. \ No newline at end of file
diff --git a/inc/lang/la/uploadmail.txt b/inc/lang/la/uploadmail.txt
new file mode 100644
index 000000000..044297973
--- /dev/null
+++ b/inc/lang/la/uploadmail.txt
@@ -0,0 +1,14 @@
+Documentum nouatum est. Hae mutatione sunt:
+
+Documentum : @MEDIA@
+Dies : @DATE@
+Machina interretis : @BROWSER@
+IP-Numerus : @IPADDRESS@
+Hospes situs : @HOSTNAME@
+Pondus : @SIZE@
+MIME Genus : @MIME@
+Sodalis : @USER@
+
+--
+Hic cursu generatus a(b)
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/lb/admin.txt b/inc/lang/lb/admin.txt
new file mode 100644
index 000000000..08f8b2fec
--- /dev/null
+++ b/inc/lang/lb/admin.txt
@@ -0,0 +1,3 @@
+====== Administratioun ======
+
+Hei ënnendrënner fënns de eng Lëscht mat administrativen Aufgaben déi am Dokuwiki zuer Verfügung stinn.
diff --git a/inc/lang/lb/adminplugins.txt b/inc/lang/lb/adminplugins.txt
new file mode 100644
index 000000000..95814007d
--- /dev/null
+++ b/inc/lang/lb/adminplugins.txt
@@ -0,0 +1 @@
+===== Zousätzlech Pluginen ===== \ No newline at end of file
diff --git a/inc/lang/lb/backlinks.txt b/inc/lang/lb/backlinks.txt
new file mode 100644
index 000000000..8b8fbd4ec
--- /dev/null
+++ b/inc/lang/lb/backlinks.txt
@@ -0,0 +1,3 @@
+====== Linken zeréck ======
+
+Dëst ass eng Lëscht mat Säiten déi schéngen op déi aktuell Säit zeréck ze verlinken.
diff --git a/inc/lang/lb/conflict.txt b/inc/lang/lb/conflict.txt
new file mode 100644
index 000000000..3a84e722f
--- /dev/null
+++ b/inc/lang/lb/conflict.txt
@@ -0,0 +1,5 @@
+====== Et gëtt méi eng nei Versioun ======
+
+Et gëtt méi eng nei Versioun vum Dokument wats de g'ännert hues. Dat geschitt wann en anere Benotzer dat selwecht Dokument ännert wärenddeems du et änners.
+
+Ënnersich d'Ënnerscheeder déi hei ënnendrënner ugewise gi grëndlech. Wanns de ''Späicheren'' auswiels, da gëtt deng Version gespäicher. Dréck op ''Ofbriechen'' fir déi aktuell Versioun ze halen.
diff --git a/inc/lang/lb/denied.txt b/inc/lang/lb/denied.txt
new file mode 100644
index 000000000..487bf2198
--- /dev/null
+++ b/inc/lang/lb/denied.txt
@@ -0,0 +1,3 @@
+======Erlaabnis verweigert======
+
+Et deet mer leed, du hues net genuch Rechter fir weiderzefueren. Hues de vläicht vergiess dech anzeloggen?
diff --git a/inc/lang/lb/diff.txt b/inc/lang/lb/diff.txt
new file mode 100644
index 000000000..7838b9808
--- /dev/null
+++ b/inc/lang/lb/diff.txt
@@ -0,0 +1,3 @@
+====== Ënnerscheeder ======
+
+Hei sinn d'Ënnerscheeder zwëscht 2 Versiounen vun der Säit.
diff --git a/inc/lang/lb/draft.txt b/inc/lang/lb/draft.txt
new file mode 100644
index 000000000..2e2fc9daa
--- /dev/null
+++ b/inc/lang/lb/draft.txt
@@ -0,0 +1,5 @@
+====== Entworf fond ======
+
+Deng lescht Ännersessioun op dëser Säit gouf net richteg ofgeschloss. DokuWiki huet automatesch en Entworf wärend denger Aarbecht gespäichert deens de elo kanns benotzen fir mat dengen Ännerunge weiderzefueren. Hei ënnendrënner gesäiss de wat vun denger leschter Sessioun gespäichert gouf.
+
+Decidéier w.e.g. obs de deng verlueren Ännerungssessioun //zeréckhuelen//, den Entworf //läschen// oder d'Änneren //ofbrieche// wëlls.
diff --git a/inc/lang/lb/edit.txt b/inc/lang/lb/edit.txt
new file mode 100644
index 000000000..ca039d16f
--- /dev/null
+++ b/inc/lang/lb/edit.txt
@@ -0,0 +1 @@
+Änner d'Säit an dréck ''Späicheren''. Kuck [[wiki:syntax]] fir d'Wiki-Syntax. Änner d'Säit w.e.g. nëmme wanns de se **verbessere** kanns. Wanns de Saache probéiere wëlls, da léier deng éischt Schréck an der [[playground:playground|Sandkaul]].
diff --git a/inc/lang/lb/editrev.txt b/inc/lang/lb/editrev.txt
new file mode 100644
index 000000000..6d7a12929
--- /dev/null
+++ b/inc/lang/lb/editrev.txt
@@ -0,0 +1,2 @@
+**Du hues eng al Versioun vum Dokument gelueden!** Wanns de se änners, mëss de eng nei Versioun mat dësen Daten.
+---- \ No newline at end of file
diff --git a/inc/lang/lb/index.txt b/inc/lang/lb/index.txt
new file mode 100644
index 000000000..183e07a0f
--- /dev/null
+++ b/inc/lang/lb/index.txt
@@ -0,0 +1,3 @@
+====== Index ======
+
+Dëst ass em Index vun all de Säiten gesënnert no [[doku>namespaces|namespaces]].
diff --git a/inc/lang/lb/lang.php b/inc/lang/lb/lang.php
new file mode 100644
index 000000000..d16d1a0c3
--- /dev/null
+++ b/inc/lang/lb/lang.php
@@ -0,0 +1,199 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Dës Säit änneren';
+$lang['btn_source'] = 'Säitequell weisen';
+$lang['btn_show'] = 'Säit weisen';
+$lang['btn_create'] = 'Dës Säit uleeën';
+$lang['btn_search'] = 'Sichen';
+$lang['btn_save'] = 'Späicheren';
+$lang['btn_preview'] = 'Kucken ouni ofzespäicheren';
+$lang['btn_top'] = 'Zréck no uewen';
+$lang['btn_newer'] = '<< méi rezent';
+$lang['btn_older'] = 'manner rezent >>';
+$lang['btn_revs'] = 'Al Versiounen';
+$lang['btn_recent'] = 'Kierzlech Ännerungen';
+$lang['btn_upload'] = 'Eroplueden';
+$lang['btn_cancel'] = 'Ofbriechen';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit'] = 'Änneren';
+$lang['btn_login'] = 'Login';
+$lang['btn_logout'] = 'Logout';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Update';
+$lang['btn_delete'] = 'Läschen';
+$lang['btn_back'] = 'Zeréck';
+$lang['btn_backlink'] = 'Linker zeréck';
+$lang['btn_backtomedia'] = 'Zeréck bei d\'Auswiel vun de Mediadateien';
+$lang['btn_profile'] = 'Profil aktualiséieren';
+$lang['btn_reset'] = 'Zerécksetzen';
+$lang['btn_resendpwd'] = 'Nei Passwuert schécken';
+$lang['btn_draft'] = 'Entworf änneren';
+$lang['btn_recover'] = 'Entworf zeréckhuelen';
+$lang['btn_draftdel'] = 'Entworf läschen';
+$lang['btn_register'] = 'Registréieren';
+$lang['loggedinas'] = 'Ageloggt als';
+$lang['user'] = 'Benotzernumm';
+$lang['pass'] = 'Passwuert';
+$lang['newpass'] = 'Nei Passwuert';
+$lang['oldpass'] = 'Aktuell Passwuert confirméieren';
+$lang['passchk'] = 'nach eng Kéier';
+$lang['remember'] = 'Verhal mech';
+$lang['fullname'] = 'Richtegen Numm';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'Benotzerprofil';
+$lang['badlogin'] = 'Entschëllegt, de Benotzernumm oder d\'Passwuert war falsch';
+$lang['minoredit'] = 'Kleng Ännerungen';
+$lang['draftdate'] = 'Entworf automatesch gespäichert den';
+$lang['nosecedit'] = 'D\'Säit gouf an Zwëschenzäit g\'ännert, Sektiounsinfo veralt. Ganz Säit gouf aplaz gelueden.';
+$lang['regmissing'] = 'Du muss all d\'Felder ausfëllen.';
+$lang['reguexists'] = 'Et get schonn e Benotzer mat deem Numm.';
+$lang['regsuccess'] = 'De Benotzer gouf erstallt an d\'Passwuert via Email geschéckt.';
+$lang['regsuccess2'] = 'De Benotzer gouf erstallt.';
+$lang['regmailfail'] = 'Et gesäit aus wéi wann e Feeler beim schécke vun der Passwuertmail virkomm wier. Kontaktéier den Admin w.e.g.!';
+$lang['regbadmail'] = 'Déi Emailadress gesäit ongëlteg aus - wanns de mengs dat wier e Feeler, da kontaktéier den Admin w.e.g.';
+$lang['regbadpass'] = 'Déi 2 Passwieder si net t\'selwecht. Probéier nach eng Kéier w.e.g.';
+$lang['regpwmail'] = 'Däin DokuWiki Passwuert';
+$lang['reghere'] = 'Hues du nach keen Account? Da maach der een';
+$lang['profna'] = 'Dëse Wiki ënnestëtzt keng Ännerunge vum Profil';
+$lang['profnochange'] = 'Keng Ännerungen. Näischt ze man.';
+$lang['profnoempty'] = 'En eidele Numm oder Emailadress ass net erlaabt.';
+$lang['profchanged'] = 'Benotzerprofil erfollegräicht aktualiséiert.';
+$lang['pwdforget'] = 'Passwuert vergiess? Fro der e Neit';
+$lang['resendna'] = 'Dëse Wiki ënnerstëtzt net d\'Neiverschécke vu Passwieder.';
+$lang['resendpwd'] = 'Nei Passwuert schécke fir';
+$lang['resendpwdmissing'] = 'Du muss all Felder ausfëllen.';
+$lang['resendpwdnouser'] = 'Kann dëse Benotzer net an der Datebank fannen.';
+$lang['resendpwdbadauth'] = 'Den "Auth"-Code ass ongëlteg. Kuck no obs de dee ganze Konfirmationslink benotzt hues.';
+$lang['resendpwdconfirm'] = 'De Konfirmatiounslink gouf iwwer Email geschéckt.';
+$lang['resendpwdsuccess'] = 'Däi nei Passwuert gouf iwwer Email geschéckt.';
+$lang['license'] = 'Wann näischt anescht do steet, ass den Inhalt vun dësem Wiki ënner folgender Lizenz:';
+$lang['licenseok'] = 'Pass op: Wanns de dës Säit änners, bass de dermat averstan dass den Inhalt ënner folgender Lizenz lizenzéiert gëtt:';
+$lang['txt_upload'] = 'Wiel eng Datei fir eropzelueden';
+$lang['txt_filename'] = 'Eroplueden als (optional)';
+$lang['txt_overwrt'] = 'Bestehend Datei iwwerschreiwen';
+$lang['lockedby'] = 'Am Moment gespaart vun';
+$lang['lockexpire'] = 'D\'Spär leeft of ëm';
+$lang['js']['willexpire'] = 'Deng Spär fir d\'Säit ze änneren leeft an enger Minutt of.\nFir Konflikter ze verhënneren, dréck op Kucken ouni ofzespäicheren.';
+$lang['js']['notsavedyet'] = "Net gespäicher Ännerunge gi verluer.\nWierklech weiderfueren?";
+$lang['rssfailed'] = 'Et ass e Feeler virkomm beim erofluede vun dësem Feed: ';
+$lang['nothingfound'] = 'Näischt fond.';
+$lang['mediaselect'] = 'Mediadateien';
+$lang['fileupload'] = 'Mediadateien eroplueden';
+$lang['uploadsucc'] = 'Upload erfollegräich';
+$lang['uploadfail'] = 'Feeler beim Upload. Vläicht falsch Rechter?';
+$lang['uploadwrong'] = 'Eroplueden net erlaabt. Dës Dateiendung ass verbueden!';
+$lang['uploadexist'] = 'Datei gët et schonn. Näischt gemaach.';
+$lang['uploadbadcontent'] = 'Den eropgeluedenen Inhalt stëmmt net mat der Dateiendung %s iwwereneen.';
+$lang['uploadspam'] = 'D\'Eropluede gouf duerch d\'Schwaarz Spamlëscht blockéiert.';
+$lang['uploadxss'] = 'D\'Eropluede gouf wéinst méiglechem béisaartegem Inhalt blockéiert.';
+$lang['uploadsize'] = 'Déi eropgelueden Datei war ze grouss. (max. %s)';
+$lang['deletesucc'] = 'D\'Datei "%s" gouf geläscht.';
+$lang['deletefail'] = '"%s" konnt net geläscht ginn. Kontroléier d\'Rechter.';
+$lang['mediainuse'] = 'D\'Datei "%s" gouf net geläscht - se ass nach am Gebrauch.';
+$lang['namespaces'] = 'Namespaces';
+$lang['mediafiles'] = 'Verfügbar Dateien am';
+$lang['js']['keepopen'] = 'Fënster beim Auswielen oploossen';
+$lang['js']['hidedetails'] = 'Deteiler verstoppen';
+$lang['mediausage'] = 'Benotz folgend Syntax fir dës Datei ze referenzéieren:';
+$lang['mediaview'] = 'Originaldatei weisen';
+$lang['mediaroot'] = 'root';
+$lang['mediaextchange'] = 'Dateiendung vun .%s op .%s g\'ännert!';
+$lang['reference'] = 'Referenzen fir';
+$lang['ref_inuse'] = 'D\'Datei ka net geläscht ginn wëll se nach ëmmer vu folgende Säite gebraucht gëtt:';
+$lang['ref_hidden'] = 'Verschidde Referenze sinn op Säiten wous de keng Rechter hues fir se ze kucken';
+$lang['hits'] = 'Treffer';
+$lang['quickhits'] = 'Säitenimm déi iwwereneestëmmen';
+$lang['toc'] = 'Inhaltsverzeechnes';
+$lang['current'] = 'aktuell';
+$lang['yours'] = 'Deng Versioun';
+$lang['diff'] = 'Weis d\'Ënnerscheeder zuer aktueller Versioun';
+$lang['diff2'] = 'Weis d\'Ënnerscheeder zwescht den ausgewielte Versiounen';
+$lang['line'] = 'Linn';
+$lang['breadcrumb'] = 'Spuer';
+$lang['youarehere'] = 'Du bass hei';
+$lang['lastmod'] = 'Fir d\'lescht g\'ännert';
+$lang['by'] = 'vun';
+$lang['deleted'] = 'geläscht';
+$lang['created'] = 'erstallt';
+$lang['restored'] = 'al Versioun zeréckgeholl';
+$lang['external_edit'] = 'extern Ännerung';
+$lang['summary'] = 'Resumé vun den Ännerungen';
+$lang['noflash'] = 'Den <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> get gebraucht fir dësen Inhalt unzeweisen.';
+$lang['mail_newpage'] = 'Säit bäigesat:';
+$lang['mail_changed'] = 'Säit geännert:';
+$lang['mail_subscribe_list'] = 'g\'ännert Säiten am Namespace:';
+$lang['mail_new_user'] = 'Neie Benotzer:';
+$lang['mail_upload'] = 'Datei eropgelueden:';
+$lang['qb_bold'] = 'Fetten Text';
+$lang['qb_italic'] = 'Schiefen Text';
+$lang['qb_underl'] = 'Ënnerstrachenen Text';
+$lang['qb_code'] = 'Code Text';
+$lang['qb_strike'] = 'Duerchgestrachenen Text';
+$lang['qb_h1'] = 'Iwwerschrëft vum 1. Niveau';
+$lang['qb_h2'] = 'Iwwerschrëft vum 2. Niveau';
+$lang['qb_h3'] = 'Iwwerschrëft vum 3. Niveau';
+$lang['qb_h4'] = 'Iwwerschrëft vum 4. Niveau';
+$lang['qb_h5'] = 'Iwwerschrëft vum 5. Niveau';
+$lang['qb_h'] = 'Iwwerschrëft';
+$lang['qb_hs'] = 'Iwwerschrëft auswielen';
+$lang['qb_hplus'] = 'Méi grouss Iwwerschrëft';
+$lang['qb_hminus'] = 'Méi kleng Iwwerschrëft';
+$lang['qb_hequal'] = 'Iwwerschrëft vum selwechte Niveau';
+$lang['qb_link'] = 'Interne Link';
+$lang['qb_extlink'] = 'Externe Link';
+$lang['qb_hr'] = 'Horizontale Stréch';
+$lang['qb_ol'] = 'Nummeréiert Lëscht';
+$lang['qb_ul'] = 'Onnummeréiert Lëscht';
+$lang['qb_media'] = 'Biller an aner Dateie bäisetzen';
+$lang['qb_sig'] = 'Ënnerschrëft afügen';
+$lang['qb_smileys'] = 'Smilien';
+$lang['qb_chars'] = 'Spezialzeechen';
+$lang['upperns'] = 'An de Namespace uewendriwwer sprangen';
+$lang['admin_register'] = 'Neie Benotzer bäisetzen';
+$lang['metaedit'] = 'Metadaten änneren';
+$lang['metasaveerr'] = 'Feeler beim Schreiwe vun de Metadaten';
+$lang['metasaveok'] = 'Metadate gespäichert';
+$lang['img_backto'] = 'Zeréck op';
+$lang['img_title'] = 'Titel';
+$lang['img_caption'] = 'Beschreiwung';
+$lang['img_date'] = 'Datum';
+$lang['img_fname'] = 'Dateinumm';
+$lang['img_fsize'] = 'Gréisst';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Schlësselwieder';
+$lang['authmodfailed'] = 'Falsch Konfiguratioun vun der Benotzerautentifikatioun. Informéier w.e.g. de Wiki Admin.';
+$lang['authtempfail'] = 'D\'Benotzerautentifikatioun ass de Moment net verfügbar. Wann dës Situatioun unhält, dann informéier w.e.g. de Wiki Admin.';
+$lang['i_chooselang'] = 'Wiel deng Sprooch';
+$lang['i_installer'] = 'DokuWiki Installer';
+$lang['i_wikiname'] = 'Numm vum Wiki';
+$lang['i_enableacl'] = 'ACL uschalten (rekommandéiert)';
+$lang['i_problems'] = 'Den Installer huet Problemer fond. Se stinn hei ënnendrënner. Du kanns net weiderfueren bis de se behuewen hues.';
+$lang['i_modified'] = 'Aus Sécherheetsgrënn funktionnéiert dëse Script nëmme mat enger neier an onverännerter Dokuwiki Installatioun. Entweder muss de d\'Dateie frësch extrahéieren oder kuck d\'komplett <a href="http://dokuwiki.org/install">Dokuwiki Installatiounsinstruktiounen</a>';
+$lang['i_funcna'] = 'PHP-Funktioun <code>%s</code> ass net verfügbar. Vläicht huet däi Provider se aus iergend engem Grond ausgeschalt.';
+$lang['i_phpver'] = 'Deng PHP-Versioun <code>%s</code> ass méi kleng wéi déi gebrauchte Versioun <code>%s</code>. Du muss deng PHP-Installatioun aktualiséieren. ';
+$lang['i_pol0'] = 'Oppene Wiki (liese, schreiwen an eroplueden fir jidfereen)';
+$lang['i_pol1'] = 'Ëffentleche Wiki (liesen fir jidfereen, schreiwen an eroplueden fir registréiert Benotzer)';
+$lang['i_pol2'] = 'Zouene Wiki (liesen, schreiwen, eroplueden nëmme fir registréiert Benotzer)';
+$lang['i_retry'] = 'Nach eng Kéier probéieren';
+$lang['recent_global'] = 'Du kucks am Moment d\'Ännerungen innerhalb vum <b>%s</b> Namespace. Du kanns och <a href="%s">d\'Kierzilech Ännerungen vum ganze Wiki kucken</a>.';
+$lang['years'] = 'virun %d Joer';
+$lang['months'] = 'virun %d Méint';
+$lang['weeks'] = 'virun %d Wochen';
+$lang['days'] = 'virun %d Deeg';
+$lang['hours'] = 'virun %d Stonnen';
+$lang['minutes'] = 'virun %d Minutten';
+$lang['seconds'] = 'virun %d Sekonnen';
diff --git a/inc/lang/lb/locked.txt b/inc/lang/lb/locked.txt
new file mode 100644
index 000000000..944efb251
--- /dev/null
+++ b/inc/lang/lb/locked.txt
@@ -0,0 +1,3 @@
+====== Säit gespaart ======
+
+Dës Säit ass am Moment duerch en anere Benotzer fir Ännerunge gespart. Du muss waarde bis e mat sengen Ännerunge fäerdeg ass oder d'Spär ofleeft. \ No newline at end of file
diff --git a/inc/lang/lb/login.txt b/inc/lang/lb/login.txt
new file mode 100644
index 000000000..7d0548ee7
--- /dev/null
+++ b/inc/lang/lb/login.txt
@@ -0,0 +1,3 @@
+====== Aloggen ======
+
+Du bass am Moment net ageloggt! Gëff deng Autoriséierungsinformatiounen hei ënnendrënner an. Du muss d'Cookien erlaabt hunn fir dech kënnen anzeloggen.
diff --git a/inc/lang/lb/mailtext.txt b/inc/lang/lb/mailtext.txt
new file mode 100644
index 000000000..520cd8483
--- /dev/null
+++ b/inc/lang/lb/mailtext.txt
@@ -0,0 +1,17 @@
+Et gouf eng Säit an dengem DokuWiki g'ännert oder nei erstallt. Hei sinn d'Detailer:
+
+Datum : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+Al Versioun : @OLDPAGE@
+Nei Versioun : @NEWPAGE@
+Zesummefaassung: @SUMMARY@
+Benotzer : @USER@
+
+@DIFF@
+
+
+--
+Dës Mail gouf generéiert vum DokuWiki op
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/lb/newpage.txt b/inc/lang/lb/newpage.txt
new file mode 100644
index 000000000..93917614d
--- /dev/null
+++ b/inc/lang/lb/newpage.txt
@@ -0,0 +1,4 @@
+======Dësen Thema gëtt et nach net======
+
+Du hues op e Link vun enger Säit geklickt, déi et nach net gëtt. Wanns de déi néideg Rechter hues, da kanns de dës Säit uleeën andeems de op ''Dës Säit uleeën'' klicks.
+
diff --git a/inc/lang/lb/norev.txt b/inc/lang/lb/norev.txt
new file mode 100644
index 000000000..45a36ee91
--- /dev/null
+++ b/inc/lang/lb/norev.txt
@@ -0,0 +1,3 @@
+====== Keng sou Versioun ======
+
+Déi Versioun gëtt et net. Benotz de Kneppchen ''Al Versiounen'' fir eng Lëscht vun ale Versiounen vun dësem Dokument.
diff --git a/inc/lang/lb/password.txt b/inc/lang/lb/password.txt
new file mode 100644
index 000000000..bd8062e42
--- /dev/null
+++ b/inc/lang/lb/password.txt
@@ -0,0 +1,10 @@
+Moien @FULLNAME@!
+
+Hei sinn deng Benotzerdaten fir @TITLE@ op @DOKUWIKIURL@
+
+Benotzernumm : @LOGIN@
+Passwuert : @PASSWORD@
+
+--
+Dës Mail gouf generéiert vun DokuWiki op
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/lb/preview.txt b/inc/lang/lb/preview.txt
new file mode 100644
index 000000000..f131cdad8
--- /dev/null
+++ b/inc/lang/lb/preview.txt
@@ -0,0 +1,3 @@
+======Net gespäichert Versioun======
+
+Dëst ass nëmmen eng net gespäichert Versioun; d'Ännerunge sinn nach **net** gespäichert!
diff --git a/inc/lang/lb/pwconfirm.txt b/inc/lang/lb/pwconfirm.txt
new file mode 100644
index 000000000..11246572b
--- /dev/null
+++ b/inc/lang/lb/pwconfirm.txt
@@ -0,0 +1,15 @@
+Moien @FULLNAME@!
+
+Iergendeen huet e neit Passwuert fir däin @TITLE@
+login op @DOKUWIKIURL@ gefrot
+
+Wanns de kee nei Passwuert gefrot hues, dann ignoréier dës Mail.
+
+Fir ze konfirméieren dass du wierklech en neit Passwuert gefrot hues,
+klick op folgende Link.
+
+@CONFIRM@
+
+--
+Des Mail gouf generéiert vun DokuWiki op
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/lb/read.txt b/inc/lang/lb/read.txt
new file mode 100644
index 000000000..3f52bd679
--- /dev/null
+++ b/inc/lang/lb/read.txt
@@ -0,0 +1 @@
+Dës Säit ass nëmme fir ze kucken. Du kanns d'Quell kucken, mee net änneren. Fro däin Administrator wanns de mengs dat wier falsch.
diff --git a/inc/lang/lb/recent.txt b/inc/lang/lb/recent.txt
new file mode 100644
index 000000000..c7359e202
--- /dev/null
+++ b/inc/lang/lb/recent.txt
@@ -0,0 +1,4 @@
+====== Rezent Ännerungen ======
+
+Folgend Säite goufen an der lescht g'ännert.
+
diff --git a/inc/lang/lb/register.txt b/inc/lang/lb/register.txt
new file mode 100644
index 000000000..1e017e997
--- /dev/null
+++ b/inc/lang/lb/register.txt
@@ -0,0 +1,4 @@
+====== Als neie Benotzer registréieren ======
+
+Fëll alles hei ënnendrënner aus fir en neie Kont op dësem Wiki unzeleeën. Pass op dass de eng **gëlteg Emailadress** ugëss - wanns de net gefrot gëss hei e Passwuert anzeginn, da kriss de e neit op déi Adress geschéckt. De Benotzernumm soll e gëltege [[doku>pagename|Säitenumm]] sinn.
+
diff --git a/inc/lang/lb/registermail.txt b/inc/lang/lb/registermail.txt
new file mode 100644
index 000000000..0f4fee8ec
--- /dev/null
+++ b/inc/lang/lb/registermail.txt
@@ -0,0 +1,14 @@
+Et huet sech e neie Benotzer registréiert. Hei sinn d'Deteiler:
+
+Benotzernumm: @NEWUSER@
+Ganze Numm : @NEWNAME@
+Email : @NEWEMAIL@
+
+Datum : @DATE@
+Browser : @BROWSER@
+IP-Adress : @IPADDRESS@
+Hostnumm : @HOSTNAME@
+
+--
+Des Mail gouf generéiert vun DokuWiki op
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/lb/resendpwd.txt b/inc/lang/lb/resendpwd.txt
new file mode 100644
index 000000000..6ca4518dc
--- /dev/null
+++ b/inc/lang/lb/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Nei Passwuert schécken ======
+
+Gëff w.e.g. däi Benotzernumm an de Formulär hei ënnendrënner an fir e neit Passwuert fir dëse Wiki unzefroen. E Konfirmatiounslink gëtt dann op deng registréiert Emailadress geschéckt.
diff --git a/inc/lang/lb/revisions.txt b/inc/lang/lb/revisions.txt
new file mode 100644
index 000000000..7dec32759
--- /dev/null
+++ b/inc/lang/lb/revisions.txt
@@ -0,0 +1,3 @@
+====== Al Versiounen ======
+
+Hei sinn déi al Versiounen vun dësem Dokument. Fir op eng al Versioun zeréckzegoen, wiel se hei ënnendrënner eraus, klick ''Dës Säit änneren'' a späicher se.
diff --git a/inc/lang/lb/searchpage.txt b/inc/lang/lb/searchpage.txt
new file mode 100644
index 000000000..5e15a2c60
--- /dev/null
+++ b/inc/lang/lb/searchpage.txt
@@ -0,0 +1,5 @@
+======Sich======
+
+Hei ënnendrënner sinn d'Resultater vun der Sich. Wanns de net fënns wats de gesicht hues kanns de eng nei Säit mam Numm vun denger Sich uleeën.
+
+=====Resultater===== \ No newline at end of file
diff --git a/inc/lang/lb/showrev.txt b/inc/lang/lb/showrev.txt
new file mode 100644
index 000000000..f6e2deee8
--- /dev/null
+++ b/inc/lang/lb/showrev.txt
@@ -0,0 +1,2 @@
+**Dat hei ass eng al Versioun vum Document!**
+---- \ No newline at end of file
diff --git a/inc/lang/lb/updateprofile.txt b/inc/lang/lb/updateprofile.txt
new file mode 100644
index 000000000..326d62217
--- /dev/null
+++ b/inc/lang/lb/updateprofile.txt
@@ -0,0 +1,4 @@
+====== Profil aktualiséieren ======
+
+Du brauchs just d'Felder auszefëllen déis de wëlls änneren. Du kanns däi Benotzernumm net änneren.
+
diff --git a/inc/lang/lb/uploadmail.txt b/inc/lang/lb/uploadmail.txt
new file mode 100644
index 000000000..3c2587cb4
--- /dev/null
+++ b/inc/lang/lb/uploadmail.txt
@@ -0,0 +1,14 @@
+Eng Datei gouf op däin DokuWiki eropgelueden. Hei sinn d'Deteiler:
+
+Datei : @MEDIA@
+Datum : @DATE@
+Browser : @BROWSER@
+IP-Adress : @IPADDRESS@
+Hostnumm : @HOSTNAME@
+Gréisst : @SIZE@
+MIME Typ : @MIME@
+Benotzer : @USER@
+
+--
+Dës Mail gouf generéiert vun DokuWiki op
+@DOKUWIKIURL@
diff --git a/inc/lang/lt/admin.txt b/inc/lang/lt/admin.txt
new file mode 100644
index 000000000..fd9ae9a87
--- /dev/null
+++ b/inc/lang/lt/admin.txt
@@ -0,0 +1,4 @@
+====== Administracija ======
+
+Žemiau matote veiksmų, kuriuos gali atlikti administratorius, sąrašą.
+
diff --git a/inc/lang/lt/backlinks.txt b/inc/lang/lt/backlinks.txt
new file mode 100644
index 000000000..ad0d5b83a
--- /dev/null
+++ b/inc/lang/lt/backlinks.txt
@@ -0,0 +1,4 @@
+====== Atgalinės nuorodos ======
+
+Čia matote sąrašą puslapių, kuriuose yra nuorodos į esamą puslapį.
+
diff --git a/inc/lang/lt/conflict.txt b/inc/lang/lt/conflict.txt
new file mode 100644
index 000000000..be0c5ff4f
--- /dev/null
+++ b/inc/lang/lt/conflict.txt
@@ -0,0 +1,6 @@
+====== Egzistuoja naujesnė versija ======
+
+Rasta naujesnė dokumento, kurį redagavote, versija. Tai atsitinka tada, kai kitas vartotojas modifikuoja dokumentą tuo metu, kai jūs jį redaguojate.
+
+Atidžiai peržvelkite žemiau esančius skirtumus ir nuspręskite, kurią versiją išsaugoti. Paspausdami ''Išsaugoti'' išsaugosite saviškę versiją. Paspausdami ''Atšaukti'' išsaugosite esamą versiją.
+
diff --git a/inc/lang/lt/denied.txt b/inc/lang/lt/denied.txt
new file mode 100644
index 000000000..c25fb5f0c
--- /dev/null
+++ b/inc/lang/lt/denied.txt
@@ -0,0 +1,4 @@
+====== Priėjimas uždraustas ======
+
+Jūs neturite reikiamų teisių, kad galėtumėte tęsti. Turbūt pamiršote prisijungti :-).
+
diff --git a/inc/lang/lt/diff.txt b/inc/lang/lt/diff.txt
new file mode 100644
index 000000000..dc5e59f89
--- /dev/null
+++ b/inc/lang/lt/diff.txt
@@ -0,0 +1,4 @@
+====== Skirtumai ======
+
+Čia matote skirtumus tarp pasirinktos versijos ir esamo dokumento.
+
diff --git a/inc/lang/lt/edit.txt b/inc/lang/lt/edit.txt
new file mode 100644
index 000000000..8fadf97ad
--- /dev/null
+++ b/inc/lang/lt/edit.txt
@@ -0,0 +1,2 @@
+Modifikuokite šį puslapį ir paspauskite ''Išsaugoti''. Apie wiki sintaksę galite paskaityti [[wiki:syntax|čia]]. Prašome redaguoti šį puslapį tik tada, kai galite jį **patobulinti**. Jei tik norite išbandyti wiki galimybes, prašytume tai daryti [[playground:playground|čia]].
+
diff --git a/inc/lang/lt/editrev.txt b/inc/lang/lt/editrev.txt
new file mode 100644
index 000000000..9e5eaeece
--- /dev/null
+++ b/inc/lang/lt/editrev.txt
@@ -0,0 +1,2 @@
+**Jūs naudojate seną šio dokumento versiją!** jei ją išsaugosite, su šiais duomenimis sukursite naują versiją.
+---- \ No newline at end of file
diff --git a/inc/lang/lt/index.txt b/inc/lang/lt/index.txt
new file mode 100644
index 000000000..d13683c47
--- /dev/null
+++ b/inc/lang/lt/index.txt
@@ -0,0 +1,4 @@
+====== Indeksas ======
+
+Čia matote visų šiuo metu egzistuojančių puslapių sąrašą. Jie išrūšiuoti pagal [[doku>namespaces|pavadinimą]].
+
diff --git a/inc/lang/lt/lang.php b/inc/lang/lt/lang.php
new file mode 100644
index 000000000..50fb3194b
--- /dev/null
+++ b/inc/lang/lt/lang.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * lithuanian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Linas Valiukas <shirshegsm@gmail.com>
+ * @author Edmondas Girkantas <eg@zemaitija.net>
+ * @author Arūnas Vaitekūnas <aras@fan.lt>
+ * @author audrius.klevas@gmail.com
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Redaguoti šį puslapį';
+$lang['btn_source'] = 'Parodyti puslapio kodą';
+$lang['btn_show'] = 'Parodyti puslapį';
+$lang['btn_create'] = 'Sukurti šį puslapį';
+$lang['btn_search'] = 'Paieška';
+$lang['btn_save'] = 'Išsaugoti';
+$lang['btn_preview'] = 'Peržiūra';
+$lang['btn_top'] = 'Į viršų';
+$lang['btn_newer'] = '<< naujesnė';
+$lang['btn_older'] = 'senesnė >>';
+$lang['btn_revs'] = 'Senos versijos';
+$lang['btn_recent'] = 'Naujausi keitimai';
+$lang['btn_upload'] = 'Atsiųsti bylą';
+$lang['btn_cancel'] = 'Atšaukti';
+$lang['btn_index'] = 'Indeksas';
+$lang['btn_secedit'] = 'Redaguoti';
+$lang['btn_login'] = 'Prisijungti';
+$lang['btn_logout'] = 'Atsijungti';
+$lang['btn_admin'] = 'Administracija';
+$lang['btn_update'] = 'Atnaujinti';
+$lang['btn_delete'] = 'Ištrinti';
+$lang['btn_back'] = 'Atgal';
+$lang['btn_backlink'] = 'Atgalinės nuorodos';
+$lang['btn_backtomedia'] = 'Atgal į Mediabylos išsirinkimą';
+$lang['btn_subscribe'] = 'Užsisakyti keitimų prenumeratą';
+$lang['btn_unsubscribe'] = 'Atsisakyti keitimų prenumeratos';
+$lang['btn_profile'] = 'Atnaujinti profilį';
+$lang['btn_reset'] = 'Atstata';
+$lang['btn_resendpwd'] = 'Išsiųsti naują slaptažodį';
+$lang['btn_draft'] = 'Redaguoti juodraštį';
+$lang['btn_recover'] = 'Atkurti juodraštį';
+$lang['btn_draftdel'] = 'Šalinti juodraštį';
+$lang['btn_register'] = 'Registruotis';
+$lang['loggedinas'] = 'Prisijungęs kaip';
+$lang['user'] = 'Vartotojo vardas';
+$lang['pass'] = 'Slaptažodis';
+$lang['newpass'] = 'Naujas slaptažodis';
+$lang['oldpass'] = 'Patvirtinti esamą slaptažodį';
+$lang['passchk'] = 'dar kartą';
+$lang['remember'] = 'Prisiminti mane';
+$lang['fullname'] = 'Visas vardas';
+$lang['email'] = 'El. pašto adresas';
+$lang['profile'] = 'Vartotojo profilis';
+$lang['badlogin'] = 'Nurodėte blogą vartotojo vardą arba slaptažodį.';
+$lang['minoredit'] = 'Nedidelis pataisymas';
+$lang['draftdate'] = 'Juodraštis automatiškai išsaugotas';
+$lang['nosecedit'] = 'Puslapis buvo kažkieno pataisytas, teksto dalies informacija tapo pasenusi, todėl pakrautas visas puslapis.';
+$lang['regmissing'] = 'Turite užpildyti visus laukus.';
+$lang['reguexists'] = 'Vartotojas su pasirinktu prisijungimo vardu jau egzistuoja.';
+$lang['regsuccess'] = 'Vartotojas sukurtas, slaptažodis išsiųstas el. paštu.';
+$lang['regsuccess2'] = 'Vartotojas sukurtas.';
+$lang['regmailfail'] = 'Siunčiant slaptažodį el. paštu įvyko klaida - susisiekite su administracija!';
+$lang['regbadmail'] = 'Nurodytas el. pašto adresas yra neteisingas - jei manote, kad tai klaida, susisiekite su administracija';
+$lang['regbadpass'] = 'Įvesti slaptažodžiai nesutampa, bandykite dar kartą.';
+$lang['regpwmail'] = 'Jūsų DokuWiki slaptažodis';
+$lang['reghere'] = 'Dar neužsiregistravote? Padarykite tai dabar';
+$lang['profna'] = 'Ši vikisvetainė neleidžia pakeisti profilio';
+$lang['profnochange'] = 'Nėra pakeitimų, todėl nėra ką atlikti.';
+$lang['profnoempty'] = 'Tuščias vardo arba el. pašto adreso laukas nėra leidžiamas.';
+$lang['profchanged'] = 'Vartotojo profilis sėkmingai atnaujintas.';
+$lang['pwdforget'] = 'Pamiršote slaptažodį? Gaukite naują';
+$lang['resendna'] = 'Ši vikisvetainė neleidžia persiųsti slaptažodžių.';
+$lang['resendpwd'] = 'Atsiųsti naują slaptažodį';
+$lang['resendpwdmissing'] = 'Jūs turite užpildyti visus laukus.';
+$lang['resendpwdnouser'] = 'Tokio vartotojo nėra duomenų bazėje.';
+$lang['resendpwdbadauth'] = 'Atsiprašome, bet šis tapatybės nustatymo kodas netinkamas. Įsitikinkite, kad panaudojote pilną patvirtinimo nuorodą.';
+$lang['resendpwdconfirm'] = 'Patvirtinimo nuoroda išsiųsta el. paštu.';
+$lang['resendpwdsuccess'] = 'Jūsų naujas slaptažodis buvo išsiųstas el. paštu.';
+$lang['license'] = 'Jei nenurodyta kitaip, šio wiki turinys ginamas tokia licencija:';
+$lang['licenseok'] = 'Pastaba: Redaguodami šį puslapį jūs sutinkate jog jūsų turinys atitinka licencijavima pagal šią licenciją';
+$lang['txt_upload'] = 'Išsirinkite atsiunčiamą bylą';
+$lang['txt_filename'] = 'Įveskite wikivardą (nebūtina)';
+$lang['txt_overwrt'] = 'Perrašyti egzistuojančią bylą';
+$lang['lockedby'] = 'Užrakintas vartotojo';
+$lang['lockexpire'] = 'Užraktas bus nuimtas';
+$lang['js']['willexpire'] = 'Šio puslapio redagavimo užrakto galiojimo laikas baigsis po minutės.\nNorėdami išvengti nesklandumų naudokite peržiūros mygtuką ir užraktas atsinaujins.';
+$lang['js']['notsavedyet'] = "Pakeitimai nebus išsaugoti.\nTikrai tęsti?";
+$lang['rssfailed'] = 'Siunčiant šį feed\'ą įvyko klaida: ';
+$lang['nothingfound'] = 'Paieškos rezultatų nėra.';
+$lang['mediaselect'] = 'Mediabylos išsirinkimas';
+$lang['fileupload'] = 'Mediabylos atsiuntimas';
+$lang['uploadsucc'] = 'Atsiuntimas pavyko';
+$lang['uploadfail'] = 'Atsiuntimas nepavyko. Blogi priėjimo leidimai??';
+$lang['uploadwrong'] = 'Atsiuntimas atmestas. Bylos tipas neleistinas';
+$lang['uploadexist'] = 'Tokia byla jau egzistuoja. Veiksmai atšaukti.';
+$lang['uploadbadcontent'] = 'Įkeltas turinys neatitinka %s failo išplėtimo.';
+$lang['uploadspam'] = 'Įkėlimas blokuotas pagal šiukšlintojų juodajį šąrašą.';
+$lang['uploadxss'] = 'Įkėlimas blokuotas greičiausiai dėl netinkamo teksto.';
+$lang['uploadsize'] = 'Įkeltas failas per didelis (maks. %s)';
+$lang['deletesucc'] = 'Byla "%s" ištrinta.';
+$lang['deletefail'] = 'Byla "%s" negali būti ištrinta - patikrinkite leidimus.';
+$lang['mediainuse'] = 'Byla "%s" nebuvo ištrinta - ji vis dar naudojama.';
+$lang['namespaces'] = 'Pavadinimai';
+$lang['mediafiles'] = 'Prieinamos bylos';
+$lang['js']['keepopen'] = 'Pažymėjus palikti langą atvertą';
+$lang['js']['hidedetails'] = 'Paslėpti Detales';
+$lang['js']['nosmblinks'] = 'Nurodos į "Windows shares" veikia tik su Microsoft Internet Explorer naršykle.
+Vis dėlto, jūs galite nukopijuoti šią nuorodą.';
+$lang['mediausage'] = 'Failo nuorodai užrašyti naudokite tokią sintaksę:';
+$lang['mediaview'] = 'Žiūrėti pirminį failą';
+$lang['mediaroot'] = 'pradžia (root)';
+$lang['mediaextchange'] = 'Failo galūnė pasikeitė iš .%s į .%s!';
+$lang['reference'] = 'Paminėjimai';
+$lang['ref_inuse'] = 'Byla negali būti ištrinta, nes ji vis dar yra naudojama šiuose puslapiuose:';
+$lang['ref_hidden'] = 'Kai kurie paminėjimai yra puslapiuose, kurių jums neleista skaityti.';
+$lang['hits'] = 'Atidarymai';
+$lang['quickhits'] = 'Sutampantys pavadinimai';
+$lang['toc'] = 'Turinys';
+$lang['current'] = 'esamas';
+$lang['yours'] = 'Jūsų versija';
+$lang['diff'] = 'rodyti skirtumus tarp šios ir esamos versijos';
+$lang['diff2'] = 'Parodyti skirtumus tarp pasirinktų versijų';
+$lang['line'] = 'Linija';
+$lang['breadcrumb'] = 'Kelias';
+$lang['youarehere'] = 'Jūs esate čia';
+$lang['lastmod'] = 'Keista';
+$lang['by'] = 'vartotojo';
+$lang['deleted'] = 'ištrintas';
+$lang['created'] = 'sukurtas';
+$lang['restored'] = 'atstatyta sena versija';
+$lang['external_edit'] = 'redaguoti papildomomis priemonėmis';
+$lang['summary'] = 'Redaguoti santrauką';
+$lang['noflash'] = '<a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> reikalingas šios medžiagos peržiūrai.';
+$lang['mail_newpage'] = '[DokuWiki] puslapis pridėtas:';
+$lang['mail_changed'] = '[DokuWiki] puslapis pakeistas:';
+$lang['mail_new_user'] = 'naujas vartotojas:';
+$lang['mail_upload'] = 'failas įkeltas:';
+$lang['qb_bold'] = 'Pusjuodis';
+$lang['qb_italic'] = 'Kursyvas';
+$lang['qb_underl'] = 'Pabrauktas';
+$lang['qb_code'] = 'Kodas';
+$lang['qb_strike'] = 'Perbraukta';
+$lang['qb_h1'] = 'Pirmo lygio antraštė';
+$lang['qb_h2'] = 'Antro lygio antraštė';
+$lang['qb_h3'] = 'Trečio lygio antraštė';
+$lang['qb_h4'] = 'Ketvirto lygio antraštė';
+$lang['qb_h5'] = 'Penkto lygio antraštė';
+$lang['qb_link'] = 'Vidinė nuoroda';
+$lang['qb_extlink'] = 'Išorinė nuoroda';
+$lang['qb_hr'] = 'Horizontali linija';
+$lang['qb_ol'] = 'Numeruotas sąrašas';
+$lang['qb_ul'] = 'Nenumetuotas sąrašas';
+$lang['qb_media'] = 'Paveikslėliai ir kitos bylos';
+$lang['qb_sig'] = 'Įterpti parašą';
+$lang['qb_smileys'] = 'Šypsenėlės';
+$lang['qb_chars'] = 'Specialūs simboliai';
+$lang['js']['del_confirm'] = 'Ar tikrai ištrinti pažymėtą(us) įrašą(us)?';
+$lang['admin_register'] = 'Sukurti naują vartotoją';
+$lang['metaedit'] = 'Redaguoti metaduomenis';
+$lang['metasaveerr'] = 'Nepavyko išsaugoti metaduomenų';
+$lang['metasaveok'] = 'Metaduomenys išsaugoti';
+$lang['img_backto'] = 'Atgal į';
+$lang['img_title'] = 'Pavadinimas';
+$lang['img_caption'] = 'Antraštė';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Bylos pavadinimas';
+$lang['img_fsize'] = 'Dydis';
+$lang['img_artist'] = 'Fotografas';
+$lang['img_copyr'] = 'Autorinės teisės';
+$lang['img_format'] = 'Formatas';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Raktiniai žodžiai';
+$lang['subscribe_success'] = '%s užsakyta "%s" prenumerata';
+$lang['subscribe_error'] = '%s užsakant "%s" prenumeratą įvyko klaida';
+$lang['subscribe_noaddress'] = 'Jūs nesatė nurodęs el. pašto adreso, todėl negalima Jums užsakyti prenumeratos';
+$lang['unsubscribe_success'] = '%s ištrintas iš "%s" prenumeratos';
+$lang['unsubscribe_error'] = '%s trinant iš "%s" prenumeratos įvyko klaida';
+$lang['authmodfailed'] = 'Bloga vartotojo tapatumo nustatymo konfigūracija. Praneškite apie tai savo administratoriui.';
+$lang['authtempfail'] = 'Vartotojo tapatumo nustatymas laikinai nepasiekiamas. Jei ši situacija kartojasi, tai praneškite savo administratoriui.';
+$lang['i_chooselang'] = 'Pasirinkite kalbą';
+$lang['i_installer'] = 'DokuWiki Instaliatorius';
+$lang['i_wikiname'] = 'Wiki vardas';
+$lang['i_enableacl'] = 'Įjungti ACL (rekomenduojama)';
+$lang['i_superuser'] = 'Supervartotojas';
+$lang['i_problems'] = 'Instaliavimo metu buvo klaidų, kurios pateiktos žemiau. Tęsti negalima, kol nebus pašalintos priežastys.';
diff --git a/inc/lang/lt/locked.txt b/inc/lang/lt/locked.txt
new file mode 100644
index 000000000..3f6d000f6
--- /dev/null
+++ b/inc/lang/lt/locked.txt
@@ -0,0 +1,3 @@
+====== Puslapis užrakintas ======
+
+Šis puslapis yra apsaugotas (užrakintas) nuo kitų vartotojų pakeitimų. Norėdami redaguoti puslapį, turėsite palaukti, kol kitas vartotojas baigs tai daryti arba „užrakto“ galiojimo laikas pasibaigs.
diff --git a/inc/lang/lt/login.txt b/inc/lang/lt/login.txt
new file mode 100644
index 000000000..2a6e21db2
--- /dev/null
+++ b/inc/lang/lt/login.txt
@@ -0,0 +1,5 @@
+====== Prisijungimas ======
+
+Šiuo metu jūs nesate prisijungęs. Įveskite savo prisijungimo duomenis žemiau. „Cookies“ palaikymas jūsų naršyklėje turi būti įjungtas.
+
+
diff --git a/inc/lang/lt/mailtext.txt b/inc/lang/lt/mailtext.txt
new file mode 100644
index 000000000..63b2f591e
--- /dev/null
+++ b/inc/lang/lt/mailtext.txt
@@ -0,0 +1,18 @@
+Jūsų DokuWiki buvo sukurtas arba pakeistas puslapis. Detalės:
+
+Data : @DATE@
+Naršyklė : @BROWSER@
+IP adresas : @IPADDRESS@
+Host'as : @HOSTNAME@
+Sena versija: @OLDPAGE@
+Nauja versija: @NEWPAGE@
+Redagavimo aprašas: @SUMMARY@
+Vartotojas : @USER@
+
+Pakeitimo diff'as:
+
+@DIFF@
+
+
+--
+Šis laiškas buvo sugeneruotas DokuWiki (@DOKUWIKIURL@).
diff --git a/inc/lang/lt/newpage.txt b/inc/lang/lt/newpage.txt
new file mode 100644
index 000000000..c28e30bd4
--- /dev/null
+++ b/inc/lang/lt/newpage.txt
@@ -0,0 +1,4 @@
+====== Šis puslapis dar neegzistuoja ======
+
+Nuoroda, kurią jūs paspaudėte, atvedė į dar neegzistuojantį puslapį. Jūs galite jį sukurti paspausdami ''Sukurti šį puslapį'' mygtuką.
+
diff --git a/inc/lang/lt/norev.txt b/inc/lang/lt/norev.txt
new file mode 100644
index 000000000..028ebe7f2
--- /dev/null
+++ b/inc/lang/lt/norev.txt
@@ -0,0 +1,5 @@
+====== Tokios versijos nėra ======
+
+Nurodyta versija neegzistuoja. Norėdami pamatyti visas dokumento versijas, paspauskite ''Senos versijos'' mygtuką
+
+
diff --git a/inc/lang/lt/password.txt b/inc/lang/lt/password.txt
new file mode 100644
index 000000000..8c65cf8c5
--- /dev/null
+++ b/inc/lang/lt/password.txt
@@ -0,0 +1,9 @@
+Labas, @FULLNAME@!
+
+Čia yra jūsų prisijungimo duomenys prie tinklalapio @TITLE@ (@DOKUWIKIURL@):
+
+Prisijungimo vardas: @LOGIN@
+Slaptažodis: @PASSWORD@
+
+--
+Šis laiškas sugeneruotas DokuWiki sistemos (@DOKUWIKIURL@).
diff --git a/inc/lang/lt/preview.txt b/inc/lang/lt/preview.txt
new file mode 100644
index 000000000..2d24e2164
--- /dev/null
+++ b/inc/lang/lt/preview.txt
@@ -0,0 +1,5 @@
+====== Peržiūra ======
+
+Čia matote, kaip atrodo jūsų pakeitimai. **Pakeitimai dar nėra išsaugoti!**
+
+
diff --git a/inc/lang/lt/read.txt b/inc/lang/lt/read.txt
new file mode 100644
index 000000000..91ea7e656
--- /dev/null
+++ b/inc/lang/lt/read.txt
@@ -0,0 +1,3 @@
+Šį puslapį galima tik skaityti. Jūs galite peržvelgti jo kodą (source), bet negalite jo keisti. Jei manote, kad tai klaida - susisiekite su administratoriumi.
+
+
diff --git a/inc/lang/lt/recent.txt b/inc/lang/lt/recent.txt
new file mode 100644
index 000000000..506538629
--- /dev/null
+++ b/inc/lang/lt/recent.txt
@@ -0,0 +1,5 @@
+====== Naujausi keitimai ======
+
+Šie puslapiai buvo neseniai pakeisti.
+
+
diff --git a/inc/lang/lt/register.txt b/inc/lang/lt/register.txt
new file mode 100644
index 000000000..f595826f3
--- /dev/null
+++ b/inc/lang/lt/register.txt
@@ -0,0 +1,4 @@
+====== Naujo vartotojo registracija ======
+
+Norėdami tapti nauju registruotu šio tinklalapio vartotoju, užpildykite žemiau esančią formą. Būtinai turite nurodyti **veikiantį el. pašto adresą**, nes jūsų slaptažodis bus išsiųstas pastaruoju adresu. Prisijungimo vardas turėtų būti sukurtas pagal [[doku>pagename|puslapio pavadinimo]] taisykles.
+
diff --git a/inc/lang/lt/resendpwd.txt b/inc/lang/lt/resendpwd.txt
new file mode 100644
index 000000000..753827108
--- /dev/null
+++ b/inc/lang/lt/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Siųsti naują slaptažodį ======
+
+Naujo slaptažodžio gavimui, užpildykite visus žemiau esančius laukus. Naujas slaptažodis bus atsiųstas į jūsų užregistruotą el. pašto adresą. Vartotojo vardas turi būti toks pat kaip ir wiki sistemoje.
diff --git a/inc/lang/lt/revisions.txt b/inc/lang/lt/revisions.txt
new file mode 100644
index 000000000..9999767bd
--- /dev/null
+++ b/inc/lang/lt/revisions.txt
@@ -0,0 +1,4 @@
+====== Senos versijos ======
+
+Čia matote senas šio dokumento versijas. Jei norite atstatyti dokumentą į jo senesniąją versiją, paspauskite "Redaguoti šį puslapį" prie norimos versijos ir išsaugokite ją.
+
diff --git a/inc/lang/lt/searchpage.txt b/inc/lang/lt/searchpage.txt
new file mode 100644
index 000000000..a83a6a58a
--- /dev/null
+++ b/inc/lang/lt/searchpage.txt
@@ -0,0 +1,5 @@
+====== Paieška ======
+
+Žemiau matote Jūsų atliktos paieškos rezultatus. Jeigu neradote to, ko ieškojote, galite sukurti naują puslapį šiuo pavadinimu paspausdami "Redaguoti šį puslapį".
+
+===== Rezultatai ===== \ No newline at end of file
diff --git a/inc/lang/lt/showrev.txt b/inc/lang/lt/showrev.txt
new file mode 100644
index 000000000..ed774244a
--- /dev/null
+++ b/inc/lang/lt/showrev.txt
@@ -0,0 +1,2 @@
+**Čia yra sena dokumento versija!**
+----
diff --git a/inc/lang/lt/updateprofile.txt b/inc/lang/lt/updateprofile.txt
new file mode 100644
index 000000000..7ede1a00a
--- /dev/null
+++ b/inc/lang/lt/updateprofile.txt
@@ -0,0 +1,4 @@
+====== Redaguoti savo profilį ======
+
+Užpildykite tik tuos laukus, kuriuos norite pakeisti. Vartotojo vardo keisti nebūtina.
+
diff --git a/inc/lang/lv/admin.txt b/inc/lang/lv/admin.txt
new file mode 100644
index 000000000..3b37fa389
--- /dev/null
+++ b/inc/lang/lv/admin.txt
@@ -0,0 +1,6 @@
+====== Administrēšana ======
+
+DokuWiki pieejamas šādas administrēšanas iespējas:
+
+
+
diff --git a/inc/lang/lv/adminplugins.txt b/inc/lang/lv/adminplugins.txt
new file mode 100644
index 000000000..e8d208d24
--- /dev/null
+++ b/inc/lang/lv/adminplugins.txt
@@ -0,0 +1 @@
+===== Papildu moduļi ===== \ No newline at end of file
diff --git a/inc/lang/lv/backlinks.txt b/inc/lang/lv/backlinks.txt
new file mode 100644
index 000000000..19bebf7b2
--- /dev/null
+++ b/inc/lang/lv/backlinks.txt
@@ -0,0 +1,5 @@
+====== Saistītās lapas ======
+
+Norāde uz šo lapu ir atrodama dokumentos:
+
+
diff --git a/inc/lang/lv/conflict.txt b/inc/lang/lv/conflict.txt
new file mode 100644
index 000000000..5aa6442c9
--- /dev/null
+++ b/inc/lang/lv/conflict.txt
@@ -0,0 +1,8 @@
+====== Ir jaunāka versija ======
+
+Tevis labotajam dokumentam jau ir jaunāka versija. Tā gadās, ja cits lietotājs tavas labošanas laikā ir paguvis veikt savus labojumus.
+
+Rūpīgi pārlūko šeit parādītās atšķirības un tad izlem, kuru variantu paturēt. Ja nospiedīsi ''Saglabāt'', saglabāsies tavs teksts. Ja nospiedīsi ''Atlikt'' paliks pašreizējais variants.
+
+
+
diff --git a/inc/lang/lv/denied.txt b/inc/lang/lv/denied.txt
new file mode 100644
index 000000000..c7df462c8
--- /dev/null
+++ b/inc/lang/lv/denied.txt
@@ -0,0 +1,6 @@
+====== Piekļuve aizliegta ======
+
+Atvaino, tev nav tiesību turpināt. Varbūt aizmirsi ielogoties?
+
+
+
diff --git a/inc/lang/lv/diff.txt b/inc/lang/lv/diff.txt
new file mode 100644
index 000000000..40e1b5405
--- /dev/null
+++ b/inc/lang/lv/diff.txt
@@ -0,0 +1,7 @@
+====== Atšķirības ======
+
+Norādītais vecais variants no patreizējās lapas atšķiras ar:
+
+
+
+
diff --git a/inc/lang/lv/draft.txt b/inc/lang/lv/draft.txt
new file mode 100644
index 000000000..525f7cbb2
--- /dev/null
+++ b/inc/lang/lv/draft.txt
@@ -0,0 +1,5 @@
+====== Atrasts melnraksta fails ======
+
+Iepriekšējā šīs lapas labošana nav pabeigta. DokuWiki darba laikā automātiski saglabāja melnrakstu, kuru tagad var labot tālāk. Zemāk redzami iepriekšējās labošanas dati.
+
+Nolem, vai vajag //atjaunot// zudušos labojumus, //dzēst// saglabāto melnrakstu vai //atlikt// labošanu.
diff --git a/inc/lang/lv/edit.txt b/inc/lang/lv/edit.txt
new file mode 100644
index 000000000..9da6f2d23
--- /dev/null
+++ b/inc/lang/lv/edit.txt
@@ -0,0 +1,2 @@
+Labo lapu un uzklikšķini uz ''Saglabāt''. Par lietojamo sintaksi skaties rakstu [[wiki:syntax]]. Lūdzu labo tika tad, ja vari lapu **uzlabot**. Ja gribi tikai kaut ko izmēģināt, izmanto [[wiki:playground|smilšukasti]].
+
diff --git a/inc/lang/lv/editrev.txt b/inc/lang/lv/editrev.txt
new file mode 100644
index 000000000..6fa7a4c05
--- /dev/null
+++ b/inc/lang/lv/editrev.txt
@@ -0,0 +1 @@
+---- **Tu skaties vecu dokumenta versiju!** Ja to saglabāsi, tad izveidosies jauns dokuments ar šo veco saturu. ----
diff --git a/inc/lang/lv/index.txt b/inc/lang/lv/index.txt
new file mode 100644
index 000000000..6baa2a3e2
--- /dev/null
+++ b/inc/lang/lv/index.txt
@@ -0,0 +1,4 @@
+====== Rādītājs ======
+
+Visu pieejamo lapu rādītājs. Sakārtots pēc [[doku>namespaces|sadaļām]].
+
diff --git a/inc/lang/lv/install.html b/inc/lang/lv/install.html
new file mode 100644
index 000000000..9967d2edd
--- /dev/null
+++ b/inc/lang/lv/install.html
@@ -0,0 +1,12 @@
+<p>Šī lapa palīdz <a href="http://dokuwiki.org">Dokuwiki</a>pirmajā instalācijā un konfigurēšanā.
+Vairāk par instalatoru var lasīt tā
+<a href="http://dokuwiki.org/installer">documentācijas lapā</a>.</p>
+
+<p>DokuWiki lapu un ar to saistīto datu (piem.: attēlu, meklēšanas indeksu, veco versiju utt.) glabāšanai lieto parastus failus. Lai Dokuwiki veiksmīgi darbotos <strong>vajag</strong> rakstīšanas tiesības direktorijās, kur šie faili glabājas. Instalators tiesības nomainīt nespēj. Tas parasti jums jāizdara komandrindā vai ar FTP vadības paneli (piem. cPanel).</p>
+
+<p>Instalators konfigurēs DokuWiki <acronym title="access control list">ACL</acronym> lietošanai, kas ļauj administratoram ielogoties un piekļūt DokuWiki administrēšanas izvēlnei, lai instalētu moduļus, pārvaldītu lietotājus, notiektu piekļuves tiesības Wiki lapām un mainītu DokuWiki konfigurāciju.
+Tas nav vajadzīgs, lai DokuWiki darbotos, bet ar to var vieglāk administrēt.</p>
+
+<p>Pieredzējušiem lietotājiem ar īpašām prasībām jāmeklē sīkākas ziņas
+<a href="http://dokuwiki.org/install">uzstādīšanas instrukcijā</a>
+un <a href="http://dokuwiki.org/config">konfigurēšanas padomos</a>.</p> \ No newline at end of file
diff --git a/inc/lang/lv/lang.php b/inc/lang/lv/lang.php
new file mode 100644
index 000000000..f88302f2f
--- /dev/null
+++ b/inc/lang/lv/lang.php
@@ -0,0 +1,309 @@
+<?php
+/**
+ * latvian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Labot lapu';
+$lang['btn_source'] = 'Parādīt lapas kodu';
+$lang['btn_show'] = 'Parādīt lapu';
+$lang['btn_create'] = 'Izveidot lapu';
+$lang['btn_search'] = 'Meklēt';
+$lang['btn_save'] = 'Saglabāt';
+$lang['btn_preview'] = 'Priekšskats';
+$lang['btn_top'] = 'Atpakaļ uz sākumu';
+$lang['btn_newer'] = '<< jaunāki';
+$lang['btn_older'] = 'vecāki >>';
+$lang['btn_revs'] = 'Vecās versijas';
+$lang['btn_recent'] = 'Jaunākie grozījumi';
+$lang['btn_upload'] = 'Augšupielādēt';
+$lang['btn_cancel'] = 'Atlikt';
+$lang['btn_index'] = 'Rādītājs';
+$lang['btn_secedit'] = 'Labot';
+$lang['btn_login'] = 'Ieiet';
+$lang['btn_logout'] = 'Iziet';
+$lang['btn_admin'] = 'Administrēt';
+$lang['btn_update'] = 'Atjaunot';
+$lang['btn_delete'] = 'Dzēst';
+$lang['btn_back'] = 'Atpakaļ';
+$lang['btn_backlink'] = 'Norādes uz lapu';
+$lang['btn_backtomedia'] = 'Atpakaļ uz mēdiju failu izvēli';
+$lang['btn_subscribe'] = 'Abonēt izmaiņu paziņojumus';
+$lang['btn_profile'] = 'Labot savu profilu';
+$lang['btn_reset'] = 'Atsaukt izmaiņas';
+$lang['btn_resendpwd'] = 'Nosūtīt jaunu paroli';
+$lang['btn_draft'] = 'Labot melnrakstu';
+$lang['btn_recover'] = 'Atjaunot melnrakstu';
+$lang['btn_draftdel'] = 'Dzēst melnrakstu';
+$lang['btn_revert'] = 'Atjaunot';
+$lang['btn_register'] = 'Reģistrēties';
+$lang['btn_apply'] = 'Labi';
+$lang['btn_media'] = 'Mēdiju pārvaldnieks';
+$lang['loggedinas'] = 'Pieteicies kā';
+$lang['user'] = 'Lietotājvārds';
+$lang['pass'] = 'Parole';
+$lang['newpass'] = 'Jaunā parole';
+$lang['oldpass'] = 'Atkārto patreizējo paroli';
+$lang['passchk'] = 'vēlreiz';
+$lang['remember'] = 'Atceries mani';
+$lang['fullname'] = 'Pilns vārds';
+$lang['email'] = 'E-pasts';
+$lang['profile'] = 'Lietotāja vārds';
+$lang['badlogin'] = 'Atvaino, lietotājvārds vai parole aplama.';
+$lang['minoredit'] = 'Sīki labojumi';
+$lang['draftdate'] = 'Melnraksts automātiski saglabāts';
+$lang['nosecedit'] = 'Lapa pa šo laiku ir mainījusies, sekcijas informācija novecojusi. Ielādēta lapas pilnās versija.';
+$lang['regmissing'] = 'Atvaino, jāaizpilda visas ailes.';
+$lang['reguexists'] = 'Atvaino, tāds lietotājs jau ir.';
+$lang['regsuccess'] = 'Lietotājs izveidots. Parole nosūtīta pa pastu.';
+$lang['regsuccess2'] = 'Lietotājs izveidots.';
+$lang['regmailfail'] = 'Šķiet, ka ir problēmas nosūtīt pastu. Lūdzu sazinies ar administratoru!';
+$lang['regbadmail'] = 'Uzdotā epasta adrese izskatās aplama. Ja tas nav tiesa, sazinies ar administratoru.';
+$lang['regbadpass'] = 'Abas ierakstītās paroles nav vienādas, lūdzu atkārto.';
+$lang['regpwmail'] = 'Tava DokuWiki parole';
+$lang['reghere'] = 'Tev vēl nav sava konta? Izveido!';
+$lang['profna'] = 'Labot profilu nav iespējams';
+$lang['profnochange'] = 'Izmaiņu nav. Nav, ko darīt.';
+$lang['profnoempty'] = 'Bez vārda vai e-pasta adreses nevar.';
+$lang['profchanged'] = 'Profils veiksmīgi izlabots.';
+$lang['pwdforget'] = 'Aizmirsi paroli? Saņem jaunu';
+$lang['resendna'] = 'Paroļu izsūtīšanu nepiedāvāju.';
+$lang['resendpwd'] = 'Nosūtīt jaunu paroli lietotājam';
+$lang['resendpwdmissing'] = 'Atvaino, jāizpilda visas ailes.';
+$lang['resendpwdnouser'] = 'Atvaino, tāda lietotāja nav.';
+$lang['resendpwdbadauth'] = 'Atvaino, šis autorizācijas kods nav derīgs. Pārliecinies, ka lietoji pilnu apstiprināšanas adresi.';
+$lang['resendpwdconfirm'] = 'Apstiprināšanas adrese nosūtīta pa epastu.';
+$lang['resendpwdsuccess'] = 'Jaunā parole nosūtīta pa e-pastu.';
+$lang['license'] = 'Ja nav norādīts citādi, viki saturs pieejams ar šādas licenzes noteikumiem:';
+$lang['licenseok'] = 'Ievēro: Labojot lapu, tu piekrīti šādiem licenzes noteikumiem.';
+$lang['searchmedia'] = 'Meklētais faila vārds: ';
+$lang['searchmedia_in'] = 'Meklēt iekš %s';
+$lang['txt_upload'] = 'Norādi augšupielādējamo failu';
+$lang['txt_filename'] = 'Ievadi vikivārdu (nav obligāts)';
+$lang['txt_overwrt'] = 'Aizstāt esošo failu';
+$lang['lockedby'] = 'Patlaban bloķējis ';
+$lang['lockexpire'] = 'Bloķējums beigsies ';
+$lang['js']['willexpire'] = 'Tavs bloķējums uz šo lapu pēc minūtes beigsies.\nLai izvairītos no konflikta, nospied Iepriekšapskata pogu\n un bloķējuma laiku sāks skaitīt no jauna.';
+$lang['js']['notsavedyet'] = 'Veiktas bet nav saglabātas izmaiņas.
+Vai tiešām tās nevajag?';
+$lang['js']['searchmedia'] = 'Meklēt failus';
+$lang['js']['keepopen'] = 'Pēc faila izvēles logu paturēt atvērtu';
+$lang['js']['hidedetails'] = 'Slēpt detaļas';
+$lang['js']['mediatitle'] = 'Saites īpašības';
+$lang['js']['mediadisplay'] = 'Saites tips';
+$lang['js']['mediaalign'] = 'Slēgums';
+$lang['js']['mediasize'] = 'Attēla izmērs';
+$lang['js']['mediatarget'] = 'Saite ved uz ';
+$lang['js']['mediaclose'] = 'Aizvērt';
+$lang['js']['mediainsert'] = 'Ievietot';
+$lang['js']['mediadisplayimg'] = 'Rādīt attēlu';
+$lang['js']['mediadisplaylnk'] = 'Rādīt tikai saiti';
+$lang['js']['mediasmall'] = 'Mazs';
+$lang['js']['mediamedium'] = 'Vidējs';
+$lang['js']['medialarge'] = 'Liels';
+$lang['js']['mediaoriginal'] = 'Oriģināls';
+$lang['js']['medialnk'] = 'Saite uz detaļām';
+$lang['js']['mediadirect'] = 'Tieša saite uz oriģinālu';
+$lang['js']['medianolnk'] = 'Bez saites';
+$lang['js']['medianolink'] = 'Bez saites uz attēlu';
+$lang['js']['medialeft'] = 'kreisais';
+$lang['js']['mediaright'] = 'labais';
+$lang['js']['mediacenter'] = 'centra';
+$lang['js']['medianoalign'] = 'neizlīdzināt';
+$lang['js']['nosmblinks'] = 'Saites uz Windows resursiem darbojas tikai Microsoft Internet Explorer.
+Protams, ka vari saiti kopēt un iespraust citā programmā.';
+$lang['js']['linkwiz'] = 'Saišu vednis';
+$lang['js']['linkto'] = 'Saite uz: ';
+$lang['js']['del_confirm'] = 'Dzēst šo šķirkli?';
+$lang['js']['restore_confirm'] = 'Tiešām atjaunot šo versiju';
+$lang['js']['media_diff'] = 'Skatīt atšķirību';
+$lang['js']['media_diff_both'] = 'Blakus';
+$lang['js']['media_diff_opacity'] = 'Pārklāti';
+$lang['js']['media_select'] = 'Norādīt failus...';
+$lang['js']['media_upload_btn'] = 'Augšuplādēt';
+$lang['js']['media_done_btn'] = 'Gatavs';
+$lang['js']['media_drop'] = 'Nomet te augšuplādējamos failus';
+$lang['js']['media_overwrt'] = 'Rakstīt pāri esošajiem failiem';
+$lang['rssfailed'] = 'Kļūda saņemot saturu no ';
+$lang['nothingfound'] = 'Nekas nav atrasts.';
+$lang['mediaselect'] = 'Mēdiju faila izvēle';
+$lang['fileupload'] = 'Mēdiju faila augšupielāde';
+$lang['uploadsucc'] = 'Veiksmīgi ielādēts';
+$lang['uploadfail'] = 'Ielādes kļūme. Varbūt aplamas tiesības?';
+$lang['uploadwrong'] = 'Ielāde aizliegta. Neatļauts faila paplašinājums';
+$lang['uploadexist'] = 'Neko nedarīju, jo fails jau ir.';
+$lang['uploadbadcontent'] = 'Augšupielādētā saturs neatbilst faila paplašinājumam %s.';
+$lang['uploadspam'] = 'Augšupielāde bloķēta ar melno sarakstu.';
+$lang['uploadxss'] = 'Augšupielāde bloķēta iespējama slikta satura dēļ.';
+$lang['uploadsize'] = 'Augšup lādētais fails pārāk liels. Maksimums ir %s.';
+$lang['deletesucc'] = 'Fails "%s" dzēsts.';
+$lang['deletefail'] = 'Nevar dzēst "%s". Pārbaudi tiesības.';
+$lang['mediainuse'] = 'Fails "%s" nav izdzēsts, to lieto.';
+$lang['namespaces'] = 'Nodaļas';
+$lang['mediafiles'] = 'Pieejamie faili';
+$lang['accessdenied'] = 'Šo lapu nav atļauts skatīt.';
+$lang['mediausage'] = 'Atsaucei uz failu lietot šādu sintaksi:';
+$lang['mediaview'] = 'Skatīt oriģinālo failu';
+$lang['mediaroot'] = 'sakne';
+$lang['mediaupload'] = 'Augšupielādēt failu patreizējā nodaļā. Lai izveidotu apakšnodaļu, pieraksti to, atdalot ar kolu, pirms augšupielādējamā faila vārda.';
+$lang['mediaextchange'] = 'Faila paplašinājums mainīts no .%s uz .%s!';
+$lang['reference'] = 'Norādes uz failu';
+$lang['ref_inuse'] = 'Failu nevar dzēst, jo izmanto šādas lapas:';
+$lang['ref_hidden'] = 'Dažas norādes ir lapās, ko nav tiesību skatīt';
+$lang['hits'] = 'Apmeklējumi';
+$lang['quickhits'] = 'Atbilstošās lapas';
+$lang['toc'] = 'Satura rādītājs';
+$lang['current'] = 'patlaban';
+$lang['yours'] = 'Tava versija';
+$lang['diff'] = 'atšķirības no patreizējas versijas';
+$lang['diff2'] = 'norādīto versiju atšķirības';
+$lang['difflink'] = 'Saite uz salīdzināšanas skatu.';
+$lang['diff_type'] = 'Skatīt atšķirības:';
+$lang['diff_inline'] = 'Iekļauti';
+$lang['diff_side'] = 'Blakus';
+$lang['line'] = 'Rinda';
+$lang['breadcrumb'] = 'Apmeklēts';
+$lang['youarehere'] = 'Tu atrodies šeit';
+$lang['lastmod'] = 'Labota';
+$lang['by'] = ', labojis';
+$lang['deleted'] = 'dzēsts';
+$lang['created'] = 'izveidots';
+$lang['restored'] = 'vecā versija atjaunota';
+$lang['external_edit'] = 'ārpussistēmas labojums';
+$lang['summary'] = 'Anotācija';
+$lang['noflash'] = 'Lai attēlotu lapas saturu, vajag <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>.';
+$lang['download'] = 'Lejuplādēt «kodiņu»((snippet))';
+$lang['mail_newpage'] = 'lapa pievienota:';
+$lang['mail_changed'] = 'lapa mainīta:';
+$lang['mail_subscribe_list'] = 'Nodaļā mainītās lapas:';
+$lang['mail_new_user'] = 'Jauns lietotājs:';
+$lang['mail_upload'] = 'augšupielādētais fails:';
+$lang['changes_type'] = 'Skatīt izmaiņas';
+$lang['pages_changes'] = 'Lapās';
+$lang['media_changes'] = 'Mēdiju failos';
+$lang['both_changes'] = 'Gan lapās, gan mēdiju failos';
+$lang['qb_bold'] = 'Trekninājums';
+$lang['qb_italic'] = 'Kursīvs';
+$lang['qb_underl'] = 'Pasvītrojums';
+$lang['qb_code'] = 'Vienplatuma burti';
+$lang['qb_strike'] = 'Pārsvītrots teksts';
+$lang['qb_h1'] = '1. līmeņa virsraksts';
+$lang['qb_h2'] = '2. līmeņa virsraksts';
+$lang['qb_h3'] = '3. līmeņa virsraksts';
+$lang['qb_h4'] = '4. līmeņa virsraksts';
+$lang['qb_h5'] = '5. līmeņa virsraksts';
+$lang['qb_h'] = 'Virsraksts';
+$lang['qb_hs'] = 'Izraudzīties virsrakstu';
+$lang['qb_hplus'] = 'Lielāks virsraksts';
+$lang['qb_hminus'] = 'Mazāks virsraksts';
+$lang['qb_hequal'] = 'Tāds pats virsraksts';
+$lang['qb_link'] = 'Iekšēja saite';
+$lang['qb_extlink'] = 'Ārēja saite';
+$lang['qb_hr'] = 'Horizontāla līnija';
+$lang['qb_ol'] = 'Numurēts saraksts';
+$lang['qb_ul'] = 'Nenumurēts saraksts';
+$lang['qb_media'] = 'Pielikt attēlus un citus failus.';
+$lang['qb_sig'] = 'Ievietot parakstu';
+$lang['qb_smileys'] = 'Emotikoni';
+$lang['qb_chars'] = 'Īpašās zīmes';
+$lang['upperns'] = 'vienu nodaļu līmeni augstāk';
+$lang['admin_register'] = 'Pievienot jaunu lietotāju';
+$lang['metaedit'] = 'Labot metadatus';
+$lang['metasaveerr'] = 'Metadati nav saglabāti';
+$lang['metasaveok'] = 'Metadati saglabāti';
+$lang['img_backto'] = 'Atpakaļ uz';
+$lang['img_title'] = 'Virsraksts';
+$lang['img_caption'] = 'Apraksts';
+$lang['img_date'] = 'Datums';
+$lang['img_fname'] = 'Faila vārds';
+$lang['img_fsize'] = 'Izmērs';
+$lang['img_artist'] = 'Fotogrāfs';
+$lang['img_copyr'] = 'Autortiesības';
+$lang['img_format'] = 'Formāts';
+$lang['img_camera'] = 'Fotoaparāts';
+$lang['img_keywords'] = 'Atslēgvārdi';
+$lang['img_width'] = 'Platums';
+$lang['img_height'] = 'Augstums';
+$lang['img_manager'] = 'Skatīt mēdiju pārvaldniekā';
+$lang['subscr_subscribe_success'] = '%s pievienots %s abonēšanas sarakstam';
+$lang['subscr_subscribe_error'] = 'Kļūme pievienojot %s %s abonēšanas sarakstam.';
+$lang['subscr_subscribe_noaddress'] = 'Nav zināma jūsu e-pasta adrese, tāpēc nevarat abonēt.';
+$lang['subscr_unsubscribe_success'] = '%s abonements uz %s atsaukts';
+$lang['subscr_unsubscribe_error'] = 'Kļūme svītrojot %s no %s abonēšanas saraksta';
+$lang['subscr_already_subscribed'] = '%s jau abonē %s';
+$lang['subscr_not_subscribed'] = '%s neabonē %s';
+$lang['subscr_m_not_subscribed'] = 'Šī lapa vai nodaļa nav abonēta';
+$lang['subscr_m_new_header'] = 'Pievienot abonementu';
+$lang['subscr_m_current_header'] = 'Patlaban ir abonēts';
+$lang['subscr_m_unsubscribe'] = 'Atteikties no abonēšanas';
+$lang['subscr_m_subscribe'] = 'Abonēt';
+$lang['subscr_m_receive'] = 'Saņemt';
+$lang['subscr_style_every'] = 'vēstuli par katru izmaiņu';
+$lang['subscr_style_digest'] = 'kopsavilkumu par katru lapu (reizi %.2f dienās)';
+$lang['subscr_style_list'] = 'kopš pēdējās vēstules notikušo labojumu sarakstu (reizi %.2f dienās)';
+$lang['authmodfailed'] = 'Aplami konfigurēta lietotāju autentifikācija. Lūdzu ziņo Wiki administratoram.';
+$lang['authtempfail'] = 'Lietotāju autentifikācija pašlaik nedarbojas. Ja tas turpinās ilgstoši, lūduz ziņo Wiki administratoram.';
+$lang['i_chooselang'] = 'Izvēlies valodu';
+$lang['i_installer'] = 'DokuWiki instalētājs';
+$lang['i_wikiname'] = 'Wiki vārds';
+$lang['i_enableacl'] = 'Lietot ACL (ieteikts)';
+$lang['i_superuser'] = 'Superuser';
+$lang['i_problems'] = 'Instalētājs atrada zemāk minētās problēmas. Kamēr tās nenovērš, nav iespējam turpināt.';
+$lang['i_modified'] = 'Drošības nolūkos šis skripts darbosies tika ar jaunu nemodificētu Dokuwiki instalāciju.
+Vai nu no jauna jāatarhivē faili no lejupielādētās pakas vai jāraugās pēc padoma pilnā Dokuwiki instalācijas instrukcijā <a href="http://dokuwiki.org/install"></a>';
+$lang['i_funcna'] = 'PHP funkcija <code>%s</code> nav pieejama. Varbūt jūsu servera īpašnieks to kāda iemesla dēļ atslēdzis?';
+$lang['i_phpver'] = 'Jūsu PHP versija <code>%s</code> ir par vecu. Vajag versiju <code>%s</code>. Atjaunojiet savu PHP instalāciju.';
+$lang['i_permfail'] = 'Dokuwiki nevar ierakstīt <code>%s</code>. Jālabo direktorijas tiesības!';
+$lang['i_confexists'] = '<code>%s</code> jau ir';
+$lang['i_writeerr'] = 'Nevar izveidot <code>%s</code>. Jāpārbauda direktorijas/faila tiesības un fails jāizveido pašam.';
+$lang['i_badhash'] = 'nepazīstams vai izmainīts dokuwiki.php fails (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - neatļauta vai tukša vērtība';
+$lang['i_success'] = 'Konfigurēšana veiksmīgi pabeigta. Tagad vari nodzēst failu install.php. Tālāk turpini <a href="doku.php">savā jaunajā DokuWiki</a>.';
+$lang['i_failure'] = 'Rakstot konfigurācijas failu, gadījās dažas kļūmes. Pirms lieto <a href="doku.php">savu jauno DokuWiki</a>, tās varbūt jāizlabo.';
+$lang['i_policy'] = 'Sākotnējā ACL politika';
+$lang['i_pol0'] = 'Atvērts Wiki (raksta, lasa un augšupielādē ikviens)';
+$lang['i_pol1'] = 'Publisks Wiki (lasa ikviens, raksta un augšupielādē reģistrēti lietotāji)';
+$lang['i_pol2'] = 'Slēgts Wiki (raksta, lasa un augšupielādē tikai reģistrēti lietotāji)';
+$lang['i_retry'] = 'Atkārtot';
+$lang['i_license'] = 'Ar kādu licenci saturs tiks publicēts:';
+$lang['recent_global'] = 'Tu skati izmaiņas nodaļā <b>%s</b>. Ir iespējams <a href="%s">skatīt jaunākos grozījums visā viki</a>. ';
+$lang['years'] = 'pirms %d gadiem';
+$lang['months'] = 'pirms %d mēnešiem';
+$lang['weeks'] = 'pirms %d nedēļām';
+$lang['days'] = 'pirms %d dienām';
+$lang['hours'] = 'pirms %d stundām';
+$lang['minutes'] = 'pirms %d minūtēm';
+$lang['seconds'] = 'pirms %d sekundēm';
+$lang['wordblock'] = 'Grozījumus nevarēju saglabāt, jo tie satur aizliegto vārdu (spamu).';
+$lang['media_uploadtab'] = 'Augšuplādēt';
+$lang['media_searchtab'] = 'Meklēt';
+$lang['media_file'] = 'Fails';
+$lang['media_viewtab'] = 'Skatīt';
+$lang['media_edittab'] = 'Labot';
+$lang['media_historytab'] = 'Vēsture';
+$lang['media_list_thumbs'] = 'Sīktēli';
+$lang['media_list_rows'] = 'Rindas';
+$lang['media_sort_name'] = 'Nosaukums';
+$lang['media_sort_date'] = 'Datums';
+$lang['media_namespaces'] = 'Norādīt nodaļu';
+$lang['media_files'] = 'Faili nodaļā %s';
+$lang['media_upload'] = 'Augšuplādēt nodaļā %s';
+$lang['media_search'] = 'Meklēt nodaļā %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s nodaļā %s';
+$lang['media_edit'] = 'Labot %s';
+$lang['media_history'] = '%s vēsture';
+$lang['media_meta_edited'] = 'metadati laboti';
+$lang['media_perm_read'] = 'Atvainojiet, jums nav tiesību skatīt failus. ';
+$lang['media_perm_upload'] = 'Atvainojiet, jums nav tiesību augšupielādēt. ';
+$lang['media_update'] = 'Augšupielādēt jaunu versiju';
+$lang['media_restore'] = 'Atjaunot šo versiju';
+$lang['plugin_install_err'] = 'Modulis aplami instalēts. Pārdēvē moduļa direktoriju %s par %s.';
diff --git a/inc/lang/lv/locked.txt b/inc/lang/lv/locked.txt
new file mode 100644
index 000000000..7d57ce98b
--- /dev/null
+++ b/inc/lang/lv/locked.txt
@@ -0,0 +1,5 @@
+====== Lapa aizņemta ======
+
+Lapa aizņemta, to patlaban labo cits lietotājs. Tev ir jāgaida, kamēr to pabeigs labot vai arī iztecēs labotājam atvēlētais laiks.
+
+
diff --git a/inc/lang/lv/login.txt b/inc/lang/lv/login.txt
new file mode 100644
index 000000000..a98d21d1a
--- /dev/null
+++ b/inc/lang/lv/login.txt
@@ -0,0 +1,3 @@
+====== Login ======
+Tu neesi ielogojies! Ievadi savu lietotājvārdu un paroli. Pārlūkprogrammai jāpieņem //cookies//.
+
diff --git a/inc/lang/lv/mailtext.txt b/inc/lang/lv/mailtext.txt
new file mode 100644
index 000000000..cd4a5d6d8
--- /dev/null
+++ b/inc/lang/lv/mailtext.txt
@@ -0,0 +1,18 @@
+Tavā DokuWiki pievienota vai labota lapa. Šeit ir sīkākas ziņas:
+
+Datums : @DATE@
+Pārlūks : @BROWSER@
+IP adrese : @IPADDRESS@
+Dators : @HOSTNAME@
+Vecā versija : @OLDPAGE@
+Jaunā versija: @NEWPAGE@
+Anotācija : @SUMMARY@
+Lietotājs : @USER@
+
+@DIFF@
+
+
+--
+Vēstuli nosūtījusi DokuWiki programma no
+@DOKUWIKIURL@ datora
+
diff --git a/inc/lang/lv/newpage.txt b/inc/lang/lv/newpage.txt
new file mode 100644
index 000000000..a4a05fdc5
--- /dev/null
+++ b/inc/lang/lv/newpage.txt
@@ -0,0 +1,5 @@
+====== Šķirklis vēl nav izveidots ======
+
+Tu izvēlējies saiti uz vēl neizveidotu šķirkli. Ja tiesības ļauj, vari to izveidot, uzklikšķinot uz pogas ''Izveidot lapu''.
+
+
diff --git a/inc/lang/lv/norev.txt b/inc/lang/lv/norev.txt
new file mode 100644
index 000000000..b7c46245f
--- /dev/null
+++ b/inc/lang/lv/norev.txt
@@ -0,0 +1,5 @@
+====== Nav šādas versijas ======
+
+Norādītās lapas versijas nav. Lieto pogu ''Vecās versijas'', lai redzētu dokumenta veco versiju sarakstu.
+
+
diff --git a/inc/lang/lv/password.txt b/inc/lang/lv/password.txt
new file mode 100644
index 000000000..be5e7e2a7
--- /dev/null
+++ b/inc/lang/lv/password.txt
@@ -0,0 +1,9 @@
+Sveiki, @FULLNAME@!
+
+Tavi dati @TITLE@ lapām uz servera @DOKUWIKIURL@ ir
+
+Lietotājvārds: @LOGIN@
+Parole: @PASSWORD@
+
+--
+Šo dokumentu izveidojusi DokuWiki programma uz servera @DOKUWIKIURL@
diff --git a/inc/lang/lv/preview.txt b/inc/lang/lv/preview.txt
new file mode 100644
index 000000000..c3d618a12
--- /dev/null
+++ b/inc/lang/lv/preview.txt
@@ -0,0 +1,5 @@
+====== Priekšskats ======
+
+Tavs teksts izskatīsies šādi. Ievēro, tas vēl **nav saglabāts** !
+
+
diff --git a/inc/lang/lv/pwconfirm.txt b/inc/lang/lv/pwconfirm.txt
new file mode 100644
index 000000000..308ca29a1
--- /dev/null
+++ b/inc/lang/lv/pwconfirm.txt
@@ -0,0 +1,14 @@
+Sveiki, @FULLNAME@!
+
+Kāds pieprasījis jaunu paroli tavam @TITLE@ kontam
+@DOKUWIKIURL@ sistēmā.
+
+Ja paroli neesi prasījis, ignorē šo vēstuli.
+
+Lai apstiprinātu, ka esi paroli pieprasījis lieto norādīto saiti.
+
+@CONFIRM@
+
+--
+Šo vēstuli ģenerējusi DokuWiki no
+@DOKUWIKIURL \ No newline at end of file
diff --git a/inc/lang/lv/read.txt b/inc/lang/lv/read.txt
new file mode 100644
index 000000000..876e53cb8
--- /dev/null
+++ b/inc/lang/lv/read.txt
@@ -0,0 +1,4 @@
+Šī lapa ir tikai lasāma. Vari apskatīt izejas kodu, bet nevari to mainīt. Ja domā, ka tas nav pareizi, vaicā administratoram.
+
+
+
diff --git a/inc/lang/lv/recent.txt b/inc/lang/lv/recent.txt
new file mode 100644
index 000000000..70cf1aa1e
--- /dev/null
+++ b/inc/lang/lv/recent.txt
@@ -0,0 +1,8 @@
+====== Jaunākie grozījumi ======
+
+Jaunākie labojumi ir:
+
+
+
+
+
diff --git a/inc/lang/lv/register.txt b/inc/lang/lv/register.txt
new file mode 100644
index 000000000..5e6477d37
--- /dev/null
+++ b/inc/lang/lv/register.txt
@@ -0,0 +1,4 @@
+====== Jauna lietotāja reģistrācija ======
+
+Lai izveidotu jaunu kontu, aizpildi visas prasītās ailes. Pārliecinies, ka uzdod **derīgu pasta adresi**, jo jauno paroli tev nosūtīs pa pastu. Lietotājvārdam jāatbilst [[doku>pagename|wiki vārdu nosacījumiem]].
+
diff --git a/inc/lang/lv/registermail.txt b/inc/lang/lv/registermail.txt
new file mode 100644
index 000000000..50fd8a92b
--- /dev/null
+++ b/inc/lang/lv/registermail.txt
@@ -0,0 +1,14 @@
+Reģistrēts jauns lietotājs. Tā dati:
+
+Lietotājvārds : @NEWUSER@
+Pilns vārds : @NEWNAME@
+E-pasts : @NEWEMAIL@
+
+Datums : @DATE@
+Pārlūks : @BROWSER@
+IP aderese : @IPADDRESS@
+Datora vārds: @HOSTNAME@
+
+--
+Šo vēstuli ģenerējis DokuWiki no
+@DOKUWIKIURL \ No newline at end of file
diff --git a/inc/lang/lv/resendpwd.txt b/inc/lang/lv/resendpwd.txt
new file mode 100644
index 000000000..3f4597ac0
--- /dev/null
+++ b/inc/lang/lv/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Nosūtīt jaunu paroli ======
+
+Azipildi zemāk prasīto, lai saņemtu savam kontam jaunu paroli. Jauno paroli nosūtīs uz reģistrēto e-pasta adresi. Lietotāja vārdam jābūt tavam //wiki sistēmas// lietotājavārdam.
diff --git a/inc/lang/lv/revisions.txt b/inc/lang/lv/revisions.txt
new file mode 100644
index 000000000..51ad8495d
--- /dev/null
+++ b/inc/lang/lv/revisions.txt
@@ -0,0 +1,5 @@
+====== Vecās versijas ======
+
+Dokumentam ir šādas vecās versijas. Lai atgrieztos pie vecā varianta, izvēlies to no saraksta, uzklikšķini uz "Labot šo lapu" un saglabā to.
+
+
diff --git a/inc/lang/lv/searchpage.txt b/inc/lang/lv/searchpage.txt
new file mode 100644
index 000000000..22eb55f04
--- /dev/null
+++ b/inc/lang/lv/searchpage.txt
@@ -0,0 +1,4 @@
+====== Meklēšana ======
+
+Te vari redzēt meklēšanas rezultātus. Ja neatradi meklēto, nospiežot pogu "Labot lapu", vari izveidot jaunu lapu ar tevis meklētajiem atslēgvārdiem nosaukumā.
+===== Atrasts =====
diff --git a/inc/lang/lv/showrev.txt b/inc/lang/lv/showrev.txt
new file mode 100644
index 000000000..7d5c0fa07
--- /dev/null
+++ b/inc/lang/lv/showrev.txt
@@ -0,0 +1,2 @@
+**Šī ir veca dokumenta versija!**
+----
diff --git a/inc/lang/lv/stopwords.txt b/inc/lang/lv/stopwords.txt
new file mode 100644
index 000000000..846c86946
--- /dev/null
+++ b/inc/lang/lv/stopwords.txt
@@ -0,0 +1,48 @@
+# Šis ir to vārdu sarakstus, kurus indeksētājs neņem vērā. Katru vārdu savā rindā!
+# Labojot failu ievēro, ja jālieto UNIX rindu aplauzumi (single newline)
+# Nevajag likt sarakstā par 3 burtiem īsākus vārdus, tos tā pat neņem vērā
+# Angļu valodai saraksts ņemts no http://www.ranks.nl/stopwords/
+gar
+par
+pār
+pret
+starp
+caur
+uz
+aiz
+apakš
+bez
+iz
+kopš
+no
+pēc
+pie
+pirms
+priekš
+uz
+virs
+zem
+apakšpus
+ārpus
+augšpus
+iekšpus
+lejpus
+otrpus
+šaipus
+viņpus
+virspus
+dēļ
+labad
+pēc
+līdz
+pa
+vai
+jā
+nē
+kaut
+nav
+itin
+jo
+taču
+
+
diff --git a/inc/lang/lv/subscr_digest.txt b/inc/lang/lv/subscr_digest.txt
new file mode 100644
index 000000000..98784050c
--- /dev/null
+++ b/inc/lang/lv/subscr_digest.txt
@@ -0,0 +1,19 @@
+Labdien!
+
+@TITLE@ viki nodaļā @PAGE@ ir mainījušās šadas lapas:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Vecā versija: @OLDPAGE@
+Jaunā versija: @NEWPAGE@
+
+Lai atceltu izmaiņu paziņošanu, ielogojieties
+@DOKUWIKIURL@, apmeklējiet
+@SUBSCRIBE@
+un atsakieties no lapas vai nodaļas izmaiņu paziņojumiem .
+
+--
+Šo vēstuli izveidoja DokuWiki no
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/lv/subscr_form.txt b/inc/lang/lv/subscr_form.txt
new file mode 100644
index 000000000..9e3145f8e
--- /dev/null
+++ b/inc/lang/lv/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Abonementu pārvaldnieks ======
+
+Te varat mainīt savu lapas vai nodaļas abonementu. \ No newline at end of file
diff --git a/inc/lang/lv/subscr_list.txt b/inc/lang/lv/subscr_list.txt
new file mode 100644
index 000000000..986b3786a
--- /dev/null
+++ b/inc/lang/lv/subscr_list.txt
@@ -0,0 +1,16 @@
+Labdien!
+
+@TITLE@ viki nodaļā @PAGE@ ir mainījušās šadas lapas:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Lai atceltu izmaiņu paziņošanu, ielogojieties
+@DOKUWIKIURL@, apmeklējiet
+@SUBSCRIBE@
+un atsakieties no lapas vai nodaļas izmaiņu paziņojumiem .
+
+--
+Šo vēstuli izveidoja DokuWiki no
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/lv/subscr_single.txt b/inc/lang/lv/subscr_single.txt
new file mode 100644
index 000000000..ca6177809
--- /dev/null
+++ b/inc/lang/lv/subscr_single.txt
@@ -0,0 +1,23 @@
+Labdien!
+
+@TITLE@ viki nodaļā @PAGE@ ir mainījušās šadas lapas:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Datums : @DATE@
+Lietotājs : @USER@
+Izmaiņu anotācija: @SUMMARY@
+Vecā versija: @OLDPAGE@
+Jaunā versija: @NEWPAGE@
+
+
+Lai atceltu izmaiņu paziņošanu, ielogojieties
+@DOKUWIKIURL@, apmeklējiet
+@SUBSCRIBE@
+un atsakieties no lapas vai nodaļas izmaiņu paziņojumiem .
+
+--
+Šo vēstuli izveidoja DokuWiki no
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/lv/updateprofile.txt b/inc/lang/lv/updateprofile.txt
new file mode 100644
index 000000000..12fbd8de4
--- /dev/null
+++ b/inc/lang/lv/updateprofile.txt
@@ -0,0 +1,8 @@
+====== Atjaunot sava konta datus ======
+
+Jāaizpilda tikai tie lauki, kuru saturu vēlies mainīt. Nav iespējams mainīt savu lietotājvārdu.
+
+
+
+
+
diff --git a/inc/lang/lv/uploadmail.txt b/inc/lang/lv/uploadmail.txt
new file mode 100644
index 000000000..5975d5bd0
--- /dev/null
+++ b/inc/lang/lv/uploadmail.txt
@@ -0,0 +1,14 @@
+Fails augšupielādēts DokuWiki. Sīkākas ziņas:
+
+Fails : @MEDIA@
+Datums : @DATE@
+Pārlūks : @BROWSER@
+IP adrese : @IPADDRESS@
+Datora vārds : @HOSTNAME@
+Izmērs : @SIZE@
+MIME tips : @MIME@
+Lietotājs : @USER@
+
+--
+Vēstuli nosūtījusi DokuWiki programma no
+@DOKUWIKIURL@ datora. \ No newline at end of file
diff --git a/inc/lang/mg/admin.txt b/inc/lang/mg/admin.txt
new file mode 100644
index 000000000..2c4fc3f6c
--- /dev/null
+++ b/inc/lang/mg/admin.txt
@@ -0,0 +1,4 @@
+====== Administration ======
+
+Hitanao eo ambany lisitry ny asa fanaovana admin misy amin'ny DokuWiki.
+
diff --git a/inc/lang/mg/backlinks.txt b/inc/lang/mg/backlinks.txt
new file mode 100644
index 000000000..c625e6504
--- /dev/null
+++ b/inc/lang/mg/backlinks.txt
@@ -0,0 +1,5 @@
+====== Verindrohy ======
+
+Lisitr'ireo pejy misy rohy manondro amin'ity pejy ity.
+
+
diff --git a/inc/lang/mg/conflict.txt b/inc/lang/mg/conflict.txt
new file mode 100644
index 000000000..96b369e39
--- /dev/null
+++ b/inc/lang/mg/conflict.txt
@@ -0,0 +1,6 @@
+====== A newer version exists ======
+
+Efa misy kinova vaovao ny tahirin-kevitra novainao. Rehefa misy olona hafa nanova koa nandritra anao nanova no mitranga ny toy izao.
+
+Jereo ny tsy fitoviany miseho etsy ambany ireo, avy eo safidio izay kinova tianao hotazonina. Raha misafidy ny bokotra ''Raketo'' ianao, dia ny nataonao no horaketina. Ny bokotra ''Aoka ihany'' tsindriana raha hitazonana izay kinova misy ao.
+
diff --git a/inc/lang/mg/denied.txt b/inc/lang/mg/denied.txt
new file mode 100644
index 000000000..edf20f1a1
--- /dev/null
+++ b/inc/lang/mg/denied.txt
@@ -0,0 +1,4 @@
+====== Tsy tafiditra ======
+
+Miala tsiny fa tsy manana alalana hanohizana mankany ianao. Angamba hadinonao ny niditra.
+
diff --git a/inc/lang/mg/diff.txt b/inc/lang/mg/diff.txt
new file mode 100644
index 000000000..8d7d69b45
--- /dev/null
+++ b/inc/lang/mg/diff.txt
@@ -0,0 +1,4 @@
+====== Tsy fitoviana ======
+
+Ireto ny maha-samihafa ny kinova nosafidiana sy ny kinovan'ny pejy amin'izao.
+
diff --git a/inc/lang/mg/edit.txt b/inc/lang/mg/edit.txt
new file mode 100644
index 000000000..2cde9deb1
--- /dev/null
+++ b/inc/lang/mg/edit.txt
@@ -0,0 +1,2 @@
+Rehefa avy manova ny pejy dia tsindrio ny bokotra ''Raketo''. Jereo ny [[wiki:syntax]] misy ny fomba fanoratana. Raha misy zavatra tianao handramana dia ianaro ao amin'ny [[wiki:playground]].
+
diff --git a/inc/lang/mg/editrev.txt b/inc/lang/mg/editrev.txt
new file mode 100644
index 000000000..a6ff5ba32
--- /dev/null
+++ b/inc/lang/mg/editrev.txt
@@ -0,0 +1,2 @@
+**Kinovan'ny pejy taloha no nosokafanao!** Raha raketinao io, dia hanamboatra kinova vaovao miaraka amin'io ianao.
+---- \ No newline at end of file
diff --git a/inc/lang/mg/index.txt b/inc/lang/mg/index.txt
new file mode 100644
index 000000000..614fd6434
--- /dev/null
+++ b/inc/lang/mg/index.txt
@@ -0,0 +1,4 @@
+====== Index ======
+
+Ity misy index mahasarona ireo pejy misy milahatra arakaraka ny [[doku>namespaces|namespaces]].
+
diff --git a/inc/lang/mg/lang.php b/inc/lang/mg/lang.php
new file mode 100644
index 000000000..4142f00d0
--- /dev/null
+++ b/inc/lang/mg/lang.php
@@ -0,0 +1,135 @@
+<?php
+/**
+ * mg language file
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+
+$lang['btn_edit'] = 'Hanova ny pejy';
+$lang['btn_source'] = 'Asehoy ny source';
+$lang['btn_show'] = 'Asehoy ny pejy';
+$lang['btn_create'] = 'Amboary ity pejy';
+$lang['btn_search'] = 'Hikaroka';
+$lang['btn_save'] = 'Raketo';
+$lang['btn_preview']= 'Topi-maso';
+$lang['btn_top'] = 'Ho ery ambony';
+$lang['btn_newer'] = '<< taloha kokoa';
+$lang['btn_older'] = 'taoriana kokoa >>';
+$lang['btn_revs'] = 'Kinova taloha';
+$lang['btn_recent'] = 'Fiovana farany';
+$lang['btn_upload'] = 'Alefaso';
+$lang['btn_cancel'] = 'Aoka ihany';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit']= 'Edit';
+$lang['btn_login'] = 'Hiditra';
+$lang['btn_logout'] = 'Hivoaka';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Update';
+$lang['btn_delete'] = 'Fafao';
+$lang['btn_back'] = 'Miverina';
+$lang['btn_backtomedia'] = 'Fitsongana fichier Media';
+$lang['btn_register'] = 'Hisoratra';
+
+$lang['loggedinas'] = 'Anaranao:';
+$lang['user'] = 'Anarana';
+$lang['pass'] = 'Alahidy';
+$lang['passchk'] = 'Ataovy indray';
+$lang['remember'] = 'Tsarovy';
+$lang['fullname'] = 'Anarana feno';
+$lang['email'] = 'Imailaka';
+$lang['badlogin'] = 'Miala tsiny fa misy diso ny anarana na ny alahidy.';
+
+$lang['regmissing'] = 'Tsy maintsy fenoina ny saha rehetra.';
+$lang['reguexists'] = 'Indrisy fa efa nisy namandrika io anarana io.';
+$lang['regsuccess'] = 'Voaforona ny kaontinao, halefa any imailaka ny alahidy.';
+$lang['regsuccess2']= 'Voaforona ilay kaonty.';
+$lang['regmailfail']= 'Ohatra ny nisy olana ny nandefasana imailaka. Miangavy anao hilaza ny Admin!';
+$lang['regbadmail'] = 'Toa tsy mandeha ny imailaka nomenao - Raha heverinao fa erreur io dia ilazao ny admin';
+$lang['regbadpass'] = 'Tsy mitovy ny alahidy roa nomenao, avereno indray.';
+$lang['regpwmail'] = 'Ny alahidy Wiki-nao';
+$lang['reghere'] = 'Mbola tsy manana kaonty ianao? Manaova vaovao';
+
+$lang['txt_upload'] = 'Misafidiana rakitra halefa';
+$lang['txt_filename'] = 'Ampidiro ny anaran\'ny wiki (tsy voatery)';
+$lang['txt_overwrt'] = 'Fafana izay rakitra efa misy?';
+$lang['lockedby'] = 'Mbola voahidin\'i';
+$lang['lockexpire'] = 'Afaka ny hidy amin\'ny';
+$lang['js']['willexpire'] = 'Efa ho lany fotoana afaka iray minitra ny hidy ahafahanao manova ny pejy.\nMba hialana amin\'ny conflit dia ampiasao ny bokotra topi-maso hamerenana ny timer-n\'ny hidy.';
+
+$lang['js']['notsavedyet'] = "Misy fiovana tsy voarakitra, ho very izany ireo.\nAzo antoka fa hotohizana?";
+$lang['rssfailed'] = 'An error occured while fetching this feed: ';
+$lang['nothingfound']= 'Tsy nahitana n\'inon\'inona.';
+
+$lang['mediaselect'] = 'Safidy rakitra Media';
+$lang['fileupload'] = 'Fandefasana rakitra Media';
+$lang['uploadsucc'] = 'Voalefa soa aman-tsara';
+$lang['uploadfail'] = 'Tsy lasa ilay izy. Mety tsy fananana alalana?';
+$lang['uploadwrong'] = 'Nolavina ny lefa. Voarara io extension-na rakitra io!';
+$lang['uploadexist'] = 'Efa misy ilay rakitra. Tsy nisy inona natao.';
+$lang['deletesucc'] = 'Voafafa ny rakitra "%s" .';
+$lang['deletefail'] = 'Tsy afaka nofafana ny "%s" - Hamarino ny alalana.';
+$lang['mediainuse'] = 'Tsy voafafa ny rakitra "%s" - mbola misy mampiasa io.';
+$lang['namespaces'] = 'Namespaces';
+$lang['mediafiles'] = 'Rakitra misy amin\'ny';
+
+$lang['reference'] = 'References for';
+$lang['ref_inuse'] = 'Tsy afaka fafana io rakitra io, satria mbola ampiasain\'ireto pejy ireto:';
+$lang['ref_hidden'] = 'Misy references vitsivitsy amina pejy tsy anananao alalana hamaky';
+
+$lang['hits'] = 'Hits';
+$lang['quickhits'] = 'Anaram-pejy mifanaraka';
+$lang['toc'] = 'Fizahan-takila';
+$lang['current'] = 'current';
+$lang['yours'] = 'Kinova-nao';
+$lang['diff'] = 'Asehoy ny tsy fitoviana amin\'ny kinova amin\'izao';
+$lang['line'] = 'Andalana';
+$lang['breadcrumb'] = 'Taiza ianao';
+$lang['lastmod'] = 'Novaina farany:';
+$lang['by'] = '/';
+$lang['deleted'] = 'voafafa';
+$lang['created'] = 'Voamboatra';
+$lang['restored'] = 'Naverina tamin\'ny kinova taloha';
+$lang['summary'] = 'Fanovana teo';
+
+$lang['mail_newpage'] = 'pejy niampy:';
+$lang['mail_changed'] = 'pejy niova:';
+
+$lang['js']['nosmblinks'] = "rohy mankamin\'ny fizarana Windows dia amin\'ny Microsoft Internet Explorer ihany no miasa.\nAzo atao ihany anefa ny manao dika-petaka ny rohy.";
+
+$lang['qb_bold'] = 'Matavy';
+$lang['qb_italic'] = 'Mandry';
+$lang['qb_underl'] = 'Voatsipika';
+$lang['qb_code'] = 'Code programa';
+$lang['qb_strike'] = 'Disoina';
+$lang['qb_h1'] = 'Lohateny laharana 1';
+$lang['qb_h2'] = 'Lohateny laharana 2';
+$lang['qb_h3'] = 'Lohateny laharana 3';
+$lang['qb_h4'] = 'Lohateny laharana 4';
+$lang['qb_h5'] = 'Lohateny laharana 5';
+$lang['qb_link'] = 'Rohy ato anatiny';
+$lang['qb_extlink'] = 'Rohy mivoaka';
+$lang['qb_hr'] = 'Tsipika marindrano';
+$lang['qb_ol'] = 'Tanisa milahatra';
+$lang['qb_ul'] = 'Tanisa tsy milahatra';
+$lang['qb_media'] = 'Hanampy sary na rakitra hafa';
+$lang['qb_sig'] = 'Manisy sonia';
+
+$lang['js']['del_confirm']= 'Hofafana ilay andalana?';
+
+$lang['admin_acl'] = 'Fitantanana ACL (Access Control List)...';
+$lang['admin_register']= 'Ampio mpampiasa vaovao...';
+
+$lang['acl_group'] = 'Vondrona';
+$lang['acl_user'] = 'Mpampiasa';
+$lang['acl_perms'] = 'Alalana @';
+$lang['page'] = 'Pejy';
+$lang['namespace'] = 'Namespace';
+
+$lang['acl_perm1'] = 'Mamaky';
+$lang['acl_perm2'] = 'Manova';
+$lang['acl_perm4'] = 'Manamboatra';
+$lang['acl_perm8'] = 'Mandefa rakitra';
+$lang['acl_perm16'] = 'Mamafa';
+$lang['acl_new'] = 'Ampio andalana vaovao';
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/lang/mg/locked.txt b/inc/lang/mg/locked.txt
new file mode 100644
index 000000000..5705659a3
--- /dev/null
+++ b/inc/lang/mg/locked.txt
@@ -0,0 +1,4 @@
+====== Pejy voahidy ======
+
+Mbola ovain'olona hafa ity pejy ity ka voahidy aloha. Andraso kely ho vitany ny azy, na ho lany fotoana ilay hidy.
+
diff --git a/inc/lang/mg/login.txt b/inc/lang/mg/login.txt
new file mode 100644
index 000000000..1ea3facb0
--- /dev/null
+++ b/inc/lang/mg/login.txt
@@ -0,0 +1,4 @@
+====== Login ======
+
+Mbola tsy niditra ianao izao! Ampidiro eto ambany ny anarana sy ny alahidy. Ilaina manaiky cookies ny navigateur-nao raha hiditra.
+
diff --git a/inc/lang/mg/mailtext.txt b/inc/lang/mg/mailtext.txt
new file mode 100644
index 000000000..ca919345a
--- /dev/null
+++ b/inc/lang/mg/mailtext.txt
@@ -0,0 +1,17 @@
+Nisy pejy niova tao amin'ny wiky. Ireto ny antsipiriany:
+
+Date : @DATE@
+Browser : @BROWSER@
+Adiresy IP : @IPADDRESS@
+Hostname : @HOSTNAME@
+Taloha : @OLDPAGE@
+Vaovao : @NEWPAGE@
+Fiovana : @SUMMARY@
+Novain'i : @USER@
+
+@DIFF@
+
+
+--
+Ity imailaka ity dia navoakan'ny wiki tao amin'ny
+@DOKUWIKIURL@
diff --git a/inc/lang/mg/newpage.txt b/inc/lang/mg/newpage.txt
new file mode 100644
index 000000000..a998caf28
--- /dev/null
+++ b/inc/lang/mg/newpage.txt
@@ -0,0 +1,3 @@
+====== Mbola tsy misy an'io pejy io ======
+
+Nanindry rohy manondro pejy mbola tsy misy ianao. Afaka amboarinao io pejy io, tsindrio ny bokotra ''Amboary ity pejy''
diff --git a/inc/lang/mg/norev.txt b/inc/lang/mg/norev.txt
new file mode 100644
index 000000000..71ecb9ba4
--- /dev/null
+++ b/inc/lang/mg/norev.txt
@@ -0,0 +1,4 @@
+====== Tsy misy io kinova io ======
+
+Tsy misy ny kinova voalaza. Ampiasao ny bokotra ''Kinova taloha'' hampisehoana ireo karazana fanovana natao tamin'ity pejy ity.
+
diff --git a/inc/lang/mg/password.txt b/inc/lang/mg/password.txt
new file mode 100644
index 000000000..000bd91c3
--- /dev/null
+++ b/inc/lang/mg/password.txt
@@ -0,0 +1,11 @@
+Miarahaba an'i @FULLNAME@!
+
+Ireto ny momba anao ho an'ny @TITLE@ ao amin'ny @DOKUWIKIURL@
+
+Anarana : @LOGIN@
+Alahidy : @PASSWORD@
+
+--
+Ity imailaka ity dia navoakan'ny wiki tao amin'ny
+@DOKUWIKIURL@
+
diff --git a/inc/lang/mg/preview.txt b/inc/lang/mg/preview.txt
new file mode 100644
index 000000000..52019cd73
--- /dev/null
+++ b/inc/lang/mg/preview.txt
@@ -0,0 +1,5 @@
+====== Topi-maso ======
+
+Topi-maso ahafahanao mijery ny fivoakan'ny soratra nataonao ity. Tandremo: Mbola **tsy voarakitra** io!
+
+
diff --git a/inc/lang/mg/read.txt b/inc/lang/mg/read.txt
new file mode 100644
index 000000000..0fe51f4a2
--- /dev/null
+++ b/inc/lang/mg/read.txt
@@ -0,0 +1,3 @@
+Vakiana fotsiny ity pejy ity. Afaka jerenao ny source, saingy tsy afaka ovainao. Anontanio ny admin raha heverinao fa tsy mety izany.
+
+
diff --git a/inc/lang/mg/recent.txt b/inc/lang/mg/recent.txt
new file mode 100644
index 000000000..4bc8245a7
--- /dev/null
+++ b/inc/lang/mg/recent.txt
@@ -0,0 +1,5 @@
+====== Fiovana farany ======
+
+Ireto pejy ireto no niova vao haingana.
+
+
diff --git a/inc/lang/mg/register.txt b/inc/lang/mg/register.txt
new file mode 100644
index 000000000..618c1f97e
--- /dev/null
+++ b/inc/lang/mg/register.txt
@@ -0,0 +1,5 @@
+====== Hanokatra kaonty vaovao ======
+
+Fenoy ny saha rehetra eto ambany raha hanokatra kaonty amin'ity wiki ity. Hamarino fa adiresy imailaka mandeha no omenao - halefa any mantsy ny alahidy. Ny anarana dia tsy maintsy manaraka ny fepetran'ny [[doku>pagename|pagename]].
+
+
diff --git a/inc/lang/mg/revisions.txt b/inc/lang/mg/revisions.txt
new file mode 100644
index 000000000..72704587a
--- /dev/null
+++ b/inc/lang/mg/revisions.txt
@@ -0,0 +1,5 @@
+====== Kinova taloha ======
+
+Ireto ny kinovan'ny pejy taloha. Raha te hamerina kinova taloha ianao, tsongay eo ambany izy hisokatra, avy eo tsindrio ny bokotra ''Hanova ny pejy'' ary ''Soraty''.
+
+
diff --git a/inc/lang/mg/searchpage.txt b/inc/lang/mg/searchpage.txt
new file mode 100644
index 000000000..68c6271df
--- /dev/null
+++ b/inc/lang/mg/searchpage.txt
@@ -0,0 +1,7 @@
+====== Karoka ======
+
+Ireto ambany ireto ny valin'ny fikarohanao.
+
+Raha tsy nahita izay notadiavinao ianao, dia afaka mamorona pejy vaovao avy amin'ny teny nanaovanao fikarohana; Ampiasao ny bokotra ''Hanova ny pejy''.
+
+===== Vokatry ny fikarohana ===== \ No newline at end of file
diff --git a/inc/lang/mg/showrev.txt b/inc/lang/mg/showrev.txt
new file mode 100644
index 000000000..92690f4dd
--- /dev/null
+++ b/inc/lang/mg/showrev.txt
@@ -0,0 +1,2 @@
+**Ity dia kinovan'ny pejy taloha!**
+----
diff --git a/inc/lang/mk/adminplugins.txt b/inc/lang/mk/adminplugins.txt
new file mode 100644
index 000000000..28e2cc1d3
--- /dev/null
+++ b/inc/lang/mk/adminplugins.txt
@@ -0,0 +1 @@
+===== Додатни приклучоци ===== \ No newline at end of file
diff --git a/inc/lang/mk/lang.php b/inc/lang/mk/lang.php
new file mode 100644
index 000000000..6614444d0
--- /dev/null
+++ b/inc/lang/mk/lang.php
@@ -0,0 +1,232 @@
+<?php
+/**
+ * mk language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesMk.php?view=co
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Уреди ја страницата';
+$lang['btn_source'] = 'Прикажи ја изворната страница';
+$lang['btn_show'] = 'Прикажи страница';
+$lang['btn_create'] = 'Креирај ја оваа страница';
+$lang['btn_search'] = 'Барај';
+$lang['btn_save'] = 'Зачувај';
+$lang['btn_preview'] = 'Преглед';
+$lang['btn_top'] = 'Назад до врв';
+$lang['btn_newer'] = '<< понови';
+$lang['btn_older'] = 'постари >>';
+$lang['btn_revs'] = 'Стари ревизии';
+$lang['btn_recent'] = 'Скорешни промени';
+$lang['btn_upload'] = 'Крени';
+$lang['btn_cancel'] = 'Откажи';
+$lang['btn_index'] = 'Индекс';
+$lang['btn_secedit'] = 'Уреди';
+$lang['btn_login'] = 'Најава';
+$lang['btn_logout'] = 'Одјава';
+$lang['btn_admin'] = 'Админ';
+$lang['btn_update'] = 'Ажурирај';
+$lang['btn_delete'] = 'Избриши';
+$lang['btn_back'] = 'Назад';
+$lang['btn_backlink'] = 'Повратни врски';
+$lang['btn_backtomedia'] = 'Назад до изборот за медиа-датотека';
+$lang['btn_subscribe'] = 'Менаџирај претплати';
+$lang['btn_profile'] = 'Ажурирај профил';
+$lang['btn_reset'] = 'Ресет';
+$lang['btn_resendpwd'] = 'Испрати нов пасворд';
+$lang['btn_draft'] = 'Уреди скица';
+$lang['btn_recover'] = 'Поврати скица';
+$lang['btn_draftdel'] = 'Избриши скица';
+$lang['btn_revert'] = 'Обнови';
+$lang['btn_register'] = 'Регистрирај се';
+$lang['loggedinas'] = 'Најавен/а како';
+$lang['user'] = 'Корисничко име';
+$lang['pass'] = 'Лозинка';
+$lang['newpass'] = 'Нова лозинка';
+$lang['oldpass'] = 'Потврдете ја сегашната лозинка';
+$lang['passchk'] = 'уште еднаш';
+$lang['remember'] = 'Запомни ме';
+$lang['fullname'] = 'Вистинско име';
+$lang['email'] = 'Е-пошта';
+$lang['profile'] = 'Кориснички профил';
+$lang['badlogin'] = 'Жалам, корисничкото име или лозинката се погрешни.';
+$lang['minoredit'] = 'Мали измени';
+$lang['draftdate'] = 'Скицата е само-снимена на';
+$lang['nosecedit'] = 'Во меѓувреме страницата беше променета, информацискиот дел е со истечен период затоа се вчита целата страница.';
+$lang['regmissing'] = 'Жалам, мора да ги пополнеш сите полиња.';
+$lang['reguexists'] = 'Жалам, корисник со ова корисничко име веќе постои.';
+$lang['regsuccess'] = 'Корисникот е креиран и лозинката е испратена по е-пошта.';
+$lang['regsuccess2'] = 'Корисникот е креиран.';
+$lang['regmailfail'] = 'Изгледа дека се појави грешка при испраќањето на е-пошта со лозинката. Ве молам контактирајте го администраторот!';
+$lang['regbadmail'] = 'Дадената адреса за е-пошта изгледа невалидна - ако мислите дека ова е грешка, контактирајте го администраторот';
+$lang['regbadpass'] = 'Двете наведени лозинки не се исти, ве молам пробајте повторно.';
+$lang['regpwmail'] = 'Вашата DokuWiki лозинка';
+$lang['reghere'] = 'Се уште немаш сметка? Направи веќе една';
+$lang['profna'] = 'Ова вики не поддржува измена на профилот';
+$lang['profnochange'] = 'Нема промени, ништо за правење.';
+$lang['profnoempty'] = 'Празно име или адреса за е-пошта не е дозволено.';
+$lang['profchanged'] = 'Корисничкиот профил е успешно ажуриран.';
+$lang['pwdforget'] = 'Ја заборавивте лозинката? Добијте нова';
+$lang['resendna'] = 'Ова вики не поддржува повторно испраќање на лозинка.';
+$lang['resendpwd'] = 'Испрати нова лозинка за';
+$lang['resendpwdmissing'] = 'Жалам, морате да ги пополните сите полиња.';
+$lang['resendpwdnouser'] = 'Жалам, таков корисник не постои во нашата база со податоци.';
+$lang['resendpwdbadauth'] = 'Жалам, овај код за валидација не е валиден. Проверете повторно дали ја искористивте целосната врска за потврда.';
+$lang['resendpwdconfirm'] = 'Врска за потврда е испратена по е-пошта.';
+$lang['resendpwdsuccess'] = 'Вашата нова лозинка е испратена по е-пошта.';
+$lang['license'] = 'Освен каде што е наведено поинаку, содржината на ова вики е лиценцирано по следнава лиценца:';
+$lang['licenseok'] = 'Забелешка: со уредување на оваа страница се согласувате да ја лиценцирате вашата содржина под следнава лиценца:';
+$lang['searchmedia'] = 'Барај име на датотека:';
+$lang['searchmedia_in'] = 'Барај во %s';
+$lang['txt_upload'] = 'Избери датотека за качување';
+$lang['txt_filename'] = 'Качи како (неморално)';
+$lang['txt_overwrt'] = 'Пребриши ја веќе постоечката датотека';
+$lang['lockedby'] = 'Моментално заклучена од';
+$lang['lockexpire'] = 'Клучот истекува на';
+$lang['js']['willexpire'] = 'Вашиот клуч за уредување на оваа страница ќе истече за една минута.\nЗа да избегнете конфликти и да го ресетирате бројачот за време, искористете го копчето за преглед.';
+$lang['js']['notsavedyet'] = "Незачуваните промени ќе бидат изгубени.\nСакате да продолжите?";
+$lang['rssfailed'] = 'Се појави грешка при повлекувањето на овој канал:';
+$lang['nothingfound'] = 'Ништо не е пронајдено.';
+$lang['mediaselect'] = 'Медиа датотеки';
+$lang['fileupload'] = 'Качување на медиа датотеки';
+$lang['uploadsucc'] = 'Качувањето е успешно';
+$lang['uploadfail'] = 'Качувањето не е успешно. Можеби има погрешни пермисии?';
+$lang['uploadwrong'] = 'Качувањето е одбиено. Наставката на датотеката е забранета!';
+$lang['uploadexist'] = 'Датотеката веќе постои. Ништо не е направено.';
+$lang['uploadbadcontent'] = 'Качената содржина не се совпаѓа со наставката %s на датотеката.';
+$lang['uploadspam'] = 'Качувањето беше блокирано од црната листа за спам.';
+$lang['uploadxss'] = 'Качувањето беше блокирано за можна злонамерна содржина.';
+$lang['uploadsize'] = 'Датотеката за качување е премногу голема. (макс. %s)';
+$lang['deletesucc'] = 'Датотеката „%s“ е избришана.';
+$lang['deletefail'] = '„%s“ не може да се избрише - проверете пермисии.';
+$lang['mediainuse'] = 'Датотеката „%s“ не е избришана - се уште е во употреба.';
+$lang['mediafiles'] = 'Достапни датотеки во';
+$lang['js']['searchmedia'] = 'Барај датотеки';
+$lang['js']['keepopen'] = 'Задржи го прозорецот отворен на означеното место';
+$lang['js']['hidedetails'] = 'Скриј детали';
+$lang['js']['nosmblinks'] = 'Поврзувањето со Windows Shares работи само со Microsoft Internet Explorer. Сепак можете да ја копирате и вметнете врската.';
+$lang['js']['linkwiz'] = 'Волшебник за врски';
+$lang['js']['linkto'] = 'Врска до:';
+$lang['js']['del_confirm'] = 'Дали навистина да ги избришам избраните датотеки?';
+$lang['mediausage'] = 'Користете ја следнава синтакса за референцирање кон оваа датотека:';
+$lang['mediaview'] = 'Види ја оригиналната датотека';
+$lang['mediaroot'] = 'root';
+$lang['mediaextchange'] = 'Наставката на датотеката е сменета од .%s во .%s!';
+$lang['reference'] = 'Референци за';
+$lang['ref_inuse'] = 'Датотеката не може да биде избришана бидејќи се уште се користи од следниве страници:';
+$lang['ref_hidden'] = 'Некои референци се на страници на кои немате пермисии за читање';
+$lang['hits'] = 'Прегледи';
+$lang['quickhits'] = 'Совпаѓачки имиња на страници';
+$lang['toc'] = 'Содржина';
+$lang['current'] = 'сегашно';
+$lang['yours'] = 'Вашата верзија';
+$lang['diff'] = 'Прикажи разлики со сегашната верзија';
+$lang['diff2'] = 'Прикажи разлики помеѓу избраните ревизии';
+$lang['line'] = 'Линија';
+$lang['breadcrumb'] = 'Следи';
+$lang['youarehere'] = 'Вие сте тука';
+$lang['lastmod'] = 'Последно изменета';
+$lang['by'] = 'од';
+$lang['deleted'] = 'отстранета';
+$lang['created'] = 'креирана';
+$lang['restored'] = 'обновена е стара ревизија';
+$lang['external_edit'] = 'надворешно уредување';
+$lang['summary'] = 'Уреди го изводот';
+$lang['noflash'] = '<a href="http://www.adobe.com/products/flashplayer/">Adobe Flash приклучокот</a> е потребен за да се прикаже оваа содржина.';
+$lang['download'] = 'Симни Snippe';
+$lang['mail_newpage'] = 'додадена е страницата:';
+$lang['mail_changed'] = 'променета е страницата:';
+$lang['mail_new_user'] = 'нов корисник:';
+$lang['mail_upload'] = 'качена е датотеката:';
+$lang['qb_bold'] = 'Задебелен текст';
+$lang['qb_italic'] = 'Накосен текст';
+$lang['qb_underl'] = 'Подвлечен текст';
+$lang['qb_code'] = 'Текст за код';
+$lang['qb_strike'] = 'Прецртан текст';
+$lang['qb_h1'] = 'Заглавие од 1-во ниво';
+$lang['qb_h2'] = 'Заглавие од 2-ро ниво';
+$lang['qb_h3'] = 'Заглавие од 3-то ниво';
+$lang['qb_h4'] = 'Заглавие од 4-то ниво';
+$lang['qb_h5'] = 'Заглавие од 5-то ниво';
+$lang['qb_h'] = 'Заглавие';
+$lang['qb_hs'] = 'Избери заглавие';
+$lang['qb_hplus'] = 'Зголеми заглавие';
+$lang['qb_hminus'] = 'Намали заглавие';
+$lang['qb_hequal'] = 'Заглавие од исто ниво';
+$lang['qb_link'] = 'Внатрешна врска';
+$lang['qb_extlink'] = 'Надворешна врска';
+$lang['qb_hr'] = 'Хоризонтален линијар';
+$lang['qb_media'] = 'Додај слики и други датотеки';
+$lang['qb_sig'] = 'Внеси потпис';
+$lang['qb_smileys'] = 'Смајлиња';
+$lang['qb_chars'] = 'Специјални знаци';
+$lang['admin_register'] = 'Додај нов корисник';
+$lang['metaedit'] = 'Уреди мета-податоци';
+$lang['metasaveerr'] = 'Запишување на мета-податоците не успеа';
+$lang['metasaveok'] = 'Мета-податоците се зачувани';
+$lang['img_backto'] = 'Назад до';
+$lang['img_title'] = 'Насловна линија';
+$lang['img_caption'] = 'Наслов';
+$lang['img_date'] = 'Датум';
+$lang['img_fname'] = 'Име на датотека';
+$lang['img_fsize'] = 'Големина';
+$lang['img_artist'] = 'Фотограф';
+$lang['img_copyr'] = 'Авторско право';
+$lang['img_format'] = 'Формат';
+$lang['img_camera'] = 'Камера';
+$lang['img_keywords'] = 'Клучни зборови';
+$lang['subscr_subscribe_success'] = 'Додаден/а е %s во претплатничката листа за %s';
+$lang['subscr_subscribe_error'] = 'Грешка при додавањето на %s во претплатничката листа за %s';
+$lang['subscr_subscribe_noaddress'] = 'Нема адреса за е-пошта поврзана со Вашата најава, не може да бидете додадени на претплатничката листа';
+$lang['subscr_unsubscribe_success'] = 'Отстранет/а е %s од претплатничката листа за %s';
+$lang['subscr_unsubscribe_error'] = 'Грешка при отстранувањето на %s од претплатничката листа за %s';
+$lang['subscr_already_subscribed'] = '%s е веќе претплатен/а на %s';
+$lang['subscr_not_subscribed'] = '%s е не претплатен/а на %s';
+$lang['subscr_m_not_subscribed'] = 'Моментално не сте пријавени на сегашната страница или ';
+$lang['subscr_m_new_header'] = 'Додај претплата';
+$lang['subscr_m_current_header'] = 'Моментални претплати';
+$lang['subscr_m_unsubscribe'] = 'Отплатување';
+$lang['subscr_m_subscribe'] = 'Претплата';
+$lang['subscr_m_receive'] = 'Прими';
+$lang['subscr_style_every'] = 'е-пошта за секоја промена';
+$lang['subscr_style_digest'] = 'е-пошта со преглед од промените за секоја страница';
+$lang['subscr_style_list'] = 'листа на променети страници од последната е-пошта';
+$lang['authmodfailed'] = 'Лоша конфигурација за автентикација на корисник. Ве молам информирајте го вики администратор.';
+$lang['authtempfail'] = 'Автентикација на корисник е привремено недостапна. Ако оваа ситуација истрајува, ве молам известете го вики администратор.';
+$lang['i_chooselang'] = 'Избере јазик';
+$lang['i_installer'] = 'Инсталер за DokuWiki';
+$lang['i_wikiname'] = 'вики име';
+$lang['i_enableacl'] = 'Овозможи ACL (препорачано)';
+$lang['i_superuser'] = 'Супер корисник';
+$lang['i_problems'] = 'Инсталерот пронајде неколку проблеми кои се прикажани подолу. Не можете да продолжите понатаму се додека не ги поправите.';
+$lang['i_modified'] = 'За безбедносни причини оваа скрипта ќе работи само со нова и неизменета инсталација од DokuWiki. Или извадете ги повторно датотеките од симнатиот пакет или консултирајте се со комплетните <a href="http://dokuwiki.org/install">Dokuwiki инструкции за инсталација</a>';
+$lang['i_funcna'] = 'PHP функцијата <code>%s</code> не е достапна. Можеби вашиот хостинг провајдер ја оневозможил со причина?';
+$lang['i_phpver'] = 'Вашата верзија на PHP <code>%s</code> е пониска од потребната <code>%s</code>. Треба да ја надградите вашата PHP инсталација.';
+$lang['i_permfail'] = '<code>%s</code> не е запишлива од DokuWiki. Треба да ги поправите подесувањата за пермисии на овој директориум!';
+$lang['i_confexists'] = '<code>%s</code> веќе постои';
+$lang['i_writeerr'] = 'Не може да се креира <code>%s</code>. Треба да ги проверите пермисиите на директориумот/датотеката и рачно да ја креирате датотеката.';
+$lang['i_badhash'] = 'непозната или изменете dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - нелегална или празна вредност';
+$lang['i_success'] = 'Конфигурацијата успешно заврши. Сега можете да ја избришете датотеката install.php. Продолжете до <a href="doku.php">вашето ново DokuWiki</a>.';
+$lang['i_failure'] = 'Се појавија некои грешки при запишувањето на конфигурациските датотеки. Можеби треба да ги поравите рачно пред да можете да го користите <a href="doku.php">вашето ново DokuWiki</a>.';
+$lang['i_policy'] = 'Почетна ACL политика';
+$lang['i_pol0'] = 'Отвори вики (читај, запиши, качи за сите)';
+$lang['i_pol1'] = 'Јавно вики (читај за сите, запиши и качи за регистрирани корисници)';
+$lang['i_pol2'] = 'Затворено вики (читај, запиши, качи само за регистрирани корисници)';
+$lang['i_retry'] = 'Пробај повторно';
+$lang['years'] = 'пред %d години';
+$lang['months'] = 'пред %d месеци';
+$lang['weeks'] = 'пред %d недели';
+$lang['days'] = 'пред %d денови';
+$lang['hours'] = 'пред %d часа';
+$lang['minutes'] = 'пред %d минути';
+$lang['seconds'] = 'пред %d секунди';
diff --git a/inc/lang/mk/read.txt b/inc/lang/mk/read.txt
new file mode 100644
index 000000000..8c8726eea
--- /dev/null
+++ b/inc/lang/mk/read.txt
@@ -0,0 +1 @@
+Оваа страница е само за читање. Можете да го гледате изворот, но не можете да ја менувате. Ако мислите дека ова е погрешно, контактирајте го администраторот. \ No newline at end of file
diff --git a/inc/lang/mk/recent.txt b/inc/lang/mk/recent.txt
new file mode 100644
index 000000000..cfbba4aa2
--- /dev/null
+++ b/inc/lang/mk/recent.txt
@@ -0,0 +1,3 @@
+====== Скорешни промени ======
+
+Следниве страници беа скорешно променети. \ No newline at end of file
diff --git a/inc/lang/mk/showrev.txt b/inc/lang/mk/showrev.txt
new file mode 100644
index 000000000..a0ca7353e
--- /dev/null
+++ b/inc/lang/mk/showrev.txt
@@ -0,0 +1,2 @@
+**Ова е стара ревизија од документото!**
+---- \ No newline at end of file
diff --git a/inc/lang/mr/admin.txt b/inc/lang/mr/admin.txt
new file mode 100644
index 000000000..6f54384f2
--- /dev/null
+++ b/inc/lang/mr/admin.txt
@@ -0,0 +1,3 @@
+====== व्यवस्थापन ======
+
+खाली तुम्हाला डॉक्युविकि मधे उपलब्ध असलेल्या व्यवस्थापनाच्या क्रियांची सूची दिली आहे. \ No newline at end of file
diff --git a/inc/lang/mr/backlinks.txt b/inc/lang/mr/backlinks.txt
new file mode 100644
index 000000000..997fa68e0
--- /dev/null
+++ b/inc/lang/mr/backlinks.txt
@@ -0,0 +1,3 @@
+====== प्रतिलिंक ======
+
+ही त्या सर्व प्रृष्ठांची सूची आहे जी या पृष्ठाला परत लिंक करतात. \ No newline at end of file
diff --git a/inc/lang/mr/conflict.txt b/inc/lang/mr/conflict.txt
new file mode 100644
index 000000000..2b1bb6423
--- /dev/null
+++ b/inc/lang/mr/conflict.txt
@@ -0,0 +1,5 @@
+====== नवीन आवृत्ती उपलब्ध आहे ======
+
+तुम्ही संपादित केलेल्या दस्तावेजाची नवीन आवृत्ती उपलब्ध आहे. तुम्ही संपादित करत असलेल्या दस्तावेजामधे त्याच वेळी इतर यूजरने बदल केल्यास असे घडते.
+
+खाली दर्शाविलेले फरक नीट तपासा आणि त्यापैकी कुठले ठेवायचे ते ठरवा. जर तुम्ही 'सुरक्षित' केलं तर तुमचे बदल सुरक्षित होतील. सध्याची आवृत्ति ठेवण्यासाठी 'कॅन्सल' वर क्लिक करा. \ No newline at end of file
diff --git a/inc/lang/mr/denied.txt b/inc/lang/mr/denied.txt
new file mode 100644
index 000000000..1b499f51d
--- /dev/null
+++ b/inc/lang/mr/denied.txt
@@ -0,0 +1,3 @@
+====== परवानगी नाकारली ======
+
+क्षमा करा, पण तुम्हाला यापुढे जाण्याचे हक्क नाहीत. कदाचित तुम्ही लॉगिन करायला विसरला आहात ? \ No newline at end of file
diff --git a/inc/lang/mr/diff.txt b/inc/lang/mr/diff.txt
new file mode 100644
index 000000000..f0a845056
--- /dev/null
+++ b/inc/lang/mr/diff.txt
@@ -0,0 +1,3 @@
+====== फरक ======
+
+या पानावर तुम्हाला निवडलेली आवृत्ती व सध्याच्या आवृत्ती मधले फरक दाखवले आहेत. \ No newline at end of file
diff --git a/inc/lang/mr/draft.txt b/inc/lang/mr/draft.txt
new file mode 100644
index 000000000..aa74475d7
--- /dev/null
+++ b/inc/lang/mr/draft.txt
@@ -0,0 +1,5 @@
+====== मसुद्याची फाइल मिळाली ======
+
+तुमचा मागचा संपादानाचा सेशन नीट पूर्ण झाला नव्हता. डॉक्युविकिने तुमच्या कामाचा मसुदा आपोआप सुरक्षित केला होता , जो वापरून तुमची संपादन परत चालू करू शकता. खाली तुमच्या मागच्या सेशन मधला सुरक्षित केलेला डेटा दाखवला आहे.
+
+कृपया आता हे ठरवा की तुमच्या संपादन सेशनचे //पुनर्स्थापन// करायचे, सुरक्षित केलेला मसुदा //रद्द// करायचा का संपादनच //कॅन्सल// करायचं. \ No newline at end of file
diff --git a/inc/lang/mr/edit.txt b/inc/lang/mr/edit.txt
new file mode 100644
index 000000000..6c6347e70
--- /dev/null
+++ b/inc/lang/mr/edit.txt
@@ -0,0 +1 @@
+पान संपादित करा आणि 'सुरक्षित' वर क्लिक करा. विकी सिन्टॅक्स साठी [[wiki:syntax]] पहा.कृपया तुम्ही जर एखादे पान **सुधारित** करू शकत असाल तरच ते संपादित करा. अन्यथा जर तुम्हाला फ़क्त काही गोष्टी ट्राय करून बघायच्या असतील तर [[playground:playground|प्लेग्राऊण्ड]] मधे आपले धडे गिरवा! \ No newline at end of file
diff --git a/inc/lang/mr/editrev.txt b/inc/lang/mr/editrev.txt
new file mode 100644
index 000000000..d58c8abd0
--- /dev/null
+++ b/inc/lang/mr/editrev.txt
@@ -0,0 +1,2 @@
+**तुमची या पानाची जुनी आवृत्ती लोड केलि आहे!** जर तुमची ती सुरक्षित केली तर तुमची त्याची एक नवीन आवृत्ती तयार कराल.
+---- \ No newline at end of file
diff --git a/inc/lang/mr/index.txt b/inc/lang/mr/index.txt
new file mode 100644
index 000000000..489b20435
--- /dev/null
+++ b/inc/lang/mr/index.txt
@@ -0,0 +1,3 @@
+====== सूची ======
+
+ही सर्व उपलब्ध पानांची [[doku>namespaces|नेमस्पेस]] अनुसार तयार केलेली सूची आहे. \ No newline at end of file
diff --git a/inc/lang/mr/install.html b/inc/lang/mr/install.html
new file mode 100644
index 000000000..ddbf8245b
--- /dev/null
+++ b/inc/lang/mr/install.html
@@ -0,0 +1,10 @@
+<p>हे पान <a href="http://dokuwiki.org">डॉक्युविकि</a> च्या पहिल्या इन्स्टॉलेशन आणि कॉन्फिगरेशन साठी मदत करतं. या इंस्टॉलर विषयी जास्ती माहिती त्याच्या
+<a href="http://dokuwiki.org/installer">माहितीसंग्रह पानावर</a> उपलब्ध आहे.</p>
+
+<p> डॉक्युविकि विकी पाने व सम्बंधित माहिती ( उदा. फोटो , शोध सूची, जुन्या आवृत्ती ई.) साठवण्यासाठी सामान्य फाइलचा उपयोग करतं. डॉक्युविकिने नीट काम करण्यासाठी डॉक्युविकिला या फाइल जिथे साठवल्या आहेत त्या डिरेक्टरीमधे लेखनाचे हक्क ( write access ) असणे <strong>अत्यावश्यक</strong> आहे. या इंस्टॉलरला डिरेक्टरीचे हक्क सेट करता येत नाहीत. ते थेट तुमच्या शेल मधून सेट करावे लागतात, किंवा तुम्ही व्यावसायिक होस्टिंग वापरत असाल तर FTP वापरून अथवा तुमच्या होस्टिंग कंट्रोल पॅनल ( उदा. cPanel वगैरे ) मधून सेट करावे लागतात.</p>
+
+<p>हा इंस्टॉलर तुमच्या डॉक्युविकिचे <acronym title="access control list">ACL</acronym> कॉन्फिगरेशन ठरवेल, ज्याद्वारे तुम्हाला व्यवस्थापकीय लॉगिन, डॉक्युविकिच्या व्यवस्थापन मेनू मधे प्लगिनचे इन्स्टॉलेशन, सदस्यांची व्यवस्था, विकी पानांवरील हक्क, कॉन्फिगरेशन बदलणे ई. साठी प्रवेशाचे हक्क वगैरे बदल करता येतील. ही व्यवस्था डॉक्युविकि वापरण्यासाठी आवश्यक नाही पण वापरल्यास डॉक्युविकिचे व्यवस्थापन अधिक सुरळित होइल.</p>
+
+<p>अनुभवी सदस्य किंवा ज्याना काही ख़ास गरजा असतील त्यानी खालील लिंक्स वापराव्यात :
+<a href="http://dokuwiki.org/install">इन्स्टॉलेशनविषयी सूचना</a>
+and <a href="http://dokuwiki.org/config">कॉन्फिगरेशनची सेटिंग</a></p> \ No newline at end of file
diff --git a/inc/lang/mr/lang.php b/inc/lang/mr/lang.php
new file mode 100644
index 000000000..314a319cd
--- /dev/null
+++ b/inc/lang/mr/lang.php
@@ -0,0 +1,212 @@
+<?php
+/**
+ * mr language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesMr.php?view=co
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '`';
+$lang['singlequoteclosing'] = '\'';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'हे पृष्ठ संपादित करा';
+$lang['btn_source'] = 'पानाचा स्त्रोत दाखवा ';
+$lang['btn_show'] = 'पान दाखवा';
+$lang['btn_create'] = 'हे पृष्ठ लीहा';
+$lang['btn_search'] = 'शोधा';
+$lang['btn_save'] = 'सुरक्षित';
+$lang['btn_preview'] = 'झलक';
+$lang['btn_top'] = 'परत वर';
+$lang['btn_newer'] = 'जास्त अलीकडचे';
+$lang['btn_older'] = 'कमी अलीकडचे';
+$lang['btn_revs'] = 'जून्या आव्रुत्ती';
+$lang['btn_recent'] = 'अलीकडील बदल';
+$lang['btn_upload'] = 'अपलोड';
+$lang['btn_cancel'] = 'रद्द करा';
+$lang['btn_index'] = 'सूचि';
+$lang['btn_secedit'] = 'संपादन';
+$lang['btn_login'] = 'प्रवेश करा';
+$lang['btn_logout'] = 'बाहेर पडा';
+$lang['btn_admin'] = 'अधिकारी';
+$lang['btn_update'] = 'अद्ययावत';
+$lang['btn_delete'] = 'नष्ट';
+$lang['btn_back'] = 'मागॆ';
+$lang['btn_backlink'] = 'येथे काय जोडले आहे';
+$lang['btn_backtomedia'] = 'परत माध्यम फाइल निवडीकड़े';
+$lang['btn_subscribe'] = 'पृष्ठाच्या बदलांची पुरवणी (फीड) लावा ';
+$lang['btn_unsubscribe'] = 'पृष्ठाच्या बदलांची पुरवणी (फीड) बंद करा';
+$lang['btn_profile'] = 'प्रोफाइल अद्ययावत करा';
+$lang['btn_reset'] = 'रिसेट';
+$lang['btn_resendpwd'] = 'कृपया परवलीचा नवीन शब्द माझ्या इमेल पत्त्यावर पाठविणे.';
+$lang['btn_draft'] = 'प्रत संपादन';
+$lang['btn_recover'] = 'प्रत परत मिळवा';
+$lang['btn_draftdel'] = 'प्रत रद्द';
+$lang['btn_register'] = 'नोंदणी';
+$lang['loggedinas'] = 'लॉगिन नाव';
+$lang['user'] = 'वापरकर्ता';
+$lang['pass'] = 'परवलीचा शब्द';
+$lang['newpass'] = 'नवीन परवलीचा शब्द';
+$lang['oldpass'] = 'सध्याचा परवलीचा शब्द नक्की करा';
+$lang['passchk'] = 'परत एकदा';
+$lang['remember'] = 'लक्षात ठेवा';
+$lang['fullname'] = 'पूर्ण नावं';
+$lang['email'] = 'इमेल';
+$lang['profile'] = 'वापरकर्त्याची माहिती';
+$lang['badlogin'] = 'माफ़ करा, वापरकर्ता नावात किंवा परवलीच्या शब्दात चूक झाली आहे.';
+$lang['minoredit'] = 'छोटे बदल';
+$lang['draftdate'] = 'प्रत आपोआप सुरक्षित केल्याची तारीख';
+$lang['nosecedit'] = 'मध्यंतरीच्या काळात हे पृष्ठ बदलले आहे.विभागाची माहिती जुनी झाली होती. त्याऐवजी सबंध पृष्ठ परत लोड केले आहे.';
+$lang['regmissing'] = 'कृपया सर्व रकाने भरा.';
+$lang['reguexists'] = 'या नावाने सदस्याची नोंदणी झालेली आहे, कृपया दुसरे सदस्य नाव निवडा.';
+$lang['regsuccess'] = 'सदस्याची नोंदणी झाली आहे आणि परवलीचा शब्द इमेल केला आहे.';
+$lang['regsuccess2'] = 'सदस्याची नोंदणी झाली.';
+$lang['regmailfail'] = 'परवलीचा शब्दाची इमेल पाठवण्यात चूक झाली आहे, क्रुपया संचालकांशी संपर्क साधा.';
+$lang['regbadmail'] = 'तुम्ही दिलेला ईमेल बरोबर नाही असे दिसते - तुमच्या मते ही चूक असल्यास साईटच्या व्यवस्थापकाशी संपर्क साधा.';
+$lang['regbadpass'] = 'आपला परवलीचा शब्द चुकीचा आहे.';
+$lang['regpwmail'] = 'तुमचा डोक्युविकि परवली.';
+$lang['reghere'] = 'अजुन तुमचे खाते नाही ? एक उघडून टाका.';
+$lang['profna'] = 'ह्या विकी मधे प्रोफाइल बदलण्याची सुविधा नाही.';
+$lang['profnochange'] = 'काही बदल नाहित. करण्यासारखे काही नाही.';
+$lang['profnoempty'] = 'रिकामे नाव किंवा ईमेल चालत नाही.';
+$lang['profchanged'] = 'सदस्याची प्रोफाइल अद्ययावत झाली आहे.';
+$lang['pwdforget'] = 'परवलीचा शब्द विसरला आहे का? नविन मागवा.';
+$lang['resendna'] = 'ह्या विकी मधे परवलीचा शब्द परत पाथाव्न्याची सुविधा नाही.';
+$lang['resendpwd'] = 'नविन परवली इच्छुक';
+$lang['resendpwdmissing'] = 'कृपया सर्व रकाने भरा.';
+$lang['resendpwdnouser'] = 'माफ़ करा, हा सदस्य आमच्या माहितिसंग्रहात सापडला नाही.';
+$lang['resendpwdbadauth'] = 'माफ़ करा, हा अधिकार कोड बरोबर नाही. कृपया आपण पूर्ण शिकामोर्तबाची लिंक वापरल्याची खात्री करा.';
+$lang['resendpwdconfirm'] = 'शिक्कामोर्तबाची लिंक ईमेल द्वारा पाठवली आहे.';
+$lang['resendpwdsuccess'] = 'शिक्कामोर्तबाची लिंक ईमेल द्वारा पाठवली आहे.';
+$lang['license'] = 'विशिष्ठ नोंद केलि नसल्यास ह्या विकी वरील सर्व मजकूर खालील लायसन्स मधे मोडतो : ';
+$lang['licenseok'] = 'नोंद : हे पृष्ठ संपादित केल्यास तुम्ही तुमचे योगदान खालील लायसन्स अंतर्गत येइल : ';
+$lang['txt_upload'] = 'अपलोड करण्याची फाइल निवडा';
+$lang['txt_filename'] = 'अपलोड उर्फ़ ( वैकल्पिक )';
+$lang['txt_overwrt'] = 'अस्तित्वात असलेल्या फाइलवरच सुरक्षित करा.';
+$lang['lockedby'] = 'सध्या लॉक करणारा :';
+$lang['lockexpire'] = 'सध्या लॉक करणारा :';
+$lang['js']['willexpire'] = 'हे पृष्ठ संपादित करण्यासाठी मिळालेले लॉक एखाद्या मिनिटात संपणार आहे.\n चुका होऊ नयेत म्हणुन कृपया प्रीव्यू बटन दाबुन लॉक ची वेळ पुन्हा चालू करा.';
+$lang['js']['notsavedyet'] = "सुरक्षित न केलेले बदल नष्ट होतील. नक्की करू का ?";
+$lang['rssfailed'] = 'ही पुरवणी आणण्यात काही चूक झाली:';
+$lang['nothingfound'] = 'काही सापडला नाही.';
+$lang['mediaselect'] = 'दृकश्राव्य फाइल';
+$lang['fileupload'] = 'दृकश्राव्य फाइल अपलोड';
+$lang['uploadsucc'] = 'अपलोड यशस्वी';
+$lang['uploadfail'] = 'अपलोड अयशस्वी.कदाचित चुकीच्या परवानग्या असतील ?';
+$lang['uploadwrong'] = 'अपलोड नाकारण्यात आला. हे फाइल एक्सटेंशन अवैध आहे!';
+$lang['uploadexist'] = 'फाइल आधीच अस्तित्वात आहे. काही केले नाही.';
+$lang['uploadbadcontent'] = 'अपलोड केलेली माहिती %s फाइल एक्सटेंशनशी मिळतिजुळति नाही.';
+$lang['uploadspam'] = 'अपलोड स्पॅम ब्लॅकलिस्टमुळे थोपवला आहे.';
+$lang['uploadxss'] = 'अपलोड संशयित हानिकारक मजकूर असल्याने थोपवला आहे.';
+$lang['uploadsize'] = 'अपलोड केलेली फाइल जास्तीच मोठी होती. (जास्तीत जास्त %s)';
+$lang['deletesucc'] = '%s ही फाइल नष्ट करण्यात आलेली आहे.';
+$lang['deletefail'] = '%s ही फाइल नष्ट करू शकलो नाही - कृपया परवानग्या तपासा.';
+$lang['mediainuse'] = '%s ही फाइल नष्ट केली नाही - ती अजुन वापरात आहे.';
+$lang['namespaces'] = 'नेमस्पेस';
+$lang['mediafiles'] = 'मध्ये उपलब्ध असलेल्या फाइल';
+$lang['js']['keepopen'] = 'निवड केल्यावर विण्डो उघडी ठेवा';
+$lang['js']['hidedetails'] = 'सविस्तर मजकूर लपवा';
+$lang['js']['nosmblinks'] = 'विन्डोज़ शेअर ला लिंक केल्यास ते फक्त मायक्रोसॉफ़्ट इन्टरनेट एक्स्प्लोरर वरच चालते. तरी तुम्ही लिंक कॉपी करू शकता.';
+$lang['mediausage'] = 'ह्या फाइलचा संदर्भ देण्यासाठी खालील सिन्टॅक्स वापरा :';
+$lang['mediaview'] = 'मूळ फाइल बघू ';
+$lang['mediaroot'] = 'रूट';
+$lang['mediaupload'] = 'सध्याच्या नेमस्पेसमधे इथेच फाइल अपलोड करा. उप-नेमस्पेस बनवण्यासाठि त्याचे नाव तुमच्या "अपलोड उर्फ़" मधे दिलेल्या फाइल नावाच्या आधी विसर्गचिन्हाने वेगळे करून ते वापरा.';
+$lang['mediaextchange'] = 'फाइलचे एक्सटेंशन .%s चे बदलून .%s केले आहे.';
+$lang['reference'] = 'च्या साठी संदर्भ';
+$lang['ref_inuse'] = 'फाइल नष्ट केली जाऊ शकत नाही. ती अजुन खालील पृष्ठे वापरत आहेत :';
+$lang['ref_hidden'] = 'काही संदर्भ तुम्हाला वाचण्याची परवानगी नसलेल्या पृष्ठावर आहेत';
+$lang['hits'] = 'हिट्स';
+$lang['quickhits'] = 'जुळणारि पाने';
+$lang['toc'] = 'अनुक्रमणिका';
+$lang['current'] = 'चालू';
+$lang['yours'] = 'तुमची आवृत्ति';
+$lang['diff'] = 'सध्याच्या आवृत्तिंशी फरक दाखवा';
+$lang['diff2'] = 'निवडलेल्या आवृत्तिंमधील फरक दाखवा';
+$lang['line'] = 'ओळ';
+$lang['breadcrumb'] = 'मागमूस';
+$lang['youarehere'] = 'तुम्ही इथे आहात';
+$lang['lastmod'] = 'सर्वात शेवटचा बदल';
+$lang['by'] = 'द्वारा';
+$lang['deleted'] = 'काढून टाकले';
+$lang['created'] = 'निर्माण केले';
+$lang['restored'] = 'जुनी आवृत्ति पुनर्स्थापित केली';
+$lang['external_edit'] = 'बाहेरून संपादित';
+$lang['summary'] = 'सारांश बदला';
+$lang['noflash'] = 'ही माहिती दाखवण्यासाठी <a href="http://www.adobe.com/products/flashplayer/">अडोब फ्लॅश प्लेअर</a> ची गरज आहे.';
+$lang['mail_newpage'] = 'पृष्ठ जोडले : ';
+$lang['mail_changed'] = 'पृष्ठ बदलले : ';
+$lang['mail_new_user'] = 'नवीन सदस्य : ';
+$lang['mail_upload'] = 'फाइल अपलोड केली : ';
+$lang['qb_bold'] = 'ठळक मजकूर';
+$lang['qb_italic'] = 'तिरका मजकूर';
+$lang['qb_underl'] = 'अधोरेखित मजकूर';
+$lang['qb_code'] = 'कोड मजकूर';
+$lang['qb_strike'] = 'रद्द मजकूर';
+$lang['qb_h1'] = 'पहिल्या पातळीचे शीर्षक';
+$lang['qb_h2'] = 'दुसर्या पातळीचे शीर्षक';
+$lang['qb_h3'] = 'तिसर्या पातळीचे शीर्षक';
+$lang['qb_h4'] = 'चवथ्या पातळीचे शीर्षक';
+$lang['qb_h5'] = 'पाचव्या पातळीचे शीर्षक';
+$lang['qb_link'] = 'अंतर्गत लिंक';
+$lang['qb_extlink'] = 'बाह्य लिंक';
+$lang['qb_hr'] = 'आडवी पट्टी';
+$lang['qb_ol'] = 'अनुक्रमित यादीतील वस्तु';
+$lang['qb_ul'] = 'साध्या यादीतील वस्तु';
+$lang['qb_media'] = 'प्रतिमा आणि इतर फाइल टाका';
+$lang['qb_sig'] = 'स्वाक्षरी टाका';
+$lang['qb_smileys'] = 'स्माइली';
+$lang['qb_chars'] = 'ख़ास चिन्ह';
+$lang['js']['del_confirm'] = 'निवडलेल्या गोष्टी नक्की नष्ट करू का ?';
+$lang['admin_register'] = 'नवीन सदस्य';
+$lang['metaedit'] = 'मेटाडेटा बदला';
+$lang['metasaveerr'] = 'मेटाडेटा सुरक्षित झाला नाही';
+$lang['metasaveok'] = 'मेटाडेटा सुरक्षित झाला';
+$lang['img_backto'] = 'परत जा';
+$lang['img_title'] = 'नाव';
+$lang['img_caption'] = 'टीप';
+$lang['img_date'] = 'तारीख';
+$lang['img_fname'] = 'फाइल नाव';
+$lang['img_fsize'] = 'साइझ';
+$lang['img_artist'] = 'फोटोग्राफर';
+$lang['img_copyr'] = 'कॉपीराइट';
+$lang['img_format'] = 'प्रकार';
+$lang['img_camera'] = 'कॅमेरा';
+$lang['img_keywords'] = 'मुख्य शब्द';
+$lang['subscribe_success'] = '%s ला %s च्या पुरवणिसाठि नोंदवले';
+$lang['subscribe_error'] = '%s ला %s च्या पुरवणिसाठि नोंदवताना चूक झाली';
+$lang['subscribe_noaddress'] = 'तुमच्या लॉगिनशी सम्बंधित कुठलाही पत्ता नाही , त्यामुळे पुरवणिसाठि नोंद केली जाऊ शकत नाही';
+$lang['unsubscribe_success'] = '%s ला %s च्या पुरवणी यादी मधून काढून टाकले';
+$lang['unsubscribe_error'] = '%s ला %s च्या पुरवणी यादी मधून काढून टाकण्यात चूक झाली';
+$lang['authmodfailed'] = 'सदस्य अधिकृत करण्याची व्यवस्था चुकीची आहे. कृपया तुमच्या विकीच्या व्यवस्थापकाशी सम्पर्क साधा.';
+$lang['authtempfail'] = 'सदस्य अधिकृत करण्याची सुविधा सध्या चालू नाही. सतत हा मजकूर दिसल्यास कृपया तुमच्या विकीच्या व्यवस्थापकाशी सम्पर्क साधा.';
+$lang['i_chooselang'] = 'तुमची भाषा निवडा';
+$lang['i_installer'] = 'डॉक्युविकि इनस्टॉलर';
+$lang['i_wikiname'] = 'विकी नाम';
+$lang['i_enableacl'] = 'ACL चालू करा ( अधिक चांगले )';
+$lang['i_superuser'] = 'सुपर-सदस्य';
+$lang['i_problems'] = 'इनस्टॉलरला काही अडचणि आल्या आहेत. त्या ठीक केल्याशिवाय तुम्ही पुढे जाऊ शकत नाही.';
+$lang['i_modified'] = 'सुरक्षिततेच्या कारणासठि ही स्क्रिप्ट फ़क्त नवीन आणि बदललेल्या डॉक्युविकि इन्स्टॉलेशन मधेच चालेल. तुम्ही एकतर डाउनलोड केलेले पॅकेज मधील फाइल परत प्रसारित करा किंवा <a href="http://dokuwiki.org/install">डॉक्युविकि इन्स्टॉलेशन विषयी सूचना</a> वाचा.';
+$lang['i_funcna'] = 'PHP मधलं <code>%s</code> हे फंक्शन उपलब्ध नाही. बहुधा तुमच्या होस्टिंग पुरवणाराने ते काही कारणाने अनुपलब्ध केलं असावं.';
+$lang['i_phpver'] = 'तुमची PHP आवृत्ति <code>%s</code> ही आवश्यक असलेल्या <code>%s</code> ह्या आवृत्तिपेक्षा कमी आहे. कृपया तुमचे PHP इन्स्टॉलेशन अद्ययावत करा.';
+$lang['i_permfail'] = '<code>%s</code> या डिरेक्टरी मध्ये डॉक्युविकि बदल करू शकत नाही. कृपया या डिरेक्टरीच्या परवानग्या ठीक करा.';
+$lang['i_confexists'] = '<code>%s</code> आधीच अस्तित्वात आहे.';
+$lang['i_writeerr'] = '<code>%s</code> निर्माण करू शकलो नाही. तुम्हाला डिरेक्टरी / फाइल च्या परवानग्या तपासून स्वतःच ही फाइल बनवावी लागेल.';
+$lang['i_badhash'] = 'अनाकलनीय किंवा बदललेले dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = 'code>%s</code> - अवैध किंवा रिकामा मजकूर.';
+$lang['i_success'] = 'व्यवस्था लावण्याचे काम यशस्वीरीत्या पार पडले. आता तुम्ही install.php डिलीट करू शकता. <a href="doku.php">तुमच्या नविन डॉक्युविकि </a> वर जा.';
+$lang['i_failure'] = 'कॉन्फिगुरेशनच्या फाइल सुरक्षित करताना काही अडचणी आल्या आहेत. <a href="doku.php">तुमची नवीन डॉक्युविकि </a> वापरण्याआधी तुम्हाला ह्या फाइल स्वतः ठीक कराव्या लागतील.';
+$lang['i_policy'] = 'आरंभीची ACL पॉलिसी';
+$lang['i_pol0'] = 'मुक्त विकी ( सर्वांना वाचन, लेखन व अपलोड करण्याची परवानगी )';
+$lang['i_pol1'] = 'सार्वजनिक विकी ( सर्वांना वाचण्याची मुभा , लेखन व अपलोडची परवानगी फक्त नोंदणीकृत सदस्यांना )';
+$lang['i_pol2'] = 'बंदिस्त विकी ( वाचन , लेखन व अपलोडची परवानगी फक्त नोंदणीकृत सदस्यांना ) ';
+$lang['i_retry'] = 'पुन्हा प्रयत्न';
+$lang['recent_global'] = 'तुम्ही सध्या <b>%s</b> या नेमस्पेस मधील बदल पाहात आहात.तुम्ही <a href="%s">पूर्ण विकी मधले बदल </a> सुद्धा पाहू शकता.';
diff --git a/inc/lang/mr/locked.txt b/inc/lang/mr/locked.txt
new file mode 100644
index 000000000..dae909c40
--- /dev/null
+++ b/inc/lang/mr/locked.txt
@@ -0,0 +1,3 @@
+====== पान लॉक आहे ======
+
+हे पान सध्या दुसर्या सदस्याने संपादनासाठी लॉक केले आहे. तुम्हाला त्याचे संपादन करून होईपर्यंत किंवा लॉक संपेपर्यंत थांबावे लागेल. \ No newline at end of file
diff --git a/inc/lang/mr/login.txt b/inc/lang/mr/login.txt
new file mode 100644
index 000000000..f2fef4c45
--- /dev/null
+++ b/inc/lang/mr/login.txt
@@ -0,0 +1,3 @@
+====== लॉगिन ======
+
+तुम्ही सध्या लॉगिन केलेले नाही! तुमचे नाव-पासवर्ड देऊन खाली लॉगिन करा. लॉगिन करण्यासाठी तुमच्या ब्राउजरमधे कुकीज चालू असल्या पाहिजेत. \ No newline at end of file
diff --git a/inc/lang/mr/mailtext.txt b/inc/lang/mr/mailtext.txt
new file mode 100644
index 000000000..18fa23846
--- /dev/null
+++ b/inc/lang/mr/mailtext.txt
@@ -0,0 +1,15 @@
+तुमच्या डॉक्युविकिमधील एक पान बदलले किंवा नवीन टाकले गेले आहे. त्याची माहिती पुढील प्रमाणे :
+
+दिनांक : @DATE@
+ब्राउजर : @BROWSER@
+IP-पत्ता : @IPADDRESS@
+मशिनचे नाव ( Host name ) : @HOSTNAME@
+जुनी आवृत्ती : @OLDPAGE@
+नवी आवृत्ती : @NEWPAGE@
+संपादन सारांश : @SUMMARY@
+सदस्य : @USER@
+
+@DIFF@
+
+--
+हा ईमेल @DOKUWIKIURL@ येथील डॉक्युविकिद्वारा आपोआप तयार केला गेला आहे. \ No newline at end of file
diff --git a/inc/lang/mr/newpage.txt b/inc/lang/mr/newpage.txt
new file mode 100644
index 000000000..00a1c6b60
--- /dev/null
+++ b/inc/lang/mr/newpage.txt
@@ -0,0 +1,3 @@
+====== हा मुद्दा अजून अस्तित्त्वात नाही ======
+
+तुमची अशा एखाद्या मुद्द्याच्या लिंक वरून इथे आला आहात जो अजून अस्तित्त्वात नाही. जर तुम्हाला परवानगी असेल तर तुमची त्या मुद्द्यावर "हे पान नवीन तयार करा" हे बटण क्लिक करून स्वतः एक पान तयार करू शकता. \ No newline at end of file
diff --git a/inc/lang/mr/norev.txt b/inc/lang/mr/norev.txt
new file mode 100644
index 000000000..180b031fe
--- /dev/null
+++ b/inc/lang/mr/norev.txt
@@ -0,0 +1,3 @@
+====== अशी कुठली आवृत्ती नाही ======
+
+ही आवृत्ती अस्तित्त्वात नाही. "जुन्या आवृत्त्या" बटण वापरून या दस्तावेजाच्या सर्व जुन्या आवृत्त्या तुमची पाहू शकता. \ No newline at end of file
diff --git a/inc/lang/mr/password.txt b/inc/lang/mr/password.txt
new file mode 100644
index 000000000..090c01dfd
--- /dev/null
+++ b/inc/lang/mr/password.txt
@@ -0,0 +1,9 @@
+नमस्कार @FULLNAME@!
+
+खाली तुमच्या @DOKUWIKIURL@ येथील @TITLE@ साठी सदस्य माहिती दिली आहे.
+
+लॉगिन : @LOGIN@
+पासवर्ड : @PASSWORD@
+
+--
+हा ईमेल @DOKUWIKIURL@ येथील डॉक्युविकिद्वारा आपोआप तयार केला गेला आहे. \ No newline at end of file
diff --git a/inc/lang/mr/preview.txt b/inc/lang/mr/preview.txt
new file mode 100644
index 000000000..8277398dd
--- /dev/null
+++ b/inc/lang/mr/preview.txt
@@ -0,0 +1,3 @@
+====== झलक ======
+
+ही तुमचा मजकूर कसा दिसेल त्याची एक झलक आहे. लक्षात ठेवा : हा मजकूर अजुन **सुरक्षित केलेला नाही** ! \ No newline at end of file
diff --git a/inc/lang/mr/pwconfirm.txt b/inc/lang/mr/pwconfirm.txt
new file mode 100644
index 000000000..ec0b707a1
--- /dev/null
+++ b/inc/lang/mr/pwconfirm.txt
@@ -0,0 +1,11 @@
+नमस्कार @FULLNAME@!
+
+कोणीतरी तुमच्या @TITLE@ या @DOKUWIKIURL@ येथील लॉगिनसाठी नवीन पासवर्ड मागवला आहे.
+जर तुम्ही हा पासवर्ड मागवला नसेल तर कृपया ह्या ईमेलकड़े दुर्लक्ष करा.
+
+जर नक्की तुम्हीच हा पासवर्ड मागवला असेल तर खालील लिंकवर क्लिक करून ते नक्की करा.
+
+@CONFIRM@
+
+--
+हा ईमेल @DOKUWIKIURL@ येथील डॉक्युविकिद्वारा आपोआप तयार केला गेला आहे. \ No newline at end of file
diff --git a/inc/lang/mr/read.txt b/inc/lang/mr/read.txt
new file mode 100644
index 000000000..b834dd750
--- /dev/null
+++ b/inc/lang/mr/read.txt
@@ -0,0 +1 @@
+हे पान फक्त वाचता येऊ शकतं. तुम्ही त्याचा मूळ विकी मजकूर पाहू शकता पण तो बदलू शकत नाही. जर हे चुकीचं असेल तर तुमच्या विकी व्यवस्थापकाशी संपर्क साधा. \ No newline at end of file
diff --git a/inc/lang/mr/recent.txt b/inc/lang/mr/recent.txt
new file mode 100644
index 000000000..9a6d6f151
--- /dev/null
+++ b/inc/lang/mr/recent.txt
@@ -0,0 +1,3 @@
+====== अलीकडील बदल ======
+
+खालील पाने हल्लीच बदलली आहेत \ No newline at end of file
diff --git a/inc/lang/mr/register.txt b/inc/lang/mr/register.txt
new file mode 100644
index 000000000..3aca31278
--- /dev/null
+++ b/inc/lang/mr/register.txt
@@ -0,0 +1,3 @@
+====== नवीन सदस्य म्हणुन नोंदणी करा ======
+
+खाली तुमची माहिती भरून या विकी वर नवीन खातं उघडा. कृपया आपण देत असलेला ईमेल चालू असल्याची खात्री करा - जर तुम्हाला इथे पासवर्ड टाकायला सांगितला नाही तयार एक नवीन पासवर्ड तुम्हाला त्या ईमेल वर पाठवला जाइल. तुमचं लॉगिन नाम एक वैध [[doku>pagename|पेजनेम]] असले पाहिजे. \ No newline at end of file
diff --git a/inc/lang/mr/registermail.txt b/inc/lang/mr/registermail.txt
new file mode 100644
index 000000000..a6fea4d06
--- /dev/null
+++ b/inc/lang/mr/registermail.txt
@@ -0,0 +1,13 @@
+एक नवीन सदस्याची नोंदणी झाली आहे. त्याची माहीत पुढीलप्रमाणे :
+
+सदस्य नाम : @NEWUSER@
+पूर्ण नाव : @NEWNAME@
+ईमेल : @NEWEMAIL@
+
+दिनांक : @DATE@
+ब्राउजर : @BROWSER@
+IP-पत्ता : @IPADDRESS@
+होस्ट नाम : @HOSTNAME@
+
+--
+हा ईमेल @DOKUWIKIURL@ येथील डॉक्युविकिद्वारा आपोआप तयार केला गेला आहे. \ No newline at end of file
diff --git a/inc/lang/mr/resendpwd.txt b/inc/lang/mr/resendpwd.txt
new file mode 100644
index 000000000..64b95a45f
--- /dev/null
+++ b/inc/lang/mr/resendpwd.txt
@@ -0,0 +1,3 @@
+====== नवीन पासवर्ड पाठव ======
+
+या विकिवरील तुमच्या अकाउंटसाठी नवीन पासवर्ड मिळवण्यासाठी कृपया तुमचे सदस्य नाम खालच्या फॉर्म मधे टाका. ही पासवर्डची मागणी नक्की करण्यासाठी तुम्ही नोंदणी करताना दिलेल्या ईमेल पत्त्यावर एक लिंक पाठवली जाइल. \ No newline at end of file
diff --git a/inc/lang/mr/revisions.txt b/inc/lang/mr/revisions.txt
new file mode 100644
index 000000000..fb842c763
--- /dev/null
+++ b/inc/lang/mr/revisions.txt
@@ -0,0 +1,3 @@
+====== जुन्या आवृत्त्या ======
+
+ह्या सद्य दस्तावेजच्या जुन्या आवृत्त्या आहेत. एखाद्या जुन्या आवृत्तीवर परत जाण्यासाठी टी खालून निवडा, "हे पान संपादित करा" वर क्लिक करा आणि ते सुरक्षित करा. \ No newline at end of file
diff --git a/inc/lang/mr/searchpage.txt b/inc/lang/mr/searchpage.txt
new file mode 100644
index 000000000..23e10b1d3
--- /dev/null
+++ b/inc/lang/mr/searchpage.txt
@@ -0,0 +1,5 @@
+====== शोध ======
+
+तुम्हाला खाली तुमच्या शोधाचे फलित दिसतील. जर तुमची शोधत असलेली गोष्ट तुम्हाला सापडली नाही, तर योग्य बटण वापरून तुम्ही शोधत असलेल्या गोष्टीविषयी तुम्ही एखादे पान निर्माण किंवा संपादित करू शकता.
+
+====== फलित ====== \ No newline at end of file
diff --git a/inc/lang/mr/showrev.txt b/inc/lang/mr/showrev.txt
new file mode 100644
index 000000000..aeaeee500
--- /dev/null
+++ b/inc/lang/mr/showrev.txt
@@ -0,0 +1,2 @@
+** ही ह्या दस्तावेजची जुनी आवृत्ती आहे. **
+-- \ No newline at end of file
diff --git a/inc/lang/mr/stopwords.txt b/inc/lang/mr/stopwords.txt
new file mode 100644
index 000000000..2b413a928
--- /dev/null
+++ b/inc/lang/mr/stopwords.txt
@@ -0,0 +1,39 @@
+# ही अशा शब्दांची यादी आहे जी अनुक्रमक (इंडेक्सर) दुर्लक्षित करतो, जर एक ओळित एक शब्द आला तरच.
+# ही यादी बदलल्यास केवळ यूनिक्स पद्धतीची लाइन एंडिंग वापरा. तीन अक्षरापेक्षा लहान शब्द टाकण्याची
+# गरज नाही - ते आपोआपच दुर्लक्षित केले जातात. ही यादी 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 \ No newline at end of file
diff --git a/inc/lang/mr/updateprofile.txt b/inc/lang/mr/updateprofile.txt
new file mode 100644
index 000000000..c08810f3e
--- /dev/null
+++ b/inc/lang/mr/updateprofile.txt
@@ -0,0 +1,3 @@
+====== तुमची सदस्य माहिती अद्ययावत करा ======
+
+फ़क्त तुम्हाला बदल करायचा असेल तेच रकाने परत भरा. तुमची तुमचे सदस्य नाम बदलू शकत नाही. \ No newline at end of file
diff --git a/inc/lang/mr/uploadmail.txt b/inc/lang/mr/uploadmail.txt
new file mode 100644
index 000000000..66e736598
--- /dev/null
+++ b/inc/lang/mr/uploadmail.txt
@@ -0,0 +1,13 @@
+एक फाइल तुमच्या डॉक्युविकिवर अपलोड केली गेली आहे. त्याची माहिती याप्रमाणे :
+
+फाइल : @MEDIA@
+दिनांक : @DATE@
+ब्राउजर : @BROWSER@
+IP-पत्ता : @IPADDRESS@
+होस्टनाम : @HOSTNAME@
+साइज़ : @SIZE@
+MIME टाइप : @MIME@
+सदस्य : @USER@
+
+--
+हा ईमेल @DOKUWIKIURL@ येथील डॉक्युविकिद्वारा आपोआप तयार केला गेला आहे. \ No newline at end of file
diff --git a/inc/lang/ms/lang.php b/inc/lang/ms/lang.php
new file mode 100644
index 000000000..92dc86b5a
--- /dev/null
+++ b/inc/lang/ms/lang.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * ms language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesMs.php?view=co
+ * @author Markos
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Sunting halaman ini';
+$lang['btn_source'] = 'Lihat sumber';
+$lang['btn_show'] = 'Baca';
+$lang['btn_create'] = 'Cipta halaman';
+$lang['btn_search'] = 'Cari';
+$lang['btn_save'] = 'Simpan';
+$lang['btn_preview'] = 'Pratonton';
+$lang['btn_top'] = 'Balik ke mula';
+$lang['btn_newer'] = '<< lebih kini';
+$lang['btn_older'] = 'lebih awal >>';
+$lang['btn_revs'] = 'Sejarah';
+$lang['btn_recent'] = 'Perubahan Terkini';
+$lang['btn_upload'] = 'Unggah (upload)';
+$lang['btn_cancel'] = 'Batal';
+$lang['btn_secedit'] = 'Sunting';
+$lang['btn_login'] = 'Masuk';
+$lang['btn_logout'] = 'Keluar';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Kemaskini';
+$lang['btn_delete'] = 'Hapus';
+$lang['btn_back'] = 'Balik';
+$lang['btn_backlink'] = 'Pautan ke halaman ini';
+$lang['btn_backtomedia'] = 'Balik ke rangkaian pilihan fail media';
+$lang['btn_subscribe'] = 'Pantau';
+$lang['btn_profile'] = 'Kemaskinikan profil';
+$lang['btn_reset'] = 'Batalkan suntingan';
+$lang['btn_resendpwd'] = 'Emel kata laluan baru';
+$lang['btn_draft'] = 'Sunting draf';
+$lang['btn_recover'] = 'Pulihkan draf';
+$lang['btn_draftdel'] = 'Hapuskan draf';
+$lang['btn_revert'] = 'Pulihkan';
+$lang['btn_register'] = 'Daftaran';
+$lang['btn_apply'] = 'Simpan';
+$lang['btn_media'] = 'Manager media';
+$lang['loggedinas'] = 'Log masuk sebagai';
+$lang['user'] = 'Nama pengguna';
+$lang['pass'] = 'Kata laluan';
+$lang['newpass'] = 'Kata laluan baru';
+$lang['oldpass'] = 'Kata laluan lama';
+$lang['passchk'] = 'sekali lagi';
+$lang['remember'] = 'Sentiasa ingati kata laluan saya.';
+$lang['fullname'] = 'Nama sebenar';
+$lang['email'] = 'E-mel';
+$lang['profile'] = 'Profil pengguna';
+$lang['badlogin'] = 'Maaf, ralat log masuk. Nama pengguna atau kata laluan salah.';
+$lang['minoredit'] = 'Suntingan Kecil';
+$lang['draftdate'] = 'Draf automatik disimpan pada';
+$lang['nosecedit'] = 'Halaman ini telah bertukar pada waktu sementara dan info bahagian ini telah luput. Seluruh halaman telah disarat.';
+$lang['regmissing'] = 'Maaf, semua medan mesti diisi';
+$lang['reguexists'] = 'Maaf, nama pengguna yang dimasukkan telah diguna. Sila pilih nama yang lain.';
+$lang['regsuccess'] = 'Akaun pengguna telah dicipta dan kata laluan telah dikirim kepada e-mel anda.';
+$lang['regsuccess2'] = 'Akaun pegguna telah dicipta.';
+$lang['regbadmail'] = 'Format alamat e-mel tidak sah. Sila masukkan semula ataupun kosongkan sahaja medan tersebut.';
+$lang['regbadpass'] = 'Kedua-dua kata laluan tidak sama. Sila masukkan semula.';
+$lang['regpwmail'] = 'Kata laluan Dokuwiki anda';
+$lang['reghere'] = 'Belum mendaftar akaun? Dapat akaun baru';
+$lang['profna'] = 'Wiki ini tidak menyokong modifikasi profil';
+$lang['profnoempty'] = 'Medan nama pengguna atau e-mel yang kosong tidak dibenarkan.';
+$lang['profchanged'] = 'Profil pengguna telah dikemaskini.';
+$lang['pwdforget'] = 'Terlupa kata laluan? Dapatkan yang baru';
+$lang['resendpwd'] = 'Kirimkan kata laluan baru untuk';
+$lang['resendpwdmissing'] = 'Maaf, semua medan perlu diisi.';
+$lang['resendpwdnouser'] = 'Maaf, nama pengguna ini tidak dapat dicari dalam database kami.';
+$lang['resendpwdbadauth'] = 'Maaf, kod authorasi ini tidak sah. Semak bahawa anda telah menggunakan seluruh pautan pengesahan yang dikirim.';
+$lang['resendpwdconfirm'] = 'Pautan pengesahan telah dikirimkan ke e-mel anda.';
+$lang['resendpwdsuccess'] = 'Kata laluan baru telah dikirimkan ke e-mel anda.';
+$lang['license'] = 'Selain daripada yang dinyata, isi wiki ini disediakan dengan lesen berikut:';
+$lang['licenseok'] = 'Perhatian: Dengan menyunting halaman ini, anda setuju untuk isi-isi anda dilesen menggunakan lesen berikut:';
+$lang['searchmedia'] = 'Cari nama fail:';
+$lang['searchmedia_in'] = 'Cari di %s';
+$lang['txt_upload'] = 'Pilih fail untuk diunggah';
+$lang['txt_filename'] = 'Unggah fail dengan nama (tidak wajib)';
+$lang['txt_overwrt'] = 'Timpa fail sekarang';
+$lang['lockedby'] = 'Halaman ini telah di';
+$lang['fileupload'] = 'Muat naik fail';
+$lang['uploadsucc'] = 'Pemuatan naik berjaya';
+$lang['uploadfail'] = 'Ralat muat naik';
+$lang['uploadxss'] = 'Fail ini mengandungi kod HTML atau kod skrip yang mungkin boleh disalah tafsir oleh pelayar web.';
+$lang['toc'] = 'Jadual Kandungan';
+$lang['current'] = 'kini';
+$lang['restored'] = 'Telah dikembalikan ke semakan sebelumnya';
+$lang['summary'] = 'Paparan';
diff --git a/inc/lang/ne/admin.txt b/inc/lang/ne/admin.txt
new file mode 100644
index 000000000..7a829dbe5
--- /dev/null
+++ b/inc/lang/ne/admin.txt
@@ -0,0 +1,2 @@
+====== व्यवस्थापन ======
+तल तपाईले DokuWikiमा उपलव्ध व्यवस्थापकिय कार्यहरुको सुची पाउन सक्नुहुन्छ । \ No newline at end of file
diff --git a/inc/lang/ne/backlinks.txt b/inc/lang/ne/backlinks.txt
new file mode 100644
index 000000000..51b95731d
--- /dev/null
+++ b/inc/lang/ne/backlinks.txt
@@ -0,0 +1,2 @@
+====== पछाडि लिङ्क ======
+यो पृष्ठहरुको सुचीहरुले पछाडि लिङ्क स्वयंलाई नै गरेको छ। \ No newline at end of file
diff --git a/inc/lang/ne/conflict.txt b/inc/lang/ne/conflict.txt
new file mode 100644
index 000000000..457e108ad
--- /dev/null
+++ b/inc/lang/ne/conflict.txt
@@ -0,0 +1,5 @@
+====== नयाँ संस्करण उपलब्ध छ ======
+
+तपाईले सम्पादन गर्नुभएको पाठको नयाँ सस्करण उपलब्ध छ। तपाईले सम्पादन गरिरहनु भएको समयमा अर्को प्रयोगकर्ताले यो पाठ परिवर्तन गरेकोले यस्तो भएको हो ।
+
+दुबैका फरक दाज्नुहोस् र दुईमा कुन राख्नेहो निश्चित गर्नुहोस् ।तपाईले "वचत गर्नुहोस् " छान्नु भयो भने तपाईको संस्करण वचत हुनेछ। "रद्द गर्नुहोस्" छान्नु भयो भने अहिलेको संस्करण वचत हुनेछ । \ No newline at end of file
diff --git a/inc/lang/ne/denied.txt b/inc/lang/ne/denied.txt
new file mode 100644
index 000000000..ab4bcf290
--- /dev/null
+++ b/inc/lang/ne/denied.txt
@@ -0,0 +1,3 @@
+====== अनुमति अमान्य ======
+
+माफ गर्नुहोला तपाईलाई अगाडि बढ्न अनुमति छैन। सम्भवत: तपाईले प्रवेश गर्न भुल्नु भयो। \ No newline at end of file
diff --git a/inc/lang/ne/diff.txt b/inc/lang/ne/diff.txt
new file mode 100644
index 000000000..76d75fbfb
--- /dev/null
+++ b/inc/lang/ne/diff.txt
@@ -0,0 +1,3 @@
+====== भिन्नताहरु ======
+
+यसले यो पृष्ठको छानिएको संस्करण र हालको संकरण बीच भिन्नताहरु देखाउँछ । \ No newline at end of file
diff --git a/inc/lang/ne/draft.txt b/inc/lang/ne/draft.txt
new file mode 100644
index 000000000..88630c992
--- /dev/null
+++ b/inc/lang/ne/draft.txt
@@ -0,0 +1,5 @@
+====== ड्राफ्ट फाइल भेटियो ======
+
+तपाईको यो पृष्ठको गत सम्पादन सफलतापूर्वक सम्पन्न भएको थिएन ।DokuWiki ले स्वचालितरुपमा ड्राफ्ट वचतगरेको छ त्यस देखि तपाईले आफ्नो सम्पादन कार्यमा निरन्तरता दिन सक्नुहुन्छ। तल तपाईले गत सत्रमा बचत गरिएको सामग्री देख्न सक्नुहुन्छ ।
+
+कृपया निर्णय दिनुहोस् कि तपाई गत सत्रमा बचत गरिएको सत्रको सम्पादनकार्य //recover// , //delete// वा //cancel// के गर्न चाहनुहुन्छ भनेर।
diff --git a/inc/lang/ne/edit.txt b/inc/lang/ne/edit.txt
new file mode 100644
index 000000000..be498a61b
--- /dev/null
+++ b/inc/lang/ne/edit.txt
@@ -0,0 +1 @@
+पृष्ठ सम्पादन गर्नुहोस र "बचत" मा थिच्नुहोस् । सिन्टेक्सको लागि [[wiki:syntax]] हेर्नुहोस् । यो पृष्ठलाई **सुधार्न** सक्नुहुन्छ भने मात्र सम्पादन गर्नुहोस् ।यदि कुनै प्रयोग गर्न या , जान्न चाहनुहुन्छ भने [[playground:playground|playground]] को प्रयोग गर्नुहोस् । \ No newline at end of file
diff --git a/inc/lang/ne/editrev.txt b/inc/lang/ne/editrev.txt
new file mode 100644
index 000000000..0db67c2bb
--- /dev/null
+++ b/inc/lang/ne/editrev.txt
@@ -0,0 +1,2 @@
+** तपाईले यस कागजातको पुरानो संस्करण खोल्नु भएको छ ।** यदि यसलाई वचत गर्नुभयो भने यसैसामग्रीबाट नयाँ संस्करणको निर्माण हुनेछ ।
+---- \ No newline at end of file
diff --git a/inc/lang/ne/index.txt b/inc/lang/ne/index.txt
new file mode 100644
index 000000000..cb06f0307
--- /dev/null
+++ b/inc/lang/ne/index.txt
@@ -0,0 +1,3 @@
+====== सुची ======
+
+यो सबै उपलाब्ध पृष्ठहरुको [[doku>namespaces|namespaces]] का आधारमा मिलाइएको सुची हो । \ No newline at end of file
diff --git a/inc/lang/ne/lang.php b/inc/lang/ne/lang.php
new file mode 100644
index 000000000..21f979753
--- /dev/null
+++ b/inc/lang/ne/lang.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author Saroj Kumar Dhakal <lotusnagarkot@yahoo.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'यो पृष्ठ सम्पादन गर्नुहोस् ';
+$lang['btn_source'] = 'यो पृष्ठको स्रोत देखाउनुहोस् ';
+$lang['btn_show'] = 'पृष्ठ देखाउनुहोस् ';
+$lang['btn_create'] = 'यो पृष्ठ निर्माण गर्नुहोस्';
+$lang['btn_search'] = 'खोज्नुहोस् ';
+$lang['btn_save'] = 'वचत गर्नुहोस्';
+$lang['btn_preview'] = 'पूर्वरुप ';
+$lang['btn_top'] = 'माथि फर्कनुहोस्';
+$lang['btn_newer'] = '<< यो भन्दा पछिको';
+$lang['btn_older'] = 'यो भन्दा पहिलेको >>';
+$lang['btn_revs'] = 'पुरानो संकरण';
+$lang['btn_recent'] = 'हालैका परिवर्तनहरु ';
+$lang['btn_upload'] = 'अपलोड ';
+$lang['btn_cancel'] = 'रद्द गर्नुहोस् ';
+$lang['btn_index'] = 'सुची';
+$lang['btn_secedit'] = 'सम्पादन गर्नुहोस्';
+$lang['btn_login'] = 'प्रवेश गर्नुहोस् ';
+$lang['btn_logout'] = 'बाहिर जानुहोस् ';
+$lang['btn_admin'] = 'एड्मिन(व्यवस्थापक)';
+$lang['btn_update'] = 'अध्यावधिक गर्नुहोस्';
+$lang['btn_delete'] = 'मेटाउनुहोस् ';
+$lang['btn_back'] = 'पछाडि';
+$lang['btn_backlink'] = 'पछाडिका लिङ्कहरु ';
+$lang['btn_backtomedia'] = 'मिडिया छनौटमा फर्कनुहोस्';
+$lang['btn_subscribe'] = 'पृष्ठ परिवर्तन ग्राह्य गर्नुहोस्';
+$lang['btn_unsubscribe'] = 'पृष्ठ परिवर्तन अग्राह्य गर्नुहोस्';
+$lang['btn_profile'] = 'प्रोफाइल अध्यावधिक गर्नुहोस् ';
+$lang['btn_reset'] = 'पूर्वरुपमा फर्काउनुहोस';
+$lang['btn_resendpwd'] = 'नयाँ प्रवेश शव्द(पासवर्ड) पठाउनुहोस् ';
+$lang['btn_draft'] = ' ड्राफ्ट सम्पादन गर्नुहोस् ';
+$lang['btn_recover'] = 'पहिलेको ड्राफ्ट हासिल गर्नुहोस ';
+$lang['btn_draftdel'] = ' ड्राफ्ट मेटाउनुहोस् ';
+$lang['btn_register'] = 'दर्ता गर्नुहोस्';
+$lang['loggedinas'] = 'प्रवेश गर्नुहोस् ';
+$lang['user'] = 'प्रयोगकर्ता ';
+$lang['pass'] = 'प्रवेशशव्द';
+$lang['newpass'] = 'नयाँ प्रवेशशव्द';
+$lang['oldpass'] = 'नयाँ प्रवेशशव्द निश्चित गर्नुहोस ';
+$lang['passchk'] = 'एकपटक पुन:';
+$lang['remember'] = 'मलाई सम्झनु';
+$lang['fullname'] = 'पूरा नाम';
+$lang['email'] = 'इमेल';
+$lang['profile'] = 'प्रयोगकर्ताको प्रोफाइल';
+$lang['badlogin'] = 'माफ गर्नुहोस् , प्रयोगकर्तानाम वा प्रवेशशव्द गलत भयो ';
+$lang['minoredit'] = 'सामान्य परिवर्तन';
+$lang['draftdate'] = 'ड्राफ्ट स्वचालित रुपमा वचत भएको';
+$lang['nosecedit'] = 'यो पृष्ठ यसै बखतमा परिवर्तन भयो, खण्ड जानकारी अध्यावधिक हुन सकेन र पूरै पृष्ठ लोड भयो । ';
+$lang['regmissing'] = 'माफ गर्नुहोला , सबै ठाउमा भर्नुपर्नेछ ।';
+$lang['reguexists'] = 'यो नामको प्रयोगकर्ता पहिले देखि रहेको छ।';
+$lang['regsuccess'] = 'यो प्रयोगकर्ता बनाइएको छ र प्रवेशशव्द इमेलमा पठइएको छ।';
+$lang['regsuccess2'] = 'यो प्रयोगकर्ता बनाइएको छ ।';
+$lang['regmailfail'] = 'इमेलबाट प्रवेशशब्द पठउन गल्ति भयो । कृपया एड्मिन(व्यवस्थापक)लाई सम्पर्क गर्नुहोस् !';
+$lang['regbadmail'] = 'दिएको इमेल ठेगाना गलत भए जस्तो देखिन्छ - यदि यो सहि हो भने एड्मिन(व्यवस्थापक)लाई सम्पर्क गर्नुहोस् !';
+$lang['regbadpass'] = 'दिइएका प्रवेशशव्दहरु मिल्दैनन् , पुन: प्रयास गर्नुहोस् ।';
+$lang['regpwmail'] = 'तपाईको DokuWiki प्रवेशशब्द ';
+$lang['reghere'] = 'तपाईको आफ्नै खाता छैन ? अहिल्यै एउटा बनाउनुहोस् ';
+$lang['profna'] = 'यो विकिले यो प्रोफाइल परिवर्तन समर्थन गर्दैन ।';
+$lang['profnochange'] = 'केहि परिवर्तन छैन , केहि गर्नु छैन ।';
+$lang['profnoempty'] = 'खाली नाम वा इमेल ठेगानालाई अनुमति छैन ।';
+$lang['profchanged'] = 'प्रयोगकर्ताको प्रफाइल सफलरुपमा परिवर्तन भयो ।';
+$lang['pwdforget'] = 'आफ्नो पासवर्ड भुल्नु भयो ? नयाँ हासिल गर्नुहोस् ';
+$lang['resendna'] = 'यो विकिबाट प्रवेशशव्द पठाउन समर्थित छैन ।';
+$lang['resendpwd'] = 'नयाँ प्रवेशशव्द पठाउनुहोस् ';
+$lang['resendpwdmissing'] = 'माफ गर्नुहोस् , तपाईले सबै ठाउ भर्नुपर्छ। ';
+$lang['resendpwdnouser'] = 'माफ गर्नुहोस्, हाम्रो डेटावेसमा यो प्रयोगकर्ता भेटिएन ।';
+$lang['resendpwdbadauth'] = 'माफ गर्नुहोस् , यो अनुमति चिन्ह गलत छ। तपाईले पूरै जानकारी लिङ्क प्रयोग गर्नु पर्नेछ। ';
+$lang['resendpwdconfirm'] = 'तपाईको इमेलमा कन्फरमेशन लिङ्क पठाइएको छ। ';
+$lang['resendpwdsuccess'] = 'तपाईको प्रवेशशव्द इमेलबाट पठाइएको छ। ';
+$lang['license'] = 'खुलाइएको बाहेक, यस विकिका विषयवस्तुहरु निम्त प्रमाण द्वारा प्रमाणिक गरिएको छ।';
+$lang['licenseok'] = 'नोट: यस पृष्ठ सम्पादन गरी तपाईले आफ्नो विषयवस्तु तलको प्रमाण पत्र अन्तर्गत प्रमाणिक गर्न राजी हुनु हुनेछ ।';
+$lang['txt_upload'] = 'अपलोड गर्नलाई फाइल छा्न्नुहो्स्';
+$lang['txt_filename'] = 'अर्को रुपमा अपलोड गर्नुहोस् (ऐच्छिक)';
+$lang['txt_overwrt'] = 'रहेको उहि नामको फाइललाई मेटाउने';
+$lang['lockedby'] = 'अहिले ताल्चा लगाइएको';
+$lang['lockexpire'] = 'ताल्चा अवधि सकिने :';
+$lang['js']['willexpire'] = 'तपाईलले यो पृष्ठ सम्पादन गर्न लगाउनु भएको ताल्चाको अवधि एक मिनेट भित्र सकिदै छ। \n द्वन्द हुन नदिन पूर्वरुप वा ताल्चा समय परिवर्तन गर्नुहोस् ।';
+$lang['js']['notsavedyet'] = "तपाईले वचन गर्नु नभएको परिवर्रन हराउने छ। \n साच्चै जारी गर्नुहुन्छ ।";
+$lang['rssfailed'] = 'यो फिड लिइ आउदा गल्ति भयो ।';
+$lang['nothingfound'] = 'केहि पनि भेटिएन ।';
+$lang['mediaselect'] = 'मिडिया फाइलहरू ';
+$lang['fileupload'] = 'मिडिया फाइल अपलोड ';
+$lang['uploadsucc'] = 'अपलोड सफल ';
+$lang['uploadfail'] = 'अपलोड असफल । सायद गलत अनुमति । ';
+$lang['uploadwrong'] = 'अपलोड असमर्थित । फाइल एक्सटेन्सन अमान्य। ';
+$lang['uploadexist'] = 'फाइल पहिलेदेखि छ। केहि गरिएन ।';
+$lang['uploadbadcontent'] = 'अपलोड गरिएको वस्तु %s फाइल एक्टेन्सन अनुसार मिलेन ।';
+$lang['uploadspam'] = 'अपलोड स्प्याम कालो सुचीले रोकिएको छ। ';
+$lang['uploadxss'] = 'अपलोड सम्भवत: हानिकारक वस्तुको कारणले रोकिएको। ';
+$lang['deletesucc'] = 'फाइल "%s" मेटिएको छ। ';
+$lang['deletefail'] = '"%s" मेट्न सकिएन - अनुमति हेर्नुहोस् ।';
+$lang['mediainuse'] = 'फाइल "%s" मेटिएको छैन - प्रयोगमा छ।';
+$lang['namespaces'] = 'नेमस्पेसहरु ';
+$lang['mediafiles'] = ' उपलब्ध फाइलहरु ';
+$lang['js']['keepopen'] = 'छनौटमा विन्डो खुला राख्नुहोस् ';
+$lang['js']['hidedetails'] = 'जानकारी लुकाउनु होस् ';
+$lang['js']['nosmblinks'] = 'विन्डोहरु लिङ्क गर्दा माइक्रो सफ्ट एक्सप्लोररमामात्र काम साझा हुन्छ । तर कपि गर्न र टास्न मिल्छ। ';
+$lang['mediausage'] = 'फाइललाई रेफरेन्स गर्न निम्न सुत्र प्रयोग गर्नुहोस् :';
+$lang['mediaview'] = 'सक्कली फाइल हेर्नुहोस् ';
+$lang['mediaroot'] = 'रुट(मूख्य प्रयोगकर्ता)';
+$lang['mediaupload'] = 'अहिलेको नेमस्पेसमा यहा अपलोड गर्नुहोस् । सबनेमस्पेसहरु बनाउन "रुपमा आपलोड" छानी फाइलहरुलाई कोलोन(:) ले छुट्टयाउनुहोस् ।';
+$lang['mediaextchange'] = 'फाइल एकस्टेन्सन .%s देखि .%s मा परिवरतित भयो ';
+$lang['reference'] = 'रेफररेन्स ';
+$lang['ref_inuse'] = 'फाइल मेट्न मिलेन , किनभने यो निम्न पृष्ठहरुद्वारा प्रयोगमा छ। ';
+$lang['ref_hidden'] = 'केहि रेफरेन्स यस्ता पृष्ठहरुमा छन् जुन हेर्न तपाईलाई अनुमति छैन ।';
+$lang['hits'] = 'मिलेको';
+$lang['quickhits'] = 'मिलेका पृष्ठनामहरु ';
+$lang['toc'] = 'वस्तुहरुको सुची';
+$lang['current'] = 'हालको';
+$lang['yours'] = 'तपाईको संस्करण';
+$lang['diff'] = 'हालको संस्करण सँगको भिन्नता';
+$lang['diff2'] = 'रोजिएका संस्करण वीचका भिन्नताहरु ';
+$lang['line'] = 'हरफ';
+$lang['breadcrumb'] = 'छुट्ट्याउनुहोस् ';
+$lang['youarehere'] = 'तपाई यहा हुनुहुन्छ';
+$lang['lastmod'] = 'अन्तिम पटक सच्याइएको';
+$lang['by'] = 'द्वारा ';
+$lang['deleted'] = 'हटाइएको';
+$lang['created'] = 'निर्माण गरिएको';
+$lang['restored'] = 'पुरानो संस्करण पुनर्‌प्रयोग गरिएको';
+$lang['external_edit'] = 'बाह्य सम्पादन';
+$lang['summary'] = 'सम्पादनको बारेमा';
+$lang['mail_newpage'] = 'थपिएको पृष्ठ';
+$lang['mail_changed'] = 'परिवर्तित पृष्ठ';
+$lang['mail_new_user'] = 'नयाँ प्रयोगकर्ता ';
+$lang['mail_upload'] = 'अपलोड गरिएको फाइल';
+$lang['qb_bold'] = 'मोटो पाठ(बोल्ड)';
+$lang['qb_italic'] = 'इटालिक पाठ';
+$lang['qb_underl'] = 'निम्न रेखांकित(अन्डरलाइन) पाठ';
+$lang['qb_code'] = 'चिन्ह(कोड) पाठ';
+$lang['qb_strike'] = 'स्ट्राइकथ्रु पाठ';
+$lang['qb_h1'] = 'पहिलो स्तरको शिर्षक(लेभल १ हेडलाइन)';
+$lang['qb_h2'] = 'दोस्रो स्तरको शिर्षक(लेभल २ हेडलाइन)';
+$lang['qb_h3'] = 'तेस्रो स्तरको शिर्षक(लेभल ३ हेडलाइन)';
+$lang['qb_h4'] = 'चौथो स्तरको शिर्षक(लेभल ४ हेडलाइन)';
+$lang['qb_h5'] = 'पाचौँ स्तरको शिर्षक(लेभल ५ हेडलाइन)';
+$lang['qb_link'] = 'आन्तरिक लिङ्क ';
+$lang['qb_extlink'] = 'वाह्य लिङ्क';
+$lang['qb_hr'] = 'क्षितिज (होरिजोन्टल) रुल';
+$lang['qb_ol'] = 'मिलाइएको सुची';
+$lang['qb_ul'] = 'नमिलाइएको सुची';
+$lang['qb_media'] = 'तस्विर र अरु फाइलहरु थप्नुहोस्';
+$lang['qb_sig'] = 'हस्ताक्षर थप्नुहोस् ';
+$lang['qb_smileys'] = 'स्माइलीहरु ';
+$lang['qb_chars'] = 'विशेष वर्णहरु ';
+$lang['js']['del_confirm'] = 'साच्चै छानिएका वस्तुहरु मेट्ने हो ?';
+$lang['admin_register'] = 'नयाँ प्रयोगकर्ता थप्नुहोस् ';
+$lang['metaedit'] = 'मेटाडेटा सम्पादन गर्नुहोस्';
+$lang['metasaveerr'] = 'मेटाडाटा लेखन असफल';
+$lang['metasaveok'] = 'मेटाडाटा वचत भयो ';
+$lang['img_backto'] = 'फिर्ता';
+$lang['img_title'] = 'शिर्षक';
+$lang['img_caption'] = 'निम्न लेख';
+$lang['img_date'] = 'मिति';
+$lang['img_fname'] = 'फाइलनाम';
+$lang['img_fsize'] = 'आकार';
+$lang['img_artist'] = 'चित्रकार';
+$lang['img_copyr'] = 'सर्वाधिकार';
+$lang['img_format'] = 'ढाचा';
+$lang['img_camera'] = 'क्यामेरा';
+$lang['img_keywords'] = 'खोज शब्द';
+$lang['subscribe_success'] = '%s ,%s को ग्राह्यताको लागि थपियो ';
+$lang['subscribe_error'] = '%s ,%s को ग्राह्यताको लागि थपिदा त्रुटि';
+$lang['subscribe_noaddress'] = 'तपाईको खातासँग कुनै पनि ठेगाना संबन्धित छैन , तपाईलाई ग्रहाक सुचीमा राखन मिलेन।';
+$lang['unsubscribe_success'] = '%s लाई %s को ग्रहाक सुचीबाट हटाइयो';
+$lang['unsubscribe_error'] = '%s लाई %s को ग्राहक सुचीबाट हटाउदा त्रुटि';
+$lang['authmodfailed'] = 'खराब प्रयोगकर्ता प्रामाणिकरण विधि ।तपाईको विकी एड्मिनलाई खवर गर्नुहोस् ।';
+$lang['authtempfail'] = 'प्रयोगकर्ता प्रामाणिकरण अस्थाइरुपमा अनुपलब्ध छ। यदि यो समस्या रहि रहेमा तपाईको विकि एड्मिनलाई खवर गर्नुहोला ।';
+$lang['i_chooselang'] = 'भाषा छान्नुहोस् ';
+$lang['i_installer'] = 'DokuWiki स्थापक';
+$lang['i_wikiname'] = 'विकी नाम';
+$lang['i_enableacl'] = 'ACL लागु गर्नुहोस्( सिफारिस गरिएको)';
+$lang['i_superuser'] = 'मूख्य प्रयोगकर्ता';
+$lang['i_problems'] = 'स्थापकले तल देखाइएको त्रुटि फेला पार्‌यो ।तपाईले यो त्रुटि नसच्याए सम्म अगि बढ्न सक्नुहुने छैन।';
+$lang['i_modified'] = 'सुरक्षाको कारणले यो स्क्रिप्ट नया तथा नसच्याइएको Dokuwiki स्थापनामा मात्र काम गर्छ। तपाईले कि डाउनलोड गर्नुभएको प्याकेज पुन: खोल्नुहोस् कि <a href="http://dokuwiki.org/install">Dokuwiki स्थापना विधि</a>';
+$lang['i_funcna'] = 'PHP function <code>%s</code> उपलव्ध छैन । हुनसक्छ तपाईको होस्टिङ्ग प्रदायकले कुनै कारण वश यसलाई वन्द गरिदिएका हुनसक्छन् । ';
+$lang['i_phpver'] = 'तपाईको PHP संस्करण <code>%s</code> चाहिएको <code>%s</code> भन्दा कम छ। तपाईले आफ्नो PHP स्थापना अध्यावधिक गर्नुपर्छ ।';
+$lang['i_permfail'] = '<code>%s</code> DokuWiki द्वारा लेख्य छैन । तपाईले डाइरेक्टरीको अनुमति परिवर्तन गर्नुपर्छ !';
+$lang['i_confexists'] = '<code>%s</code> पहिले देखि नै रहेको छ।';
+$lang['i_writeerr'] = '<code>%s</code> बनाउन असमर्थ । तपाईले डाइरेक्टरी / फाइल अनुमति जाच्नु पर्छ र फाइल आफैले बनाउनु पर्छ ।';
+$lang['i_badhash'] = 'पहिचान हुन नसकेको वा परिवर्तित okuwiki.php (hash=code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - अवैध वा रित्तो मान ';
+$lang['i_success'] = 'स्थापना सफलरुपमा समाप्त भयो ।तपाई install.php मेट्न सक्नुहु्न्छ । <a href="doku.php">तपाईको नयाँ DokuWiki</a> निरन्तर गर्न सक्नुहुन्छ ।';
+$lang['i_failure'] = 'स्थापना समयमा केहि त्रुटि फेला पर्यो ।तपाईले आफैले यसलाई <a href="doku.php">तपाईको नयाँ DokuWiki</a> प्रयोग गर्नु अगि सच्याउनुपर्ने हुन्छ ।';
+$lang['i_policy'] = 'सुरुको ACL निति';
+$lang['i_pol0'] = 'खुल्ला विकि (पठन, लेखन , अपलोड ) सबैका लागि';
+$lang['i_pol1'] = 'Public विकि (पठन सवैका लागि,लेखन र अपलोड दर्ता गरिएका प्रयपगकर्ताका लागि ) ';
+$lang['i_pol2'] = 'बन्द विकि (पठन , लेखन, अपलोड ) दर्ता भएका प्रयोगकर्ताका लागि मात्र ।';
+$lang['i_retry'] = 'पुन: प्रयास गर्नुहोस् ';
+$lang['recent_global'] = 'तपाई अहिले <b>%s</b> नेमस्पेस भित्र भएका परिवर्तन हेर्दैहुनुहुन्छ। तपाई <a href="%s">पुरै विकिमा भएको परिवर्तन हेर्न सक्नुहुन्छ</a>.';
diff --git a/inc/lang/ne/locked.txt b/inc/lang/ne/locked.txt
new file mode 100644
index 000000000..85f5390a0
--- /dev/null
+++ b/inc/lang/ne/locked.txt
@@ -0,0 +1,3 @@
+====== पृष्ठमा ताला लगाएको छ ======
+
+यो पृष्ठ अर्को प्रयोगकर्ताद्वारा सम्पादनका लागि ताला लगाइएको छ । तपाईले सम्पादन समाप्त नहुन्जेल या तालाको समय समाप्त नहुन्जेल सम्म प्रतिक्षागर्नु पर्छ । \ No newline at end of file
diff --git a/inc/lang/ne/norev.txt b/inc/lang/ne/norev.txt
new file mode 100644
index 000000000..28c4efb66
--- /dev/null
+++ b/inc/lang/ne/norev.txt
@@ -0,0 +1,2 @@
+====== कुनै त्यस्तो पुन:संस्करण भेटिएन ======
+खुलाइएको पुन:संस्करण अस्तित्वमा छैन ।यस कागजातको सम्पूर्ण संस्करणको सुचीको लागि "पुरानो पुन:संस्करण" बटन प्रयोग गर्नुहोस् । \ No newline at end of file
diff --git a/inc/lang/ne/pwconfirm.txt b/inc/lang/ne/pwconfirm.txt
new file mode 100644
index 000000000..1d8cd9fd6
--- /dev/null
+++ b/inc/lang/ne/pwconfirm.txt
@@ -0,0 +1,12 @@
+नमस्कार @FULLNAME@!
+
+कसैद्वारा तपाईको @TITLE@ को लागि नयाँ प्रवेशशब्द माग भएको छ ।@DOKUWIKIURL@मा प्रवेश ।
+
+यदि तपाईले नयाँ प्रवेशशब्दको माग गर्नुभएको हैन भने यस इमेललाई वेवास्ता गर्न सक्नुहुन्छ ।
+
+कृपया तपाईको माग साच्चै पठाइएको थियो भन्ने यकिन गराउनाको लागि तलाको लिङ्कमा प्रयोग गर्नुहोस् ।
+
+@CONFIRM@
+
+--
+यो पत्र DokuWiki ले @DOKUWIKIURL@ मा तयार पारेको हो ।
diff --git a/inc/lang/ne/read.txt b/inc/lang/ne/read.txt
new file mode 100644
index 000000000..e004cd39b
--- /dev/null
+++ b/inc/lang/ne/read.txt
@@ -0,0 +1 @@
+यो पृष्ठ पढ्नको लागि मात्र हो । तपाई स्रोतहेर्न सक्नुहुन्छ ,तर सम्पादन भने गर्न सक्नुहुन्न । तपाईको व्यवस्थापक(administrator) सँग के समस्या छ भनेर सोध्नु होला । \ No newline at end of file
diff --git a/inc/lang/ne/recent.txt b/inc/lang/ne/recent.txt
new file mode 100644
index 000000000..239903fd7
--- /dev/null
+++ b/inc/lang/ne/recent.txt
@@ -0,0 +1,2 @@
+====== हालैको परिवर्तन ======
+निम्न पृष्ठहरु हालै परिवर्तन गरिएका छन् । \ No newline at end of file
diff --git a/inc/lang/ne/resendpwd.txt b/inc/lang/ne/resendpwd.txt
new file mode 100644
index 000000000..aec9dfb95
--- /dev/null
+++ b/inc/lang/ne/resendpwd.txt
@@ -0,0 +1,3 @@
+====== नयाँ प्रवेशशब्द पठाउनुहोस् ======
+
+कृपया तपाईको यस विकीमा रहेको खाताको लाहि नयाँ प्रवेशशव्द अनुरोध गर्न तपाईँको नाम निम्न फर्ममा प्रविष्ट गर्नुहोस । एउटा किटानी लिङ्क तपाईले दर्ता गर्नु भएको इमेल ठेगानामा पठाइने छ । \ No newline at end of file
diff --git a/inc/lang/ne/searchpage.txt b/inc/lang/ne/searchpage.txt
new file mode 100644
index 000000000..a8139f0ab
--- /dev/null
+++ b/inc/lang/ne/searchpage.txt
@@ -0,0 +1,3 @@
+====== खोज ======
+तपाईले आफ्नो खोजको निम्न नतिजा पाउन सक्नुहुन्छ। यदि तपाईले आफुले खोजेको पाउनुभएन भने, तपाईलेको उपयुक्त बटन प्रयोग गरी खोज सँग सम्बन्धित शिर्षकहरु भएका पृष्ठ सृजना या सम्पादन गर्न सक्नुहुन्छ ।
+===== नतिजा ===== \ No newline at end of file
diff --git a/inc/lang/ne/showrev.txt b/inc/lang/ne/showrev.txt
new file mode 100644
index 000000000..5b22e9737
--- /dev/null
+++ b/inc/lang/ne/showrev.txt
@@ -0,0 +1,2 @@
+** यो कागजातको पुरानो पुन:संस्करण हो !**
+--- \ No newline at end of file
diff --git a/inc/lang/ne/updateprofile.txt b/inc/lang/ne/updateprofile.txt
new file mode 100644
index 000000000..e3027e429
--- /dev/null
+++ b/inc/lang/ne/updateprofile.txt
@@ -0,0 +1,3 @@
+‌‌‍‍‍======तपाईँको खाताको जानकारी अद्यावधिक गर्नुहोस्======
+
+तपाईँले आफूले परिवर्तन गर्न चाहेको फिल्ड मात्र परिवर्तन गरे पुग्छ । तपाईँले आफ्नो प्रयोगकर्ता नाम परिवर्तन गर्न पाउनुहुने छैन ।
diff --git a/inc/lang/ne/uploadmail.txt b/inc/lang/ne/uploadmail.txt
new file mode 100644
index 000000000..74ea46407
--- /dev/null
+++ b/inc/lang/ne/uploadmail.txt
@@ -0,0 +1,13 @@
+एउटा फाइल तपाईको DokuWiki मा भरण गरिएको छ। थप जानकारी निम्न रहेका छन् :
+फाइल : @MEDIA@
+मिति : @DATE@
+ब्राउजर : @BROWSER@
+आइपि ठगाना : @IPADDRESS@
+होस्टनाम : @HOSTNAME@
+आकार : @SIZE@
+MIME प्रकार : @MIME@
+प्रयोगकर्ता : @USER@
+
+--
+यो पत्र DokuWiki ले
+@DOKUWIKIURL@मा स्वत: तयार पारेको हो। \ No newline at end of file
diff --git a/inc/lang/nl/admin.txt b/inc/lang/nl/admin.txt
new file mode 100644
index 000000000..7138456f1
--- /dev/null
+++ b/inc/lang/nl/admin.txt
@@ -0,0 +1,3 @@
+====== Beheer ======
+
+Hieronder zie je een lijst van beheertaken beschikbaar in DokuWiki.
diff --git a/inc/lang/nl/adminplugins.txt b/inc/lang/nl/adminplugins.txt
new file mode 100644
index 000000000..916a9ca9b
--- /dev/null
+++ b/inc/lang/nl/adminplugins.txt
@@ -0,0 +1 @@
+===== Additionele plugins ===== \ No newline at end of file
diff --git a/inc/lang/nl/backlinks.txt b/inc/lang/nl/backlinks.txt
new file mode 100644
index 000000000..6edbf4021
--- /dev/null
+++ b/inc/lang/nl/backlinks.txt
@@ -0,0 +1,4 @@
+====== Backlinks ======
+
+Dit is een lijst van pagina's die terug lijken te wijzen naar de huidige pagina.
+
diff --git a/inc/lang/nl/conflict.txt b/inc/lang/nl/conflict.txt
new file mode 100644
index 000000000..926214517
--- /dev/null
+++ b/inc/lang/nl/conflict.txt
@@ -0,0 +1,5 @@
+====== Er bestaat een nieuwere versie ======
+
+Er bestaat een nieuwere versie van het document dat aangepast wordt. Dit komt voor als een andere gebruiker dit document tegelijk met jou wijzigt.
+
+Bekijk de verschillen die beneden weergegeven worden uitvoerig, beslis dan welke versie de beste is en dus bewaard moet worden. Klik op ''opslaan'' om de eigen versie te bewaren. Klik op ''annuleren'' om de huidige versie te bewaren.
diff --git a/inc/lang/nl/denied.txt b/inc/lang/nl/denied.txt
new file mode 100644
index 000000000..6a8bf773f
--- /dev/null
+++ b/inc/lang/nl/denied.txt
@@ -0,0 +1,3 @@
+====== Toegang geweigerd ======
+
+Sorry: je hebt niet voldoende rechten om verder te gaan. Misschien ben je vergeten in te loggen?
diff --git a/inc/lang/nl/diff.txt b/inc/lang/nl/diff.txt
new file mode 100644
index 000000000..ef5a1b189
--- /dev/null
+++ b/inc/lang/nl/diff.txt
@@ -0,0 +1,3 @@
+====== Verschillen ======
+
+Dit geeft de verschillen weer tussen de geselecteerde revisie en de huidige revisie van de pagina.
diff --git a/inc/lang/nl/draft.txt b/inc/lang/nl/draft.txt
new file mode 100644
index 000000000..a6bf5275d
--- /dev/null
+++ b/inc/lang/nl/draft.txt
@@ -0,0 +1,5 @@
+===== Conceptbestand gevonden =====
+
+Je laatste bewerking op deze pagina is niet volledig afgerond. DokuWiki heeft automatisch een concept van je werk opgeslagen waarmee je nu verder kunt gaan. Hieronder tref je het concept aan.
+
+Beslis of je het concept wilt //herstellen//, //verwijderen// of het bewerken wilt //annuleren//.
diff --git a/inc/lang/nl/edit.txt b/inc/lang/nl/edit.txt
new file mode 100644
index 000000000..e539050bc
--- /dev/null
+++ b/inc/lang/nl/edit.txt
@@ -0,0 +1 @@
+Pas de pagina aan en klik op ''Opslaan''. Zie [[wiki:syntax]] voor de Wiki syntax. Pas de pagina allen aan als hij **verbeterd** kan worden. Als je iets wilt uitproberen kun je spelen in de [[playground:playground|zandbak]].
diff --git a/inc/lang/nl/editrev.txt b/inc/lang/nl/editrev.txt
new file mode 100644
index 000000000..1b2d130c7
--- /dev/null
+++ b/inc/lang/nl/editrev.txt
@@ -0,0 +1,2 @@
+**Er is een oude revisie van het document geladen!** Als je nu opslaat bewaar je een nieuwe versie met deze inhoud.
+----
diff --git a/inc/lang/nl/index.txt b/inc/lang/nl/index.txt
new file mode 100644
index 000000000..288957ed4
--- /dev/null
+++ b/inc/lang/nl/index.txt
@@ -0,0 +1,4 @@
+====== Index ======
+
+Dit is een index van alle beschikbare pagina's gesorteerd op [[doku>wiki:namespaces|namespaces]].
+
diff --git a/inc/lang/nl/install.html b/inc/lang/nl/install.html
new file mode 100644
index 000000000..8ddec7aab
--- /dev/null
+++ b/inc/lang/nl/install.html
@@ -0,0 +1,14 @@
+<p>Deze pagina helpt u bij de eerste installatie en configuratie van <a href="http://wiki.splitbrain.org">Dokuwiki</a>.
+Meer informatie over deze installer is beschikbaar op zijn eigen <a href="http://wiki.splitbrain.org/wiki:installer">documentatiepagina</a>.</p>
+
+<p>DokuWiki gebruikt platte tekstbestanden voor het opslaan van wikipagina's en andere informatie die bij deze pagina's horen (bijvoorbeeld plaatjes, zoek-indexen, oude revisies enz.). Om goed te kunnen functioneren, <strong>moet</strong>
+DokuWiki schrijftoegang hebben tot de directories die deze bestanden bevatten.
+De installer kan zelf deze toegangspermissies niet regelen. Dit moet normaal gesproken direct in de command shell worden ingevoerd, of in het geval van hosting via FTP of via uw hosting control panel (bijvoorbeeld cPanel).</p>
+
+<p>Deze installer zal uw DokuWiki configureren voor <acronym title="access control list">ACL</acronym>,
+wat de beheerder in staat stelt in te loggen en toegang te verkrijgen tot het beheersdeel van de DokuWiki voor het installeren van plugins, beheren van gebruikers, toegangsrechten tot wiki pagina's en veranderen van configuratie-instellingen.
+Het is niet noodzakelijk voor DokuWiki om te functioneren maar het maakt het een stuk makkelijker om Dokuwiki te beheren.</p>
+
+<p>Ervaren gebruikers of gebruikers die een aangepaste configuratie nodig hebben kunnen voor details terecht op de volgende pagina's:
+<a href="http://wiki.splitbrain.org/wiki:install">installatie-instructies</a>
+en <a href="http://wiki.splitbrain.org/wiki:config">configuratie-instellingen</a>.</p>
diff --git a/inc/lang/nl/lang.php b/inc/lang/nl/lang.php
new file mode 100644
index 000000000..64d7d89f7
--- /dev/null
+++ b/inc/lang/nl/lang.php
@@ -0,0 +1,322 @@
+<?php
+/**
+ * dutch language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author François Kooman <fkooman.tuxed.net>
+ * @author Jack van Klaren <dokuwiki@afentoe.xs4all.nl>
+ * @author Riny Heijdendael <riny@heijdendael.nl>
+ * @author Koen Huybrechts <huybkoen@gmail.com>
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Matthias Carchon <webmaster@c-mattic.be>
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Pagina aanpassen';
+$lang['btn_source'] = 'Toon broncode';
+$lang['btn_show'] = 'Toon pagina';
+$lang['btn_create'] = 'Maak deze pagina aan';
+$lang['btn_search'] = 'Zoeken';
+$lang['btn_save'] = 'Opslaan';
+$lang['btn_preview'] = 'Voorbeeld';
+$lang['btn_top'] = 'Terug naar boven';
+$lang['btn_newer'] = '<< recenter';
+$lang['btn_older'] = 'ouder >>';
+$lang['btn_revs'] = 'Oude revisies';
+$lang['btn_recent'] = 'Recente aanpassingen';
+$lang['btn_upload'] = 'Upload';
+$lang['btn_cancel'] = 'Annuleren';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit'] = 'Aanpassen';
+$lang['btn_login'] = 'Inloggen';
+$lang['btn_logout'] = 'Uitloggen';
+$lang['btn_admin'] = 'Beheer';
+$lang['btn_update'] = 'Bijwerken';
+$lang['btn_delete'] = 'Verwijder';
+$lang['btn_back'] = 'Terug';
+$lang['btn_backlink'] = 'Referenties';
+$lang['btn_backtomedia'] = 'Terug naar Bestandsselectie';
+$lang['btn_subscribe'] = 'Inschrijven wijzigingen';
+$lang['btn_profile'] = 'Profiel aanpassen';
+$lang['btn_reset'] = 'Wissen';
+$lang['btn_resendpwd'] = 'Stuur een nieuw wachtwoord';
+$lang['btn_draft'] = 'Bewerk concept';
+$lang['btn_recover'] = 'Herstel concept';
+$lang['btn_draftdel'] = 'Verwijder concept';
+$lang['btn_revert'] = 'Herstellen';
+$lang['btn_register'] = 'Registreren';
+$lang['btn_apply'] = 'Toepassen';
+$lang['btn_media'] = 'Media beheerder';
+$lang['loggedinas'] = 'Ingelogd als';
+$lang['user'] = 'Gebruikersnaam';
+$lang['pass'] = 'Wachtwoord';
+$lang['newpass'] = 'Nieuw wachtwoord';
+$lang['oldpass'] = 'Bevestig huidig wachtwoord';
+$lang['passchk'] = 'nogmaals';
+$lang['remember'] = 'Bewaar';
+$lang['fullname'] = 'Volledige naam';
+$lang['email'] = 'E-mail';
+$lang['profile'] = 'Gebruikersprofiel';
+$lang['badlogin'] = 'Sorry, gebruikersnaam of wachtwoord onjuist';
+$lang['minoredit'] = 'Kleine wijziging';
+$lang['draftdate'] = 'Concept automatisch opgeslagen op';
+$lang['nosecedit'] = 'De pagina is tussentijds veranderd, sectie-informatie was verouderd, volledige pagina geladen.';
+$lang['regmissing'] = 'Vul alle velden in';
+$lang['reguexists'] = 'Er bestaat al een gebruiker met deze loginnaam.';
+$lang['regsuccess'] = 'De gebruiker is aangemaakt. Het wachtwoord is per e-mail verzonden.';
+$lang['regsuccess2'] = 'De gebruiker is aangemaakt.';
+$lang['regmailfail'] = 'Het lijkt erop dat het sturen van de wachtwoordmail mislukt is. Neem contact op met de beheerder!';
+$lang['regbadmail'] = 'Het opgegeven e-mailadres lijkt ongeldig - als je denkt dat dit niet klopt neem dan contact op met de beheerder.';
+$lang['regbadpass'] = 'De twee ingevoerde wachtwoorden zijn niet identiek. Probeer het nog eens.';
+$lang['regpwmail'] = 'Je DokuWiki wachtwoord';
+$lang['reghere'] = 'Je hebt nog geen account? Vraag er eentje aan';
+$lang['profna'] = 'Deze wiki ondersteunt geen profielwijzigingen';
+$lang['profnochange'] = 'Geen wijzigingen, niets gedaan';
+$lang['profnoempty'] = 'Een lege gebruikersnaam of e-mailadres is niet toegestaan';
+$lang['profchanged'] = 'Gebruikersprofiel succesvol aangepast';
+$lang['pwdforget'] = 'Je wachtwoord vergeten? Vraag een nieuw wachtwoord aan';
+$lang['resendna'] = 'Deze wiki ondersteunt het verzenden van wachtwoorden niet';
+$lang['resendpwd'] = 'Stuur een nieuw wachtwoord voor';
+$lang['resendpwdmissing'] = 'Sorry, je moet alle velden invullen.';
+$lang['resendpwdnouser'] = 'Sorry, we kunnen deze gebruikersnaam niet vinden in onze database.';
+$lang['resendpwdbadauth'] = 'Sorry, deze authentiecatiecode is niet geldig. Controleer of je de volledige bevestigings-link hebt gebruikt.';
+$lang['resendpwdconfirm'] = 'Een bevestigingslink is per e-mail verzonden.';
+$lang['resendpwdsuccess'] = 'Je nieuwe wachtwoord is per e-mail verzonden.';
+$lang['license'] = 'Tenzij anders vermeld valt de inhoud van deze wiki onder de volgende licentie:';
+$lang['licenseok'] = 'Let op: Door deze pagina aan te passen geef je de inhoud vrij onder de volgende licentie:';
+$lang['searchmedia'] = 'Bestandsnaam zoeken:';
+$lang['searchmedia_in'] = 'Zoek in %s';
+$lang['txt_upload'] = 'Selecteer een bestand om te uploaden';
+$lang['txt_filename'] = 'Vul nieuwe naam in (optioneel)';
+$lang['txt_overwrt'] = 'Overschrijf bestaand bestand';
+$lang['lockedby'] = 'Momenteel in gebruik door';
+$lang['lockexpire'] = 'Exclusief gebruiksrecht vervalt op';
+$lang['js']['willexpire'] = 'Je exclusieve gebruiksrecht voor het aanpassen van deze pagina verloopt over een minuut.\nKlik op de Voorbeeld-knop om het exclusieve gebruiksrecht te verlengen.';
+$lang['js']['notsavedyet'] = 'Nog niet bewaarde wijzigingen zullen verloren gaan.
+Weet je zeker dat je wilt doorgaan?';
+$lang['js']['searchmedia'] = 'Zoek naar bestanden';
+$lang['js']['keepopen'] = 'Houd scherm open bij selectie';
+$lang['js']['hidedetails'] = 'Verberg details';
+$lang['js']['mediatitle'] = 'Linkinstellingen';
+$lang['js']['mediadisplay'] = 'Linktype';
+$lang['js']['mediaalign'] = 'Uitlijning';
+$lang['js']['mediasize'] = 'Afbeeldingsomvang';
+$lang['js']['mediatarget'] = 'Linkdoel';
+$lang['js']['mediaclose'] = 'Sluiten';
+$lang['js']['mediainsert'] = 'Invoegen';
+$lang['js']['mediadisplayimg'] = 'De afbeelding weergeven';
+$lang['js']['mediadisplaylnk'] = 'Alleen de link weergeven';
+$lang['js']['mediasmall'] = 'Kleine versie';
+$lang['js']['mediamedium'] = 'Middelgrote versie';
+$lang['js']['medialarge'] = 'Grote versie';
+$lang['js']['mediaoriginal'] = 'Originele versie';
+$lang['js']['medialnk'] = 'Link naar detailpagina';
+$lang['js']['mediadirect'] = 'Directe link naar origineel';
+$lang['js']['medianolnk'] = 'Geen link';
+$lang['js']['medianolink'] = 'Link niet naar de afbeelding';
+$lang['js']['medialeft'] = 'Afbeelding links uitlijnen';
+$lang['js']['mediaright'] = 'Afbeelding rechts uitlijnen';
+$lang['js']['mediacenter'] = 'Afbeelding centreren';
+$lang['js']['medianoalign'] = 'Geen uitlijning gebruiken';
+$lang['js']['nosmblinks'] = 'Linken naar Windows shares werkt alleen in Microsoft Internet Explorer.
+Je kan de link wel kopiëren en plakken.';
+$lang['js']['linkwiz'] = 'Linkwizard';
+$lang['js']['linkto'] = 'Link naar:';
+$lang['js']['del_confirm'] = 'Item(s) verwijderen?';
+$lang['js']['restore_confirm'] = 'Werkelijk deze versie terugzetten?';
+$lang['js']['media_diff'] = 'Verschillen bekijken:';
+$lang['js']['media_diff_both'] = 'Naast elkaar';
+$lang['js']['media_diff_opacity'] = 'Doorschijnend';
+$lang['js']['media_diff_portions'] = 'Swipe';
+$lang['js']['media_select'] = 'Selecteer bestanden';
+$lang['js']['media_upload_btn'] = 'Uploaden';
+$lang['js']['media_done_btn'] = 'Klaar';
+$lang['js']['media_drop'] = 'Sleep bestanden hierheen om ze te uploaden';
+$lang['js']['media_cancel'] = 'Verwijderen';
+$lang['js']['media_overwrt'] = 'Bestaande bestanden overschrijven';
+$lang['rssfailed'] = 'Er is een fout opgetreden bij het ophalen van de feed: ';
+$lang['nothingfound'] = 'Er werd niets gevonden.';
+$lang['mediaselect'] = 'Bestandsselectie';
+$lang['fileupload'] = 'Bestandsupload';
+$lang['uploadsucc'] = 'Upload geslaagd';
+$lang['uploadfail'] = 'Upload mislukt. Misschien verkeerde permissies?';
+$lang['uploadwrong'] = 'Upload mislukt. Deze bestandsextensie is verboden!';
+$lang['uploadexist'] = 'Bestand bestaat reeds. Er is niets gewijzigd.';
+$lang['uploadbadcontent'] = 'Het geüploade bestand heeft niet de bestandsextensie %s.';
+$lang['uploadspam'] = 'De upload is geblokkeerd door de spam blacklist.';
+$lang['uploadxss'] = 'De upload is geblokkeerd wegens mogelijk onveilige inhoud.';
+$lang['uploadsize'] = 'Het geüploade bestand is te groot. (max. %s)';
+$lang['deletesucc'] = 'Het bestand "%s" is verwijderd.';
+$lang['deletefail'] = '"%s" kan niet worden verwijderd - controleer permissies.';
+$lang['mediainuse'] = 'Het bestand "%s" is niet verwijderd - het is nog in gebruik.';
+$lang['namespaces'] = 'Namespaces';
+$lang['mediafiles'] = 'Beschikbare bestanden in';
+$lang['accessdenied'] = 'U heeft geen toegang tot deze pagina.';
+$lang['mediausage'] = 'Gebruik de volgende syntax om aan het bestand te refereren:';
+$lang['mediaview'] = 'Bekijk het orginele bestand';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Upload een bestand naar de huidige namespace. Om een subnamespace aan te maken, laat je die voorafgaan aan de bestandsnaam bij "Upload als", gescheiden door een dubbele punt.';
+$lang['mediaextchange'] = 'Bestandsextensie veranderd van .%s naar .%s!';
+$lang['reference'] = 'Referenties voor';
+$lang['ref_inuse'] = 'Het bestand kan niet worden verwijderd omdat het nog in gebruik is op de volgende pagina\'s:';
+$lang['ref_hidden'] = 'Enkele referenties staan op pagina\'s waarvoor je geen leesrechten hebt';
+$lang['hits'] = 'Hits';
+$lang['quickhits'] = 'Overeenkomende paginanamen';
+$lang['toc'] = 'Inhoud';
+$lang['current'] = 'huidige';
+$lang['yours'] = 'Jouw versie';
+$lang['diff'] = 'Toon verschillen met huidige revisie';
+$lang['diff2'] = 'Toon verschillen tussen geselecteerde revisies';
+$lang['difflink'] = 'Link naar deze vergelijking';
+$lang['diff_type'] = 'Bekijk verschillen:';
+$lang['diff_inline'] = 'Inline';
+$lang['diff_side'] = 'Zij aan zij';
+$lang['line'] = 'Regel';
+$lang['breadcrumb'] = 'Spoor';
+$lang['youarehere'] = 'Je bent hier';
+$lang['lastmod'] = 'Laatst gewijzigd';
+$lang['by'] = 'door';
+$lang['deleted'] = 'verwijderd';
+$lang['created'] = 'aangemaakt';
+$lang['restored'] = 'oude revisie hersteld';
+$lang['external_edit'] = 'Externe bewerking';
+$lang['summary'] = 'Samenvatting wijziging';
+$lang['noflash'] = 'De <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> is vereist om de pagina te kunnen weergeven.';
+$lang['download'] = 'Download fragment';
+$lang['mail_newpage'] = 'pagina toegevoegd:';
+$lang['mail_changed'] = 'pagina aangepast:';
+$lang['mail_subscribe_list'] = 'Pagina\'s veranderd in namespace:';
+$lang['mail_new_user'] = 'nieuwe gebruiker:';
+$lang['mail_upload'] = 'bestand geüpload:';
+$lang['changes_type'] = 'Bekijk wijzigingen van';
+$lang['pages_changes'] = 'Pagina\'s';
+$lang['media_changes'] = 'Media bestanden';
+$lang['both_changes'] = 'Zowel pagina\'s als media bestanden';
+$lang['qb_bold'] = 'Vette tekst';
+$lang['qb_italic'] = 'Cursieve tekst';
+$lang['qb_underl'] = 'Onderstreepte tekst';
+$lang['qb_code'] = 'Code tekst';
+$lang['qb_strike'] = 'Doorgestreepte tekst';
+$lang['qb_h1'] = 'Niveau 1 kop';
+$lang['qb_h2'] = 'Niveau 2 kop';
+$lang['qb_h3'] = 'Niveau 3 kop';
+$lang['qb_h4'] = 'Niveau 4 kop';
+$lang['qb_h5'] = 'Niveau 5 kop';
+$lang['qb_h'] = 'Koptekst';
+$lang['qb_hs'] = 'Kies koptekst';
+$lang['qb_hplus'] = 'Hogere koptekst';
+$lang['qb_hminus'] = 'Lagere koptekst';
+$lang['qb_hequal'] = 'Koptekst op zelfde niveau';
+$lang['qb_link'] = 'Interne link';
+$lang['qb_extlink'] = 'Externe link';
+$lang['qb_hr'] = 'Horizontale lijn';
+$lang['qb_ol'] = 'Geordende lijst';
+$lang['qb_ul'] = 'Ongeordende lijst';
+$lang['qb_media'] = 'Voeg plaatjes en andere bestanden toe';
+$lang['qb_sig'] = 'Handtekening invoegen';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Speciale tekens';
+$lang['upperns'] = 'Spring naar bovenliggende namespace';
+$lang['admin_register'] = 'Nieuwe gebruiker toevoegen';
+$lang['metaedit'] = 'Metadata wijzigen';
+$lang['metasaveerr'] = 'Schrijven van metadata mislukt';
+$lang['metasaveok'] = 'Metadata bewaard';
+$lang['img_backto'] = 'Terug naar';
+$lang['img_title'] = 'Titel';
+$lang['img_caption'] = 'Bijschrift';
+$lang['img_date'] = 'Datum';
+$lang['img_fname'] = 'Bestandsnaam';
+$lang['img_fsize'] = 'Grootte';
+$lang['img_artist'] = 'Fotograaf';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Formaat';
+$lang['img_camera'] = 'Camera';
+$lang['img_keywords'] = 'Trefwoorden';
+$lang['img_width'] = 'Breedte';
+$lang['img_height'] = 'Hoogte';
+$lang['img_manager'] = 'In media beheerder bekijken';
+$lang['subscr_subscribe_success'] = '%s is ingeschreven voor %s';
+$lang['subscr_subscribe_error'] = 'Fout bij inschrijven van %s voor %s';
+$lang['subscr_subscribe_noaddress'] = 'Er is geen emailadres geassocieerd met uw account, u kunt daardoor niet worden ingeschreven.';
+$lang['subscr_unsubscribe_success'] = '%s is nu uitgeschreven bij %s.';
+$lang['subscr_unsubscribe_error'] = 'Fout bij uitschrijven van %s bij %s.';
+$lang['subscr_already_subscribed'] = '%s is reeds ingeschreven bij %s.';
+$lang['subscr_not_subscribed'] = '%s is niet ingeschreven bij %s.';
+$lang['subscr_m_not_subscribed'] = 'Je bent momenteel niet ingeschreven bij de huidige pagina of namespace.';
+$lang['subscr_m_new_header'] = 'Inschrijving toevoegen';
+$lang['subscr_m_current_header'] = 'Huidige inschrijvingen';
+$lang['subscr_m_unsubscribe'] = 'Uitschrijven';
+$lang['subscr_m_subscribe'] = 'Inschrijven';
+$lang['subscr_m_receive'] = 'Ontvang';
+$lang['subscr_style_every'] = 'Email bij iedere wijziging';
+$lang['subscr_style_digest'] = 'Samenvattings-email met wijzigingen per pagina (elke %.2f dagen)';
+$lang['subscr_style_list'] = 'Lijst van veranderde pagina\'s sinds laatste email (elke %.2f dagen)';
+$lang['authmodfailed'] = 'Ongeldige gebruikersauthenticatie-configuratie. Informeer de wikibeheerder.';
+$lang['authtempfail'] = 'Gebruikersauthenticatie is tijdelijk niet beschikbaar. Als deze situatie zich blijft voordoen, informeer dan de wikibeheerder.';
+$lang['i_chooselang'] = 'Kies je taal';
+$lang['i_installer'] = 'DokuWiki Installer';
+$lang['i_wikiname'] = 'Wikinaam';
+$lang['i_enableacl'] = 'ACLs inschakelen (aanbevolen)';
+$lang['i_superuser'] = 'Superuser';
+$lang['i_problems'] = 'De installer vond problemen, hieronder aangegeven. Verhelp deze voor je doorgaat.';
+$lang['i_modified'] = 'Uit veiligheidsoverwegingen werkt dit script alleen met nieuwe en onveranderde DokuWiki-installaties. Pak de bestanden opnieuw uit of raadpleeg de <a href="http://wiki.splitbrain.org/wiki:install">Dokuwiki installatie-instructies</a>';
+$lang['i_funcna'] = 'PHP functie <code>%s</code> is niet beschikbaar. Wellicht heeft je hosting provider deze uitgeschakeld?';
+$lang['i_phpver'] = 'PHP-versie <code>%s</code> is lager dan de vereiste <code>%s</code>. Upgrade PHP.';
+$lang['i_permfail'] = '<code>%s</code> is niet schrijfbaar voor DokuWiki. Pas de permissie-instellingen van deze directory aan.';
+$lang['i_confexists'] = '<code>%s</code> bestaat reeds';
+$lang['i_writeerr'] = 'Niet mogelijk om <code>%s</code> aan te maken. Controleer de directory/bestandspermissies en maak het bestand handmatig aan.';
+$lang['i_badhash'] = 'Onbekende of aangepaste dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - onjuiste of lege waarde';
+$lang['i_success'] = 'De configuratie is succesvol afgerond. Je kunt nu het bestand install.php verwijderen. Ga naar <a href="doku.php">je nieuwe DokuWiki</a>.';
+$lang['i_failure'] = 'Fouten deden zich voor tijdens het schrijven naar de configuratiebestanden. Pas deze aan voor je gebruik kunt maken van <a href="doku.php">je nieuwe DokuWiki</a>.';
+$lang['i_policy'] = 'Initieel ACL-beleid';
+$lang['i_pol0'] = 'Open wiki (lezen, schrijven, uploaden voor iedereen)';
+$lang['i_pol1'] = 'Publieke wiki (lezen voor iedereen, schrijven en uploaden voor geregistreerde gebruikers)';
+$lang['i_pol2'] = 'Besloten wiki (lezen, schrijven en uploaden alleen voor geregistreerde gebruikers)';
+$lang['i_retry'] = 'Opnieuw';
+$lang['i_license'] = 'Kies a.u.b. een licentie die u voor uw inhoud wilt gebruiken:';
+$lang['recent_global'] = 'Je bekijkt momenteel de wijzigingen binnen de <b>%s</b> namespace. Je kunt ook de <a href="%s">recente wijzigingen van de hele wiki</a> bekijken.';
+$lang['years'] = '%d jaar geleden';
+$lang['months'] = '%d maand geleden';
+$lang['weeks'] = '%d weken geleden';
+$lang['days'] = '%d dagen geleden';
+$lang['hours'] = '%d uren geleden';
+$lang['minutes'] = '%d minuten geleden';
+$lang['seconds'] = '%d seconden geleden';
+$lang['wordblock'] = 'Uw wijziging is niet opgeslagen omdat deze niet-toegestane tekst bevat (spam).';
+$lang['media_uploadtab'] = 'Uploaden';
+$lang['media_searchtab'] = 'Zoeken';
+$lang['media_file'] = 'Bestand';
+$lang['media_viewtab'] = 'Beeld';
+$lang['media_edittab'] = 'Bewerken';
+$lang['media_historytab'] = 'Geschiedenis';
+$lang['media_list_thumbs'] = 'Miniatuurweergaven';
+$lang['media_list_rows'] = 'Regels';
+$lang['media_sort_name'] = 'Naam';
+$lang['media_sort_date'] = 'Datum';
+$lang['media_namespaces'] = 'Kies naamruimte';
+$lang['media_files'] = 'Bestanden in %s';
+$lang['media_upload'] = 'Upload naar %s';
+$lang['media_search'] = 'Zoeken in %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s bij %s';
+$lang['media_edit'] = '%s bewerken';
+$lang['media_history'] = 'Geschiedenis van %s';
+$lang['media_meta_edited'] = 'Metagegevens bewerkt';
+$lang['media_perm_read'] = 'Sorry, u heeft niet voldoende rechten om bestanden te lezen.';
+$lang['media_perm_upload'] = 'Sorry, u heeft niet voldoende rechten om bestanden te uploaden.';
+$lang['media_update'] = 'Upload nieuwe versie';
+$lang['media_restore'] = 'Deze versie terugzetten';
+$lang['plugin_install_err'] = 'Plugin is juist geinstalleerd. Hernoem plugin map \'%s\' naar \'%s\'.';
diff --git a/inc/lang/nl/locked.txt b/inc/lang/nl/locked.txt
new file mode 100644
index 000000000..878fb375c
--- /dev/null
+++ b/inc/lang/nl/locked.txt
@@ -0,0 +1,3 @@
+====== Pagina in exclusief gebruik ======
+
+Deze pagina wordt momenteel aangepast door een andere gebruiker. Wacht tot deze gebruiker klaar is met aanpassen of totdat het gebruiksrecht vervalt.
diff --git a/inc/lang/nl/login.txt b/inc/lang/nl/login.txt
new file mode 100644
index 000000000..699cbf8fe
--- /dev/null
+++ b/inc/lang/nl/login.txt
@@ -0,0 +1,3 @@
+====== Login ======
+
+Je bent op dit moment niet ingelogd! Voer je login-gegevens hieronder in om in te loggen. Je browser moet cookies accepteren om in te kunnen loggen.
diff --git a/inc/lang/nl/mailtext.txt b/inc/lang/nl/mailtext.txt
new file mode 100644
index 000000000..dbe35c519
--- /dev/null
+++ b/inc/lang/nl/mailtext.txt
@@ -0,0 +1,17 @@
+Er is een pagina in je DokuWiki toegevoegd of gewijzigd. Hier zijn de details
+
+Datum : @DATE@
+Browser : @BROWSER@
+IP-Adres : @IPADDRESS@
+Hostname : @HOSTNAME@
+Oude revisie : @OLDPAGE@
+Nieuwe revisie: @NEWPAGE@
+Samenvatting : @SUMMARY@
+User : @USER@
+
+@DIFF@
+
+
+--
+Deze mail werd gegenereerd door DokuWiki op
+@DOKUWIKIURL@
diff --git a/inc/lang/nl/newpage.txt b/inc/lang/nl/newpage.txt
new file mode 100644
index 000000000..0e4b95ec0
--- /dev/null
+++ b/inc/lang/nl/newpage.txt
@@ -0,0 +1,3 @@
+====== Dit onderwerp bestaat nog niet ======
+
+De pagina over dit onderwerp bestaat nog niet. Aanmaken kan door op de ''Maak deze pagina aan'' te klikken.
diff --git a/inc/lang/nl/norev.txt b/inc/lang/nl/norev.txt
new file mode 100644
index 000000000..849fc5138
--- /dev/null
+++ b/inc/lang/nl/norev.txt
@@ -0,0 +1,4 @@
+====== Revisie bestaat niet ======
+
+De opgegeven revisie bestaat niet. Klik op ''Oude revisies'' voor een lijst van oude revisies van dit document.
+
diff --git a/inc/lang/nl/password.txt b/inc/lang/nl/password.txt
new file mode 100644
index 000000000..294dcbd1a
--- /dev/null
+++ b/inc/lang/nl/password.txt
@@ -0,0 +1,10 @@
+Beste @FULLNAME@!
+
+Hier is je gebruikersinformatie for @TITLE@ op @DOKUWIKIURL@
+
+Gebruikersnaam: @LOGIN@
+Wachtwoord : @PASSWORD@
+
+--
+Deze mail werd gegenereerd door DokuWiki op
+@DOKUWIKIURL@
diff --git a/inc/lang/nl/preview.txt b/inc/lang/nl/preview.txt
new file mode 100644
index 000000000..4d2927aff
--- /dev/null
+++ b/inc/lang/nl/preview.txt
@@ -0,0 +1,4 @@
+====== Preview ======
+
+Dit is een preview van de tekst zoals hij er uit komt te zien. Let op: het is nog **niet opgeslagen!**
+
diff --git a/inc/lang/nl/pwconfirm.txt b/inc/lang/nl/pwconfirm.txt
new file mode 100644
index 000000000..ab72ae7c4
--- /dev/null
+++ b/inc/lang/nl/pwconfirm.txt
@@ -0,0 +1,13 @@
+Beste @FULLNAME@!
+
+Iemand heeft een nieuw wachtwoord aangevraagd voor je @TITLE@ login op @DOKUWIKIURL@
+
+Als je geen nieuw wachtwoord hebt aangevraagd kun je deze e-mail negeren.
+
+Volg de volgende link om te bevestigen dat je inderdaad een nieuw wachtwoord wilt:
+
+@CONFIRM@
+
+--
+Deze mail werd gegenereerd door DokuWiki op
+@DOKUWIKIURL@
diff --git a/inc/lang/nl/read.txt b/inc/lang/nl/read.txt
new file mode 100644
index 000000000..fcb791811
--- /dev/null
+++ b/inc/lang/nl/read.txt
@@ -0,0 +1,2 @@
+Deze pagina is niet beschrijfbaar. Je kan de broncode bekijken maar niks veranderen. Neem contact op met de beheerder als je denkt dat dit niet klopt.
+
diff --git a/inc/lang/nl/recent.txt b/inc/lang/nl/recent.txt
new file mode 100644
index 000000000..4b507f2ca
--- /dev/null
+++ b/inc/lang/nl/recent.txt
@@ -0,0 +1,3 @@
+====== Recente wijzigingen ======
+
+De volgende pagina's zijn recent aangepast.
diff --git a/inc/lang/nl/register.txt b/inc/lang/nl/register.txt
new file mode 100644
index 000000000..338edcca3
--- /dev/null
+++ b/inc/lang/nl/register.txt
@@ -0,0 +1,4 @@
+====== Registreer als nieuwe gebruiker ======
+
+Vul alle informatie hieronder in om een nieuw account voor deze wiki aan te maken. Zorg dat je een **geldig e-mailadres** opgeeft - als je je wachtwoord hier niet in kunt vullen wordt het naar dit adres verzonden. De gebruikersnaam moet een geldige [[doku>wiki:pagename|pagename]] zijn.
+
diff --git a/inc/lang/nl/registermail.txt b/inc/lang/nl/registermail.txt
new file mode 100644
index 000000000..5efb25144
--- /dev/null
+++ b/inc/lang/nl/registermail.txt
@@ -0,0 +1,14 @@
+Een nieuwe gebruiker heeft zich geregistreerd. Dit zijn de details:
+
+Gebruikersnaam: @NEWUSER@
+Volledige naam: @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Datum : @DATE@
+Browser : @BROWSER@
+IP-adres : @IPADDRESS@
+Hostname : @HOSTNAME@
+
+--
+Dit bericht is gegenereerd door DokuWiki op
+@DOKUWIKIURL@
diff --git a/inc/lang/nl/resendpwd.txt b/inc/lang/nl/resendpwd.txt
new file mode 100644
index 000000000..ed4617748
--- /dev/null
+++ b/inc/lang/nl/resendpwd.txt
@@ -0,0 +1,3 @@
+==== Verstuur een nieuw wachtwoord ====
+
+Voer uw gebruikersnaam in het formulier hieronder in om een nieuw wachtwoord aan te vragen voor deze wiki. Een bevestigingslink zal worden verzonden naar het geregistreerde e-mailadres.
diff --git a/inc/lang/nl/revisions.txt b/inc/lang/nl/revisions.txt
new file mode 100644
index 000000000..7a78917fc
--- /dev/null
+++ b/inc/lang/nl/revisions.txt
@@ -0,0 +1,4 @@
+====== Oude revisies ======
+
+Dit zijn de oude revisies van het document. Om terug te keren naar een oude revisie selecteer je hem hieronder en klik je op de ''Pagina aanpassen'' en vervolgens op ''Opslaan''.
+
diff --git a/inc/lang/nl/searchpage.txt b/inc/lang/nl/searchpage.txt
new file mode 100644
index 000000000..3ace704c8
--- /dev/null
+++ b/inc/lang/nl/searchpage.txt
@@ -0,0 +1,5 @@
+====== Zoeken ======
+
+Hieronder zijn de resultaten van de zoekopdracht. Niks gevonden? Maak een nieuwe pagina met als naam je zoekopdracht. Klik hiervoor op ''Pagina aanpassen''.
+
+===== Resultaten =====
diff --git a/inc/lang/nl/showrev.txt b/inc/lang/nl/showrev.txt
new file mode 100644
index 000000000..c1bfa4e2b
--- /dev/null
+++ b/inc/lang/nl/showrev.txt
@@ -0,0 +1,2 @@
+**Dit is een oude revisie van het document!**
+----
diff --git a/inc/lang/nl/stopwords.txt b/inc/lang/nl/stopwords.txt
new file mode 100644
index 000000000..3056c4a70
--- /dev/null
+++ b/inc/lang/nl/stopwords.txt
@@ -0,0 +1,37 @@
+# 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/
+aan
+als
+bij
+dan
+dat
+die
+dit
+een
+had
+heb
+hem
+het
+hij
+hoe
+hun
+kan
+men
+met
+mij
+nog
+ons
+ook
+tot
+uit
+van
+was
+wat
+wel
+wij
+zal
+zei
+zij
+zou
diff --git a/inc/lang/nl/subscr_digest.txt b/inc/lang/nl/subscr_digest.txt
new file mode 100644
index 000000000..0e6c2c5ba
--- /dev/null
+++ b/inc/lang/nl/subscr_digest.txt
@@ -0,0 +1,15 @@
+Halllo!
+
+De pagina @PAGE@ in de @TITLE@ wiki is veranderd. Hier zijn de wijzigingen:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Vorige revisie: @OLDPAGE@
+Nieuwe revisie: @NEWPAGE@
+
+Om het verzenden van deze wijzigingsberichtente te stoppen, logt u in op het wiki op @DOKUWIKIURL@ en navigeert u naar @SUBSCRIBE@. Vervolgens kunt u zich voor elke gewenste pagina of namespace uitschrijven.
+
+--
+Deze email is gegenereerd door DokuWiki op @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/nl/subscr_form.txt b/inc/lang/nl/subscr_form.txt
new file mode 100644
index 000000000..a554f843e
--- /dev/null
+++ b/inc/lang/nl/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Beheer inschrijvingen ======
+
+Deze pagina stelt u in staat uw inschrijven voor de huidige pagina en namespace te configureren. \ No newline at end of file
diff --git a/inc/lang/nl/subscr_list.txt b/inc/lang/nl/subscr_list.txt
new file mode 100644
index 000000000..5e1a62144
--- /dev/null
+++ b/inc/lang/nl/subscr_list.txt
@@ -0,0 +1,12 @@
+Halllo!
+
+Pagina's in de namespace @PAGE@ van de @TITLE@ wiki zijn veranderd. Hier zijn de veranderde pagina's:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Om het verzenden van deze wijzigingsberichtente te stoppen, logt u in op het wiki op @DOKUWIKIURL@ en navigeert u naar @SUBSCRIBE@. Vervolgens kunt u zich voor elke gewenste pagina of namespace uitschrijven.
+
+--
+Deze email is gegenereerd door DokuWiki op @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/nl/subscr_single.txt b/inc/lang/nl/subscr_single.txt
new file mode 100644
index 000000000..3e74bce17
--- /dev/null
+++ b/inc/lang/nl/subscr_single.txt
@@ -0,0 +1,18 @@
+Halllo!
+
+De pagina @PAGE@ in de @TITLE@ wiki is veranderd. Hier zijn de wijzigingen:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Datum: @DATE@
+Gebruiker: @USER@
+Wijzigingssamenvatting: @SUMMARY@
+Vorige revisie: @OLDPAGE@
+Nieuwe revisie: @NEWPAGE@
+
+Om het verzenden van deze wijzigingsberichtente te stoppen, logt u in op het wiki op @DOKUWIKIURL@ en navigeert u naar @SUBSCRIBE@. Vervolgens kunt u zich voor elke gewenste pagina of namespace uitschrijven.
+
+--
+Deze email is gegenereerd door DokuWiki op @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/nl/updateprofile.txt b/inc/lang/nl/updateprofile.txt
new file mode 100644
index 000000000..2368a09fd
--- /dev/null
+++ b/inc/lang/nl/updateprofile.txt
@@ -0,0 +1,3 @@
+===== Wijzig uw gebruikersprofiel =====
+
+Je hoeft alleen de velden aan te passen die je wilt wijzigen. Je gebruikersnaam is niet aan te passen.
diff --git a/inc/lang/nl/uploadmail.txt b/inc/lang/nl/uploadmail.txt
new file mode 100644
index 000000000..1816400d7
--- /dev/null
+++ b/inc/lang/nl/uploadmail.txt
@@ -0,0 +1,14 @@
+Er is een bestand geüpload naar uw DokuWiki. Hier zijn de details;
+
+Bestand : @MEDIA@
+Datum : @DATE@
+Browser : @BROWSER@
+IP-adres : @IPADDRESS@
+Hostname : @HOSTNAME@
+Grootte : @SIZE@
+MIME type: @MIME@
+Gebruiker: @USER@
+
+--
+Dit bericht is gegenereerd door DokuWiki op
+@DOKUWIKIURL@
diff --git a/inc/lang/no/admin.txt b/inc/lang/no/admin.txt
new file mode 100644
index 000000000..765177fb3
--- /dev/null
+++ b/inc/lang/no/admin.txt
@@ -0,0 +1,3 @@
+====== Administrasjon ======
+
+Nedenfor finner du en liste over administrative oppgaver i DokuWiki.
diff --git a/inc/lang/no/adminplugins.txt b/inc/lang/no/adminplugins.txt
new file mode 100644
index 000000000..df78672d7
--- /dev/null
+++ b/inc/lang/no/adminplugins.txt
@@ -0,0 +1 @@
+====== Ekstra programtillegg ====== \ No newline at end of file
diff --git a/inc/lang/no/backlinks.txt b/inc/lang/no/backlinks.txt
new file mode 100644
index 000000000..9fe72066e
--- /dev/null
+++ b/inc/lang/no/backlinks.txt
@@ -0,0 +1,3 @@
+====== Tilbakelinker ======
+
+Dette er en liste over sider som ser ut til å linke tilbake til den aktuelle siden. \ No newline at end of file
diff --git a/inc/lang/no/conflict.txt b/inc/lang/no/conflict.txt
new file mode 100644
index 000000000..49961d0df
--- /dev/null
+++ b/inc/lang/no/conflict.txt
@@ -0,0 +1,6 @@
+====== Det finnes en nyere versjon ======
+
+Det fins en nyere utgave av dokumentet du har redigert. Dette kan skje når en annen bruker redigerer dokumentet samtidig med deg.
+
+Legg nøye merke til forskjellene som vises under, og velg deretter hvilken versjon du vil beholde. Om du velger ''**Lagre**'', så kommer din versjon til å lagres. Velg ''**Avbryt**'' for å beholde den nyeste versjonen (ikke din).
+
diff --git a/inc/lang/no/denied.txt b/inc/lang/no/denied.txt
new file mode 100644
index 000000000..6e7f1f28b
--- /dev/null
+++ b/inc/lang/no/denied.txt
@@ -0,0 +1,3 @@
+====== Adgang forbudt ======
+
+Beklager, men du har ikke rettigheter til dette. Kanskje du har glemt å logge inn?
diff --git a/inc/lang/no/diff.txt b/inc/lang/no/diff.txt
new file mode 100644
index 000000000..e4c2eb080
--- /dev/null
+++ b/inc/lang/no/diff.txt
@@ -0,0 +1,4 @@
+====== Forskjeller ======
+
+Her vises forskjeller mellom den valgte versjonen og den nåværende versjonen av dokumentet.
+
diff --git a/inc/lang/no/draft.txt b/inc/lang/no/draft.txt
new file mode 100644
index 000000000..8bcea65aa
--- /dev/null
+++ b/inc/lang/no/draft.txt
@@ -0,0 +1,6 @@
+====== Kladdfil funnet ======
+
+Din siste endring av denne siden ble ikke avsluttet riktig. DokuWiki lagret automatisk en kladd under ditt arbeid som du nå kan bruke for å fortsette redigeringen. Nedenfor kan du se de lagrede data.
+
+Vennligst avgjør om du vil //gjennopprette// din tapte sesjon, //slette// kladden eller //avbryte// redigeringen.
+
diff --git a/inc/lang/no/edit.txt b/inc/lang/no/edit.txt
new file mode 100644
index 000000000..bdb3bc854
--- /dev/null
+++ b/inc/lang/no/edit.txt
@@ -0,0 +1,2 @@
+Rediger siden og klikk på ''**Lagre**''. Se [[wiki:syntax]] for Wikisyntaks. Rediger siden bare hvis du kan **forbedre** sidens innhold. Hvis du vil teste ut hvordan saker og ting fungerer, kan du gjøre det på [[playground:playground|lekeplassen]].
+
diff --git a/inc/lang/no/editrev.txt b/inc/lang/no/editrev.txt
new file mode 100644
index 000000000..652a84c38
--- /dev/null
+++ b/inc/lang/no/editrev.txt
@@ -0,0 +1,2 @@
+**Du har hentet en tidligere versjon av dokumentet!** Hvis du lagrer den tidligere versjonen så kommer du til å lage en ny og aktiv versjon med dette innholdet.
+----
diff --git a/inc/lang/no/index.txt b/inc/lang/no/index.txt
new file mode 100644
index 000000000..e2ea95933
--- /dev/null
+++ b/inc/lang/no/index.txt
@@ -0,0 +1,4 @@
+====== Indeks ======
+
+Dette er en fortegnelse over alle tilgjengelige sider, sortert etter [[doku>namespaces|navnerom]].
+
diff --git a/inc/lang/no/install.html b/inc/lang/no/install.html
new file mode 100644
index 000000000..541445494
--- /dev/null
+++ b/inc/lang/no/install.html
@@ -0,0 +1,24 @@
+<p>Denne siden assisterer under førstegangs installasjon og konfigurasjon av
+<a href="http://dokuwiki.org">Dokuwiki</a>. Mer informasjon for denne
+installasjonen er tilgjengelig på
+<a href="http://dokuwiki.org/installer">dokumentasjonssiden</a>.</p>
+
+<p>DokuWiki bruker vanlige filer for lagring av wikisider og annen
+informasjon assosiert med disse sidene (f.eks. bilder, søkeindekser, eldre
+revisjoner osv.). For å kunne virke <strong>må</strong> DokuWiki
+ha skrivetilgang til de mapper som lagrer disse filene.
+Denne installasjonen kan ikke sette opp mapperettigheter. Det må normalt
+gjøres direkte fra et kommandoskall, eller om du bruker en leverandør,
+via FTP eller ditt kontrollpanel på tjener (f.eks. cPanel).</p>
+
+<p>Denne installasjonen vil sette opp din DokuWiki-konfigurasjon for
+<acronym title="access control list">ACL</acronym>, som igjen tillater administrator
+innlogging og tilgang til DokuWikiens administratormeny for installasjon av tillegg,
+brukerbehandling, adgangskontrollbehandling til wikisider og endring av konfigurasjon.
+Det er ikke påkrevd for at DokuWiki skal virke, men det vil gjøre Dokuwiki enklere å
+administrere.</p>
+
+<p>Erfarne brukere eller brukere med spessielle oppsettingskrav bør se på disse lenkene
+for detaljer rundt
+<a href="http://dokuwiki.org/install">installasjonsinstrukser</a>
+og <a href="http://dokuwiki.org/config">konfigurasjonsinnstillinger</a>.</p>
diff --git a/inc/lang/no/lang.php b/inc/lang/no/lang.php
new file mode 100644
index 000000000..5dd5f6ea7
--- /dev/null
+++ b/inc/lang/no/lang.php
@@ -0,0 +1,328 @@
+<?php
+/**
+ * Norwegian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Reidar Mosvold <Reidar.Mosvold@hit.no>
+ * @author Jorge Barrera Grandon <jorge@digitalwolves.org>
+ * @author Rune Rasmussen [http://www.syntaxerror.no/]
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen <me@jakobnielsen.net>
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '«';
+$lang['doublequoteclosing'] = '»';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Rediger denne siden';
+$lang['btn_source'] = 'Vis kildekode';
+$lang['btn_show'] = 'Vis siden';
+$lang['btn_create'] = 'Lag denne siden';
+$lang['btn_search'] = 'Søk';
+$lang['btn_save'] = 'Lagre';
+$lang['btn_preview'] = 'Forhåndsvis';
+$lang['btn_top'] = 'Til toppen av siden';
+$lang['btn_newer'] = '<< nyere';
+$lang['btn_older'] = 'eldre >>';
+$lang['btn_revs'] = 'Historikk';
+$lang['btn_recent'] = 'Siste endringer';
+$lang['btn_upload'] = 'Last opp';
+$lang['btn_cancel'] = 'Avbryt';
+$lang['btn_index'] = 'Indeks';
+$lang['btn_secedit'] = 'Rediger';
+$lang['btn_login'] = 'Logg inn';
+$lang['btn_logout'] = 'Logg ut';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Oppdater';
+$lang['btn_delete'] = 'Slett';
+$lang['btn_back'] = 'Tilbake';
+$lang['btn_backlink'] = 'Tilbakelenker';
+$lang['btn_backtomedia'] = 'Tilbake til valg av mediafil';
+$lang['btn_subscribe'] = 'Abonnér på endringer';
+$lang['btn_profile'] = 'Oppdater profil';
+$lang['btn_reset'] = 'Tilbakestill';
+$lang['btn_resendpwd'] = 'Send nytt passord';
+$lang['btn_draft'] = 'Rediger kladd';
+$lang['btn_recover'] = 'Gjennvinn kladd';
+$lang['btn_draftdel'] = 'Slett kladd';
+$lang['btn_revert'] = 'Gjenopprette';
+$lang['btn_register'] = 'Registrer deg';
+$lang['btn_apply'] = 'Bruk';
+$lang['btn_media'] = 'Mediefiler';
+$lang['loggedinas'] = 'Innlogget som';
+$lang['user'] = 'Brukernavn';
+$lang['pass'] = 'Passord';
+$lang['newpass'] = 'Nytt passord';
+$lang['oldpass'] = 'Bekreft gjeldende passord';
+$lang['passchk'] = 'Bekreft passord';
+$lang['remember'] = 'Husk meg';
+$lang['fullname'] = 'Fullt navn';
+$lang['email'] = 'E-post';
+$lang['profile'] = 'Brukerprofil';
+$lang['badlogin'] = 'Ugyldig brukernavn og/eller passord.';
+$lang['minoredit'] = 'Mindre endringer';
+$lang['draftdate'] = 'Kladd autolagret';
+$lang['nosecedit'] = 'Siden ble endret i mellomtiden, seksjonsinfo har blitt foreldet - lastet full side istedet.';
+$lang['regmissing'] = 'Vennligst fyll ut alle felt.';
+$lang['reguexists'] = 'Det finnes allerede en konto med dette brukernavnet.';
+$lang['regsuccess'] = 'Brukerkonto har blitt laget og passord har blitt sendt via e-post.';
+$lang['regsuccess2'] = 'Brukeren har blitt laget.';
+$lang['regmailfail'] = 'En feil oppstod da passordet ditt skulle sendes via e-post. Vennligst kontakt administratoren!';
+$lang['regbadmail'] = 'Den angitte e-post adressen ser ut til å være ugyldig. Vennligst kontakt administratoren om du anser dette som feilaktig.';
+$lang['regbadpass'] = 'De to angitte passordene er ikke like, vennligst forsøk igjen.';
+$lang['regpwmail'] = 'Ditt DokuWiki passord';
+$lang['reghere'] = 'Har du ikke en konto ennå? Lag deg en';
+$lang['profna'] = 'Denne wikien støtter ikke profilendringer';
+$lang['profnochange'] = 'Ingen endringer, ingenting å gjøre.';
+$lang['profnoempty'] = 'Tomt navn- eller e-postfelt er ikke tillatt.';
+$lang['profchanged'] = 'Brukerprofilen ble vellykket oppdatert.';
+$lang['pwdforget'] = 'Glemt passordet ditt? Få deg et nytt';
+$lang['resendna'] = 'Denne wikien støtter ikke nyutsending av passord.';
+$lang['resendpwd'] = 'Send nytt passord for';
+$lang['resendpwdmissing'] = 'Beklager, du må fylle inn alle felt.';
+$lang['resendpwdnouser'] = 'Beklager, vi kan ikke finne denne brukeren i vår database.';
+$lang['resendpwdbadauth'] = 'Beklager, denne autorisasjonskoden er ikke gyldig. Sjekk at du brukte hele bekreftelseslenken.';
+$lang['resendpwdconfirm'] = 'En bekreftelseslenke er blitt sendt på e-post.';
+$lang['resendpwdsuccess'] = 'Ditt nye passord er blitt sendt på e-post.';
+$lang['license'] = 'Der annet ikke er angitt, er innholdet på denne wiki utgitt under følgende lisens:';
+$lang['licenseok'] = 'Merk: Ved å endre på denne siden godtar du at ditt innhold utgis under følgende lisens:';
+$lang['searchmedia'] = 'Søk filnavn';
+$lang['searchmedia_in'] = 'Søk i %s';
+$lang['txt_upload'] = 'Velg fil som skal lastes opp';
+$lang['txt_filename'] = 'Skriv inn wikinavn (alternativt)';
+$lang['txt_overwrt'] = 'Overskriv eksisterende fil';
+$lang['lockedby'] = 'Låst av';
+$lang['lockexpire'] = 'Låsingen utløper';
+$lang['js']['willexpire'] = 'Din redigeringslås for dette dokumentet kommer snart til å utløpe.\nFor å unngå versjonskonflikter bør du forhåndsvise dokumentet ditt for å forlenge redigeringslåsen.';
+$lang['js']['notsavedyet'] = 'Ulagrede endringer vil gå tapt!
+Vil du fortsette?';
+$lang['js']['searchmedia'] = 'Søk etter filer';
+$lang['js']['keepopen'] = 'Hold vindu åpent ved valg';
+$lang['js']['hidedetails'] = 'Skjul detaljer';
+$lang['js']['mediatitle'] = 'Lenkeinnstillinger';
+$lang['js']['mediadisplay'] = 'Lenketype';
+$lang['js']['mediaalign'] = 'Justering';
+$lang['js']['mediasize'] = 'Bildestørrelse';
+$lang['js']['mediatarget'] = 'Lenkemål';
+$lang['js']['mediaclose'] = 'Lukk';
+$lang['js']['mediainsert'] = 'Sett inn';
+$lang['js']['mediadisplayimg'] = 'Vis bilde.';
+$lang['js']['mediadisplaylnk'] = 'Vis bare lenken.';
+$lang['js']['mediasmall'] = 'Liten versjon';
+$lang['js']['mediamedium'] = 'Medium versjon';
+$lang['js']['medialarge'] = 'Stor versjon';
+$lang['js']['mediaoriginal'] = 'Original versjon';
+$lang['js']['medialnk'] = 'Lenke til detaljside';
+$lang['js']['mediadirect'] = 'Direktelenke til original';
+$lang['js']['medianolnk'] = 'Ingen lenke';
+$lang['js']['medianolink'] = 'Ikke lenk bildet';
+$lang['js']['medialeft'] = 'Venstrejuster bilde';
+$lang['js']['mediaright'] = 'Høyrejuster bilde';
+$lang['js']['mediacenter'] = 'Midtstill bilde';
+$lang['js']['medianoalign'] = 'Ingen justering';
+$lang['js']['nosmblinks'] = 'Lenker til Windows-ressurser fungerer bare i Microsoft sin Internet Explorer.
+Du kan fortsatt kopiere og lime inn lenken.';
+$lang['js']['linkwiz'] = 'guide til lenker';
+$lang['js']['linkto'] = 'Lenke til:';
+$lang['js']['del_confirm'] = 'Slett denne oppføringen?';
+$lang['js']['restore_confirm'] = 'Er du sikker på at du vil gjenopprette denne versjonen?';
+$lang['js']['media_diff'] = 'Vis forskjeller:';
+$lang['js']['media_diff_both'] = 'Side ved side';
+$lang['js']['media_diff_opacity'] = 'Gjennomskinnelighet';
+$lang['js']['media_diff_portions'] = 'Glidebryter';
+$lang['js']['media_select'] = 'Velg filer…';
+$lang['js']['media_upload_btn'] = 'Last opp';
+$lang['js']['media_done_btn'] = 'Ferdig';
+$lang['js']['media_drop'] = 'Dra filer hit for å laste dem opp';
+$lang['js']['media_cancel'] = 'fjern';
+$lang['js']['media_overwrt'] = 'Erstatt eksisterende filer';
+$lang['rssfailed'] = 'En feil oppstod da denne kilden skulle hentes:';
+$lang['nothingfound'] = 'Ingen data funnet.';
+$lang['mediaselect'] = 'Valg av mediafil';
+$lang['fileupload'] = 'Mediafil Opplasting';
+$lang['uploadsucc'] = 'Opplastingen var vellykket';
+$lang['uploadfail'] = 'Opplastingen var mislykket. Kanskje feil rettigheter?';
+$lang['uploadwrong'] = 'Opplastingen ble nektet. Denne filendelsen er ikke tillatt!';
+$lang['uploadexist'] = 'Filen eksisterer. Ingenting har blitt gjort.';
+$lang['uploadbadcontent'] = 'Det opplastede innholdet passer ikke til filendelsen %s.';
+$lang['uploadspam'] = 'Opplastingen ble blokkert av svartelisten for spam.';
+$lang['uploadxss'] = 'Opplastingen ble blokkert på grunn av mulig skadelig innhold.';
+$lang['uploadsize'] = 'Den opplastede filen var for stor. (max. %s)';
+$lang['deletesucc'] = 'Filen "%s" har blitt slettet.';
+$lang['deletefail'] = '"%s" kunne ikke slettes - sjekk rettighetene.';
+$lang['mediainuse'] = 'Filen "%s" har ikke biltt slettet - den er fortsatt i bruk.';
+$lang['namespaces'] = 'Navnerom';
+$lang['mediafiles'] = 'Tilgjengelige filer i';
+$lang['accessdenied'] = 'Du har ikke tilgang til å se denne siden';
+$lang['mediausage'] = 'Bruk følgende syntaks til å referere til denne filen:';
+$lang['mediaview'] = 'Vis original fil';
+$lang['mediaroot'] = 'rot';
+$lang['mediaupload'] = 'Last opp en fil til gjeldende navnerom her. For å opprette undernavnerom, før dem opp før filnavn i "Last opp som" adskilt med kolon.';
+$lang['mediaextchange'] = 'Filendelse endret fra .%s til .%s!';
+$lang['reference'] = 'Referanser for';
+$lang['ref_inuse'] = 'Denne filen kan ikke slettes fordi den er fortsatt i bruk på følgende sider:';
+$lang['ref_hidden'] = 'Noen referanser er på sider du ikke har tilgang til å lese';
+$lang['hits'] = 'Treff';
+$lang['quickhits'] = 'Matchende wikinavn';
+$lang['toc'] = 'Innholdsfortegnelse';
+$lang['current'] = 'nåværende versjon';
+$lang['yours'] = 'Din versjon';
+$lang['diff'] = 'Vis forskjeller mot nåværende versjon';
+$lang['diff2'] = 'Vis forskjeller mellom valgte versjoner';
+$lang['difflink'] = 'Lenk til denne sammenligningen';
+$lang['diff_type'] = 'Vis forskjeller:';
+$lang['diff_inline'] = 'I teksten';
+$lang['diff_side'] = 'Side ved side';
+$lang['line'] = 'Linje';
+$lang['breadcrumb'] = 'Spor';
+$lang['youarehere'] = 'Du er her';
+$lang['lastmod'] = 'Sist endret';
+$lang['by'] = 'av';
+$lang['deleted'] = 'fjernet';
+$lang['created'] = 'opprettet';
+$lang['restored'] = 'gjenopprettet til en tidligere versjon';
+$lang['external_edit'] = 'ekstern redigering';
+$lang['summary'] = 'Redigeringskommentar';
+$lang['noflash'] = 'For at dette innholdet skal vises må du ha <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>.';
+$lang['download'] = 'Last ned utdraget';
+$lang['mail_newpage'] = 'side lagt til:';
+$lang['mail_changed'] = 'side endret:';
+$lang['mail_subscribe_list'] = 'side endret i \'namespace\':';
+$lang['mail_new_user'] = 'ny bruker:';
+$lang['mail_upload'] = 'fil opplastet:';
+$lang['changes_type'] = 'Vis endringer av';
+$lang['pages_changes'] = 'Sider';
+$lang['media_changes'] = 'Mediefiler';
+$lang['both_changes'] = 'Både sider og mediefiler';
+$lang['qb_bold'] = 'Fet tekst';
+$lang['qb_italic'] = 'Kursiv tekst';
+$lang['qb_underl'] = 'Understreket tekst';
+$lang['qb_code'] = 'Kodetekst';
+$lang['qb_strike'] = 'Gjennomstreket tekst';
+$lang['qb_h1'] = 'Overskrift nivå 1';
+$lang['qb_h2'] = 'Overskrift nivå 2';
+$lang['qb_h3'] = 'Overskrift nivå 3';
+$lang['qb_h4'] = 'Overskrift nivå 4';
+$lang['qb_h5'] = 'Overskrift nivå 5';
+$lang['qb_h'] = 'Overskrift';
+$lang['qb_hs'] = 'Velg overskrift';
+$lang['qb_hplus'] = 'Høyere overskrift';
+$lang['qb_hminus'] = 'Lavere overskrift';
+$lang['qb_hequal'] = 'Overskrift på samme nivå';
+$lang['qb_link'] = 'Intern lenke';
+$lang['qb_extlink'] = 'Ekstern lenke';
+$lang['qb_hr'] = 'Horisontal linje';
+$lang['qb_ol'] = 'Sortert listepunkt';
+$lang['qb_ul'] = 'Usortert listepunkt';
+$lang['qb_media'] = 'Legg til bilder og andre filer';
+$lang['qb_sig'] = 'Føy til signatur';
+$lang['qb_smileys'] = 'Smilefjes';
+$lang['qb_chars'] = 'Spesialtegn';
+$lang['upperns'] = 'gå til overordnet navnerom';
+$lang['admin_register'] = 'Legg til ny bruker';
+$lang['metaedit'] = 'Rediger metadata';
+$lang['metasaveerr'] = 'Skriving av metadata feilet';
+$lang['metasaveok'] = 'Metadata lagret';
+$lang['img_backto'] = 'Tilbake til';
+$lang['img_title'] = 'Tittel';
+$lang['img_caption'] = 'Bildetekst';
+$lang['img_date'] = 'Dato';
+$lang['img_fname'] = 'Filnavn';
+$lang['img_fsize'] = 'Størrelse';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Opphavsrett';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Nøkkelord';
+$lang['img_width'] = 'Bredde';
+$lang['img_height'] = 'Høyde';
+$lang['img_manager'] = 'Vis i mediefilbehandler';
+$lang['subscr_subscribe_success'] = 'La til %s som abonnent på %s';
+$lang['subscr_subscribe_error'] = 'Klarte ikke å legge til %s som abonnent på %s';
+$lang['subscr_subscribe_noaddress'] = 'Brukeren din er ikke registrert med noen adresse. Du kan derfor ikke legges til som abonnent.';
+$lang['subscr_unsubscribe_success'] = 'Avsluttet %s sitt abonnement på %s';
+$lang['subscr_unsubscribe_error'] = 'Klarte ikke å avslutte %s sitt abonnement på %s';
+$lang['subscr_already_subscribed'] = '%s abonnerer allerede på %s';
+$lang['subscr_not_subscribed'] = '%s abonnerer ikke på %s';
+$lang['subscr_m_not_subscribed'] = 'Du abonnerer ikke på denne sida eller dette navnerommet';
+$lang['subscr_m_new_header'] = 'Legg til abonnement';
+$lang['subscr_m_current_header'] = 'Gjeldende abonnementer';
+$lang['subscr_m_unsubscribe'] = 'Stoppe abonnement';
+$lang['subscr_m_subscribe'] = 'Abonnere på';
+$lang['subscr_m_receive'] = 'Motta';
+$lang['subscr_style_every'] = 'e-post for alle endringer';
+$lang['subscr_style_digest'] = 'e-post med sammendrag av endringer for hver side (%.2f dager mellom hver)';
+$lang['subscr_style_list'] = 'liste med sider som er endra siden forrige e-post (%.2f dager mellom hver)';
+$lang['authmodfailed'] = 'Feilkonfigurert brukerautorisasjon. Vennligst innformer Wiki-admin.';
+$lang['authtempfail'] = 'Brukerautorisasjon er midlertidig utilgjengelig. Om dette vedvarer, vennligst informer Wiki-admin.';
+$lang['i_chooselang'] = 'Velg språk';
+$lang['i_installer'] = 'DokuWiki-installasjon';
+$lang['i_wikiname'] = 'Wikinavn';
+$lang['i_enableacl'] = 'Aktiver ACL (anbefalt)';
+$lang['i_superuser'] = 'Superbruker';
+$lang['i_problems'] = 'Installasjonen oppdaget noen problemer, disse listes nedenfor. Du kan ikke fortsett før du har løst disse.';
+$lang['i_modified'] = 'For sikkerhets skyld vil dette skriptet bare virke med en ny og uendret Dokuwiki-installsjon.
+ Du bør enten pakke ut filene på nytt fra den nedlastede pakken, eller konsultere den komplette
+ <a href="http://dokuwiki.org/install">Dokuwiki-installasjonsinstruksen</a>';
+$lang['i_funcna'] = 'PHP-funksjonen <code>%s</code> er ikke tilgjengelig. Kanskje din leverandør har deaktivert den av noen grunn?';
+$lang['i_phpver'] = 'Din PHP versjon <code>%s</code> er lavere enn kravet <code>%s</code>. Du må oppgradere PHP installasjonen. ';
+$lang['i_permfail'] = '<code>%s</code> er ikke skrivbar for DokuWiki. Du må fikse rettighetene for denne mappen!';
+$lang['i_confexists'] = '<code>%s</code> eksisterer allerede';
+$lang['i_writeerr'] = 'Kunne ikke opprette <code>%s</code>. Du må sjekke mappe-/filrettigheter og opprette filen manuelt.';
+$lang['i_badhash'] = 'ikke gjenkjent eller modifisert dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - ugyldig eller tom verdi';
+$lang['i_success'] = 'Konfigurasjonen ble vellykket fullført. Du kan slette install.php filen nå. Fortsett til
+ <a href="doku.php">din nye DokuWiki</a>.';
+$lang['i_failure'] = 'En eller flere feil oppstod ved skriving til konfigurasjonsfilene. Du må kanskje fikse dem manuelt før
+ du kan bruke <a href="doku.php">din nye DokuWiki</a>.';
+$lang['i_policy'] = 'Innledende ACL-politikk';
+$lang['i_pol0'] = 'Åpen Wiki (les, skriv og opplasting for alle)';
+$lang['i_pol1'] = 'Offentlig Wiki (les for alle, skriving og opplasting bare for registrerte brukere)';
+$lang['i_pol2'] = 'Lukket Wiki (les, skriv og opplasting bare for registrerte brukere)';
+$lang['i_retry'] = 'Prøv igjen';
+$lang['i_license'] = 'Velg lisens som du vil legge ut innholdet under:';
+$lang['recent_global'] = 'Du ser nå på endringene i navnerommet <b>%s</b>. Du kan også<a href="%s">se på nylig foretatte endringer for hele wikien</a>.';
+$lang['years'] = '%d år siden';
+$lang['months'] = '%d måneder siden';
+$lang['weeks'] = '%d uker siden';
+$lang['days'] = '%d dager siden';
+$lang['hours'] = '%d timer siden';
+$lang['minutes'] = '%d minutter siden';
+$lang['seconds'] = '%d sekunder siden';
+$lang['wordblock'] = 'Din endring ble ikke lagret ettersom den inneholder blokkert tekst (søppel).';
+$lang['media_uploadtab'] = 'Last opp';
+$lang['media_searchtab'] = 'Søk';
+$lang['media_file'] = 'Fil';
+$lang['media_viewtab'] = 'Vis';
+$lang['media_edittab'] = 'Rediger';
+$lang['media_historytab'] = 'Historikk';
+$lang['media_list_thumbs'] = 'Miniatyrbilder';
+$lang['media_list_rows'] = 'Rader';
+$lang['media_sort_name'] = 'etter navn';
+$lang['media_sort_date'] = 'etter dato';
+$lang['media_namespaces'] = 'Velg navnerom';
+$lang['media_files'] = 'Filer i %s';
+$lang['media_upload'] = 'Last opp til navnerommet <strong>%s</strong>.';
+$lang['media_search'] = 'Søk i navnerommet <strong>%s</strong>.';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s på %s';
+$lang['media_edit'] = 'Rediger';
+$lang['media_history'] = 'Dette er de tidligere versjonene av filen.';
+$lang['media_meta_edited'] = 'metadata er endra';
+$lang['media_perm_read'] = 'Beklager, du har ikke tilgang til å lese filer.';
+$lang['media_perm_upload'] = 'Beklager, du har ikke tilgang til å laste opp filer.';
+$lang['media_update'] = 'Last opp ny versjon';
+$lang['media_restore'] = 'Gjenopprett denne versjonen';
+$lang['plugin_install_err'] = 'Tillegget ble feil installert. Skift navn på mappen \'%s\' til \'%s\'.';
diff --git a/inc/lang/no/locked.txt b/inc/lang/no/locked.txt
new file mode 100644
index 000000000..cb14c892e
--- /dev/null
+++ b/inc/lang/no/locked.txt
@@ -0,0 +1,3 @@
+====== Dokumentet er låst ======
+
+Dette dokumentet er for tiden låst for redigering av en annen bruker. Du må vente til denne brukeren er ferdig med sin redigering, eller til dokumentlåsen opphører å gjelde.
diff --git a/inc/lang/no/login.txt b/inc/lang/no/login.txt
new file mode 100644
index 000000000..149cf0031
--- /dev/null
+++ b/inc/lang/no/login.txt
@@ -0,0 +1,4 @@
+====== Logg inn ======
+
+Du er ikke innlogget! Angi ditt brukernavn og passord nedenfor for å logge inn. Støtte for såkalte "cookies" må være aktivert i din nettleser for at du skal kunne logge inn.
+
diff --git a/inc/lang/no/mailtext.txt b/inc/lang/no/mailtext.txt
new file mode 100644
index 000000000..9c0714c2f
--- /dev/null
+++ b/inc/lang/no/mailtext.txt
@@ -0,0 +1,17 @@
+En side i din DokuWiki har blitt lagt til eller blitt endret. Informasjon om endringen:
+
+Dato : @DATE@
+Nettleser : @BROWSER@
+IP-adresse : @IPADDRESS@
+Vertsnavn : @HOSTNAME@
+Tidligere versjon : @OLDPAGE@
+Aktuell versjon : @NEWPAGE@
+Redigeringskommentar : @SUMMARY@
+Bruker : @USER@
+
+@DIFF@
+
+
+--
+Denne meldingen ble laget av DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/no/newpage.txt b/inc/lang/no/newpage.txt
new file mode 100644
index 000000000..86cad00ed
--- /dev/null
+++ b/inc/lang/no/newpage.txt
@@ -0,0 +1,3 @@
+====== Dette emnet har ikke noe innhold ======
+
+Du har klikket på en lenke til et emne som ikke finnes ennå. Du kan opprette det ved å klikke på ''**Lag denne siden**''.
diff --git a/inc/lang/no/norev.txt b/inc/lang/no/norev.txt
new file mode 100644
index 000000000..cc58c99e3
--- /dev/null
+++ b/inc/lang/no/norev.txt
@@ -0,0 +1,4 @@
+====== Versjonen finnes ikke ======
+
+Den angitte versjonen finnes ikke. Bruk ''**Historikk**'' for en oversikt over de versjoner som finnes av dette dokumentet.
+
diff --git a/inc/lang/no/password.txt b/inc/lang/no/password.txt
new file mode 100644
index 000000000..bc4e89f2b
--- /dev/null
+++ b/inc/lang/no/password.txt
@@ -0,0 +1,10 @@
+Hei @FULLNAME@!
+
+Her er dine brukeropplysninger for @TITLE@ på @DOKUWIKIURL@
+
+Brukernavn : @LOGIN@
+Passord : @PASSWORD@
+
+--
+Denne meldingen ble laget av DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/no/preview.txt b/inc/lang/no/preview.txt
new file mode 100644
index 000000000..2bed20e86
--- /dev/null
+++ b/inc/lang/no/preview.txt
@@ -0,0 +1,4 @@
+====== Forhåndsvisning ======
+
+Dette er en forhåndsvisning av hvordan din tekst kommer til å se ut når den blir vist. Husk at den er **ikke lagret** ennå!
+
diff --git a/inc/lang/no/pwconfirm.txt b/inc/lang/no/pwconfirm.txt
new file mode 100644
index 000000000..36163c6e7
--- /dev/null
+++ b/inc/lang/no/pwconfirm.txt
@@ -0,0 +1,15 @@
+Hei @FULLNAME@!
+
+Noen har bedt om nytt passord for din @TITLE@ innlogging
+på @DOKUWIKIURL@
+
+Om du ikke ba om nytt passord kan du bare overse denne e-posten.
+
+For å bekrefte at forespørselen virkelig kom fra deg kan du bruke
+følgende lenke:
+
+@CONFIRM@
+
+--
+Denne e-posten ble generert av DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/no/read.txt b/inc/lang/no/read.txt
new file mode 100644
index 000000000..27fcb5118
--- /dev/null
+++ b/inc/lang/no/read.txt
@@ -0,0 +1,2 @@
+Denne siden er skrivebeskyttet. Du kan se på den, men ikke endre den. Kontakt administratoren hvis du mener at du bør kunne endre siden.
+
diff --git a/inc/lang/no/recent.txt b/inc/lang/no/recent.txt
new file mode 100644
index 000000000..857013c32
--- /dev/null
+++ b/inc/lang/no/recent.txt
@@ -0,0 +1,5 @@
+====== Siste nytt ======
+
+Følgende sider har nylig blitt oppdatert.
+
+
diff --git a/inc/lang/no/register.txt b/inc/lang/no/register.txt
new file mode 100644
index 000000000..160e47364
--- /dev/null
+++ b/inc/lang/no/register.txt
@@ -0,0 +1,4 @@
+====== Registrer deg som bruker ======
+
+Angi all informasjon som det blir spurt om nedenfor for å lage en ny brukerkonto for denne wikien. Vær spesielt nøye med å angi en **gyldig e-postadresse** - ditt passord vil bli sendt til den e-postadressen du angir. Brukernavnet må være et gyldig [[doku>pagename|sidenavn]].
+
diff --git a/inc/lang/no/registermail.txt b/inc/lang/no/registermail.txt
new file mode 100644
index 000000000..35ed253ab
--- /dev/null
+++ b/inc/lang/no/registermail.txt
@@ -0,0 +1,14 @@
+En ny bruker har registrert seg, her er detaljene:
+
+Brukernavn : @NEWUSER@
+Fult navn : @NEWNAME@
+E-post : @NEWEMAIL@
+
+Dato : @DATE@
+Nettleser : @BROWSER@
+IP-adresse : @IPADDRESS@
+Tjener : @HOSTNAME@
+
+--
+Denne e-posten ble generert av DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/no/resendpwd.txt b/inc/lang/no/resendpwd.txt
new file mode 100644
index 000000000..21625d3f5
--- /dev/null
+++ b/inc/lang/no/resendpwd.txt
@@ -0,0 +1,4 @@
+====== Send nytt passord ======
+
+Fyll inn ditt brukernavn i skjema nedenfor for å be om nytt passord for din konto i denne wiki. En bekreftelseslenke vil bli sent til din e-postadresse.
+
diff --git a/inc/lang/no/revisions.txt b/inc/lang/no/revisions.txt
new file mode 100644
index 000000000..023fd8dce
--- /dev/null
+++ b/inc/lang/no/revisions.txt
@@ -0,0 +1,4 @@
+====== Historikk ======
+
+Her vises tidligere versjoner av dokumentet. For å sette dette dokumentet tilbake til en tidligere versjon kan du velge den ønskede versjonen nedenfor, klikke på **''Rediger denne siden''** og lagre dokumentet.
+
diff --git a/inc/lang/no/searchpage.txt b/inc/lang/no/searchpage.txt
new file mode 100644
index 000000000..e94e7895b
--- /dev/null
+++ b/inc/lang/no/searchpage.txt
@@ -0,0 +1,5 @@
+====== Søk ======
+
+Du ser resultatet av dette søket nedenfor. Hvis du ikke finner det du leter etter, så kan du skape en ny side med samme navn som ditt søk ved å klikke på ''**Lag denne siden**''-knappen.
+
+===== Resultat =====
diff --git a/inc/lang/no/showrev.txt b/inc/lang/no/showrev.txt
new file mode 100644
index 000000000..06514f2bd
--- /dev/null
+++ b/inc/lang/no/showrev.txt
@@ -0,0 +1,2 @@
+**Dette er en gammel utgave av dokumentet!**
+----
diff --git a/inc/lang/no/stopwords.txt b/inc/lang/no/stopwords.txt
new file mode 100644
index 000000000..9a4c302d9
--- /dev/null
+++ b/inc/lang/no/stopwords.txt
@@ -0,0 +1,68 @@
+# Dette er en liste med ord som indeksereren ignorerer, ett ord per linje.
+# Når du redigerer siden, pass på å bruke UNIX linjeslutt (enkel ny linje).
+# Ord kortere enn 3 bokstaver er automatisk ignorert.
+# Listen er basert på http://helmer.aksis.uib.no/nta/ord10000.txt
+i
+og
+det
+er
+på
+til
+som
+en
+for
+av
+at
+har
+med
+de
+ikke
+den
+han
+om
+et
+fra
+men
+vi
+var
+jeg
+seg
+sier
+vil
+kan
+ble
+skal
+etter
+også
+så
+ut
+år
+nå
+da
+dette
+blir
+ved
+mot
+hadde
+to
+hun
+over
+være
+ha
+må
+går
+opp
+få
+andre
+eller
+bare
+sin
+mer
+inn
+før
+bli
+vært
+enn
+alle
+www \ No newline at end of file
diff --git a/inc/lang/no/subscr_digest.txt b/inc/lang/no/subscr_digest.txt
new file mode 100644
index 000000000..6afd0cc5c
--- /dev/null
+++ b/inc/lang/no/subscr_digest.txt
@@ -0,0 +1,20 @@
+Hei!
+
+Siden @PAGE@ på wikien @TITLE@ har blitt endret.
+Her er endringene:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Gammel versjon : @OLDPAGE@
+Ny versjon: @NEWPAGE@
+
+For å avslutte varslingen, logg inn på
+@DOKUWIKIURL@ og gå til
+@NEWPAGE@
+og avslutt abonnementet på endringer av siden eller i navnerommet.
+
+--
+Denne e-posten ble generert av DokuWiki på
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/no/subscr_form.txt b/inc/lang/no/subscr_form.txt
new file mode 100644
index 000000000..f62b25bec
--- /dev/null
+++ b/inc/lang/no/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Administrere abonnement ======
+
+Denne siden lar deg administrere abonnementene dine for denne siden og dette navnerommet. \ No newline at end of file
diff --git a/inc/lang/no/subscr_list.txt b/inc/lang/no/subscr_list.txt
new file mode 100644
index 000000000..72cd307cb
--- /dev/null
+++ b/inc/lang/no/subscr_list.txt
@@ -0,0 +1,17 @@
+Hei!
+
+Sider i navnerommet @PAGE@ på wikien @TITLE@ har blitt endra.
+Her er endringene:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+For å avslutte varslinga, logg inn på
+@DOKUWIKIURL@ og gå til
+@NEWPAGE@
+og avslutt abonnementet på endringer av sida eller i navnerommet.
+
+--
+Denne e-posten ble generert av DokuWiki på
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/no/subscr_single.txt b/inc/lang/no/subscr_single.txt
new file mode 100644
index 000000000..25296da58
--- /dev/null
+++ b/inc/lang/no/subscr_single.txt
@@ -0,0 +1,23 @@
+Hei!
+
+Siden @PAGE@ på wikien @TITLE@ har blitt endret.
+Her er endringene:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Dato : @DATE@
+Bruker : @USER@
+Sammendrag: @SUMMARY@
+Gammel versjon : @OLDPAGE@
+Ny versjon: @NEWPAGE@
+
+For å avslutte varslingen, logg inn på
+@DOKUWIKIURL@, gå til
+@NEWPAGE@
+og avslutt abonnementet på endringer av siden eller i navnerommet.
+
+--
+Denne e-posten ble generert av DokuWiki på
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/no/updateprofile.txt b/inc/lang/no/updateprofile.txt
new file mode 100644
index 000000000..b2e37e76d
--- /dev/null
+++ b/inc/lang/no/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Oppdater din brukerprofil ======
+
+Du behøver bare fylle ut de felter du ønsker å endre. Du kan ikke endre brukernavnet ditt.
+
+
diff --git a/inc/lang/no/uploadmail.txt b/inc/lang/no/uploadmail.txt
new file mode 100644
index 000000000..2890d962d
--- /dev/null
+++ b/inc/lang/no/uploadmail.txt
@@ -0,0 +1,15 @@
+En fil ble lastet opp på din DokuWiki. Her er detaljene:
+
+Fil : @MEDIA@
+Gammel versjon: @OLD@
+Dato : @DATE@
+Nettleser : @BROWSER@
+IP-adresse : @IPADDRESS@
+Vertnavn : @HOSTNAME@
+Størrelse : @SIZE@
+MIME-type : @MIME@
+Bruker : @USER@
+
+--
+Denne e-posten ble generert av DokuWiki på
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pl/admin.txt b/inc/lang/pl/admin.txt
new file mode 100644
index 000000000..cea45f9d0
--- /dev/null
+++ b/inc/lang/pl/admin.txt
@@ -0,0 +1,4 @@
+====== Administracja ======
+
+Czynności administracyjne DokuWiki.
+
diff --git a/inc/lang/pl/adminplugins.txt b/inc/lang/pl/adminplugins.txt
new file mode 100644
index 000000000..0fb03993e
--- /dev/null
+++ b/inc/lang/pl/adminplugins.txt
@@ -0,0 +1 @@
+===== Dodatkowe Wtyczki ===== \ No newline at end of file
diff --git a/inc/lang/pl/backlinks.txt b/inc/lang/pl/backlinks.txt
new file mode 100644
index 000000000..4edccb09b
--- /dev/null
+++ b/inc/lang/pl/backlinks.txt
@@ -0,0 +1,4 @@
+====== Odnośnik z innych stron ======
+
+Strony zawierające odnośniki do aktualnej strony.
+
diff --git a/inc/lang/pl/conflict.txt b/inc/lang/pl/conflict.txt
new file mode 100644
index 000000000..da6f95260
--- /dev/null
+++ b/inc/lang/pl/conflict.txt
@@ -0,0 +1,6 @@
+====== Istnieje nowsza wersja strony ======
+
+Istnieje nowsza wersja edytowanej strony. Prawdopodobnie ktoś zmienił tę stronę w trakcie Twojej pracy.
+
+Przeglądnij dokładnie poniższe różnice i zdecyduj, którą wersję zatrzymać. Jeśli naciśniesz ''zapisz'' to Twoja wersja zostanie zapisana. Jeśli naciśniesz ''anuluj'' to zostanie wybrana aktualna wersja strony.
+
diff --git a/inc/lang/pl/denied.txt b/inc/lang/pl/denied.txt
new file mode 100644
index 000000000..d402463ef
--- /dev/null
+++ b/inc/lang/pl/denied.txt
@@ -0,0 +1,4 @@
+====== Brak dostępu ======
+
+Nie masz wystarczających uprawnień. Zaloguj się!
+
diff --git a/inc/lang/pl/diff.txt b/inc/lang/pl/diff.txt
new file mode 100644
index 000000000..2c896ddb3
--- /dev/null
+++ b/inc/lang/pl/diff.txt
@@ -0,0 +1,4 @@
+====== Różnice ======
+
+Różnice między wybraną wersją a wersją aktualną.
+
diff --git a/inc/lang/pl/draft.txt b/inc/lang/pl/draft.txt
new file mode 100644
index 000000000..4036c3079
--- /dev/null
+++ b/inc/lang/pl/draft.txt
@@ -0,0 +1,6 @@
+====== Znaleziono szkic strony ======
+
+Twoja ostatnia sesja edycji nie została poprawnie zakończona. DokuWiki automatycznie zachowało szkic strony podczas Twojej pracy abyś mógł (mogła) ją dokończyć. Poniżej możesz zobaczyć co zostało zapisane w czasie ostatnie sesji.
+
+Zdecyduj czy chcesz //przywrócić// ostatnią sesję, //usunąć// ją lub //anulować//.
+
diff --git a/inc/lang/pl/edit.txt b/inc/lang/pl/edit.txt
new file mode 100644
index 000000000..abb20ae1c
--- /dev/null
+++ b/inc/lang/pl/edit.txt
@@ -0,0 +1,4 @@
+Zredaguj tę stronę i naciśnij ''zapisz''.
+
+Na stronie ze [[wiki:syntax|składnią]] znajdziesz opis znaczników wiki. Jeśli chcesz poćwiczyć zajrzyj do [[playground:playground|piaskownicy]].
+
diff --git a/inc/lang/pl/editrev.txt b/inc/lang/pl/editrev.txt
new file mode 100644
index 000000000..1528cac7e
--- /dev/null
+++ b/inc/lang/pl/editrev.txt
@@ -0,0 +1,2 @@
+**Edytujesz nieaktualną wersję strony!** Jeśli ją zapiszesz to stanie się ona wersją aktualną.
+----
diff --git a/inc/lang/pl/index.txt b/inc/lang/pl/index.txt
new file mode 100644
index 000000000..1d3fd27f6
--- /dev/null
+++ b/inc/lang/pl/index.txt
@@ -0,0 +1,4 @@
+====== Indeks ======
+
+Indeks wszystkich dostępnych stron pogrupowany według [[doku>namespaces|katalogów]].
+
diff --git a/inc/lang/pl/install.html b/inc/lang/pl/install.html
new file mode 100644
index 000000000..f1d48c1ad
--- /dev/null
+++ b/inc/lang/pl/install.html
@@ -0,0 +1,23 @@
+<p>Ta strona ma na celu pomóc Ci w instalacji i konfiguracji
+<a href="http://dokuwiki.org">Dokuwiki</a>.
+Więcej informacji o instalatorze znajdziesz w
+<a href="http://dokuwiki.org/installer">dokumentacji instalatora</a>.</p>
+
+<p>DokuWiki używa zwykłych plików do przechowywania zawartości stron oraz wszelkich
+innych informacji takich jak obrazki, poprzednie wersje strony, itp.
+Żeby DokuWiki mogło poprawnie działać <strong>musisz</strong>
+nadać prawo zapisu do katalogu zawierającego te pliki. Instalator nie może wykonać
+tych czynności. Musisz zrobić to za pomocą polecenia powłoki, klienta FTP
+lub panelu kontrolnego Twojego dostawcy usług serwerowych.</p>
+
+<p>Instalator pomoże Ci w konfiguracji uprawnień
+<acronym title="access control list">ACL</acronym>,
+które z kolei umożliwią Ci założenie konta administratora oraz umożliwią dostęp
+do czynności administracyjnych takich jak instalowanie wtyczek, zarządzanie kontami,
+zarządzania uprawnieniami do stron oraz konfiguracji wiki. Użycie tego instalatora
+nie jest konieczne, jego celem jest tylko ułatwienie administracji DokuWiki.</p>
+
+<p>Zaawansowani użytkownicy lub użytkownicy mający specjalne wymagania powinni
+zapoznać się z
+<a href="http://dokuwiki.org/install">instrukcją instalacji</a>
+oraz <a href="http://dokuwiki.org/config">instrukcją konfiguracji</a>.</p>
diff --git a/inc/lang/pl/lang.php b/inc/lang/pl/lang.php
new file mode 100644
index 000000000..42af3d3c4
--- /dev/null
+++ b/inc/lang/pl/lang.php
@@ -0,0 +1,325 @@
+<?php
+/**
+ * polish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Edytuj stronę';
+$lang['btn_source'] = 'Pokaż źródło strony';
+$lang['btn_show'] = 'Pokaż stronę';
+$lang['btn_create'] = 'Utwórz stronę';
+$lang['btn_search'] = 'Szukaj';
+$lang['btn_save'] = 'Zapisz';
+$lang['btn_preview'] = 'Podgląd';
+$lang['btn_top'] = 'Do góry';
+$lang['btn_newer'] = '<< nowsze';
+$lang['btn_older'] = 'starsze >>';
+$lang['btn_revs'] = 'Poprzednie wersje';
+$lang['btn_recent'] = 'Ostatnie zmiany';
+$lang['btn_upload'] = 'Wyślij';
+$lang['btn_cancel'] = 'Anuluj';
+$lang['btn_index'] = 'Indeks';
+$lang['btn_secedit'] = 'Edytuj';
+$lang['btn_login'] = 'Zaloguj';
+$lang['btn_logout'] = 'Wyloguj';
+$lang['btn_admin'] = 'Administracja';
+$lang['btn_update'] = 'Aktualizuj';
+$lang['btn_delete'] = 'Usuń';
+$lang['btn_back'] = 'Wstecz';
+$lang['btn_backlink'] = 'Odnośniki';
+$lang['btn_backtomedia'] = 'Powrót do wyboru pliku';
+$lang['btn_subscribe'] = 'Subskrybuj zmiany';
+$lang['btn_profile'] = 'Aktualizuj profil';
+$lang['btn_reset'] = 'Resetuj';
+$lang['btn_resendpwd'] = 'Prześlij nowe hasło';
+$lang['btn_draft'] = 'Edytuj szkic';
+$lang['btn_recover'] = 'Przywróć szkic';
+$lang['btn_draftdel'] = 'Usuń szkic';
+$lang['btn_revert'] = 'Przywróć';
+$lang['btn_register'] = 'Zarejestruj się!';
+$lang['btn_apply'] = 'Zastosuj';
+$lang['btn_media'] = 'Menadżer multimediów';
+$lang['loggedinas'] = 'Zalogowany jako';
+$lang['user'] = 'Użytkownik';
+$lang['pass'] = 'Hasło';
+$lang['newpass'] = 'Nowe hasło';
+$lang['oldpass'] = 'Potwierdź aktualne hasło';
+$lang['passchk'] = 'Powtórz hasło';
+$lang['remember'] = 'Zapamiętaj';
+$lang['fullname'] = 'Imię i nazwisko';
+$lang['email'] = 'E-mail';
+$lang['profile'] = 'Profil użytkownika';
+$lang['badlogin'] = 'Nazwa użytkownika lub hasło są nieprawidłowe.';
+$lang['minoredit'] = 'Mniejsze zmiany';
+$lang['draftdate'] = 'Czas zachowania szkicu';
+$lang['nosecedit'] = 'Strona została zmodyfikowana, sekcje zostały zmienione. Załadowano całą stronę.';
+$lang['regmissing'] = 'Wypełnij wszystkie pola.';
+$lang['reguexists'] = 'Użytkownik o tej nazwie już istnieje.';
+$lang['regsuccess'] = 'Utworzono użytkownika. Hasło zostało przesłane pocztą.';
+$lang['regsuccess2'] = 'Utworzono użytkownika.';
+$lang['regmailfail'] = 'Wystąpił błąd przy wysyłaniu hasła pocztą!';
+$lang['regbadmail'] = 'Adres e-mail jest nieprawidłowy!';
+$lang['regbadpass'] = 'Hasła nie są identyczne, spróbuj ponownie.';
+$lang['regpwmail'] = 'Twoje hasło do DokuWiki';
+$lang['reghere'] = 'Nie masz jeszcze konta? Zdobądź je';
+$lang['profna'] = 'To wiki nie pozwala na zmianę profilu.';
+$lang['profnochange'] = 'Żadnych zmian, nic do zrobienia.';
+$lang['profnoempty'] = 'Pusta nazwa lub adres e-mail nie dozwolone.';
+$lang['profchanged'] = 'Zaktualizowano profil użytkownika.';
+$lang['pwdforget'] = 'Nie pamiętasz hasła? Zdobądź nowe!';
+$lang['resendna'] = 'To wiki nie pozwala na powtórne przesyłanie hasła.';
+$lang['resendpwd'] = 'Prześlij nowe hasło dla';
+$lang['resendpwdmissing'] = 'Wypełnij wszystkie pola.';
+$lang['resendpwdnouser'] = 'Nie można znaleźć tego użytkownika w bazie danych.';
+$lang['resendpwdbadauth'] = 'Błędny kod autoryzacji! Upewnij się, że użyłeś(aś) właściwego odnośnika.';
+$lang['resendpwdconfirm'] = 'Prośba o potwierdzenie została przesłana pocztą.';
+$lang['resendpwdsuccess'] = 'Nowe hasło zostało wysłane pocztą.';
+$lang['license'] = 'Wszystkie treści w tym wiki, którym nie przyporządkowano licencji, podlegają licencji:';
+$lang['licenseok'] = 'Uwaga: edytując tę stronę zgadzasz się na publikowanie jej treści pod licencją:';
+$lang['searchmedia'] = 'Szukaj pliku o nazwie:';
+$lang['searchmedia_in'] = 'Szukaj w %s';
+$lang['txt_upload'] = 'Wybierz plik do wysłania';
+$lang['txt_filename'] = 'Nazwa pliku (opcjonalnie)';
+$lang['txt_overwrt'] = 'Nadpisać istniejący plik?';
+$lang['lockedby'] = 'Aktualnie zablokowane przez';
+$lang['lockexpire'] = 'Blokada wygasa';
+$lang['js']['willexpire'] = 'Twoja blokada edycji tej strony wygaśnie w ciągu minuty. \nW celu uniknięcia konfliktów użyj przycisku podglądu aby odnowić blokadę.';
+$lang['js']['notsavedyet'] = 'Nie zapisane zmiany zostaną utracone.
+Czy na pewno kontynuować?';
+$lang['js']['searchmedia'] = 'Szukaj plików';
+$lang['js']['keepopen'] = 'Nie zamykaj okna po wyborze';
+$lang['js']['hidedetails'] = 'Ukryj szczegóły';
+$lang['js']['mediatitle'] = 'Ustawienia odnośników';
+$lang['js']['mediadisplay'] = 'Typ odnośnika';
+$lang['js']['mediaalign'] = 'Położenie';
+$lang['js']['mediasize'] = 'Rozmiar grafiki';
+$lang['js']['mediatarget'] = 'Cel odnośnika';
+$lang['js']['mediaclose'] = 'Zamknij';
+$lang['js']['mediainsert'] = 'Wstaw';
+$lang['js']['mediadisplayimg'] = 'Pokaż grafikę';
+$lang['js']['mediadisplaylnk'] = 'Pokaż tylko odnośnik.';
+$lang['js']['mediasmall'] = 'Mały rozmiar';
+$lang['js']['mediamedium'] = 'Średni rozmiar';
+$lang['js']['medialarge'] = 'Duży rozmiar';
+$lang['js']['mediaoriginal'] = 'Wersja oryginalna';
+$lang['js']['medialnk'] = 'Odnośnik do strony ze szczegółami';
+$lang['js']['mediadirect'] = 'Bezpośredni odnośnik do oryginału';
+$lang['js']['medianolnk'] = 'Bez odnośnika';
+$lang['js']['medianolink'] = 'Nie ustawiaj odnośnika do grafiki';
+$lang['js']['medialeft'] = 'Ustaw położenie po lewej stronie.';
+$lang['js']['mediaright'] = 'Ustaw położenie po prawej stronie.';
+$lang['js']['mediacenter'] = 'Ustaw położenie po środku.';
+$lang['js']['medianoalign'] = 'Nie ustawiaj położenia.';
+$lang['js']['nosmblinks'] = 'Odnośniki do zasobów sieci Windows działają tylko w przeglądarce Internet Explorer.
+Możesz skopiować odnośnik.';
+$lang['js']['linkwiz'] = 'Tworzenie odnośników';
+$lang['js']['linkto'] = 'Link do';
+$lang['js']['del_confirm'] = 'Czy na pewno usunąć?';
+$lang['js']['restore_confirm'] = 'Naprawdę przywrócić tą wersję?';
+$lang['js']['media_diff'] = 'Pokaż różnice:';
+$lang['js']['media_diff_both'] = 'Obok siebie';
+$lang['js']['media_diff_opacity'] = 'Przezroczystość';
+$lang['js']['media_diff_portions'] = 'Przesunięcie';
+$lang['js']['media_select'] = 'Wybierz pliki...';
+$lang['js']['media_upload_btn'] = 'Przesłanie plików';
+$lang['js']['media_done_btn'] = 'Zrobione';
+$lang['js']['media_drop'] = 'Upuść tutaj pliki do przesłania';
+$lang['js']['media_cancel'] = 'usuń';
+$lang['js']['media_overwrt'] = 'Nadpisz istniejące pliki';
+$lang['rssfailed'] = 'Wystąpił błąd przy pobieraniu tych danych: ';
+$lang['nothingfound'] = 'Nic nie znaleziono.';
+$lang['mediaselect'] = 'Wysyłanie pliku';
+$lang['fileupload'] = 'Wysyłanie pliku';
+$lang['uploadsucc'] = 'Wysyłanie powiodło się!';
+$lang['uploadfail'] = 'Błąd wysyłania pliku. Czy prawa do katalogów są poprawne?';
+$lang['uploadwrong'] = 'Wysyłanie zabronione. Nie można wysłać plików z takim rozszerzeniem';
+$lang['uploadexist'] = 'Plik już istnieje, nie wykonano operacji.';
+$lang['uploadbadcontent'] = 'Typ pliku "%s" nie odpowiadał jego rozszerzeniu.';
+$lang['uploadspam'] = 'Plik zablokowany przez filtr antyspamowy.';
+$lang['uploadxss'] = 'Plik zablokowany ze względu na podejrzaną zawartość.';
+$lang['uploadsize'] = 'Plik jest za duży (maksymalny rozmiar %s)';
+$lang['deletesucc'] = 'Plik "%s" został usunięty.';
+$lang['deletefail'] = 'Plik "%s" nie został usunięty, sprawdź uprawnienia.';
+$lang['mediainuse'] = 'Plik "%s" nie został usunięty, ponieważ jest używany.';
+$lang['namespaces'] = 'Katalogi';
+$lang['mediafiles'] = 'Dostępne pliki';
+$lang['accessdenied'] = 'Nie masz uprawnień, żeby wyświetlić tę stronę.';
+$lang['mediausage'] = 'Użyj następującej składni w odnośniku do tego pliku:';
+$lang['mediaview'] = 'Pokaż oryginalny plik';
+$lang['mediaroot'] = 'główny';
+$lang['mediaupload'] = 'Umieść plik w aktualnym katalogu. Aby utworzyć podkatalogi, poprzedź nazwę pliku nazwami katalogów oddzielonymi dwukropkami.';
+$lang['mediaextchange'] = 'Rozszerzenie pliku zmieniono z .%s na .%s!';
+$lang['reference'] = 'Odnośniki do';
+$lang['ref_inuse'] = 'Ten plik nie może być usunięty, ponieważ jest używany na następujących stronach:';
+$lang['ref_hidden'] = 'Odnośniki mogą znajdować się na stronach, do których nie masz uprawnień.';
+$lang['hits'] = 'trafień';
+$lang['quickhits'] = 'Pasujące hasła';
+$lang['toc'] = 'Spis treści';
+$lang['current'] = 'aktualna';
+$lang['yours'] = 'Twoja wersja';
+$lang['diff'] = 'Pokaż różnice między wersjami';
+$lang['diff2'] = 'Pokaż różnice między zaznaczonymi wersjami';
+$lang['difflink'] = 'Odnośnik do tego porównania';
+$lang['diff_type'] = 'Zobacz różnice:';
+$lang['diff_inline'] = 'W linii';
+$lang['diff_side'] = 'Jeden obok drugiego';
+$lang['line'] = 'Linia';
+$lang['breadcrumb'] = 'Ślad';
+$lang['youarehere'] = 'Jesteś tutaj';
+$lang['lastmod'] = 'ostatnio zmienione';
+$lang['by'] = 'przez';
+$lang['deleted'] = 'usunięto';
+$lang['created'] = 'utworzono';
+$lang['restored'] = 'przywrócono poprzednią wersję';
+$lang['external_edit'] = 'edycja zewnętrzna';
+$lang['summary'] = 'Opis zmian';
+$lang['noflash'] = 'Plugin <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> jest niezbędny do obejrzenia tej zawartości.';
+$lang['download'] = 'Pobierz zrzut';
+$lang['tools'] = 'Narzędzia';
+$lang['user_tools'] = 'Narzędzia użytkownika';
+$lang['site_tools'] = 'Narzędzia witryny';
+$lang['page_tools'] = 'Narzędzia strony';
+$lang['skip_to_content'] = 'przejście do zawartości';
+$lang['mail_newpage'] = 'Strona dodana:';
+$lang['mail_changed'] = 'Strona zmieniona:';
+$lang['mail_subscribe_list'] = 'Zmienione strony w katalogu:';
+$lang['mail_new_user'] = 'Nowy użytkownik:';
+$lang['mail_upload'] = 'Umieszczono plik:';
+$lang['changes_type'] = 'Zobacz zmiany';
+$lang['pages_changes'] = 'Strony';
+$lang['media_changes'] = 'Pliki multimediów';
+$lang['both_changes'] = 'Zarówno strony jak i pliki multimediów';
+$lang['qb_bold'] = 'Pogrubienie';
+$lang['qb_italic'] = 'Pochylenie';
+$lang['qb_underl'] = 'Podkreślenie';
+$lang['qb_code'] = 'Kod źródłowy';
+$lang['qb_strike'] = 'Przekreślenie';
+$lang['qb_h1'] = 'Nagłówek 1 stopnia';
+$lang['qb_h2'] = 'Nagłówek 2 stopnia';
+$lang['qb_h3'] = 'Nagłówek 3 stopnia';
+$lang['qb_h4'] = 'Nagłówek 4 stopnia';
+$lang['qb_h5'] = 'Nagłówek 5 stopnia';
+$lang['qb_h'] = 'Nagłówek';
+$lang['qb_hs'] = 'Wybierz nagłówek';
+$lang['qb_hplus'] = 'Nagłówek wyższego stopnia';
+$lang['qb_hminus'] = 'Nagłówek niższego stopnia';
+$lang['qb_hequal'] = 'Nagłówek tego samego stopnia';
+$lang['qb_link'] = 'Odnośnik wewnętrzny';
+$lang['qb_extlink'] = 'Odnośnik zewnętrzny';
+$lang['qb_hr'] = 'Linia pozioma';
+$lang['qb_ol'] = 'Numeracja';
+$lang['qb_ul'] = 'Wypunktowanie';
+$lang['qb_media'] = 'Dodaj obrazek lub inny plik';
+$lang['qb_sig'] = 'Wstaw podpis';
+$lang['qb_smileys'] = 'Emotikony';
+$lang['qb_chars'] = 'Znaki specjalne';
+$lang['upperns'] = 'Skok piętro wyżej';
+$lang['admin_register'] = 'Dodawanie użytkownika';
+$lang['metaedit'] = 'Edytuj metadane';
+$lang['metasaveerr'] = 'Zapis metadanych nie powiódł się';
+$lang['metasaveok'] = 'Metadane zapisano';
+$lang['img_backto'] = 'Wróć do';
+$lang['img_title'] = 'Tytuł';
+$lang['img_caption'] = 'Nagłówek';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Nazwa pliku';
+$lang['img_fsize'] = 'Rozmiar';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Prawa autorskie';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Aparat';
+$lang['img_keywords'] = 'Słowa kluczowe';
+$lang['img_width'] = 'Szerokość';
+$lang['img_height'] = 'Wysokość';
+$lang['img_manager'] = 'Zobacz w menadżerze multimediów';
+$lang['subscr_subscribe_success'] = 'Dodano %s do listy subskrypcji %s';
+$lang['subscr_subscribe_error'] = 'Błąd podczas dodawania %s do listy subskrypcji %s';
+$lang['subscr_subscribe_noaddress'] = 'Brak adresu skojarzonego z twoim loginem, nie możesz zostać dodany(a) do listy subskrypcji';
+$lang['subscr_unsubscribe_success'] = 'Usunięto %s z listy subskrypcji %s';
+$lang['subscr_unsubscribe_error'] = 'Błąd podczas usuwania %s z listy subskrypcji %s';
+$lang['subscr_already_subscribed'] = '%s jest już subskrybowany(a) przez %s';
+$lang['subscr_not_subscribed'] = '%s nie jest subskrybowany(a) przez %s';
+$lang['subscr_m_not_subscribed'] = 'Obecnie nie subskrybujesz bieżącej strony lub katalogu.';
+$lang['subscr_m_new_header'] = 'Dodaj subskrypcję';
+$lang['subscr_m_current_header'] = 'Aktualne subskrypcje';
+$lang['subscr_m_unsubscribe'] = 'Zrezygnuj z subskrypcji';
+$lang['subscr_m_subscribe'] = 'Subskrybuj';
+$lang['subscr_m_receive'] = 'Otrzymuj';
+$lang['subscr_style_every'] = 'email przy każdej zmianie';
+$lang['subscr_style_digest'] = 'email ze streszczeniem zmian dla każdej ze stron';
+$lang['subscr_style_list'] = 'lista zmienionych stron od czasu ostatniego emaila';
+$lang['authmodfailed'] = 'Błąd uwierzytelnienia. Powiadom administratora tego wiki.';
+$lang['authtempfail'] = 'Uwierzytelnienie użytkownika jest w tej chwili niemożliwe. Jeśli ta sytuacja się powtórzy, powiadom administratora tego wiki.';
+$lang['i_chooselang'] = 'Wybierz język';
+$lang['i_installer'] = 'Instalator DokuWiki';
+$lang['i_wikiname'] = 'Nazwa Wiki';
+$lang['i_enableacl'] = 'Włącz mechanizm uprawnień ACL (zalecane)';
+$lang['i_superuser'] = 'Administrator';
+$lang['i_problems'] = 'Instalator napotkał poniższe problemy. Nie można kontynuować póki nie zostaną usunięte.';
+$lang['i_modified'] = 'Ze względów bezpieczeństwa, ten skrypt działa tylko z nową i niezmodyfikowaną instalacją DokuWiki.
+Aby uruchomić instalator ponownie, rozpakuj archiwum DokuWiki lub zapoznaj się z <a href="http://dokuwiki.org/install">instrukcją instalacji Dokuwiki</a>';
+$lang['i_funcna'] = 'Funkcja PHP <code>%s</code> jest niedostępna.';
+$lang['i_phpver'] = 'Wersja PHP <code>%s</code> jest niższa od wymaganej <code>%s</code>. Zaktualizuj instalację PHP.';
+$lang['i_permfail'] = 'DokuWiki nie ma prawa zapisu w katalogu <code>%s</code>. Zmień uprawnienia zapisu dla tego katalogu!';
+$lang['i_confexists'] = '<code>%s</code> już istnieje';
+$lang['i_writeerr'] = 'Nie można utworzyć <code>%s</code>. Sprawdź uprawnienia do katalogu lub pliku i stwórz plik ręcznie.';
+$lang['i_badhash'] = 'nierozpoznany lub zmodyfikowany plik dokuwiki.php (skrót=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - nieprawidłowa wartość lub jej brak';
+$lang['i_success'] = 'Konfiguracja pomyślnie zakończona. Możesz teraz usunąć plik install.php. Przejdź do <a href="doku.php">Twojego nowego DokuWiki</a>.';
+$lang['i_failure'] = 'Podczas zapisu plików konfiguracyjnych wystąpiły błędy. Musisz usunąć wszystkie problemy, zanim zaczniesz korzystać z <a href="doku.php">Twojego nowego DokuWiki</a>.';
+$lang['i_policy'] = 'Wstępna polityka uprawnień ACL';
+$lang['i_pol0'] = 'Otwarte Wiki (odczyt, zapis i dodawanie plików dla wszystkich)';
+$lang['i_pol1'] = 'Publiczne Wiki (odczyt dla wszystkich, zapis i dodawanie plików tylko dla zarejestrowanych użytkowników)';
+$lang['i_pol2'] = 'Zamknięte Wiki (odczyt, zapis i dodawanie plików tylko dla zarejestrowanych użytkowników)';
+$lang['i_retry'] = 'Spróbuj ponownie';
+$lang['i_license'] = 'Wybierz licencję, na warunkach której chcesz udostępniać treści:';
+$lang['recent_global'] = 'W tej chwili przeglądasz zmiany w katalogu <b>%s</b>. Możesz przejrzeć także <a href="%s">zmiany w całym wiki</a>.';
+$lang['years'] = '%d lat temu';
+$lang['months'] = '%d miesięcy temu';
+$lang['weeks'] = '%d tygodni temu';
+$lang['days'] = '%d dni temu';
+$lang['hours'] = '%d godzin temu';
+$lang['minutes'] = '%d minut temu';
+$lang['seconds'] = '%d sekund temu';
+$lang['wordblock'] = 'Twoje ustawienia nie zostały zapisane ponieważ zawierają niedozwoloną treść (spam).';
+$lang['media_uploadtab'] = 'Przesyłanie plików';
+$lang['media_searchtab'] = 'Szukaj';
+$lang['media_file'] = 'Plik';
+$lang['media_viewtab'] = 'Widok';
+$lang['media_edittab'] = 'Zmiana';
+$lang['media_historytab'] = 'Historia';
+$lang['media_list_thumbs'] = 'Miniatury';
+$lang['media_list_rows'] = 'Wiersze';
+$lang['media_sort_name'] = 'Nazwa';
+$lang['media_sort_date'] = 'Data';
+$lang['media_namespaces'] = 'Wybierz przestrzeń nazw';
+$lang['media_files'] = 'Pliki w %s';
+$lang['media_upload'] = 'Przesyłanie plików na %s';
+$lang['media_search'] = 'Znajdź w %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s na %s';
+$lang['media_edit'] = 'Zmień %s';
+$lang['media_history'] = 'Historia dla %s';
+$lang['media_meta_edited'] = 'zmienione metadane';
+$lang['media_perm_read'] = 'Przepraszamy, nie masz wystarczających uprawnień do odczytu plików.';
+$lang['media_perm_upload'] = 'Przepraszamy, nie masz wystarczających uprawnień do przesyłania plików.';
+$lang['media_update'] = 'Prześlij nową wersję';
+$lang['media_restore'] = 'Odtwórz tą wersję';
+$lang['plugin_install_err'] = 'Wtyczka zainstalowana nieprawidłowo. Zmień nazwę katalogu wtyczki \'%s\' na \'%s\'.';
diff --git a/inc/lang/pl/locked.txt b/inc/lang/pl/locked.txt
new file mode 100644
index 000000000..e3e05fefc
--- /dev/null
+++ b/inc/lang/pl/locked.txt
@@ -0,0 +1,3 @@
+====== Strona zablokowana ======
+
+Ta strona jest zablokowana do edycji przez innego użytkownika. Musisz zaczekać aż użytkownik zakończy redagowanie lub jego blokada wygaśnie.
diff --git a/inc/lang/pl/login.txt b/inc/lang/pl/login.txt
new file mode 100644
index 000000000..b60427f4f
--- /dev/null
+++ b/inc/lang/pl/login.txt
@@ -0,0 +1,4 @@
+====== Logowanie ======
+
+Wprowadź nazwę użytkownika i hasło aby się zalogować. Twoja przeglądarka musi mieć włączoną obsługę ciasteczek (cookies).
+
diff --git a/inc/lang/pl/mailtext.txt b/inc/lang/pl/mailtext.txt
new file mode 100644
index 000000000..1180966bc
--- /dev/null
+++ b/inc/lang/pl/mailtext.txt
@@ -0,0 +1,18 @@
+Strona w Twoim DokuWiki została dodana lub zmieniona.
+Szczegółowe informacje:
+
+Data : @DATE@
+Przeglądarka : @BROWSER@
+Adres IP : @IPADDRESS@
+Nazwa DNS : @HOSTNAME@
+Stara wersja : @OLDPAGE@
+Nowa wersja : @NEWPAGE@
+Opis zmian : @SUMMARY@
+Użytkownik : @USER@
+
+@DIFF@
+
+
+--
+List został wygenerowany przez DokuWiki pod adresem
+@DOKUWIKIURL@
diff --git a/inc/lang/pl/newpage.txt b/inc/lang/pl/newpage.txt
new file mode 100644
index 000000000..532d3f4ab
--- /dev/null
+++ b/inc/lang/pl/newpage.txt
@@ -0,0 +1,4 @@
+====== Ta strona jeszcze nie istnieje ======
+
+Jesteś na stronie, która jeszcze nie istnieje. Jeśli masz wystarczające uprawnienia, możesz utworzyć tę stronę klikając ''utwórz stronę''.
+
diff --git a/inc/lang/pl/norev.txt b/inc/lang/pl/norev.txt
new file mode 100644
index 000000000..858e4a881
--- /dev/null
+++ b/inc/lang/pl/norev.txt
@@ -0,0 +1,4 @@
+====== Nie ma takiej wersji ======
+
+Nie ma takiej wersji. Kliknij przycisk ''poprzednie wersje'', aby wyświetlić listę wszystkich wersji tej strony.
+
diff --git a/inc/lang/pl/password.txt b/inc/lang/pl/password.txt
new file mode 100644
index 000000000..948472f1b
--- /dev/null
+++ b/inc/lang/pl/password.txt
@@ -0,0 +1,10 @@
+Witaj @FULLNAME@!
+
+Dane użytkownika @TITLE@ pod adresem @DOKUWIKIURL@
+
+Użytkownik : @LOGIN@
+Hasło : @PASSWORD@
+
+--
+List został wygenerowany przez DokuWiki pod adresem
+@DOKUWIKIURL@
diff --git a/inc/lang/pl/preview.txt b/inc/lang/pl/preview.txt
new file mode 100644
index 000000000..41a123cf3
--- /dev/null
+++ b/inc/lang/pl/preview.txt
@@ -0,0 +1,4 @@
+====== Podgląd ======
+
+To jest podgląd edytowanej strony. Pamiętaj, że ta strona **nie** jest jeszcze zapisana!
+
diff --git a/inc/lang/pl/pwconfirm.txt b/inc/lang/pl/pwconfirm.txt
new file mode 100644
index 000000000..f6ccca47e
--- /dev/null
+++ b/inc/lang/pl/pwconfirm.txt
@@ -0,0 +1,13 @@
+Witaj @FULLNAME@!
+
+Potwierdzenie prośby o nowe hasło dla konta @TITLE@ w wiki @DOKUWIKIURL@
+
+Jeśli to nie Ty prosiłeś(aś) o nowe hasło, zignoruj ten list.
+
+Aby potwierdzić prośbę o hasło, przejdź na następującą stronę.
+
+@CONFIRM@
+
+--
+List został wygenerowany przez DokuWiki pod adresem
+@DOKUWIKIURL@
diff --git a/inc/lang/pl/read.txt b/inc/lang/pl/read.txt
new file mode 100644
index 000000000..5f89fd93d
--- /dev/null
+++ b/inc/lang/pl/read.txt
@@ -0,0 +1,2 @@
+Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
+
diff --git a/inc/lang/pl/recent.txt b/inc/lang/pl/recent.txt
new file mode 100644
index 000000000..65a776c0e
--- /dev/null
+++ b/inc/lang/pl/recent.txt
@@ -0,0 +1,5 @@
+====== Ostatnie zmiany ======
+
+Ostatnio zmienione strony.
+
+
diff --git a/inc/lang/pl/register.txt b/inc/lang/pl/register.txt
new file mode 100644
index 000000000..91b761d15
--- /dev/null
+++ b/inc/lang/pl/register.txt
@@ -0,0 +1,4 @@
+====== Rejestracja nowego użytkownika ======
+
+Wypełnij wszystkie pola formularza aby utworzyć nowe konto w tym wiki. Pamiętaj, żeby podać **poprawny adres e-mail**, ponieważ nowe hasło może zostać do Ciebie przesłane pocztą. Nazwa użytkownika powinna być zgodna z formatem [[doku>pagename|nazw stron]].
+
diff --git a/inc/lang/pl/registermail.txt b/inc/lang/pl/registermail.txt
new file mode 100644
index 000000000..18437fa0a
--- /dev/null
+++ b/inc/lang/pl/registermail.txt
@@ -0,0 +1,15 @@
+Zarejestrował się nowy użytkownik.
+Szczegółowe informacje:
+
+Użytkownik : @NEWUSER@
+Imię i nazwisko : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Data : @DATE@
+Przeglądarka : @BROWSER@
+Adres IP : @IPADDRESS@
+Nazwa DNS : @HOSTNAME@
+
+--
+List został wygenerowany przez DokuWiki pod adresem
+@DOKUWIKIURL@
diff --git a/inc/lang/pl/resendpwd.txt b/inc/lang/pl/resendpwd.txt
new file mode 100644
index 000000000..a7cac7442
--- /dev/null
+++ b/inc/lang/pl/resendpwd.txt
@@ -0,0 +1,4 @@
+====== Przesyłanie nowego hasła ======
+
+Aby otrzymać nowe hasło, podaj nazwę Twojego konta w tym wiki. Prośba o potwierdzenie w postaci odnośnika zostanie Ci przesłana pocztą elektroniczną.
+
diff --git a/inc/lang/pl/revisions.txt b/inc/lang/pl/revisions.txt
new file mode 100644
index 000000000..afe2b6478
--- /dev/null
+++ b/inc/lang/pl/revisions.txt
@@ -0,0 +1,4 @@
+====== Poprzednie wersje ======
+
+Poprzednie wersje tej strony. Aby przywrócić poprzednią wersję wybierz ją, rozpocznij edycję a potem zapisz.
+
diff --git a/inc/lang/pl/searchpage.txt b/inc/lang/pl/searchpage.txt
new file mode 100644
index 000000000..61b9ffbf9
--- /dev/null
+++ b/inc/lang/pl/searchpage.txt
@@ -0,0 +1,5 @@
+====== Wyszukiwanie ======
+
+Wyniki wyszukiwania. Jeśli nie znaleziono szukanego hasła, możesz utworzyć nową stronę, której tytułem będzie poszukiwane hasło.
+
+===== Wyniki =====
diff --git a/inc/lang/pl/showrev.txt b/inc/lang/pl/showrev.txt
new file mode 100644
index 000000000..43e826ed5
--- /dev/null
+++ b/inc/lang/pl/showrev.txt
@@ -0,0 +1,2 @@
+**To jest stara wersja strony!**
+----
diff --git a/inc/lang/pl/stopwords.txt b/inc/lang/pl/stopwords.txt
new file mode 100644
index 000000000..f1d244a26
--- /dev/null
+++ b/inc/lang/pl/stopwords.txt
@@ -0,0 +1,89 @@
+# Lista słów ignorowanych przy indeksowaniu treści.
+# W jednej linii powinno znajdować się tylko jedno słowo.
+# Przy edycji tego pliku pamiętaj o używaniu uniksowego końca linii (LF).
+# Nie ma potrzeby wpisywania słów krótszych niż 3 znaki, ponieważ one są zawsze ignorowane.
+# Lista oparta na danych ze strony http://www.ranks.nl/stopwords/
+aby
+ale
+bardziej
+bardzo
+bez
+bowiem
+był
+była
+było
+były
+będzie
+czy
+czyli
+dla
+dlatego
+gdy
+gdzie
+ich
+innych
+jak
+jako
+jednak
+jego
+jej
+jest
+jeszcze
+jeśli
+już
+kiedy
+kilka
+która
+które
+którego
+której
+który
+których
+którym
+którzy
+lub
+między
+mnie
+mogą
+może
+można
+nad
+nam
+nas
+naszego
+naszych
+nawet
+nich
+nie
+nim
+niż
+oraz
+pod
+poza
+przed
+przede
+przez
+przy
+również
+się
+sobie
+swoje
+tak
+takie
+także
+tam
+tego
+tej
+ten
+też
+tych
+tylko
+tym
+wiele
+wielu
+więc
+wszystkich
+wszystkim
+wszystko
+właśnie
+zawsze
diff --git a/inc/lang/pl/subscr_digest.txt b/inc/lang/pl/subscr_digest.txt
new file mode 100644
index 000000000..2b1f63c1b
--- /dev/null
+++ b/inc/lang/pl/subscr_digest.txt
@@ -0,0 +1,21 @@
+Witaj!
+
+Treść strony @PAGE@ na wiki @TITLE@ uległa
+następującym zmianom:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Stara wersja: @OLDPAGE@
+Nowa wersja: @NEWPAGE@
+
+Aby zrezygnować z powiadomień o zmianach zaloguj się do wiki na
+@DOKUWIKIURL@, a następnie odwiedź
+@SUBSCRIBE@
+i anuluj otrzymywanie powiadomień o zmianach na stronach i/lub
+katalogach.
+
+--
+Ta wiadomość została wygenerowana przez DokuWiki na
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pl/subscr_form.txt b/inc/lang/pl/subscr_form.txt
new file mode 100644
index 000000000..59fdbdb89
--- /dev/null
+++ b/inc/lang/pl/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Zarządzanie Subskrypcją ======
+
+Ta strona pozwala Tobie na zarządzanie Twoimi subskrypcjami dla obecnej strony i katalogu. \ No newline at end of file
diff --git a/inc/lang/pl/subscr_list.txt b/inc/lang/pl/subscr_list.txt
new file mode 100644
index 000000000..9a74d757b
--- /dev/null
+++ b/inc/lang/pl/subscr_list.txt
@@ -0,0 +1,18 @@
+Witaj!
+
+Strony w katalogu @PAGE@ na wiki @TITLE@ uległy
+następującym zmianom:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Aby zrezygnować z powiadomień o zmianach zaloguj się do wiki na
+@DOKUWIKIURL@, a następnie odwiedź
+@SUBSCRIBE@
+i anuluj otrzymywanie powiadomień o zmianach na stronach i/lub
+katalogach.
+
+--
+Ta wiadomość została wygenerowana przez DokuWiki na
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pl/subscr_single.txt b/inc/lang/pl/subscr_single.txt
new file mode 100644
index 000000000..3f4bc7314
--- /dev/null
+++ b/inc/lang/pl/subscr_single.txt
@@ -0,0 +1,24 @@
+Witaj!
+
+Treść strony @PAGE@ na wiki @TITLE@ uległa
+następującym zmianom:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Data: @DATE@
+Użytkownik: @USER@
+Podsumowanie zmian: @SUMMARY@
+Stara wersja: @OLDPAGE@
+Nowa wersja: @NEWPAGE@
+
+Aby zrezygnować z powiadomień o zmianach zaloguj się do wiki na
+@DOKUWIKIURL@, a następnie odwiedź
+@SUBSCRIBE@
+i anuluj otrzymywanie powiadomień o zmianach na stronach i/lub
+katalogach.
+
+--
+Ta wiadomość została wygenerowana przez DokuWiki na
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pl/updateprofile.txt b/inc/lang/pl/updateprofile.txt
new file mode 100644
index 000000000..aa80f4cdf
--- /dev/null
+++ b/inc/lang/pl/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Aktualizacja profilu użytkownika ======
+
+Wystarczy, że wypełnisz tylko te pola, które chcesz zmienić. Nie możesz zmienić nazwy użytkownika.
+
+
diff --git a/inc/lang/pl/uploadmail.txt b/inc/lang/pl/uploadmail.txt
new file mode 100644
index 000000000..e76ec80e6
--- /dev/null
+++ b/inc/lang/pl/uploadmail.txt
@@ -0,0 +1,16 @@
+Umieszczono nowy plik.
+
+Szczegóły:
+
+Plik : @MEDIA@
+Data : @DATE@
+Przeglądarka : @BROWSER@
+Adres IP : @IPADDRESS@
+Nazwa DNS : @HOSTNAME@
+Rozmiar : @SIZE@
+Typ MIME : @MIME@
+Użytkownik : @USER@
+
+--
+List został wygenerowany przez DokuWiki pod adresem
+@DOKUWIKIURL@
diff --git a/inc/lang/pt-br/admin.txt b/inc/lang/pt-br/admin.txt
new file mode 100644
index 000000000..f8be56e60
--- /dev/null
+++ b/inc/lang/pt-br/admin.txt
@@ -0,0 +1,4 @@
+====== Administração ======
+
+Abaixo você encontra uma lista das tarefas administrativas disponíveis no DokuWiki.
+
diff --git a/inc/lang/pt-br/adminplugins.txt b/inc/lang/pt-br/adminplugins.txt
new file mode 100644
index 000000000..3eac7af53
--- /dev/null
+++ b/inc/lang/pt-br/adminplugins.txt
@@ -0,0 +1 @@
+===== Plugins Adicionais ===== \ No newline at end of file
diff --git a/inc/lang/pt-br/backlinks.txt b/inc/lang/pt-br/backlinks.txt
new file mode 100644
index 000000000..fce9dba54
--- /dev/null
+++ b/inc/lang/pt-br/backlinks.txt
@@ -0,0 +1,4 @@
+====== Links reversos ======
+
+Esta é uma lista de todas as páginas que apresentam links para a página atual.
+
diff --git a/inc/lang/pt-br/conflict.txt b/inc/lang/pt-br/conflict.txt
new file mode 100644
index 000000000..53d9afac7
--- /dev/null
+++ b/inc/lang/pt-br/conflict.txt
@@ -0,0 +1,5 @@
+====== Existe uma nova versão ======
+
+Existe uma versão mais nova do documento que você editou. Isso acontece quando outro usuário modifica o documento enquanto você o está editando.
+
+Examine as diferenças mostradas abaixo atentamente e então decida qual versão deve permanecer. Se você selecionar ''Salvar'', sua versão será salva. Pressione ''Cancelar'' para manter a versão atual.
diff --git a/inc/lang/pt-br/denied.txt b/inc/lang/pt-br/denied.txt
new file mode 100644
index 000000000..d7e423f42
--- /dev/null
+++ b/inc/lang/pt-br/denied.txt
@@ -0,0 +1,3 @@
+====== Permissão Negada ======
+
+Desculpe, você não tem permissões suficientes para continuar. Por acaso esqueceu de autenticar-se?
diff --git a/inc/lang/pt-br/diff.txt b/inc/lang/pt-br/diff.txt
new file mode 100644
index 000000000..517d9f275
--- /dev/null
+++ b/inc/lang/pt-br/diff.txt
@@ -0,0 +1,3 @@
+====== Diferenças ======
+
+Aqui você vê as diferenças entre duas revisões dessa página.
diff --git a/inc/lang/pt-br/draft.txt b/inc/lang/pt-br/draft.txt
new file mode 100644
index 000000000..b3d345cca
--- /dev/null
+++ b/inc/lang/pt-br/draft.txt
@@ -0,0 +1,5 @@
+====== Rascunho encontrado ======
+
+A sua última sessão de edição não foi concluída corretamente. O DokuWiki automaticamente salvou um rascunho durante o seu trabalho, que você pode usar agora para continuar a sua edição. Abaixo você pode ver os dados que foram salvos na sua última sessão.
+
+Por favor, escolha se você quer //recuperar// sua sessão de edição perdida, //excluir// o rascunho salvo automaticamente ou //cancelar// o processo de edição. \ No newline at end of file
diff --git a/inc/lang/pt-br/edit.txt b/inc/lang/pt-br/edit.txt
new file mode 100644
index 000000000..113fb8ede
--- /dev/null
+++ b/inc/lang/pt-br/edit.txt
@@ -0,0 +1,2 @@
+Edite a página e clique em ''Salvar''. Veja [[wiki:syntax|aqui]] a sintaxe do Wiki. Por favor, edite a página apenas se você puder **aprimorá-la**. Se você deseja testar alguma coisa, faça-o no [[playground:playground|playground]].
+
diff --git a/inc/lang/pt-br/editrev.txt b/inc/lang/pt-br/editrev.txt
new file mode 100644
index 000000000..c7aa47878
--- /dev/null
+++ b/inc/lang/pt-br/editrev.txt
@@ -0,0 +1,4 @@
+**Você carregou uma revisão antiga desse documento!** Se você salvá-la, irá criar uma nova versão em esses dados.
+----
+
+
diff --git a/inc/lang/pt-br/index.txt b/inc/lang/pt-br/index.txt
new file mode 100644
index 000000000..a7d17a2bc
--- /dev/null
+++ b/inc/lang/pt-br/index.txt
@@ -0,0 +1,3 @@
+====== Índice ======
+
+Esse é um índice de todas as páginas disponíveis, ordenadas por [[doku>namespaces|espaços de nomes]]. \ No newline at end of file
diff --git a/inc/lang/pt-br/install.html b/inc/lang/pt-br/install.html
new file mode 100644
index 000000000..b915f0701
--- /dev/null
+++ b/inc/lang/pt-br/install.html
@@ -0,0 +1,7 @@
+<p>Essa página irá auxiliá-lo na instalação e configuração do <a href="http://dokuwiki.org">DokuWiki</a>. Você encontra mais informações sobre esse instalador na sua <a href="http://dokuwiki.org/installer">página de documentação</a>.</p>
+
+<p>O DokuWiki utiliza arquivos em texto simples para o armazenamento das páginas wiki e de outras informações associadas a essas páginas (ex.: imagens, índices de pesquisa, revisões antigas, etc.). Para que o DokuWiki funcione corretamente, ele <strong>precisa</strong> ter permissão de escrita aos diretórios onde esses arquivos ficarão armazenados. Esse instalador não tem capacidade de configurar as permissões de diretório. Isso normalmente é feito usando-se a linha de comando ou através do FTP ou do painel de controle da sua hospedagem (ex.: cPanel).</p>
+
+<p>O instalador irá definir as configurações da <acronym title="access control list (lista de controle de acessos)">ACL</acronym> do seu DokuWiki, o que permitirá a autenticação do administrador e o acesso ao menu de administração do sistema. Esse menu é utilizado para instalar plug-ins, alterar as configurações do ambiente e gerenciar usuários e acessos às páginas do wiki. Isso não é necessário para o funcionamento do DokuWiki, mas irá torna sua administração mais simples.</p>
+
+<p>Usuários experientes ou que necessitem efetuar configurações especiais devem utilizar os seguintes links, com instruções detalhadas da <a href="http://dokuwiki.org/install">instalação</a> e da <a href="http://dokuwiki.org/config">configuração</a>.</p> \ No newline at end of file
diff --git a/inc/lang/pt-br/lang.php b/inc/lang/pt-br/lang.php
new file mode 100644
index 000000000..e4dc50ddc
--- /dev/null
+++ b/inc/lang/pt-br/lang.php
@@ -0,0 +1,282 @@
+<?php
+/**
+ * Brazilian Portuguese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Luis Fernando Enciso <lfenciso@certto.com.br>
+ * @author Alauton/Loug
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Sergio Motta <sergio@cisne.com.br>
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Editar esta página';
+$lang['btn_source'] = 'Mostrar código fonte';
+$lang['btn_show'] = 'Mostrar página';
+$lang['btn_create'] = 'Criar esta página';
+$lang['btn_search'] = 'Pesquisar';
+$lang['btn_save'] = 'Salvar';
+$lang['btn_preview'] = 'Visualizar';
+$lang['btn_top'] = 'Voltar ao topo';
+$lang['btn_newer'] = '<< mais recente';
+$lang['btn_older'] = 'menos recente >>';
+$lang['btn_revs'] = 'Revisões anteriores';
+$lang['btn_recent'] = 'Alterações recentes';
+$lang['btn_upload'] = 'Enviar';
+$lang['btn_cancel'] = 'Cancelar';
+$lang['btn_index'] = 'Índice';
+$lang['btn_secedit'] = 'Editar';
+$lang['btn_login'] = 'Entrar';
+$lang['btn_logout'] = 'Sair';
+$lang['btn_admin'] = 'Administrar';
+$lang['btn_update'] = 'Atualizar';
+$lang['btn_delete'] = 'Excluir';
+$lang['btn_back'] = 'Voltar';
+$lang['btn_backlink'] = 'Links reversos';
+$lang['btn_backtomedia'] = 'Voltar à seleção do arquivo de mídia';
+$lang['btn_subscribe'] = 'Monitorar alterações';
+$lang['btn_profile'] = 'Atualizar o perfil';
+$lang['btn_reset'] = 'Limpar';
+$lang['btn_resendpwd'] = 'Envie-me uma nova senha';
+$lang['btn_draft'] = 'Editar o rascunho';
+$lang['btn_recover'] = 'Recuperar o rascunho';
+$lang['btn_draftdel'] = 'Excluir o rascunho';
+$lang['btn_revert'] = 'Restaurar';
+$lang['btn_register'] = 'Cadastre-se';
+$lang['loggedinas'] = 'Identificado(a) como';
+$lang['user'] = 'Nome de usuário';
+$lang['pass'] = 'Senha';
+$lang['newpass'] = 'Nova senha';
+$lang['oldpass'] = 'Confirme a senha atual';
+$lang['passchk'] = 'Outra vez';
+$lang['remember'] = 'Lembre-se de mim';
+$lang['fullname'] = 'Nome completo';
+$lang['email'] = 'E-mail';
+$lang['profile'] = 'Perfil do usuário';
+$lang['badlogin'] = 'Desculpe, mas o nome de usuário ou a senha estão incorretos.';
+$lang['minoredit'] = 'Alterações mínimas';
+$lang['draftdate'] = 'O rascunho foi salvo automaticamente em';
+$lang['nosecedit'] = 'A página foi modificada nesse intervalo de tempo. Como a informação da seção estava desatualizada, foi carregada a página inteira.';
+$lang['regmissing'] = 'Desculpe, mas você precisa preencher todos os campos.';
+$lang['reguexists'] = 'Desculpe, mas já existe um usuário com esse nome.';
+$lang['regsuccess'] = 'O usuário foi criado e a senha enviada para seu e-mail.';
+$lang['regsuccess2'] = 'O usuário foi criado.';
+$lang['regmailfail'] = 'Aparentemente ocorreu um erro no envio da senha. Por favor, entre em contato com o administrador!';
+$lang['regbadmail'] = 'O endereço de e-mail fornecido é, aparentemente, inválido - se você acha que isso é um erro, entre em contato com o administrador';
+$lang['regbadpass'] = 'As senhas digitadas não são idênticas. Por favor, tente novamente.';
+$lang['regpwmail'] = 'A sua senha do DokuWiki';
+$lang['reghere'] = 'Ainda não tem uma conta? Crie uma';
+$lang['profna'] = 'Esse wiki não suporta modificações do perfil.';
+$lang['profnochange'] = 'Sem alterações, nada para fazer.';
+$lang['profnoempty'] = 'Não são permitidos nomes ou endereços de e-mail em branco.';
+$lang['profchanged'] = 'O perfil do usuário foi atualizado com sucesso.';
+$lang['pwdforget'] = 'Esqueceu sua senha? Solicite outra';
+$lang['resendna'] = 'Esse wiki não tem suporte para o reenvio de senhas.';
+$lang['resendpwd'] = 'Enviar a nova senha para';
+$lang['resendpwdmissing'] = 'Desculpe, você deve preencher todos os campos.';
+$lang['resendpwdnouser'] = 'Desculpe, não foi possível encontrar esse usuário no nosso banco de dados.';
+$lang['resendpwdbadauth'] = 'Desculpe, esse código de autorização é inválido. Certifique-se de que você usou o link de confirmação inteiro.';
+$lang['resendpwdconfirm'] = 'Um link de confirmação foi enviado por e-mail.';
+$lang['resendpwdsuccess'] = 'Sua nova senha foi enviada por e-mail.';
+$lang['license'] = 'Exceto onde for informado ao contrário, o conteúdo neste wiki está sob a seguinte licença:';
+$lang['licenseok'] = 'Observe: editando esta página você aceita disponibilizar o seu conteúdo sob a seguinte licença:';
+$lang['searchmedia'] = 'Buscar arquivo:';
+$lang['searchmedia_in'] = 'Buscar em %s';
+$lang['txt_upload'] = 'Selecione o arquivo a ser enviado';
+$lang['txt_filename'] = 'Enviar como (opcional)';
+$lang['txt_overwrt'] = 'Substituir o arquivo existente';
+$lang['lockedby'] = 'Atualmente bloqueada por';
+$lang['lockexpire'] = 'O bloqueio expira em';
+$lang['js']['willexpire'] = 'O seu bloqueio de edição deste página irá expirar em um minuto.\nPara evitar conflitos de edição, clique no botão de visualização para reiniciar o temporizador de bloqueio.';
+$lang['js']['notsavedyet'] = 'As alterações não salvas serão perdidas.
+Deseja realmente continuar?';
+$lang['js']['searchmedia'] = 'Buscar por arquivos';
+$lang['js']['keepopen'] = 'Manter a janela aberta na seleção';
+$lang['js']['hidedetails'] = 'Esconder detalhes';
+$lang['js']['mediatitle'] = 'Configurações do Link';
+$lang['js']['mediadisplay'] = 'Tipo de Link';
+$lang['js']['mediaalign'] = 'Alinhamento';
+$lang['js']['mediasize'] = 'Tamanho da Imagem';
+$lang['js']['mediatarget'] = 'Alvo do Link';
+$lang['js']['mediaclose'] = 'Fechar';
+$lang['js']['mediainsert'] = 'Inserir';
+$lang['js']['mediadisplayimg'] = 'Mostrar Imagem.';
+$lang['js']['mediadisplaylnk'] = 'Mostrar apenas Link.';
+$lang['js']['mediasmall'] = 'Versão Pequena';
+$lang['js']['mediamedium'] = 'Versão Média';
+$lang['js']['medialarge'] = 'Versão Grande';
+$lang['js']['mediaoriginal'] = 'Versão Original';
+$lang['js']['medialnk'] = 'Link para página de detalhes';
+$lang['js']['mediadirect'] = 'Link direto para original';
+$lang['js']['medianolnk'] = 'Sem Link';
+$lang['js']['medianolink'] = 'Sem link na imagem';
+$lang['js']['medialeft'] = 'Alinhamento de imagem a esquerda';
+$lang['js']['mediaright'] = 'Alinhamento de imagem a direita';
+$lang['js']['mediacenter'] = 'Alinhamento de imagem ao centro';
+$lang['js']['medianoalign'] = 'Sem alinhamento';
+$lang['js']['nosmblinks'] = 'Atalhos para pastas compartilhadas do Windows funcionam apenas no Microsoft Internet Explorer.
+Entretanto, você ainda pode copiar e colar o atalho.';
+$lang['js']['linkwiz'] = 'Link Wizard';
+$lang['js']['linkto'] = 'Link para:';
+$lang['js']['del_confirm'] = 'Deseja realmente excluir o(s) item(ns) selecionado(s)?';
+$lang['rssfailed'] = 'Ocorreu um erro durante a atualização dessa fonte: ';
+$lang['nothingfound'] = 'Não foi encontrado nada.';
+$lang['mediaselect'] = 'Arquivos de mídia';
+$lang['fileupload'] = 'Envio de arquivo de mídia';
+$lang['uploadsucc'] = 'O envio foi efetuado com sucesso';
+$lang['uploadfail'] = 'Não foi possível enviar o arquivo. Será algum problema com as permissões?';
+$lang['uploadwrong'] = 'O envio foi bloqueado. Essa extensão de arquivo é proibida!';
+$lang['uploadexist'] = 'O arquivo já existe. Não foi feito nada.';
+$lang['uploadbadcontent'] = 'O conteúdo enviado não corresponde à extensão do arquivo %s.';
+$lang['uploadspam'] = 'O envio foi bloqueado pela lista negra de spams.';
+$lang['uploadxss'] = 'O envio foi bloqueado devido à possibilidade do seu conteúdo ser malicioso.';
+$lang['uploadsize'] = 'O arquivo transmitido era grande demais. (max. %s)';
+$lang['deletesucc'] = 'O arquivo "%s" foi excluído.';
+$lang['deletefail'] = 'Não foi possível excluir "%s" - verifique as permissões.';
+$lang['mediainuse'] = 'O arquivo "%s" não foi excluído - ele ainda está em uso.';
+$lang['namespaces'] = 'Espaços de nomes';
+$lang['mediafiles'] = 'Arquivos disponíveis em';
+$lang['accessdenied'] = 'Você não tem permissão para visualizar esta página.';
+$lang['mediausage'] = 'Use a seguinte sintaxe para referenciar esse arquivo:';
+$lang['mediaview'] = 'Ver o arquivo original';
+$lang['mediaroot'] = 'raiz';
+$lang['mediaupload'] = 'Envie um arquivo para o espaço de nomes atual aqui. Para criar subespaços de nomes, preponha-os ao nome do arquivo no parâmetro "Enviar como", separados por vírgulas.';
+$lang['mediaextchange'] = 'A extensão do arquivo mudou de .%s para .%s!';
+$lang['reference'] = 'Referências para';
+$lang['ref_inuse'] = 'O arquivo não pode ser excluído, porque ele ainda está sendo utilizado nas seguintes páginas:';
+$lang['ref_hidden'] = 'Algumas referências estão em páginas que você não tem permissão para ler';
+$lang['hits'] = 'Resultados';
+$lang['quickhits'] = 'Nomes de páginas coincidentes';
+$lang['toc'] = 'Tabela de conteúdos';
+$lang['current'] = 'atual';
+$lang['yours'] = 'Sua versão';
+$lang['diff'] = 'Mostrar diferenças com a revisão atual';
+$lang['diff2'] = 'Mostrar diferenças entre as revisões selecionadas';
+$lang['difflink'] = 'Link para esta página de comparações';
+$lang['diff_type'] = 'Ver as diferenças:';
+$lang['diff_inline'] = 'Mescladas';
+$lang['diff_side'] = 'Lado a lado';
+$lang['line'] = 'Linha';
+$lang['breadcrumb'] = 'Visitou';
+$lang['youarehere'] = 'Você está aqui';
+$lang['lastmod'] = 'Última modificação';
+$lang['by'] = 'por';
+$lang['deleted'] = 'removida';
+$lang['created'] = 'criada';
+$lang['restored'] = 'revisão anterior restaurada';
+$lang['external_edit'] = 'edição externa';
+$lang['summary'] = 'Resumo da edição';
+$lang['noflash'] = 'O <a href="http://www.adobe.com/products/flashplayer/">plug-in Adobe Flash</a> é necessário para exibir este conteúdo.';
+$lang['download'] = 'Download Snippet';
+$lang['mail_newpage'] = 'página adicionada:';
+$lang['mail_changed'] = 'página modificada:';
+$lang['mail_subscribe_list'] = 'páginas alteradas no espaço de nomes:';
+$lang['mail_new_user'] = 'novo usuário:';
+$lang['mail_upload'] = 'arquivo enviado:';
+$lang['qb_bold'] = 'Texto em negrito';
+$lang['qb_italic'] = 'Texto em itálico';
+$lang['qb_underl'] = 'Texto sublinhado';
+$lang['qb_code'] = 'Texto de código';
+$lang['qb_strike'] = 'Texto tachado';
+$lang['qb_h1'] = 'Cabeçalho de nível 1';
+$lang['qb_h2'] = 'Cabeçalho de nível 2';
+$lang['qb_h3'] = 'Cabeçalho de nível 3';
+$lang['qb_h4'] = 'Cabeçalho de nível 4';
+$lang['qb_h5'] = 'Cabeçalho de nível 5';
+$lang['qb_h'] = 'Cabeçalho';
+$lang['qb_hs'] = 'Escolha o cabeçalho';
+$lang['qb_hplus'] = 'Cabeçalho de nível mais alto';
+$lang['qb_hminus'] = 'Cabeçalho de nível mais baixo';
+$lang['qb_hequal'] = 'Cabeçalho de mesmo nível';
+$lang['qb_link'] = 'Link interno';
+$lang['qb_extlink'] = 'Link externo';
+$lang['qb_hr'] = 'Linha horizontal';
+$lang['qb_ol'] = 'Item de lista ordenada';
+$lang['qb_ul'] = 'Item de lista não ordenada';
+$lang['qb_media'] = 'Adicionar imagens e/ou outros arquivos';
+$lang['qb_sig'] = 'Inserir assinatura';
+$lang['qb_smileys'] = 'Carinhas';
+$lang['qb_chars'] = 'Caracteres especiais';
+$lang['upperns'] = 'Pular para namespace acima';
+$lang['admin_register'] = 'Adicionar novo usuário';
+$lang['metaedit'] = 'Editar metadados';
+$lang['metasaveerr'] = 'Não foi possível escrever os metadados';
+$lang['metasaveok'] = 'Os metadados foram salvos';
+$lang['img_backto'] = 'Voltar para';
+$lang['img_title'] = 'Título';
+$lang['img_caption'] = 'Descrição';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Nome do arquivo';
+$lang['img_fsize'] = 'Tamanho';
+$lang['img_artist'] = 'Fotógrafo';
+$lang['img_copyr'] = 'Direitos autorais';
+$lang['img_format'] = 'Formato';
+$lang['img_camera'] = 'Câmera';
+$lang['img_keywords'] = 'Palavras-chave';
+$lang['subscr_subscribe_success'] = 'Adicionado %s à lista de monitoramentos de %s';
+$lang['subscr_subscribe_error'] = 'Ocorreu um erro na adição de %s à lista de monitoramentos de %s';
+$lang['subscr_subscribe_noaddress'] = 'Como não há nenhum endereço associado ao seu usuário, você não pode ser adicionado à lista de monitoramento';
+$lang['subscr_unsubscribe_success'] = '%s foi removido da lista de monitoramento de %s';
+$lang['subscr_unsubscribe_error'] = 'Ocorreu um erro na remoção de %s da lista de monitoramentos de %s';
+$lang['subscr_already_subscribed'] = '%s já está monitorando %s';
+$lang['subscr_not_subscribed'] = '%s não está monitorando %s';
+$lang['subscr_m_not_subscribed'] = 'Você não está monitorando nem a página atual nem o espaço de nomes.';
+$lang['subscr_m_new_header'] = 'Adicionar monitoramento';
+$lang['subscr_m_current_header'] = 'Monitoramentos atuais';
+$lang['subscr_m_unsubscribe'] = 'Cancelar monitoramento';
+$lang['subscr_m_subscribe'] = 'Monitorar';
+$lang['subscr_m_receive'] = 'Receber';
+$lang['subscr_style_every'] = 'um e-mail a cada modificação';
+$lang['subscr_style_digest'] = 'um agrupamento de e-mails com as mudanças para cada página (a cada %.2f dias)';
+$lang['subscr_style_list'] = 'uma lista de páginas modificadas desde o último e-mail (a cada %.2f dias)';
+$lang['authmodfailed'] = 'A configuração da autenticação de usuário está com problemas. Por favor, informe ao administrador do wiki.';
+$lang['authtempfail'] = 'A autenticação de usuários está temporariamente desabilitada. Se essa situação persistir, por favor, informe ao administrador do Wiki.';
+$lang['i_chooselang'] = 'Selecione o seu idioma';
+$lang['i_installer'] = 'Instalador do DokuWiki';
+$lang['i_wikiname'] = 'Nome do Wiki';
+$lang['i_enableacl'] = 'Habilitar Lista de Controle de Acessos (recomendado)';
+$lang['i_superuser'] = 'Superusuário';
+$lang['i_problems'] = 'O instalador encontrou alguns problemas, indicados abaixo. Você não pode continuar até corrigi-los.';
+$lang['i_modified'] = 'Por questões de segurança, esse script funcionará apenas em uma instalação nova e não modificada do DokuWiki.
+Você pode extrair novamente os arquivos do pacote original ou consultar as <a href="http://dokuwiki.org/install">instruções de instalação do DokuWiki</a>.';
+$lang['i_funcna'] = 'A função PHP <code>%s</code> não está disponível. O seu host a mantém desabilitada por algum motivo?';
+$lang['i_phpver'] = 'A sua versão do PHP (<code>%s</code>) é inferior à necessária (<code>%s</code>). Você precisa atualizar a sua instalação do PHP.';
+$lang['i_permfail'] = 'O DokuWiki não tem permissão de escrita em <code>%s</code>. Você precisa corrigir as configurações de permissão nesse diretório!';
+$lang['i_confexists'] = '<code>%s</code> já existe';
+$lang['i_writeerr'] = 'Não foi possível criar <code>%s</code>. É necessário checar as permissões de arquivos/diretórios e criar o arquivo manualmente.';
+$lang['i_badhash'] = 'dokuwiki.php não reconhecido ou modificado (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - valor ilegal ou em branco';
+$lang['i_success'] = 'A configuração terminou com sucesso. Agora você deve excluir o arquivo install.php. Conheça o seu <a href="doku.php">novo DokuWiki</a>!';
+$lang['i_failure'] = 'Ocorreram alguns erros durante a escrita dos arquivos de configuração. É necessário corrigi-los manualmente antes de usar seu <a href="doku.php">novo DokuWiki</a>';
+$lang['i_policy'] = 'Política inicial de permissões';
+$lang['i_pol0'] = 'Wiki aberto (leitura, escrita e envio de arquivos por todos)';
+$lang['i_pol1'] = 'Wiki público (leitura por todos, escrita e envio de arquivos por usuários registrados)';
+$lang['i_pol2'] = 'Wiki fechado (leitura, escrita e envio de arquivos somente por usuários registrados)';
+$lang['i_retry'] = 'Tentar novamente';
+$lang['i_license'] = 'Por favor escolha a licença que voce deseja utilizar para seu conteúdo:';
+$lang['recent_global'] = 'Você está observando as alterações dentro do espaço de nomes <b>%s</b>. Também é possível ver as <a href="%s">modificações recentes no wiki inteiro</a>.';
+$lang['years'] = '%d anos atrás';
+$lang['months'] = '%d meses atrás';
+$lang['weeks'] = '%d semanas atrás';
+$lang['days'] = '%d dias atrás';
+$lang['hours'] = '%d horas atrás';
+$lang['minutes'] = '%d minutos atrás';
+$lang['seconds'] = '%d segundos atrás';
+$lang['wordblock'] = 'Suas mudanças não foram salvas pois contem texto bloqueados (spam)';
diff --git a/inc/lang/pt-br/locked.txt b/inc/lang/pt-br/locked.txt
new file mode 100644
index 000000000..70658cba1
--- /dev/null
+++ b/inc/lang/pt-br/locked.txt
@@ -0,0 +1,3 @@
+====== Página bloqueada ======
+
+Essa página está bloqueada para edição por outro usuário. Você tem que esperar até que esse usuário termine a edição ou que o bloqueio expire.
diff --git a/inc/lang/pt-br/login.txt b/inc/lang/pt-br/login.txt
new file mode 100644
index 000000000..23215e16c
--- /dev/null
+++ b/inc/lang/pt-br/login.txt
@@ -0,0 +1,3 @@
+====== Autenticação ======
+
+Você não está autenticado. Digite as seus dados de usuário abaixo para entrar no sistema. É necessário habilitar os //cookies// no seu navegador para que isso funcione.
diff --git a/inc/lang/pt-br/mailtext.txt b/inc/lang/pt-br/mailtext.txt
new file mode 100644
index 000000000..e52535bf0
--- /dev/null
+++ b/inc/lang/pt-br/mailtext.txt
@@ -0,0 +1,17 @@
+Uma página em seu DokuWiki foi adicionada ou alterada. Aqui estão os detalhes:
+
+Data: @DATE@
+Navegador: @BROWSER@
+Endereço IP: @IPADDRESS@
+Nome do host: @HOSTNAME@
+Revisão antiga: @OLDPAGE@
+Nova revisão: @NEWPAGE@
+Resumo da edição: @SUMMARY@
+Usuário: @USER@
+
+@DIFF@
+
+
+--
+Essa mensagem foi gerada pelo DokuWiki em
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt-br/newpage.txt b/inc/lang/pt-br/newpage.txt
new file mode 100644
index 000000000..77ba49fa5
--- /dev/null
+++ b/inc/lang/pt-br/newpage.txt
@@ -0,0 +1,3 @@
+====== Esse tópico ainda não existe ======
+
+Você clicou em um link para um tópico que ainda não existe. Se for permitido, você poderá criá-lo usando o botão ''Criar essa página''.
diff --git a/inc/lang/pt-br/norev.txt b/inc/lang/pt-br/norev.txt
new file mode 100644
index 000000000..19024dcf7
--- /dev/null
+++ b/inc/lang/pt-br/norev.txt
@@ -0,0 +1,3 @@
+====== Essa revisão não existe ======
+
+A revisão especificada não existe. Utilize o botão ''Revisões anteriores'' para uma listagem das revisões anteriores deste documento.
diff --git a/inc/lang/pt-br/password.txt b/inc/lang/pt-br/password.txt
new file mode 100644
index 000000000..199d6e137
--- /dev/null
+++ b/inc/lang/pt-br/password.txt
@@ -0,0 +1,10 @@
+Olá @FULLNAME@!
+
+Aqui estão os seus dados de usuário para @TITLE@ em @DOKUWIKIURL@
+
+Usuário : @LOGIN@
+Senha : @PASSWORD@
+
+--
+Essa mensagem foi gerada pelo DokuWiki em
+@DOKUWIKIURL@
diff --git a/inc/lang/pt-br/preview.txt b/inc/lang/pt-br/preview.txt
new file mode 100644
index 000000000..efdc8f7f2
--- /dev/null
+++ b/inc/lang/pt-br/preview.txt
@@ -0,0 +1,3 @@
+====== Visualização ======
+
+Essa é uma visualização de como será a aparência do seu texto. Lembre-se: ele ainda **não foi gravado**!
diff --git a/inc/lang/pt-br/pwconfirm.txt b/inc/lang/pt-br/pwconfirm.txt
new file mode 100644
index 000000000..2a7c88531
--- /dev/null
+++ b/inc/lang/pt-br/pwconfirm.txt
@@ -0,0 +1,13 @@
+Olá @FULLNAME@!
+
+Alguém requisitou um nova senha para o seu usuário @TITLE@ em @DOKUWIKIURL@.
+
+Se não foi você quem fez essa requisição, simplesmente ignore essa mensagem.
+
+Se você realmente deseja receber uma nova senha, por favor, utilize o link abaixo, para confirmar sua requisição.
+
+@CONFIRM@
+
+--
+Essa mensagem foi gerada pelo DokuWiki em
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt-br/read.txt b/inc/lang/pt-br/read.txt
new file mode 100644
index 000000000..897155eed
--- /dev/null
+++ b/inc/lang/pt-br/read.txt
@@ -0,0 +1 @@
+Essa página está em modo somente de leitura. Você pode visualizar a fonte, mas não alterá-la. Informe-se com o administrador do Wiki, caso você ache que isso está incorreto.
diff --git a/inc/lang/pt-br/recent.txt b/inc/lang/pt-br/recent.txt
new file mode 100644
index 000000000..988f235b4
--- /dev/null
+++ b/inc/lang/pt-br/recent.txt
@@ -0,0 +1,4 @@
+====== Alterações Recentes ======
+
+As seguintes páginas foram alteradas recentemente.
+
diff --git a/inc/lang/pt-br/register.txt b/inc/lang/pt-br/register.txt
new file mode 100644
index 000000000..431feca98
--- /dev/null
+++ b/inc/lang/pt-br/register.txt
@@ -0,0 +1,4 @@
+====== Registre-se como um novo usuário ======
+
+Preencha todas as informações abaixo para criar uma nova conta nesse Wiki. Certifique-se de que você forneceu um **endereço de e-mail válido** - se não for pedido que você entre com uma senha aqui, ela será enviada para esse endereço. O nome de usuário deve ser um [[doku>pagename|nome de página]] válido.
+
diff --git a/inc/lang/pt-br/registermail.txt b/inc/lang/pt-br/registermail.txt
new file mode 100644
index 000000000..9bb6a00ba
--- /dev/null
+++ b/inc/lang/pt-br/registermail.txt
@@ -0,0 +1,14 @@
+Foi registrado um novo usuário. Seus detalhes são:
+
+Nome de usuário: @NEWUSER@
+Nome completo: @NEWNAME@
+E-mail: @NEWEMAIL@
+
+Data: @DATE@
+Navegador: @BROWSER@
+Endereço IP: @IPADDRESS@
+Nome do host: @HOSTNAME@
+
+--
+Essa mensagem foi gerada pelo DokuWiki em
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt-br/resendpwd.txt b/inc/lang/pt-br/resendpwd.txt
new file mode 100644
index 000000000..b74713f0f
--- /dev/null
+++ b/inc/lang/pt-br/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Enviar nova senha ======
+
+Por favor, digite o seu nome de usuário no formulário abaixo para requisitar uma nova senha para a sua conta nesse wiki. O link de confirmação será enviado para o endereço de e-mail que você forneceu. \ No newline at end of file
diff --git a/inc/lang/pt-br/revisions.txt b/inc/lang/pt-br/revisions.txt
new file mode 100644
index 000000000..1c174dcb0
--- /dev/null
+++ b/inc/lang/pt-br/revisions.txt
@@ -0,0 +1,4 @@
+====== Revisões anteriores ======
+
+Essas são as revisões anteriores desse documento. Para reverter a uma revisão antiga, selecione-a abaixo, clique em ''Editar esta página'' e salve-a.
+
diff --git a/inc/lang/pt-br/searchpage.txt b/inc/lang/pt-br/searchpage.txt
new file mode 100644
index 000000000..2fba3afe9
--- /dev/null
+++ b/inc/lang/pt-br/searchpage.txt
@@ -0,0 +1,5 @@
+====== Pesquisa ======
+
+Você pode encontrar os resultados da sua pesquisa abaixo. Se você não encontrou o que está procurando, pode criar ou editar a página com o nome que você especificou, usando o botão apropriado.
+
+===== Resultados =====
diff --git a/inc/lang/pt-br/showrev.txt b/inc/lang/pt-br/showrev.txt
new file mode 100644
index 000000000..89d9cad5a
--- /dev/null
+++ b/inc/lang/pt-br/showrev.txt
@@ -0,0 +1,2 @@
+**Essa é uma revisão anterior do documento!**
+----
diff --git a/inc/lang/pt-br/stopwords.txt b/inc/lang/pt-br/stopwords.txt
new file mode 100644
index 000000000..c781ffbf2
--- /dev/null
+++ b/inc/lang/pt-br/stopwords.txt
@@ -0,0 +1,55 @@
+# Essa é uma lista de palavras que o indexador ignora, uma palavra por linha
+# Ao editar esse arquivo, certifique-se de usar terminações de linha UNIX (newline simples)
+# Não há necessidade de incluir palavras menores que 3 caracteres - elas já são ignoradas por padrão
+# Essa lista é baseada na encontrada em http://www.ranks.nl/stopwords/portugese.html
+acerca
+algum
+alguma
+algumas
+alguns
+ambos
+antes
+após
+aquela
+aquelas
+aquele
+aqueles
+até
+bem
+bom
+cada
+com
+como
+das
+desde
+dos
+enquanto
+então
+esta
+este
+estas
+estes
+essa
+essas
+esse
+esses
+isso
+isto
+mas
+mesmo
+onde
+para
+pelo
+por
+qual
+quando
+que
+quem
+sem
+somente
+tal
+também
+uma
+umas
+uns
+www \ No newline at end of file
diff --git a/inc/lang/pt-br/subscr_digest.txt b/inc/lang/pt-br/subscr_digest.txt
new file mode 100644
index 000000000..77f76e1c3
--- /dev/null
+++ b/inc/lang/pt-br/subscr_digest.txt
@@ -0,0 +1,20 @@
+Olá!
+
+A página @PAGE@ na wiki @TITLE@ foi modificada.
+Estas foram as mudanças:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Revisão antiga:@OLDPAGE@
+Nova Revisão:@NEWPAGE@
+
+Para cancelar as notificações de mudanças, entre em
+@DOKUWIKIURL@, vá até @SUBSCRIBE@
+e cancele o monitoramento da página e/ou do espaço de
+nomes.
+
+--
+Este e-mail foi gerado pelo DokuWiki em
+@DOKUWIKIURL@
diff --git a/inc/lang/pt-br/subscr_form.txt b/inc/lang/pt-br/subscr_form.txt
new file mode 100644
index 000000000..1611ea95d
--- /dev/null
+++ b/inc/lang/pt-br/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Gerenciamento de inscrição ======
+
+Esta página permite voce gerencias as inscrições para a página e namespace corrente.
diff --git a/inc/lang/pt-br/subscr_list.txt b/inc/lang/pt-br/subscr_list.txt
new file mode 100644
index 000000000..c6011d063
--- /dev/null
+++ b/inc/lang/pt-br/subscr_list.txt
@@ -0,0 +1,28 @@
+Olá!
+
+Páginas no espaço de nomes @PAGE@ na wiki
+@TITLE@ foram modificadas.
+Estas são as páginas modificadas:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Para cancelar as notificações de alterações, entre em
+@DOKUWIKIURL@, vá até @SUBSCRIBE@
+e cancele o monitoramento da página e/ou do espaço de
+nomes.
+
+
+Para cancelar as notificações de páginas, entre na wiki @DOKUWIKIURL@
+e então visite @SUBSCRIBE@ e cancele a inscrição de edição da página ou namespace.
+
+
+Para cancelar a página de notificações, entre na wiki @DOKUWIKIURL@,
+visite a página de @SUBSCRIBE@ e cancele a inscrição de edição da página ou namespace.
+--
+Este e-mail foi gerado pelo DokuWiki em
+@DOKUWIKIURL@
+
+
+preview.txt ====== Preview ======
diff --git a/inc/lang/pt-br/subscr_single.txt b/inc/lang/pt-br/subscr_single.txt
new file mode 100644
index 000000000..b1c052e84
--- /dev/null
+++ b/inc/lang/pt-br/subscr_single.txt
@@ -0,0 +1,22 @@
+Olá!
+
+A página @PAGE@ na wiki @TITLE@ foi alterada.
+Estas foram as mudanças:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Data : @DATE@
+Usuário : @USER@
+Sumário : @SUMMARY@
+Revisão antiga:@OLDPAGE@
+Nova Revisão:@NEWPAGE@
+
+Para cancelar as notificações de mudanças, entre em
+@DOKUWIKIURL@, vá até @NEWPAGE@
+e cancele o monitoramento da página e/ou do espaço de
+nomes.
+--
+Este e-mail foi gerado pelo DokuWiki em
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt-br/updateprofile.txt b/inc/lang/pt-br/updateprofile.txt
new file mode 100644
index 000000000..b3f62f396
--- /dev/null
+++ b/inc/lang/pt-br/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Atualize o perfil da sua conta ======
+
+Você precisa preencher somente os campos que você deseja alterar. Você não pode alterar o seu nome de usuário.
+
+
diff --git a/inc/lang/pt-br/uploadmail.txt b/inc/lang/pt-br/uploadmail.txt
new file mode 100644
index 000000000..a3ac9bac7
--- /dev/null
+++ b/inc/lang/pt-br/uploadmail.txt
@@ -0,0 +1,14 @@
+Um arquivo foi enviado para o seu DokuWiki. Os detalhes são:
+
+Arquivo: @MEDIA@
+Data: @DATE@
+Navegador: @BROWSER@
+Endereço IP: @IPADDRESS@
+Nome do host: @HOSTNAME@
+Tamanho: @SIZE@
+Tipo MIME: @MIME@
+Usuário: @USER@
+
+--
+Essa mensagem foi gerada pelo DokuWiki em
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt/admin.txt b/inc/lang/pt/admin.txt
new file mode 100644
index 000000000..366792a9b
--- /dev/null
+++ b/inc/lang/pt/admin.txt
@@ -0,0 +1,3 @@
+====== Administração ======
+
+Abaixo pode encontrar uma lista de tarefas de administrativas permitidas pelo DokuWiki. \ No newline at end of file
diff --git a/inc/lang/pt/adminplugins.txt b/inc/lang/pt/adminplugins.txt
new file mode 100644
index 000000000..3eac7af53
--- /dev/null
+++ b/inc/lang/pt/adminplugins.txt
@@ -0,0 +1 @@
+===== Plugins Adicionais ===== \ No newline at end of file
diff --git a/inc/lang/pt/backlinks.txt b/inc/lang/pt/backlinks.txt
new file mode 100644
index 000000000..e78ddf874
--- /dev/null
+++ b/inc/lang/pt/backlinks.txt
@@ -0,0 +1,4 @@
+====== Backlinks ======
+
+Esta é uma lista de todos os documentos que apresentam ligações ao documento corrente.
+
diff --git a/inc/lang/pt/conflict.txt b/inc/lang/pt/conflict.txt
new file mode 100644
index 000000000..d2af1fe11
--- /dev/null
+++ b/inc/lang/pt/conflict.txt
@@ -0,0 +1,9 @@
+====== Conflito de Edição ======
+
+**Atenção**: Existe uma versão mais recente do que a versão usada no começo da sua edição. Isto acontece quando outra pessoa editou este documento entretanto e já gravou as alterações efectuadas.
+
+Por favor, examine todas as diferenças mostradas abaixo com atenção, e decida qual a versão que deverá ser tornada a mais actual: * Se escolher <Gravar> a sua versão será sobreposta à versão editada pela outra pessoa, que será perdida. * Se escolher <Cancelar> a versão editada pela outra pessoa será a versão final, e a sua será perdida.
+
+**Nota**: Sem que efectue a consolidação das alterações de ambas as revisões ao documento irá sempre perder uma das versões.
+
+----
diff --git a/inc/lang/pt/denied.txt b/inc/lang/pt/denied.txt
new file mode 100644
index 000000000..eb2614387
--- /dev/null
+++ b/inc/lang/pt/denied.txt
@@ -0,0 +1,3 @@
+====== Permissão Negada ======
+
+Não possui direitos e permissões suficientes para continuar. Talvez se tenha esquecido de iniciar sessão? \ No newline at end of file
diff --git a/inc/lang/pt/diff.txt b/inc/lang/pt/diff.txt
new file mode 100644
index 000000000..e27640aa8
--- /dev/null
+++ b/inc/lang/pt/diff.txt
@@ -0,0 +1,5 @@
+====== Diferenças ======
+
+Esta página mostra as diferenças entre a revisão do documento que escolheu e a versão actual.
+
+----
diff --git a/inc/lang/pt/draft.txt b/inc/lang/pt/draft.txt
new file mode 100644
index 000000000..1baf95c1c
--- /dev/null
+++ b/inc/lang/pt/draft.txt
@@ -0,0 +1,7 @@
+====== Rascunho encontrado ======
+
+A sessão referente à última edição desta página não terminou correctamente. Foi guardado automaticamente um rascunho durante a edição que pode ou não usar para continuar a edição. Abaixo pode ver os dados guardados da última sessão.
+
+Por favor, decida se quer **recuperar** os dados guardados, **remover** o rascunho** ou **cancelar** o processo de edição corrente.
+
+----
diff --git a/inc/lang/pt/edit.txt b/inc/lang/pt/edit.txt
new file mode 100644
index 000000000..2fa596e29
--- /dev/null
+++ b/inc/lang/pt/edit.txt
@@ -0,0 +1,4 @@
+Edite o documento e clique no botão <Gravar>. Reveja a [[wiki:syntax|sintaxe]] das regras de formatação do texto.
+
+Por favor, altere o conteúdo deste documento apenas quando puder **melhorá-lo**.\\ Se pretende testar os seus conhecimentos no uso deste motor Wiki, realize os seus testes no [[playground:playground | Recreio]].
+
diff --git a/inc/lang/pt/editrev.txt b/inc/lang/pt/editrev.txt
new file mode 100644
index 000000000..2c7697b52
--- /dev/null
+++ b/inc/lang/pt/editrev.txt
@@ -0,0 +1 @@
+**Carregou uma revisão antiga do documento!** Se a gravar irá criar uma nova versão do documento com este conteúdo, que substituirá a versão actual. \ No newline at end of file
diff --git a/inc/lang/pt/index.txt b/inc/lang/pt/index.txt
new file mode 100644
index 000000000..46a807d2d
--- /dev/null
+++ b/inc/lang/pt/index.txt
@@ -0,0 +1,3 @@
+====== Índice ======
+
+Este índice mostra todas as páginas disponíveis, agrupadas por [[doku>namespaces|espaço de nome]]. \ No newline at end of file
diff --git a/inc/lang/pt/install.html b/inc/lang/pt/install.html
new file mode 100644
index 000000000..a2fd5c7c6
--- /dev/null
+++ b/inc/lang/pt/install.html
@@ -0,0 +1,8 @@
+<p>Esta página serve de "assistente" para a primeira instalação e configuração do <a href="http://dokuwiki.org">Dokuwiki</a>. Está disponível mais informação sobre este "assistente" na sua <a href="http://dokuwiki.org/installer">página de documentação</a>.</p>
+
+<p>O DokuWiki usa ficheiros normais para armazenar as páginas Wiki e outras informações associadas a essas páginas (i.e. imagens, índices de pesquisa, revisões antigas, etc.). O DokuWiki para poder funcionar correctamente <strong>requer</strong> permissões de escrita às pastas que contêm esses ficheiros. Este "assistente" não é capaz de configurar essas permissões. Isso tem que ser feito via linha de comandos, FTP ou Painel de Controlo do serviço de alojamento (i.e. cPanel).</p>
+
+<p>Este "assistente" vai configurar o DokuWiki com
+<acronym title="access control list">ACL</acronym>, que por sua vez permite ao administrador entrar em sessão e aceder ao menu de Administração do DokuWiki para poder instalar plugins, gerir utilizadores e seus perfis, gerir acesso às páginas e à própria configuração do DokuWiki. Não é necessário para que o DokuWiki funcione, mas facilita a sua administração.</p>
+
+<p>Utilizadores experiente ou com requisitos especiais devem seguir estes links, que detalham mais em pormenor a<a href="http://dokuwiki.org/install">instalação</a> e <a href="http://dokuwiki.org/config">configuração</a> do DokuWiki.</p> \ No newline at end of file
diff --git a/inc/lang/pt/lang.php b/inc/lang/pt/lang.php
new file mode 100644
index 000000000..a96598fc3
--- /dev/null
+++ b/inc/lang/pt/lang.php
@@ -0,0 +1,322 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author José Carlos Monteiro <jose.c.monteiro@netcabo.pt>
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$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'] = 'Editar página';
+$lang['btn_source'] = 'Ver fonte';
+$lang['btn_show'] = 'Ver página';
+$lang['btn_create'] = 'Criar página';
+$lang['btn_search'] = 'Pesquisar';
+$lang['btn_save'] = 'Gravar';
+$lang['btn_preview'] = 'Prever';
+$lang['btn_top'] = 'Voltar ao topo';
+$lang['btn_newer'] = '<< mais recente';
+$lang['btn_older'] = 'menos recente >>';
+$lang['btn_revs'] = 'Revisões';
+$lang['btn_recent'] = 'Alt. Recentes';
+$lang['btn_upload'] = 'Carregar';
+$lang['btn_cancel'] = 'Cancelar';
+$lang['btn_index'] = 'Índice';
+$lang['btn_secedit'] = 'Editar';
+$lang['btn_login'] = 'Entrar';
+$lang['btn_logout'] = 'Sair';
+$lang['btn_admin'] = 'Administrar';
+$lang['btn_update'] = 'Actualizar';
+$lang['btn_delete'] = 'Apagar';
+$lang['btn_back'] = 'Voltar';
+$lang['btn_backlink'] = 'Backlinks';
+$lang['btn_backtomedia'] = 'Voltar à Selecção de Media';
+$lang['btn_subscribe'] = 'Subscrever Alterações';
+$lang['btn_profile'] = 'Actualizar Perfil';
+$lang['btn_reset'] = 'Limpar';
+$lang['btn_resendpwd'] = 'Enviar nova senha';
+$lang['btn_draft'] = 'Editar rascunho';
+$lang['btn_recover'] = 'Recuperar rascunho';
+$lang['btn_draftdel'] = 'Apagar rascunho';
+$lang['btn_revert'] = 'Restaurar';
+$lang['btn_register'] = 'Registar';
+$lang['btn_apply'] = 'Aplicar';
+$lang['btn_media'] = 'Gestor de Media';
+
+$lang['loggedinas'] = 'Está em sessão como';
+$lang['user'] = 'Utilizador';
+$lang['pass'] = 'Senha';
+$lang['newpass'] = 'Nova senha';
+$lang['oldpass'] = 'Confirme senha actual';
+$lang['passchk'] = 'Confirmar novamente';
+$lang['remember'] = 'Memorizar?';
+$lang['fullname'] = 'Nome completo';
+$lang['email'] = 'Email';
+$lang['profile'] = 'Perfil do Utilizador';
+$lang['badlogin'] = 'O utilizador inválido ou senha inválida.';
+$lang['minoredit'] = 'Alterações Menores';
+$lang['draftdate'] = 'Rascunho automaticamente gravado em';
+$lang['nosecedit'] = 'A página foi modificada entretanto. Como a informação da secção estava desactualizada, foi carregada a página inteira.';
+
+$lang['regmissing'] = 'Por favor, preencha todos os campos.';
+$lang['reguexists'] = 'Este utilizador já está inscrito. Por favor escolha outro nome de utilizador.';
+$lang['regsuccess'] = 'O utilizador foi criado e a senha foi enviada para o endereço de correio electrónico usado na inscrição.';
+$lang['regsuccess2'] = 'O utilizador foi criado.';
+$lang['regmailfail'] = 'Houve um erro no envio da senha por e-mail. Por favor, contacte o administrador!';
+$lang['regbadmail'] = 'O endereço de correio electrónico é inválido. Se o endereço está correcto, e isto é um erro, por favor, contacte o administrador!';
+$lang['regbadpass'] = 'As duas senhas não são idênticas, por favor tente de novo.';
+$lang['regpwmail'] = 'A sua senha DokuWiki';
+$lang['reghere'] = 'Para se registar, clique em';
+
+$lang['profna'] = 'Este Wiki não suporta modificações aos perfis.';
+$lang['profnochange'] = 'Nada alteração, nada a fazer.';
+$lang['profnoempty'] = 'Não são permitidos nomes ou endereços em branco.';
+$lang['profchanged'] = 'Perfil do utilizador actualizado com sucesso.';
+
+$lang['pwdforget'] = 'Esqueceu a sua senha? Pedir nova senha';
+$lang['resendna'] = 'Este wiki não suporta reenvio de senhas.';
+$lang['resendpwd'] = 'Enviar nova senha para';
+$lang['resendpwdmissing'] = 'É preciso preencher todos os campos.';
+$lang['resendpwdnouser'] = 'Não foi possível encontrar este utilizador.';
+$lang['resendpwdbadauth'] = 'O código de autenticação não é válido. Por favor, assegure-se de que o link de confirmação está completo.';
+$lang['resendpwdconfirm'] = 'O link de confirmação foi enviado por e-mail.';
+$lang['resendpwdsuccess'] = 'A nova senha foi enviada por e-mail.';
+
+$lang['license'] = 'Excepto menção em contrário, o conteúdo neste wiki está sob a seguinte licença:';
+$lang['licenseok'] = 'Nota: Ao editar esta página você aceita disponibilizar o seu conteúdo sob a seguinte licença:';
+
+$lang['searchmedia'] = 'Procurar nome de ficheiro:';
+$lang['searchmedia_in'] = 'Procurar em %s';
+$lang['txt_upload'] = 'Escolha ficheiro para carregar';
+$lang['txt_filename'] = 'Carregar como (opcional)';
+$lang['txt_overwrt'] = 'Escrever por cima do ficheiro já existente';
+$lang['lockedby'] = 'Bloqueado por';
+$lang['lockexpire'] = 'Expira em';
+$lang['js']['willexpire'] = 'O bloqueio de edição para este documento irá expirar num minuto.\nPara evitar conflitos use o botão Prever para re-iniciar o temporizador de bloqueio.';
+
+$lang['js']['notsavedyet'] = 'Alterações não gravadas serão perdidas.';
+
+$lang['js']['searchmedia'] = 'Procurar por ficheiros';
+$lang['js']['keepopen'] = 'Mantenha a janela aberta durante a selecção';
+$lang['js']['hidedetails'] = 'Esconder Detalhes';
+$lang['js']['mediatitle'] = 'Propriedades de ligação';
+$lang['js']['mediadisplay'] = 'Tipo de ligação';
+$lang['js']['mediaalign'] = 'Alinhamento';
+$lang['js']['mediasize'] = 'Tamanho da imagem';
+$lang['js']['mediatarget'] = 'Alvo da ligação';
+$lang['js']['mediaclose'] = 'Fechar';
+$lang['js']['mediainsert'] = 'Inserir';
+$lang['js']['mediadisplayimg'] = 'Mostrar a imagem';
+$lang['js']['mediadisplaylnk'] = 'Mostrar apenas a ligação';
+$lang['js']['mediasmall'] = 'Versão pequena';
+$lang['js']['mediamedium'] = 'Versão média';
+$lang['js']['medialarge'] = 'Versão grande';
+$lang['js']['mediaoriginal'] = 'Versão original';
+$lang['js']['medialnk'] = 'Ligação para a página de detalhe';
+$lang['js']['mediadirect'] = 'Ligação directa para o original';
+$lang['js']['medianolnk'] = 'Nenhuma ligação';
+$lang['js']['medianolink'] = 'Não ligar à imagem';
+$lang['js']['medialeft'] = 'Alinhar a imagem à esquerda.';
+$lang['js']['mediaright'] = 'Alinhar a imagem à direita.';
+$lang['js']['mediacenter'] = 'Alinhar a imagem ao centro.';
+$lang['js']['medianoalign'] = 'Não usar alinhamento algum.';
+$lang['js']['nosmblinks'] = 'Ligação a pastas Windows partilhadas apenas funciona com o Microsoft Internet Explorer.
+Pode no entanto copiar e colar o link.';
+$lang['js']['linkwiz'] = 'Assistente de Criação de Ligação';
+$lang['js']['linkto'] = 'Ligação para:';
+$lang['js']['del_confirm'] = 'Remover o(s) item(s) selecionados?';
+$lang['js']['restore_confirm'] = 'Restaurar esta versão?';
+$lang['rssfailed'] = 'Ocorreu um erro neste canal RSS: ';
+$lang['nothingfound'] = 'Nada foi encontrado.';
+$lang['mediaselect'] = 'Selecção de ficheiros';
+$lang['fileupload'] = 'Carregamento de ficheiros';
+$lang['uploadsucc'] = 'Carregamento com sucesso';
+$lang['uploadfail'] = 'Falhou o carregamento. Talvez por não ter permissões?';
+$lang['uploadwrong'] = 'Carregamento negado. Esta extensão está proibida.';
+$lang['uploadexist'] = 'O ficheiro já existe. Não pode ser carregado.';
+$lang['uploadbadcontent'] = 'O conteúdo carregado não corresponde à extensão %s.';
+$lang['uploadspam'] = 'O carregamento foi bloqueado pela lista negra de SPAM.';
+$lang['uploadxss'] = 'O carregamento foi bloqueado porque possivelmente contem conteúdo malicioso.';
+$lang['uploadsize'] = 'O ficheiro carregado é demasiado grande. (máx. %s)';
+$lang['deletesucc'] = 'O ficheiro "%s" foi removido.';
+$lang['deletefail'] = 'O ficheiro "%s" não pode ser removido, por favor verifique as permissões.';
+$lang['mediainuse'] = 'O ficheiro "%s" não foi removido porque está ainda a ser usado.';
+$lang['namespaces'] = 'Grupos';
+$lang['mediafiles'] = 'Ficheiros disponíveis em';
+$lang['accessdenied'] = 'Não tem permissão para ver esta página.';
+$lang['mediausage'] = 'Use a seguinte sintaxe para referenciar este ficheiro:';
+$lang['mediaview'] = 'Ver ficheiro original';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Carregar ficheiros para o grupo actual aqui. Para criar sub-grupos: escrever o nome do sub-grupo seguido de : antes do nome do ficheiro no campo "Carregar como".';
+$lang['mediaextchange'] = 'Extensão alterada de .%s para .%s!';
+$lang['reference'] = 'Referências para';
+$lang['ref_inuse'] = 'O ficheiro não pode ser removido, porque está ainda a ser usado nestes documentos:';
+$lang['ref_hidden'] = 'Algumas referências estão em documentos para os quais não tem permissão para ler';
+$lang['hits'] = 'Resultados';
+$lang['quickhits'] = 'Documentos encontrados';
+$lang['toc'] = 'Tabela de Conteúdos';
+$lang['current'] = 'Actual';
+$lang['yours'] = 'A sua versão';
+$lang['diff'] = 'mostrar diferenças com a versão actual';
+$lang['diff2'] = 'mostrar diferenças entre versões escolhidas';
+$lang['difflink'] = 'Ligação para esta vista de comparação';
+$lang['diff_type'] = 'Ver diferenças';
+$lang['diff_inline'] = 'Embutido';
+$lang['diff_side'] = 'Lado a lado';
+$lang['line'] = 'Linha';
+$lang['breadcrumb'] = 'Está em';
+$lang['youarehere'] = 'Está aqui';
+$lang['lastmod'] = 'Esta página foi modificada pela última vez em';
+$lang['by'] = 'por';
+$lang['deleted'] = 'Documento automaticamente removido.';
+$lang['created'] = 'Criação deste novo documento.';
+$lang['restored'] = 'Versão anterior restaurada.';
+$lang['external_edit'] = 'Edição externa';
+$lang['summary'] = 'Sumário da Edição';
+$lang['noflash'] = 'O <a href="http://www.adobe.com/products/flashplayer/">Plugin Adobe Flash</a> é necessário para exibir este conteúdo.';
+$lang['download'] = 'Descarregar Snippet';
+$lang['changes_type'] = 'Ver alterações de';
+$lang['pages_changes'] = 'Páginas';
+$lang['media_changes'] = 'Ficheiros Media';
+$lang['both_changes'] = 'Tanto páginas como ficheiros media';
+$lang['mail_newpage'] = 'documento adicionado:';
+$lang['mail_changed'] = 'documento modificado:';
+$lang['mail_subscribe_list'] = 'páginas alteradas no espaço de nome:';
+$lang['mail_new_user'] = 'Novo utilizador:';
+$lang['mail_upload'] = 'Ficheiro carregado:';
+$lang['qb_bold'] = 'Texto com Ênfase';
+$lang['qb_italic'] = 'Texto Itálico';
+$lang['qb_underl'] = 'Texto Sublinhado';
+$lang['qb_code'] = 'Texto Código';
+$lang['qb_strike'] = 'Texto Riscado';
+$lang['qb_h1'] = 'Cabeçalho Nível 1';
+$lang['qb_h2'] = 'Cabeçalho Nível 2';
+$lang['qb_h3'] = 'Cabeçalho Nível 3';
+$lang['qb_h4'] = 'Cabeçalho Nível 4';
+$lang['qb_h5'] = 'Cabeçalho Nível 5';
+$lang['qb_h'] = 'Cabeçalho';
+$lang['qb_hs'] = 'Seleccionar Cabeçalho';
+$lang['qb_hplus'] = 'Cabeçalho Maior';
+$lang['qb_hminus'] = 'Cabeçalho Menor';
+$lang['qb_hequal'] = 'Cabeçalho de Nível Semelhante';
+$lang['qb_link'] = 'Ligação Interna';
+$lang['qb_extlink'] = 'Ligação Externa';
+$lang['qb_hr'] = 'Barra Horizontal';
+$lang['qb_ol'] = 'Item numa Lista Ordenada';
+$lang['qb_ul'] = 'Item numa Lista Não Ordenada';
+$lang['qb_media'] = 'Incluir imagens e outros ficheiros';
+$lang['qb_sig'] = 'Inserir Assinatura';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Caracteres Especiais';
+$lang['upperns'] = 'Ir para o espaço de nomes parente';
+$lang['admin_register'] = 'Registar Novo Utilizador';
+$lang['metaedit'] = 'Editar Metadata';
+$lang['metasaveerr'] = 'Falhou a escrita de Metadata';
+$lang['metasaveok'] = 'Metadata gravada';
+$lang['img_backto'] = 'De volta a';
+$lang['img_title'] = 'Título';
+$lang['img_caption'] = 'Legenda';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Ficheiro';
+$lang['img_fsize'] = 'Tamanho';
+$lang['img_artist'] = 'Fotógrafo';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Formato';
+$lang['img_camera'] = 'Câmara';
+$lang['img_keywords'] = 'Palavras-Chave';
+$lang['img_width'] = 'Largura';
+$lang['img_height'] = 'Altura';
+$lang['img_manager'] = 'Ver em gestor de media';
+$lang['subscr_subscribe_success'] = 'Adicionado %s à lista de subscrição para %s';
+$lang['subscr_subscribe_error'] = 'Erro ao adicionar %s à lista de subscrição para %s';
+$lang['subscr_subscribe_noaddress'] = 'Não existe endereço algum associado com o seu nome de utilizador, não pode ser adicionado à lista de subscrição';
+$lang['subscr_unsubscribe_success'] = 'Removido %s da lista de subscrição para %s';
+$lang['subscr_unsubscribe_error'] = 'Erro ao remover %s da lista de subscrição para %s';
+$lang['subscr_already_subscribed'] = '%s já está subscrito em %s';
+$lang['subscr_not_subscribed'] = '%s não está subscrito em %s';
+$lang['subscr_m_not_subscribed'] = 'Não está subscrito à página ou espaço de nome corrente.';
+$lang['subscr_m_new_header'] = 'Adicionar subscrição';
+$lang['subscr_m_current_header'] = 'Subscrições correntes';
+$lang['subscr_m_unsubscribe'] = 'Des-subscrever';
+$lang['subscr_m_subscribe'] = 'Subscrever';
+$lang['subscr_m_receive'] = 'Receber';
+$lang['subscr_style_every'] = 'email em qualquer alteração';
+$lang['subscr_style_digest'] = '"digest email" de alterações em cada página (cada %.2f dias)';
+$lang['subscr_style_list'] = 'lista de páginas alteradas desde o último email (cada %.2f dias)';
+$lang['authmodfailed'] = 'Configuração de autenticação errada. Por favor, informe o Wiki Admin.';
+$lang['authtempfail'] = 'Autenticação temporariamente indisponível. Se a situação persistir, por favor informe o Wiki Admin.';
+$lang['i_chooselang'] = 'Escolha a linguagem';
+$lang['i_installer'] = 'Instalador do DokuWiki';
+$lang['i_wikiname'] = 'Nome Wiki';
+$lang['i_enableacl'] = 'Activar ACL (recomendado)';
+$lang['i_superuser'] = 'Super-utilizador';
+$lang['i_problems'] = 'O instalador encontrou alguns problemas, indicados mais abaixo. Não pode continuar até que sejam corrigidos.';
+$lang['i_modified'] = 'Por razões de segurança, este script só funciona em novas e não-modificadas instalações do Dokuwiki. Deve por isso re-extrair os ficheiros do pacote que descarregou ou então deve consultar as completas <a href="http://dokuwiki.org/install">instruções de instalação do Dokuwiki installation instructions</a>';
+$lang['i_funcna'] = 'A função PHP <code>%s</code> não está disponível. Terá o serviço de alojamento desactivado-a por alguma razão?';
+$lang['i_phpver'] = 'A versão de PHP actual <code>%s</code> é inferior à versão mínima <code>%s</code>. É preciso actualizar a instalação PHP.';
+$lang['i_permfail'] = '<code>%s</code> não permite que o DokuWiki escreva nela. É preciso corrigir as permissões desta pasta!';
+$lang['i_confexists'] = '<code>%s</code> já existe';
+$lang['i_writeerr'] = 'Não foi possível criar <code>%s</code>. É preciso verificar as permissões e criar o ficheiro manualmente.';
+$lang['i_badhash'] = 'dokuwiki.php não é o original ou não é reconhecido (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - valor ilegal ou vazio';
+$lang['i_success'] = 'A instalação e configuração inicial foram bem sucedidas. Pode remover o install.php. Aceda ao seu novo <a href="doku.php">Wiki</a> a correr o DokuWiki.';
+$lang['i_failure'] = 'Ocorreram alguns erros durante a escrita nos ficheiros de configuração. Poderá ser preciso corrigi-los manualmente antes de poder aceder ao seu novo <a href="doku.php">Wiki</a> a correr o DokuWiki.';
+$lang['i_policy'] = 'Politica ACL inicial';
+$lang['i_pol0'] = 'Wiki Aberto (ler, escrever e carregar para todos)';
+$lang['i_pol1'] = 'Wiki Público (ler para todos, escrever e carregar para utilizadores inscritos)';
+$lang['i_pol2'] = 'Wiki Fechado (ler, escrever e carregar somente para utilizadores inscritos)';
+$lang['i_retry'] = 'Repetir';
+$lang['i_license'] = 'Por favor escolha a licença sob a qual quer colocar o seu conteúdo:';
+$lang['recent_global'] = 'Você está a observar as alterações dentro do espaço de nomes <b>%s</b>. Também é possível ver as <a href="%s">modificações recentes no wiki inteiro</a>.';
+$lang['years'] = '%d anos atrás';
+$lang['months'] = '%d meses atrás';
+$lang['weeks'] = '%d semanas atrás';
+$lang['days'] = '%d dias atrás';
+$lang['hours'] = '%d horas atrás';
+$lang['minutes'] = '%d minutos atrás';
+$lang['seconds'] = '%d segundos atrás';
+$lang['wordblock'] = 'A sua alteração não foi guardada porque contém texto bloqueado (spam).';
+
+$lang['media_uploadtab'] = 'Enviar';
+$lang['media_searchtab'] = 'Procurar';
+$lang['media_viewtab'] = 'Ver';
+$lang['media_edittab'] = 'Editar';
+$lang['media_historytab'] = 'Histórico';
+$lang['media_sort'] = 'Ordenar';
+$lang['media_sort_name'] = 'Ordenar por nome';
+$lang['media_sort_date'] = 'Ordenar por data';
+$lang['media_upload'] = 'Enviar para o grupo <strong>%s</strong>.';
+$lang['media_search'] = 'Procurar no grupo <strong>%s</strong>.';
+$lang['media_view'] = '%s';
+$lang['media_edit'] = 'Editar %s';
+$lang['media_history'] = 'Histórico do %s';
+$lang['media_meta_edited']= 'metadata editada';
+$lang['media_perm_read'] = 'Perdão, não tem permissão para ler ficheiros.';
+$lang['media_perm_upload']= 'Perdão, não tem permissão para enviar ficheiros.';
+$lang['media_update'] = 'enviar nova versão';
+$lang['media_restore'] = 'Restaurar esta versão';
+
+$lang['js']['media_diff'] = 'Ver diferenças:';
+$lang['js']['media_diff_both'] = 'Lado a Lado';
+$lang['js']['media_diff_opacity'] = 'Sobreposição';
+$lang['js']['media_diff_portions'] = 'Slider'; // Needs translation. 'Deslizador' ?
+
+$lang['js']['media_select'] = 'Selecione ficheiros…';
+$lang['js']['media_upload_btn'] = 'Enviar';
+$lang['js']['media_done_btn'] = 'Feito';
+$lang['js']['media_drop'] = 'Largue ficheiros aqui para enviar';
+$lang['js']['media_cancel'] = 'remover';
+$lang['js']['media_overwrt'] = 'Escrever por cima de ficheiros existentes';
+
+$lang['plugin_install_err'] = "Plugin instalado incorrectamente. Renomeie a pasta do plugin de '%s' para '%s'.";
diff --git a/inc/lang/pt/locked.txt b/inc/lang/pt/locked.txt
new file mode 100644
index 000000000..a4bb4d606
--- /dev/null
+++ b/inc/lang/pt/locked.txt
@@ -0,0 +1,3 @@
+====== Página em Edição ======
+
+Esta página está bloqueada por outro utilizador, que se encontra a editá-la neste momento. Terá que aguardar que o utilizador termine a edição ou que o bloqueio expire. \ No newline at end of file
diff --git a/inc/lang/pt/login.txt b/inc/lang/pt/login.txt
new file mode 100644
index 000000000..42c2a983c
--- /dev/null
+++ b/inc/lang/pt/login.txt
@@ -0,0 +1,3 @@
+====== Entrar ======
+
+Não está actualmente em sessão! Introduza as suas credenciais de autenticação abaixo para para entrar em sessão. Precisa de ter cookies activos no seu navegador. \ No newline at end of file
diff --git a/inc/lang/pt/mailtext.txt b/inc/lang/pt/mailtext.txt
new file mode 100644
index 000000000..915a147ec
--- /dev/null
+++ b/inc/lang/pt/mailtext.txt
@@ -0,0 +1,20 @@
+Um documento no site Wiki @DOKUWIKIURL@ foi criado ou modificado.
+
+Aqui estão os detalhes:
+
+Data : @DATE@
+Browser : @BROWSER@
+Endereço IP : @IPADDRESS@
+Hostname : @HOSTNAME@
+Documento Ant.: @OLDPAGE@
+Documento Novo: @NEWPAGE@
+Edit Summary : @SUMMARY@
+User : @USER@
+
+@DIFF@
+
+
+
+----
+
+Esta mensagem foi gerada automaticamente pelo motor DokuWiki em @DOKUWIKIURL@
diff --git a/inc/lang/pt/newpage.txt b/inc/lang/pt/newpage.txt
new file mode 100644
index 000000000..2d9c95599
--- /dev/null
+++ b/inc/lang/pt/newpage.txt
@@ -0,0 +1,3 @@
+====== Documento Inexistente ======
+
+Seguiu uma ligação para um documento que ainda não existe. Pode criá-lo usando o botão "Criar página", se as permissões lho permitirem. \ No newline at end of file
diff --git a/inc/lang/pt/norev.txt b/inc/lang/pt/norev.txt
new file mode 100644
index 000000000..6dd8dfb6c
--- /dev/null
+++ b/inc/lang/pt/norev.txt
@@ -0,0 +1,7 @@
+====== Revisão Inexistente ======
+
+A revisão especificada não existe.
+
+Clique no botão <Revisões> para aceder à lista de revisões deste documento.
+
+----
diff --git a/inc/lang/pt/password.txt b/inc/lang/pt/password.txt
new file mode 100644
index 000000000..70ecf91eb
--- /dev/null
+++ b/inc/lang/pt/password.txt
@@ -0,0 +1,10 @@
+Olá, @FULLNAME@!
+
+Aqui estão as suas credenciais de autenticação para @TITLE@, em @DOKUWIKIURL@
+
+Utilizador : @LOGIN@
+Senha : @PASSWORD@
+
+----
+Esta mensagem foi gerada pelo DokuWiki em
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt/preview.txt b/inc/lang/pt/preview.txt
new file mode 100644
index 000000000..1a8dab0b8
--- /dev/null
+++ b/inc/lang/pt/preview.txt
@@ -0,0 +1,3 @@
+====== Previsão ======
+
+Esta é uma previsão de como ficará o conteúdo. Lembre-se: ainda **não está gravado**! \ No newline at end of file
diff --git a/inc/lang/pt/pwconfirm.txt b/inc/lang/pt/pwconfirm.txt
new file mode 100644
index 000000000..2848a116c
--- /dev/null
+++ b/inc/lang/pt/pwconfirm.txt
@@ -0,0 +1,13 @@
+Olá @FULLNAME@!
+
+Alguém efectuou um pedido para uma nova senha para o seu perfil @TITLE@ em @DOKUWIKIURL@
+
+Se não foi você que efectuou o pedido então por favor ignore esta mensagem.
+
+Senão, para confirmar o pedido, por favor siga este link:
+
+@CONFIRM@
+
+--
+
+Esta mensagem foi gerada automaticamente pelo motor DokuWiki em @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt/read.txt b/inc/lang/pt/read.txt
new file mode 100644
index 000000000..177b1e81d
--- /dev/null
+++ b/inc/lang/pt/read.txt
@@ -0,0 +1 @@
+Esta página é apenas de leitura. Pode ver a fonte, mas não alterá-la. Informe-se com o administrador deste Wiki se achar que isto não está correcto. \ No newline at end of file
diff --git a/inc/lang/pt/recent.txt b/inc/lang/pt/recent.txt
new file mode 100644
index 000000000..3957df484
--- /dev/null
+++ b/inc/lang/pt/recent.txt
@@ -0,0 +1,3 @@
+====== Alterações Recentes ======
+
+Os seguintes documentos foram alterados recentemente. \ No newline at end of file
diff --git a/inc/lang/pt/register.txt b/inc/lang/pt/register.txt
new file mode 100644
index 000000000..228cb9979
--- /dev/null
+++ b/inc/lang/pt/register.txt
@@ -0,0 +1,3 @@
+====== Inscrição como novo utilizador ======
+
+Preencha toda a informação abaixo para criar uma nova conta nesta wiki. Assegure que providencia um **endereço de email válido** - se não lhe for pedido que introduza uma nova palavra chave aqui, ser-lhe-á enviada uma para esse endereço. O nome de utilizador deve ser um [[doku>pagename|nome de página]] válido. \ No newline at end of file
diff --git a/inc/lang/pt/registermail.txt b/inc/lang/pt/registermail.txt
new file mode 100644
index 000000000..b9c1f164b
--- /dev/null
+++ b/inc/lang/pt/registermail.txt
@@ -0,0 +1,14 @@
+Inscrição de um novo utilizador. Aqui estão os detalhes:
+
+Username : @NEWUSER@
+Nome Completo : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Data : @DATE@
+Browser : @BROWSER@
+Endereço IP : @IPADDRESS@
+Hostname : @HOSTNAME@
+
+----
+
+Esta mensagem foi gerada pelo DokuWiki em @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt/resendpwd.txt b/inc/lang/pt/resendpwd.txt
new file mode 100644
index 000000000..9a54ace07
--- /dev/null
+++ b/inc/lang/pt/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Enviar nova senha ======
+
+Por favor, insira o seu nome de utilizador neste formulário para requerer uma nova senha para esta conta/perfil. Um link de confirmação será enviado para o endereço de e-mail associado. \ No newline at end of file
diff --git a/inc/lang/pt/revisions.txt b/inc/lang/pt/revisions.txt
new file mode 100644
index 000000000..0a0d35950
--- /dev/null
+++ b/inc/lang/pt/revisions.txt
@@ -0,0 +1,3 @@
+====== Revisões antigas ======
+
+Estas são as revisões antigas do documento corrente. Para reverter para uma destas revisões, escolha-a abaixo, clique no botão "Editar página" e grave. \ No newline at end of file
diff --git a/inc/lang/pt/searchpage.txt b/inc/lang/pt/searchpage.txt
new file mode 100644
index 000000000..2239330dd
--- /dev/null
+++ b/inc/lang/pt/searchpage.txt
@@ -0,0 +1,5 @@
+====== Pesquisa ======
+
+Pode encontrar os resultados da sua pesquisa abaixo. Se não encontrou o que procurava pode criar uma nova página com o nome da sua pesquisa, usando o botão apropriado.
+
+===== Resultados =====
diff --git a/inc/lang/pt/showrev.txt b/inc/lang/pt/showrev.txt
new file mode 100644
index 000000000..25d617fa3
--- /dev/null
+++ b/inc/lang/pt/showrev.txt
@@ -0,0 +1 @@
+**Esta é uma versão antiga do documento!** \ No newline at end of file
diff --git a/inc/lang/pt/stopwords.txt b/inc/lang/pt/stopwords.txt
new file mode 100644
index 000000000..373e6ee5a
--- /dev/null
+++ b/inc/lang/pt/stopwords.txt
@@ -0,0 +1,141 @@
+# Esta é uma lista de plavaras que o indexador ignora, uma palavra por linha
+# Quando você edita esta lista certifique-se que usa fim de linha usado em sistemas UNIX
+# Não é necessário incluir palavras menores que 3 letras - estas são sempre ignoradas
+# Esta lista é baseada nas encontradas em http://www.ranks.nl/stopwords/
+último
+acerca
+agora
+algmas
+alguns
+ali
+ambos
+antes
+apontar
+aquela
+aquelas
+aquele
+aqueles
+aqui
+atrás
+bem
+bom
+cada
+caminho
+cima
+com
+como
+comprido
+conhecido
+corrente
+das
+debaixo
+dentro
+desde
+desligado
+deve
+devem
+deverá
+direita
+diz
+dizer
+dois
+dos
+ela
+ele
+eles
+enquanto
+então
+está
+estão
+estado
+estar
+estará
+este
+estes
+esteve
+estive
+estivemos
+estiveram
+fará
+faz
+fazer
+fazia
+fez
+fim
+foi
+fora
+horas
+iniciar
+inicio
+irá
+ista
+iste
+isto
+ligado
+maioria
+maiorias
+mais
+mas
+mesmo
+meu
+muito
+muitos
+nós
+não
+nome
+nosso
+novo
+onde
+outro
+para
+parte
+pegar
+pelo
+pessoas
+pode
+poderá
+podia
+por
+porque
+povo
+promeiro
+quê
+qual
+qualquer
+quando
+quem
+quieto
+são
+saber
+sem
+ser
+seu
+somente
+têm
+tal
+também
+tem
+tempo
+tenho
+tentar
+tentaram
+tente
+tentei
+teu
+teve
+tipo
+tive
+todos
+trabalhar
+trabalho
+uma
+umas
+uns
+usa
+usar
+valor
+veja
+ver
+verdade
+verdadeiro
+você
diff --git a/inc/lang/pt/subscr_digest.txt b/inc/lang/pt/subscr_digest.txt
new file mode 100644
index 000000000..3f8a814c6
--- /dev/null
+++ b/inc/lang/pt/subscr_digest.txt
@@ -0,0 +1,20 @@
+Olá!
+
+A página @PAGE@ na wiki @TITLE@ mudou.
+Eis as mudanças:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Revisão Antiga: @OLDPAGE@
+Revisão Nova: @NEWPAGE@
+
+Para cancelar as notificações de página, inicie sessão na wiki em
+@DOKUWIKIURL@, visite
+@SUBSCRIBE@
+e des-subscreva as alterações à página e/ou nome espaço de nome.
+
+--
+Este email foi gerado por DokuWiki em
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt/subscr_form.txt b/inc/lang/pt/subscr_form.txt
new file mode 100644
index 000000000..9bb7b6b45
--- /dev/null
+++ b/inc/lang/pt/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Gestão de Subscrição ======
+
+Esta página permite-lhe gerir as suas subscrições para a página e espaço de nomes correntes. \ No newline at end of file
diff --git a/inc/lang/pt/subscr_list.txt b/inc/lang/pt/subscr_list.txt
new file mode 100644
index 000000000..65325b9ea
--- /dev/null
+++ b/inc/lang/pt/subscr_list.txt
@@ -0,0 +1,17 @@
+Olá!
+
+Páginas no espaço de nome @PAGE@ da wiki @TITLE@ mudaram.
+Eis as páginas alteradas:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Para cancelar as notificações de páginas, inicie sessão na wiki em
+@DOKUWIKIURL@, visite
+@SUBSCRIBE@
+e des-subscreva às alterações da página e/ou espaço de nome.
+
+--
+Este email foi gerado por DokuWiki em
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt/subscr_single.txt b/inc/lang/pt/subscr_single.txt
new file mode 100644
index 000000000..1187b5911
--- /dev/null
+++ b/inc/lang/pt/subscr_single.txt
@@ -0,0 +1,23 @@
+Olá!
+
+A página @PAGE@ no wiki @TITLE@ mudou.
+Eis as alterações:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Data : @DATE@
+Utilizador : @USER@
+Sumário de Edição: @SUMMARY@
+Revisão Antiga: @OLDPAGE@
+Revisão Nova: @NEWPAGE@
+
+Para cancelar as notificações de página, inicie sessão no wiki em
+@DOKUWIKIURL@, visite
+@NEWPAGE@
+e des-subscreva às alterações de página e/ou espaço de nome.
+
+--
+Este email foi gerado automaticamente por DokuWiki em
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/pt/updateprofile.txt b/inc/lang/pt/updateprofile.txt
new file mode 100644
index 000000000..efacfe4a2
--- /dev/null
+++ b/inc/lang/pt/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Actualize o seu perfil ======
+
+Apenas precisa de completar os campos que pretende alterar. Não é possível alterar o seu nome de utilizador. \ No newline at end of file
diff --git a/inc/lang/pt/uploadmail.txt b/inc/lang/pt/uploadmail.txt
new file mode 100644
index 000000000..bb571ffae
--- /dev/null
+++ b/inc/lang/pt/uploadmail.txt
@@ -0,0 +1,15 @@
+Um ficheiro foi carregado. Aqui estão os detalhes:
+
+Ficheiro : @MEDIA@
+Revisão antiga : @OLD@
+Data : @DATE@
+Navegador : @BROWSER@
+Endereço IP : @IPADDRESS@
+Hostname : @HOSTNAME@
+Tamanho : @SIZE@
+MIME Type : @MIME@
+Utilizador : @USER@
+
+--
+Esta mensagem foi gerada pelo DokuWiki em
+@DOKUWIKIURL@
diff --git a/inc/lang/ro/admin.txt b/inc/lang/ro/admin.txt
new file mode 100644
index 000000000..4b1a9062a
--- /dev/null
+++ b/inc/lang/ro/admin.txt
@@ -0,0 +1,3 @@
+====== Administrare ======
+
+Puteţi vedea mai jos o listă cu activităţile administrative disponibile în DokuWiki. \ No newline at end of file
diff --git a/inc/lang/ro/adminplugins.txt b/inc/lang/ro/adminplugins.txt
new file mode 100644
index 000000000..f076c3651
--- /dev/null
+++ b/inc/lang/ro/adminplugins.txt
@@ -0,0 +1 @@
+===== Plugin-uri Adiţionale ===== \ No newline at end of file
diff --git a/inc/lang/ro/backlinks.txt b/inc/lang/ro/backlinks.txt
new file mode 100644
index 000000000..3fd5e3415
--- /dev/null
+++ b/inc/lang/ro/backlinks.txt
@@ -0,0 +1,4 @@
+====== Legături înapoi ======
+
+Aceasta e o listă de pagini care au legături către pagina curentă.
+
diff --git a/inc/lang/ro/conflict.txt b/inc/lang/ro/conflict.txt
new file mode 100644
index 000000000..d7218ca5f
--- /dev/null
+++ b/inc/lang/ro/conflict.txt
@@ -0,0 +1,6 @@
+====== Există o nouă versiune ======
+
+Există o versiune nouă a documentului editat. Aceasta se întîmplă cînd un alt utilizator a schimbat documentul în timp ce îl editezi.
+
+Examinează diferenţele arătate mai jos, apoi ia decizia care versiune o reţii. Dacă alegi ''Salvează'', versiunea documentului va fi salvată. Apăsaţi ''Renunţare'' pentru a menţine versiunea curentă.
+
diff --git a/inc/lang/ro/denied.txt b/inc/lang/ro/denied.txt
new file mode 100644
index 000000000..8178995e9
--- /dev/null
+++ b/inc/lang/ro/denied.txt
@@ -0,0 +1,4 @@
+====== Acces Interzis ======
+
+Din păcate nu aveţi destule drepturi pentru a continua. Poate aţi uitat să vă logaţi?
+
diff --git a/inc/lang/ro/diff.txt b/inc/lang/ro/diff.txt
new file mode 100644
index 000000000..f33be8afd
--- /dev/null
+++ b/inc/lang/ro/diff.txt
@@ -0,0 +1,4 @@
+====== Diferenţe ======
+
+Aceasta arată diferenţele dintre revziile selectate şi versiunea curentă a paginii.
+
diff --git a/inc/lang/ro/draft.txt b/inc/lang/ro/draft.txt
new file mode 100644
index 000000000..e13671e3e
--- /dev/null
+++ b/inc/lang/ro/draft.txt
@@ -0,0 +1,5 @@
+====== Fişierul schiţă nu a fost găsit ======
+
+Ultima dvs. sesiune de editare nu s-a finalizat corect. În timpul lucrului, DocuWiki a salvat automat o schiţă, pe care o puteţi utiliza acum pentru a continua editarea. Mai jos puteţi vedea informaţiile care s-au salvat de la ultima dvs. sesiune.
+
+Decideţi dacă vreţi să //recuperaţi// sesiunea de editare pierdută, //ştergeţi// schiţa salvată automat sau să //anulaţi// procesul de editare. \ No newline at end of file
diff --git a/inc/lang/ro/edit.txt b/inc/lang/ro/edit.txt
new file mode 100644
index 000000000..1e79dc4fc
--- /dev/null
+++ b/inc/lang/ro/edit.txt
@@ -0,0 +1,2 @@
+Editează pagina şi apasă ''Salvează''. Vezi [[wiki:syntax]] pentru sintaxă. Te rog editează pagina doar pentru a o **îmbunătaţi**. Dacă vrei să testezi cîteva lucruri, învaţă sa faci primii paşi în [[playground:playground]].
+
diff --git a/inc/lang/ro/editrev.txt b/inc/lang/ro/editrev.txt
new file mode 100644
index 000000000..290dca496
--- /dev/null
+++ b/inc/lang/ro/editrev.txt
@@ -0,0 +1,2 @@
+**Ai încărcat o versuine veche a documentului!** Dacă ai salvat-o, vei crea o versiune nouă cu această dată.
+----
diff --git a/inc/lang/ro/index.txt b/inc/lang/ro/index.txt
new file mode 100644
index 000000000..5b88cc03b
--- /dev/null
+++ b/inc/lang/ro/index.txt
@@ -0,0 +1,4 @@
+====== Index ======
+
+Acesta e un index al tuturor paginilor ordonat după [[doku>namespaces|namespaces]].
+
diff --git a/inc/lang/ro/install.html b/inc/lang/ro/install.html
new file mode 100644
index 000000000..56cf3873b
--- /dev/null
+++ b/inc/lang/ro/install.html
@@ -0,0 +1,10 @@
+<p>Această pagină oferă asistenţă la instalarea pentru prima dată a <a href="http://dokuwiki.org">Dokuwiki</a>. Mai multe informaţii privind această instalare găsiţi pe <a href="http://dokuwiki.org/installer">pagina de documentaţie</a>.</p>
+
+<p>DokuWiki foloseşte fişiere obişnuite pentru stocarea paginilor wiki şi a informaţilor asociate acestor pagini (de ex. imagini, indecşi de căutare, versiuni vechi, etc). Pentru a lucra cu succes, DokuWiki <strong>trebuie</strong> să aibă drepturi de scriere în directoarele ce conţin aceste fişiere.
+Acest script de instalare nu poate seta drepturile directoarelor. De regulă, aceasta se face direct, în linie de comandă, sau în cazul găzduirii, prin FTP sau prin panoul de control al gazdei (de ex. cPanel).</p>
+
+<p>Acest script de instalare va configura DokuWiki pentru <acronym title="access control list">ACL</acronym>, care permite logarea administratorului şi accesul la meniul de administrare pentru instalarea plugin-urilor, gestiunea utilizatorilor, a accesului la paginile wiki şi modificarea setărilor de configurare.
+Nu este necesar pentru ca DokuWiki să funcţioneze, însă face mai uşoară administrarea DokuWiki.</p>
+
+<p>Utilizatorii experimentaţi sau utilizatorii ce au nevoie de setări speciale ar putea folosi această legătură privind<a href="http://dokuwiki.org/install">instrucţiunile de instalare</a> şi <a href="http://dokuwiki.org/config">setările de configurare</a>.</p>
+
diff --git a/inc/lang/ro/lang.php b/inc/lang/ro/lang.php
new file mode 100644
index 000000000..96a3d7970
--- /dev/null
+++ b/inc/lang/ro/lang.php
@@ -0,0 +1,316 @@
+<?php
+/**
+ * romanian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Tiberiu Micu <tibimicu@gmx.net>
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Editează această pagină';
+$lang['btn_source'] = 'Arată sursa paginii';
+$lang['btn_show'] = 'Arată pagina';
+$lang['btn_create'] = 'Crează această pagină';
+$lang['btn_search'] = 'Caută';
+$lang['btn_save'] = 'Salvează';
+$lang['btn_preview'] = 'Previzualizează';
+$lang['btn_top'] = 'La început';
+$lang['btn_newer'] = '<< mai recent';
+$lang['btn_older'] = 'mai vechi>>';
+$lang['btn_revs'] = 'Versiuni vechi';
+$lang['btn_recent'] = 'Modificări recente';
+$lang['btn_upload'] = 'Upload';
+$lang['btn_cancel'] = 'Renunţare';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit'] = 'Editează';
+$lang['btn_login'] = 'Login';
+$lang['btn_logout'] = 'Logout';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Actualizează';
+$lang['btn_delete'] = 'Şterge';
+$lang['btn_back'] = 'Înapoi';
+$lang['btn_backlink'] = 'Legătură anterioară';
+$lang['btn_backtomedia'] = 'Înapoi la Selecţia Mediafile';
+$lang['btn_subscribe'] = 'Subscrie Modificarea Paginii';
+$lang['btn_profile'] = 'Actualizează Profil';
+$lang['btn_reset'] = 'Resetează';
+$lang['btn_resendpwd'] = 'Trimite parola nouă';
+$lang['btn_draft'] = 'Editează schiţă';
+$lang['btn_recover'] = 'Recuperează schiţă';
+$lang['btn_draftdel'] = 'Şterge schiţă';
+$lang['btn_revert'] = 'Revenire';
+$lang['btn_register'] = 'Înregistrează';
+$lang['btn_apply'] = 'Aplică';
+$lang['btn_media'] = 'Administrare media';
+$lang['loggedinas'] = 'Logat ca şi';
+$lang['user'] = 'Utilizator';
+$lang['pass'] = 'Parola';
+$lang['newpass'] = 'Parola nouă';
+$lang['oldpass'] = 'Confirmă parola curentă';
+$lang['passchk'] = 'încă o dată';
+$lang['remember'] = 'Ţine-mă minte';
+$lang['fullname'] = 'Nume complet';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'Profil Utilizator';
+$lang['badlogin'] = 'Imi pare rău, utilizatorul şi/sau parola au fost greşite.';
+$lang['minoredit'] = 'Modificare Minoră';
+$lang['draftdate'] = 'Schiţă salvată automat la';
+$lang['nosecedit'] = 'Pagina s-a modificat între timp, secţiunea info a expirat, s-a încărcat pagina întreagă în loc.';
+$lang['regmissing'] = 'Ne pare rău, trebuie să completezi toate cîmpurile.';
+$lang['reguexists'] = 'Ne pare rău, un utilizator cu acest nume există deja logat.';
+$lang['regsuccess'] = 'Utilizatorul a fost creat. Parola a fost trimisă prin email.';
+$lang['regsuccess2'] = 'Utilizatorul a fost creat.';
+$lang['regmailfail'] = 'Se pare că a fost o eroare la trimiterea parolei prin email. Contactaţi administratorul!';
+$lang['regbadmail'] = 'Adresa de email este invalidă - dacă credeţi că este o eroare contactaţi administratorul.';
+$lang['regbadpass'] = 'Cele două parole furnizate nu sunt identice; încercaţi din nou.';
+$lang['regpwmail'] = 'Parola ta DokuWiki';
+$lang['reghere'] = 'Înca nu ai un cont? Fă-ţi unul';
+$lang['profna'] = 'Această wiki nu suportă modificarea profilului';
+$lang['profnochange'] = 'Nici o modificare; nimic de făcut.';
+$lang['profnoempty'] = 'Nu sunt admise numele sau adresa de email necompletate.';
+$lang['profchanged'] = 'Profilul de utilizator a fost actualizat succes.';
+$lang['pwdforget'] = 'Parola uitată? Luaţi una nouă';
+$lang['resendna'] = 'Această wiki nu suportă retrimiterea parolei.';
+$lang['resendpwd'] = 'Trimite parola nouă pentru';
+$lang['resendpwdmissing'] = 'Ne pare rău, trebuie completate toate câmpurile.';
+$lang['resendpwdnouser'] = 'Ne pare rău, acest utilizator nu poate fi găsit în baza de date.';
+$lang['resendpwdbadauth'] = 'Ne pare rău, acest cod de autorizare nu este corect. Verificaţi dacă aţi folosit tot link-ul de confirmare.';
+$lang['resendpwdconfirm'] = 'Un link de confirmare a fost trimis prin email.';
+$lang['resendpwdsuccess'] = 'Parola nouă';
+$lang['license'] = 'Exceptând locurile unde este altfel specificat, conţinutul acestui wiki este licenţiat sub următoarea licenţă:';
+$lang['licenseok'] = 'Notă: Prin editarea acestei pagini sunteţi de acord să vă licenţiaţi conţintul sub următoarea licenţă:';
+$lang['searchmedia'] = 'Caută numele fişierului:';
+$lang['searchmedia_in'] = 'Caută în %s';
+$lang['txt_upload'] = 'Selectează fisierul de încărcat';
+$lang['txt_filename'] = 'Încarcă fişierul ca (opţional)';
+$lang['txt_overwrt'] = 'Suprascrie fişierul existent';
+$lang['lockedby'] = 'Momentan blocat de';
+$lang['lockexpire'] = 'Blocarea expiră la';
+$lang['js']['willexpire'] = 'Blocarea pentru editarea paginii expiră intr-un minut.\nPentru a preveni conflictele foloseşte butonul de previzualizare pentru resetarea blocării.';
+$lang['js']['notsavedyet'] = 'Există modificări nesalvate, care se vor pierde.
+Doreşti să continui?';
+$lang['js']['searchmedia'] = 'Caută fişiere';
+$lang['js']['keepopen'] = 'Menţine fereastra deschisă la selecţie';
+$lang['js']['hidedetails'] = 'Ascunde Detalii';
+$lang['js']['mediatitle'] = 'Setări link';
+$lang['js']['mediadisplay'] = 'Tip link';
+$lang['js']['mediaalign'] = 'Aliniere';
+$lang['js']['mediasize'] = 'Mărime imagine';
+$lang['js']['mediatarget'] = 'Ţintă link';
+$lang['js']['mediaclose'] = 'Închide';
+$lang['js']['mediainsert'] = 'Inserează';
+$lang['js']['mediadisplayimg'] = 'Afişează imaginea.';
+$lang['js']['mediadisplaylnk'] = 'Afişează doar linkul.';
+$lang['js']['mediasmall'] = 'Versiune mică';
+$lang['js']['mediamedium'] = 'Versiune medie';
+$lang['js']['medialarge'] = 'Versiune mare';
+$lang['js']['mediaoriginal'] = 'Versiune originală';
+$lang['js']['medialnk'] = 'Link către pagina detaliilor';
+$lang['js']['mediadirect'] = 'Link direct către original';
+$lang['js']['medianolnk'] = 'Fără link';
+$lang['js']['medianolink'] = 'Nu crea link către imagine';
+$lang['js']['medialeft'] = 'Aliniază imaginea la stânga.';
+$lang['js']['mediaright'] = 'Aliniază imaginea la dreapta.';
+$lang['js']['mediacenter'] = 'Aliniază imaginea la centru.';
+$lang['js']['medianoalign'] = 'Nu utiliza aliniere.';
+$lang['js']['nosmblinks'] = 'Legăturile către sharing-uri Windows funcţioneaza numai in Microsoft Internet Explorer.
+Puteţi însă copia şi insera legătura.';
+$lang['js']['linkwiz'] = 'Asistent legătură';
+$lang['js']['linkto'] = 'Legătură la:';
+$lang['js']['del_confirm'] = 'Doriţi într-adevăr ştergerea elementelor selectate?';
+$lang['js']['restore_confirm'] = 'Sunteți sigur că doriți restaurarea acestei versiuni?';
+$lang['js']['media_diff'] = 'Arată diferențele:';
+$lang['js']['media_diff_both'] = 'Unul lângă altul';
+$lang['js']['media_diff_opacity'] = 'Străveziu';
+$lang['js']['media_diff_portions'] = 'Lovește cu putere';
+$lang['js']['media_select'] = 'Selectează fișierele...';
+$lang['js']['media_upload_btn'] = 'Încarcă';
+$lang['js']['media_done_btn'] = 'Gata';
+$lang['js']['media_drop'] = 'Lasă fișierele aici pentru încărcarea lor';
+$lang['js']['media_cancel'] = 'înlătură';
+$lang['js']['media_overwrt'] = 'Suprascrie fișierele deja existente';
+$lang['rssfailed'] = 'A apărut o eroare in timpul descărcării acestui cîmp: ';
+$lang['nothingfound'] = 'Nu am găsit nimic.';
+$lang['mediaselect'] = 'Selectare fişiere media';
+$lang['fileupload'] = 'Încarcă fişier media';
+$lang['uploadsucc'] = 'Încărcare reuşită';
+$lang['uploadfail'] = 'Încărcare eşuată. Poate din cauza permisiunilor?';
+$lang['uploadwrong'] = 'Încărcare nepermisă. Extensia fişierului e nepermisă';
+$lang['uploadexist'] = 'Fişierul există deja. Nimic nu a fost făcut.';
+$lang['uploadbadcontent'] = 'Conţinutul încărcat nu corespunde extensiei fişierului %s.';
+$lang['uploadspam'] = 'Încărcarea a fost blocată datorită listei negre de spam.';
+$lang['uploadxss'] = 'Încărcarea a fost blocată datorită unui posibil conţinut dăunător.';
+$lang['uploadsize'] = 'Fişierul uploadat a fost prea mare. (max %s)';
+$lang['deletesucc'] = 'Fişierul "%s" a fost şters.';
+$lang['deletefail'] = '"%s" nu a putut fi şters - verificaţi drepturile.';
+$lang['mediainuse'] = 'Fişierul "%s" nu a fost şters - este încă în uz.';
+$lang['namespaces'] = 'Spaţii de nume';
+$lang['mediafiles'] = 'Fişiere disponibile în';
+$lang['accessdenied'] = 'Nu vă este permis să vizualizaţi această pagină.';
+$lang['mediausage'] = 'Folosiţi următoarea sintaxă pentru a face referinţă la acest fişier:';
+$lang['mediaview'] = 'Vizualizează fişierul original';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Încarcă un fişier in acest spaţiu de nume. Pentru a crea sub-spaţii de nume, adaugă-le la fişierul de încărcat, separate de doua puncte (:).';
+$lang['mediaextchange'] = 'Extensia fişierului a fost modificată din .%s în .%s!';
+$lang['reference'] = 'Referinţă pentru';
+$lang['ref_inuse'] = 'Fişierul nu a putut fi şters întrucât este folosit încă de următoarele pagini:';
+$lang['ref_hidden'] = 'Nu aveţi permisiunea să citiţi o parte din referinţele din pagină.';
+$lang['hits'] = 'Hituri';
+$lang['quickhits'] = 'Nume de pagini potrivite';
+$lang['toc'] = 'Cuprins';
+$lang['current'] = 'curent';
+$lang['yours'] = 'Versiunea ta';
+$lang['diff'] = 'arată diferenţele faţă de versiunea curentă';
+$lang['diff2'] = 'Arată diferenţele dintre versiunile selectate';
+$lang['difflink'] = 'Link către această vizualizare comparativă';
+$lang['diff_type'] = 'Vezi diferențe:';
+$lang['diff_inline'] = 'Succesiv';
+$lang['diff_side'] = 'Alăturate';
+$lang['line'] = 'Linia';
+$lang['breadcrumb'] = 'Traseu';
+$lang['youarehere'] = 'Sunteţi aici';
+$lang['lastmod'] = 'Ultima modificare';
+$lang['by'] = 'de către';
+$lang['deleted'] = 'şters';
+$lang['created'] = 'creat';
+$lang['restored'] = 'versiune veche restaurată';
+$lang['external_edit'] = 'editare externă';
+$lang['summary'] = 'Editează sumarul';
+$lang['noflash'] = 'Plugin-ul <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> este necesar pentru afişarea corectă a conţinutului.';
+$lang['download'] = 'Bloc descărcări';
+$lang['mail_newpage'] = 'pagina adăugată:';
+$lang['mail_changed'] = 'page schimbată:';
+$lang['mail_subscribe_list'] = 'pagini modificate în spaţiul de nume:';
+$lang['mail_new_user'] = 'utilizator nou';
+$lang['mail_upload'] = 'fişier încărcat:';
+$lang['changes_type'] = 'Vizualizare modificări';
+$lang['pages_changes'] = 'Pagini';
+$lang['media_changes'] = 'Fișiere media';
+$lang['both_changes'] = 'Ambele pagini şi fişiere media';
+$lang['qb_bold'] = 'Text Îngroşat';
+$lang['qb_italic'] = 'Text Italic';
+$lang['qb_underl'] = 'Text Subliniat';
+$lang['qb_code'] = 'Text Cod';
+$lang['qb_strike'] = 'Text Tăiat';
+$lang['qb_h1'] = 'Titlu de Nivel 1';
+$lang['qb_h2'] = 'Titlu de Nivel 2';
+$lang['qb_h3'] = 'Titlu de Nivel 3';
+$lang['qb_h4'] = 'Titlu de Nivel 4';
+$lang['qb_h5'] = 'Titlu de Nivel 5';
+$lang['qb_h'] = 'Titlu';
+$lang['qb_hs'] = 'Selectaţi Titlul';
+$lang['qb_hplus'] = 'Titlu mai mare';
+$lang['qb_hminus'] = 'Titlu mai mic';
+$lang['qb_hequal'] = 'Titlu de acelaşi nivel';
+$lang['qb_link'] = 'Legătură internă';
+$lang['qb_extlink'] = 'Legătura externă';
+$lang['qb_hr'] = 'Linie Orizontal';
+$lang['qb_ol'] = 'Listă Ordonată';
+$lang['qb_ul'] = 'Listă Neordoată';
+$lang['qb_media'] = 'Adaugă imagini şi alte fişiere';
+$lang['qb_sig'] = 'Inserează semnătură';
+$lang['qb_smileys'] = 'Smiley-uri';
+$lang['qb_chars'] = 'Caractere speciale';
+$lang['upperns'] = 'sari la numele de spaţiu părinte';
+$lang['admin_register'] = 'Adaugă utilizator nou';
+$lang['metaedit'] = 'Editează Metadata';
+$lang['metasaveerr'] = 'Scrierea metadatelor a eşuat';
+$lang['metasaveok'] = 'Metadatele au fost salvate';
+$lang['img_backto'] = 'Înapoi la';
+$lang['img_title'] = 'Titlu';
+$lang['img_caption'] = 'Legendă';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Nume fişier';
+$lang['img_fsize'] = 'Dimensiune';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Camera';
+$lang['img_keywords'] = 'Cuvinte cheie';
+$lang['img_width'] = 'Lățime';
+$lang['img_height'] = 'Înălțime';
+$lang['img_manager'] = 'Vizualizează în administratorul media';
+$lang['subscr_subscribe_success'] = 'Adăugat %s la lista de abonare pentru %s';
+$lang['subscr_subscribe_error'] = 'Eroare la adăugarea %s la lista de abonare pentru %s';
+$lang['subscr_subscribe_noaddress'] = 'Nu există adresa asociată cu logarea dvs., nu puteţi fi adăugat la lista de abonare';
+$lang['subscr_unsubscribe_success'] = 'Şters %s din lista de abonare pentru %s';
+$lang['subscr_unsubscribe_error'] = 'Eroare la ştergerea %s din lista de abonare pentru %s';
+$lang['subscr_already_subscribed'] = '%s este deja abonat la %s';
+$lang['subscr_not_subscribed'] = '%s nu este abonat la %s';
+$lang['subscr_m_not_subscribed'] = 'Momentan nu sunteţi abonat la pagina curentă sau la numele de spaţiu.';
+$lang['subscr_m_new_header'] = 'Adaugă abonare';
+$lang['subscr_m_current_header'] = 'Abonări curente';
+$lang['subscr_m_unsubscribe'] = 'Dezabonaţi-vă';
+$lang['subscr_m_subscribe'] = 'Abonaţi-vă';
+$lang['subscr_m_receive'] = 'Primiţi';
+$lang['subscr_style_every'] = 'email la ficare schimbare';
+$lang['subscr_style_digest'] = 'digerează email la schimbări pentru fiecare pagină (la fiecare %.2f zile)';
+$lang['subscr_style_list'] = 'lista paginilor schimbate de la ultimul email (la fiecare %.2f zile)';
+$lang['authmodfailed'] = 'Configuraţia autentificării utilizatorului este eronată. Anunţaţi Wiki Admin-ul.';
+$lang['authtempfail'] = 'Autentificarea utilizatorului este temporar indisponibilă. Anunţaţi Wiki Admin-ul.';
+$lang['i_chooselang'] = 'Alegeţi limba';
+$lang['i_installer'] = 'DokuWiki Installer';
+$lang['i_wikiname'] = 'Numele Wiki';
+$lang['i_enableacl'] = 'Activează ACL (recomandat)';
+$lang['i_superuser'] = 'Superutilizator';
+$lang['i_problems'] = 'Programul de instalare a găsit câteva probleme, indicate mai jos. Nu puteţi continua până nu le rezolvaţi.';
+$lang['i_modified'] = 'Din motive de securitate, acest script va funcţiona doar cu o instalare nouă şi nemodificată a Docuwiki.
+Puteţi fie să extrageţi din nou fişierele din arhiva descărcată fie să consultaţi instrucţiunile de instalare Dokuwiki la <a href="http://dokuwiki.org/install">';
+$lang['i_funcna'] = 'Funcţia PHP <code>%s</code> nu este disponibilă. Probabil provider-ul dvs. a inactivat-o pentru un motiv oarecare.';
+$lang['i_phpver'] = 'Versiunea dvs. de PHP <code>%s</code> este mai veche decât cea necesară (<code>%s</code>). Trebuie să vă actualizaţi instalarea PHP.';
+$lang['i_permfail'] = '<code>%s</code> nu poate fi scris de către DokuWiki. Trebuie să modificaţi drepturile acestui director!';
+$lang['i_confexists'] = '<code>%s</code> există deja';
+$lang['i_writeerr'] = 'Nu s-a putut crea <code>%s</code>. Trebuie să verificaţi drepturile directorului/fişierului şi să creaţi fişierul manual.';
+$lang['i_badhash'] = 'dokuwiki.php nu a fost recunoscut sau a fost modificat (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - valoare nepemisă sau neintrodusă';
+$lang['i_success'] = 'Configurarea a fost finalizată cu succes. Acum puteţi sterge fişierul install.php. Continuaţi cu <a href="doku.php">your new DokuWiki</a>.';
+$lang['i_failure'] = 'Au apărut erori la scrierea fişierelor de configurare. Va trebui să le corectaţi manual înainte de a putea folosi <a href="doku.php">your new DokuWiki</a>.';
+$lang['i_policy'] = 'Politica ACL iniţială';
+$lang['i_pol0'] = 'Wiki Deschisă (citeşte, scrie şi încarcă oricine)';
+$lang['i_pol1'] = 'Wiki Deschisă (citeste oricine, scrie şi încarcă doar utilizatorul înregistrat)';
+$lang['i_pol2'] = 'Wiki Închisă (citeşte, scrie şi încarcă doar utilizatorul înregistrat)';
+$lang['i_retry'] = 'Încearcă din nou';
+$lang['i_license'] = 'Vă rugăm alegeţi licenţa sub care doriţi să vă licenţiaţi materialul:';
+$lang['recent_global'] = 'Acum vizualizaţi modificările în interiorul numelui de spaţiu <b>%s</b>. De asemenea puteţi <a href="%s">vizualiza modificările recente ale întregului wiki</a>.';
+$lang['years'] = 'acum %d ani';
+$lang['months'] = 'acum %d luni';
+$lang['weeks'] = 'acum %d săptămâni';
+$lang['days'] = 'acum %d zile';
+$lang['hours'] = 'acum %d ore';
+$lang['minutes'] = 'acum %d minute';
+$lang['seconds'] = 'acum %d secunde';
+$lang['wordblock'] = 'Modificarea dvs. nu au fost salvate deoarece conţine text blocat (spam).';
+$lang['media_uploadtab'] = 'Încarcă';
+$lang['media_searchtab'] = 'Căutare';
+$lang['media_file'] = 'Fișier';
+$lang['media_viewtab'] = 'Vizualizare';
+$lang['media_edittab'] = 'Editare';
+$lang['media_historytab'] = 'Istoric';
+$lang['media_list_thumbs'] = 'Miniaturi';
+$lang['media_list_rows'] = 'Linii';
+$lang['media_sort_name'] = 'Nume';
+$lang['media_sort_date'] = 'Data';
+$lang['media_namespaces'] = 'Alegeți numele se spațiu';
+$lang['media_files'] = 'Fișiere în %s';
+$lang['media_upload'] = 'Încarcă în %s';
+$lang['media_search'] = 'Caută în %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s în %s';
+$lang['media_edit'] = 'Editare %s';
+$lang['media_history'] = 'Istoricul pentru %s';
+$lang['media_meta_edited'] = 'metadate editate';
+$lang['media_perm_read'] = 'Ne pare rău, dar nu aveți suficiente drepturi pentru a putea citi fișiere.';
+$lang['media_perm_upload'] = 'Ne pare rău, dar nu aveți suficiente drepturi pentru a putea încărca fișiere.';
+$lang['media_update'] = 'Încarcă noua versiune';
+$lang['media_restore'] = 'Restaurează această versiune';
+$lang['plugin_install_err'] = 'Modul instalat greșit. Redenumește directorul modulului \'%s\' în \'%s\'.';
diff --git a/inc/lang/ro/locked.txt b/inc/lang/ro/locked.txt
new file mode 100644
index 000000000..94d6eb2ff
--- /dev/null
+++ b/inc/lang/ro/locked.txt
@@ -0,0 +1,3 @@
+====== Pagină blocată ======
+
+Pagina este momentan blocată de alt utilizator. Trebuie să aştepţi pînă cînd acest utilizator termină editarea ori expiră blocarea.
diff --git a/inc/lang/ro/login.txt b/inc/lang/ro/login.txt
new file mode 100644
index 000000000..2f1fda9ad
--- /dev/null
+++ b/inc/lang/ro/login.txt
@@ -0,0 +1,4 @@
+====== Login ======
+
+Nu sînteţi logat! Introduceţi datele de autentificare pentru logare. Trebuie să permiteţi cookie-uri pentru logare.
+
diff --git a/inc/lang/ro/mailtext.txt b/inc/lang/ro/mailtext.txt
new file mode 100644
index 000000000..77aca8c4b
--- /dev/null
+++ b/inc/lang/ro/mailtext.txt
@@ -0,0 +1,16 @@
+A fost adăugată sau schimbată o pagină. Aici sînt detaliile:
+
+Data : @DATE@
+Navigator : @BROWSER@
+Adresa-IP : @IPADDRESS@
+Nume gazdă : @HOSTNAME@
+Versiune veche : @OLDPAGE@
+Versiune nouă : @NEWPAGE@
+Rezumat editare: @SUMMARY@
+
+@DIFF@
+
+
+--
+Mailul a fost generat de DokuWiki la
+@DOKUWIKIURL@
diff --git a/inc/lang/ro/newpage.txt b/inc/lang/ro/newpage.txt
new file mode 100644
index 000000000..7fb9d55a6
--- /dev/null
+++ b/inc/lang/ro/newpage.txt
@@ -0,0 +1,3 @@
+====== Subiectul nu există încă ======
+
+Aţi urmat o legătură către un subiect care nu există. O puteţi crea prin apăsarea butonului ''Editează această pagină''.
diff --git a/inc/lang/ro/norev.txt b/inc/lang/ro/norev.txt
new file mode 100644
index 000000000..926f9144e
--- /dev/null
+++ b/inc/lang/ro/norev.txt
@@ -0,0 +1,4 @@
+====== Nu există versiunea ======
+
+Versiunea specificată nu există. Foloseşte butonul ''Versiuni vechi'' pentru o listă a versiunilor acestui document.
+
diff --git a/inc/lang/ro/password.txt b/inc/lang/ro/password.txt
new file mode 100644
index 000000000..a7eb12dd9
--- /dev/null
+++ b/inc/lang/ro/password.txt
@@ -0,0 +1,10 @@
+Salut @FULLNAME@!
+
+Aici sînt datele utilizator pentru @TITLE@ la @DOKUWIKIURL@
+
+Login : @LOGIN@
+Parola : @PASSWORD@
+
+--
+Mesajul a fost generat de către DokuWiki la
+@DOKUWIKIURL@
diff --git a/inc/lang/ro/preview.txt b/inc/lang/ro/preview.txt
new file mode 100644
index 000000000..1964d7476
--- /dev/null
+++ b/inc/lang/ro/preview.txt
@@ -0,0 +1,4 @@
+====== Previzualizare ======
+
+Acesta este modul în care va arăta textul. Nu uita: **Nu** e încă **salvat**!
+
diff --git a/inc/lang/ro/pwconfirm.txt b/inc/lang/ro/pwconfirm.txt
new file mode 100644
index 000000000..043e08868
--- /dev/null
+++ b/inc/lang/ro/pwconfirm.txt
@@ -0,0 +1,13 @@
+Salut @FULLNAME@!
+
+Cineva a cerut o parolă nouă pentru @TITLE@ pentru conectarea la @DOKUWIKIURL@
+
+Dacă nu aţi solicitat o parolă nouă, ignoraţi acest email.
+
+Pentru a confirma că cererea a fost într-adevăr trimisă de dumneavoastră, folosiţi link-ul de mai jos.
+
+@CONFIRM@
+
+--
+Acest mail a fost generat de DocuWiki la
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ro/read.txt b/inc/lang/ro/read.txt
new file mode 100644
index 000000000..2c0aa6d90
--- /dev/null
+++ b/inc/lang/ro/read.txt
@@ -0,0 +1,2 @@
+Această pagină poate fi doar citită. Poţi vedea sursa, dar n-o poţi modifica. Consultă administratorul dacă crezi că e ceva în neregulă.
+
diff --git a/inc/lang/ro/recent.txt b/inc/lang/ro/recent.txt
new file mode 100644
index 000000000..8d4aa043a
--- /dev/null
+++ b/inc/lang/ro/recent.txt
@@ -0,0 +1,5 @@
+====== Schimbări recente ======
+
+Următoarele pagini au fost schimbate recent.
+
+
diff --git a/inc/lang/ro/register.txt b/inc/lang/ro/register.txt
new file mode 100644
index 000000000..9fc6eec65
--- /dev/null
+++ b/inc/lang/ro/register.txt
@@ -0,0 +1,3 @@
+====== Înregistrează-te ca utilizator nou ======
+Pentru a crea un wiki nou completează mai jos toate informaţiile. Asigură-te că ai introdus o adresă de **e-mail validă** unde va fi trimisă noua parolă. Numele de utilizator trebuie de asemenea să fie valid [[doku>pagename|pagename]].
+
diff --git a/inc/lang/ro/registermail.txt b/inc/lang/ro/registermail.txt
new file mode 100644
index 000000000..fb754af67
--- /dev/null
+++ b/inc/lang/ro/registermail.txt
@@ -0,0 +1,14 @@
+Un nou utilizator s-a înregsitrat. Iată detaliile:
+
+Nume utilizator : @NEWUSER@
+Nume complet : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Data : @DATE@
+Browser : @BROWSER@
+Adresă IP : @IPADDRESS@
+Hostname : @HOSTNAME@
+
+--
+Acest mail a fost generat automat de către DokuWiki la
+@DOKUWIKIURL@
diff --git a/inc/lang/ro/resendpwd.txt b/inc/lang/ro/resendpwd.txt
new file mode 100644
index 000000000..b7de241e9
--- /dev/null
+++ b/inc/lang/ro/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Trimite parolă nouă ======
+
+Introduceţi numele de utilizator în formularul de mai jos pentru a solicita o nouă parolă pentru această wiki. Un link de confirmare va fi trimis la adresa de email înregistrată. \ No newline at end of file
diff --git a/inc/lang/ro/revisions.txt b/inc/lang/ro/revisions.txt
new file mode 100644
index 000000000..b2ff46f77
--- /dev/null
+++ b/inc/lang/ro/revisions.txt
@@ -0,0 +1,4 @@
+====== Versiune veche ======
+
+Acestea sînt versiunile vechi ale documentului curent. Pentru revenirea la o versiune mai veche, selecteaz-o de mai jos, clic pe ''Editează această pagină'' şi salveaz-o.
+
diff --git a/inc/lang/ro/searchpage.txt b/inc/lang/ro/searchpage.txt
new file mode 100644
index 000000000..c1169b88d
--- /dev/null
+++ b/inc/lang/ro/searchpage.txt
@@ -0,0 +1,5 @@
+====== Căutare ======
+
+Rezultatele căutării sînt afisate mai jos. Dacă n-aţi găsit ce-aţi căutat, puteţi creea o pagină nouă după căutare prin folosirea butonului ''Editează această pagină''.
+
+===== Rezultate =====
diff --git a/inc/lang/ro/showrev.txt b/inc/lang/ro/showrev.txt
new file mode 100644
index 000000000..c1d5e545d
--- /dev/null
+++ b/inc/lang/ro/showrev.txt
@@ -0,0 +1,2 @@
+**Aceasta e o versiune veche a documentului!**
+----
diff --git a/inc/lang/ro/stopwords.txt b/inc/lang/ro/stopwords.txt
new file mode 100644
index 000000000..29e7452d3
--- /dev/null
+++ b/inc/lang/ro/stopwords.txt
@@ -0,0 +1,29 @@
+# Aceasta este o listă de cuvinte ignorate la indexare, câte un cuvânt pe linie
+# Când editaţi acest fişier, asiguraţi-vă că folosiţi sfârşituri de linie UNIX (o singură linie nouă)
+# Nu e nevoie să includeţi cuvinte mai scurte de 3 caractere - acestea sunt, oricum, ignorate
+# Această listă se bazează pe cele ce pot fi găsite la http://www.ranks.nl/stopwords/
+about
+are
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/ro/subscr_digest.txt b/inc/lang/ro/subscr_digest.txt
new file mode 100644
index 000000000..b2f7c4ecb
--- /dev/null
+++ b/inc/lang/ro/subscr_digest.txt
@@ -0,0 +1,20 @@
+Buna ziua!
+
+Pagina @PAGE@ în @TITLE@ wiki s-a modificat.
+Acestea sunt modificările:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Vechea revizie: @OLDPAGE@
+Noua revizie: @NEWPAGE@
+
+Pentru a anula notificarea paginii, logaţi-vă pe wiki la
+@DOKUWIKIURL@ apoi navigaţi la
+@SUBSCRIBE@
+şi dezabonaţi-vă de la pagină şi/sau modificările numelui de spaţiu.
+
+--
+Acest mail a fost generat de DokuWiki la
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ro/subscr_form.txt b/inc/lang/ro/subscr_form.txt
new file mode 100644
index 000000000..8ce7f09b8
--- /dev/null
+++ b/inc/lang/ro/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Administrarea abonărilor ======
+
+Această pagină vă permite să vă administraţi abonările pentru pagina curentă şi numele de spaţiu. \ No newline at end of file
diff --git a/inc/lang/ro/subscr_list.txt b/inc/lang/ro/subscr_list.txt
new file mode 100644
index 000000000..84a5e1a3e
--- /dev/null
+++ b/inc/lang/ro/subscr_list.txt
@@ -0,0 +1,17 @@
+Bună ziua!
+
+Paginile din numele de spaţiu @PAGE@ al @TITLE@ wiki s-au modificat.
+Acestea sunt modificările:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Pentru a anula notificarea paginii, logaţi-vă pe wiki la
+@DOKUWIKIURL@ apoi navigaţi la
+@SUBSCRIBE@
+şi dezabonaţi-vă de la pagină şi/sau modificările numelui de spaţiu.
+
+--
+Acest mail a fost generat de DokuWiki la
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ro/subscr_single.txt b/inc/lang/ro/subscr_single.txt
new file mode 100644
index 000000000..aa6497b75
--- /dev/null
+++ b/inc/lang/ro/subscr_single.txt
@@ -0,0 +1,23 @@
+Bună ziua!
+
+Pagina @PAGE@ în @TITLE@ wiki s-a modificat.
+Acestea sunt modificările:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Data: @DATE@
+Utilizator: @USER@
+Sumarul editării: @SUMMARY@
+Vechea revizie: @OLDPAGE@
+Noua revizie: @NEWPAGE@
+
+Pentru a anula notificarea paginii, logaţi-vă pe wiki la
+@DOKUWIKIURL@ apoi navigaţi la
+@SUBSCRIBE@
+şi dezabonaţi-vă de la pagină şi/sau modificările numelui de spaţiu.
+
+--
+Acest mail a fost generat de DokuWiki la
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ro/updateprofile.txt b/inc/lang/ro/updateprofile.txt
new file mode 100644
index 000000000..e5988ec51
--- /dev/null
+++ b/inc/lang/ro/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Actualizare profil utilizator ======
+
+Trebuie să completaţi doar câmpurile pe care doriţi să le modificaţi. Nu puteţi modifica numele de utilizator. \ No newline at end of file
diff --git a/inc/lang/ro/uploadmail.txt b/inc/lang/ro/uploadmail.txt
new file mode 100644
index 000000000..39faed370
--- /dev/null
+++ b/inc/lang/ro/uploadmail.txt
@@ -0,0 +1,14 @@
+Un fişier a fost încărcat în DocuWiki. Iată detaliile:
+
+Fişier : @MEDIA@
+Data : @DATE@
+Browser : @BROWSER@
+Adresă IP : @IPADDRESS@
+Hostname : @HOSTNAME@
+Dimensiune : @SIZE@
+MIME Type : @MIME@
+Utilizator : @USER@
+
+--
+Acest mail a fost generat automat de către DokuWiki la
+@DOKUWIKIURL@
diff --git a/inc/lang/ru/admin.txt b/inc/lang/ru/admin.txt
new file mode 100644
index 000000000..e00daa447
--- /dev/null
+++ b/inc/lang/ru/admin.txt
@@ -0,0 +1,4 @@
+====== Управление ======
+
+Ниже вы сможете найти список административных операций, доступных в «ДокуВики».
+
diff --git a/inc/lang/ru/adminplugins.txt b/inc/lang/ru/adminplugins.txt
new file mode 100644
index 000000000..6e3fc26f2
--- /dev/null
+++ b/inc/lang/ru/adminplugins.txt
@@ -0,0 +1 @@
+===== Дополнительные плагины ===== \ No newline at end of file
diff --git a/inc/lang/ru/backlinks.txt b/inc/lang/ru/backlinks.txt
new file mode 100644
index 000000000..a3b638d19
--- /dev/null
+++ b/inc/lang/ru/backlinks.txt
@@ -0,0 +1,4 @@
+====== Обратные ссылки ======
+
+Это список страниц, которые ссылаются на текущую страницу.
+
diff --git a/inc/lang/ru/conflict.txt b/inc/lang/ru/conflict.txt
new file mode 100644
index 000000000..6c5e33dce
--- /dev/null
+++ b/inc/lang/ru/conflict.txt
@@ -0,0 +1,5 @@
+====== Существует более новая версия ======
+
+Существует более новая версия документа, который вы редактировали. Такое случается, когда другой пользователь изменил документ, пока вы делали то же самое.
+
+Внимательно изучите различия, приведенные ниже, и решите, какую версию оставить. Если вы выберете «Сохранить», то ваша версия будет сохранена. Нажав «Отменить», вы оставите текущую версию.
diff --git a/inc/lang/ru/denied.txt b/inc/lang/ru/denied.txt
new file mode 100644
index 000000000..2cc33cff7
--- /dev/null
+++ b/inc/lang/ru/denied.txt
@@ -0,0 +1,3 @@
+====== Доступ запрещён ======
+
+Извините, у вас не хватает прав для этого действия. Может быть, вы забыли войти в вики под своим логином?
diff --git a/inc/lang/ru/diff.txt b/inc/lang/ru/diff.txt
new file mode 100644
index 000000000..4d1d4d031
--- /dev/null
+++ b/inc/lang/ru/diff.txt
@@ -0,0 +1,4 @@
+====== Различия ======
+
+Здесь показаны различия между выбранной ревизией и текущей версией данной страницы.
+
diff --git a/inc/lang/ru/draft.txt b/inc/lang/ru/draft.txt
new file mode 100644
index 000000000..cb35f72b6
--- /dev/null
+++ b/inc/lang/ru/draft.txt
@@ -0,0 +1,6 @@
+====== Найден черновик ======
+
+Последний раз редактирование этой страницы не было корректно завершено. Во время вашей работы был автоматически сохранён черновик, который вы теперь можете восстановить и продолжить прерванную правку. Ниже вы видите автоматически сохранённую версию.
+
+Пожалуйста, решите, хотите ли вы //восстановить// потерянную версию, //удалить// черновик, или //отменить// редактирование.
+
diff --git a/inc/lang/ru/edit.txt b/inc/lang/ru/edit.txt
new file mode 100644
index 000000000..aac399d7c
--- /dev/null
+++ b/inc/lang/ru/edit.txt
@@ -0,0 +1,2 @@
+Отредактируйте страницу и нажмите «Сохранить». Прочтите [[wiki:syntax|справочную страницу]] для ознакомления с синтаксисом вики. Пожалуйста, редактируйте только в том случае, если планируете **улучшить** содержимое. Если вы просто хотите потестировать что-либо, воспользуйтесь специальной страницей: [[playground:playground]].
+
diff --git a/inc/lang/ru/editrev.txt b/inc/lang/ru/editrev.txt
new file mode 100644
index 000000000..97b799a70
--- /dev/null
+++ b/inc/lang/ru/editrev.txt
@@ -0,0 +1,2 @@
+**Вы загрузили старую ревизию документа.** Сохранив её, вы создадите новую текущую версию с этим содержимым.
+----
diff --git a/inc/lang/ru/index.txt b/inc/lang/ru/index.txt
new file mode 100644
index 000000000..fc42f87ff
--- /dev/null
+++ b/inc/lang/ru/index.txt
@@ -0,0 +1,4 @@
+====== Содержание ======
+
+Перед вами список доступных страниц, упорядоченный по ([[doku>namespaces|пространствам имён]]).
+
diff --git a/inc/lang/ru/install.html b/inc/lang/ru/install.html
new file mode 100644
index 000000000..b830b06c0
--- /dev/null
+++ b/inc/lang/ru/install.html
@@ -0,0 +1,7 @@
+<p>Эта страница предназначена помочь в первоначальной установке и конфигурации «<a href="http://www.dokuwiki.org/">ДокуВики</a>». Дополнительная информация о программе установки доступна на её <a href="http://www.dokuwiki.org/installer">странице документации</a>.</p>
+
+<p>«ДокуВики» использует обычные файлы для хранения страниц и дополнительной информации (например, изображений, поискового индекса, предыдущих версий страницы, и т. д.). Для успешной работы «ДокуВики» <strong>необходим</strong> доступ на запись к директориям с этими файлами. Данная программа установки не может самостоятельно изменять системные права доступа к директориям. Обычно это делается напрямую из командной строки (shell), или, если вы используете удалённый хостинг, через FTP или панель управления своего хостинга (например, cPanel).</p>
+
+<p>Программа установки включит использование списков контроля доступа (<acronym title="access control list">ACL</acronym>) в вашей «ДокуВики». Это позволит администратору, после авторизации в «ДокуВики», использовать специальное меню для установки плагинов, управления пользователями и доступом к страницам вики, а также для настройки конфигурационных параметров. Списки контроля доступа не обязательны для работы «ДокуВики», однако они позволяют упростить управление вашей «ДокуВики».</p>
+
+<p>Опытным пользователям и пользователям со специальными требованиями к установке рекомендуется обратиться по следующим ссылкам для уточнения подробностей <a href="http://www.dokuwiki.org/install">процесса установки</a> и <a href="http://www.dokuwiki.org/config">параметров конфигурации</a>.</p>
diff --git a/inc/lang/ru/lang.php b/inc/lang/ru/lang.php
new file mode 100644
index 000000000..10fca5477
--- /dev/null
+++ b/inc/lang/ru/lang.php
@@ -0,0 +1,346 @@
+<?php
+/**
+ * Russian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Yuri Pimenov <up@ftpsearch.lv>
+ * @author Igor Tarasov <tigr@mail15.com>
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Kaens Bard <kaens@mail.ru>
+ * @author Andrew Pleshakov <beotiger@mail.ru>
+ * @author Змей Этерийский <evil_snake@eternion.ru>
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva <irinaponomareva@webperfectionist.com>
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$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'] = 'Править страницу';
+$lang['btn_source'] = 'Показать исходный текст';
+$lang['btn_show'] = 'Показать страницу';
+$lang['btn_create'] = 'Создать страницу';
+$lang['btn_search'] = 'Поиск';
+$lang['btn_save'] = 'Сохранить';
+$lang['btn_preview'] = 'Просмотр';
+$lang['btn_top'] = 'Наверх';
+$lang['btn_newer'] = '<< более новые';
+$lang['btn_older'] = 'более старые >>';
+$lang['btn_revs'] = 'История страницы';
+$lang['btn_recent'] = 'Недавние изменения';
+$lang['btn_upload'] = 'Загрузить';
+$lang['btn_cancel'] = 'Отменить';
+$lang['btn_index'] = 'Все страницы';
+$lang['btn_secedit'] = 'Править';
+$lang['btn_login'] = 'Войти';
+$lang['btn_logout'] = 'Выйти';
+$lang['btn_admin'] = 'Управление';
+$lang['btn_update'] = 'Обновить';
+$lang['btn_delete'] = 'Удалить';
+$lang['btn_back'] = 'Назад';
+$lang['btn_backlink'] = 'Ссылки сюда';
+$lang['btn_backtomedia'] = 'Вернуться к выбору медиафайла';
+$lang['btn_subscribe'] = 'Подписаться (все правки)';
+$lang['btn_profile'] = 'Профиль';
+$lang['btn_reset'] = 'Сброс';
+$lang['btn_resendpwd'] = 'Выслать новый пароль';
+$lang['btn_draft'] = 'Править черновик';
+$lang['btn_recover'] = 'Восстановить черновик';
+$lang['btn_draftdel'] = 'Удалить черновик';
+$lang['btn_revert'] = 'Восстановить';
+$lang['btn_register'] = 'Зарегистрироваться';
+$lang['btn_apply'] = 'Применить';
+$lang['btn_media'] = 'Media Manager';
+
+$lang['loggedinas'] = 'Зашли как';
+$lang['user'] = 'Логин';
+$lang['pass'] = 'Пароль';
+$lang['newpass'] = 'Новый пароль';
+$lang['oldpass'] = 'Введите текущий пароль';
+$lang['passchk'] = 'повторите';
+$lang['remember'] = 'Запомнить меня';
+$lang['fullname'] = 'Полное имя';
+$lang['email'] = 'Эл. адрес';
+$lang['profile'] = 'Профиль пользователя';
+$lang['badlogin'] = 'Извините, неверное имя пользователя или пароль.';
+$lang['minoredit'] = 'Небольшие изменения';
+$lang['draftdate'] = 'Черновик сохранён';
+$lang['nosecedit'] = 'За это время страница была изменена и информация о секции устарела. Загружена полная версия страницы.';
+
+$lang['regmissing'] = 'Извините, вам следует заполнить все поля.';
+$lang['reguexists'] = 'Извините, пользователь с таким логином уже существует.';
+$lang['regsuccess'] = 'Пользователь создан, пароль выслан на адрес электронной почты.';
+$lang['regsuccess2'] = 'Пользователь создан.';
+$lang['regmailfail'] = 'Похоже есть проблема с отправкой пароля по почте. Пожалуйста, сообщите об этом администратору.';
+$lang['regbadmail'] = 'Данный вами адрес электронной почты выглядит неправильным. Если вы считаете это ошибкой, сообщите администратору.';
+$lang['regbadpass'] = 'Два введённых пароля не идентичны. Пожалуйста, попробуйте ещё раз.';
+$lang['regpwmail'] = 'Ваш пароль для системы «ДокуВики»';
+$lang['reghere'] = 'У вас ещё нет аккаунта? Зарегистрируйтесь';
+
+$lang['profna'] = 'Данная вики не поддерживает изменение профиля';
+$lang['profnochange'] = 'Изменений не было внесено, профиль не обновлён.';
+$lang['profnoempty'] = 'Логин и адрес электронной почты не могут быть пустыми.';
+$lang['profchanged'] = 'Профиль пользователя успешно обновлён.';
+
+$lang['pwdforget'] = 'Забыли пароль? Получите новый';
+$lang['resendna'] = 'Данная вики не поддерживает повторную отправку пароля.';
+$lang['resendpwd'] = 'Выслать пароль для';
+$lang['resendpwdmissing'] = 'Вы должны заполнить все поля формы.';
+$lang['resendpwdnouser'] = 'Пользователь с таким логином не обнаружен в нашей базе данных.';
+$lang['resendpwdbadauth'] = 'Извините, неверный код авторизации. Убедитесь, что вы полностью скопировали ссылку. ';
+$lang['resendpwdconfirm'] = 'Ссылка для подтверждения пароля была выслана по электронной почте. ';
+$lang['resendpwdsuccess'] = 'Ваш новый пароль был выслан по электронной почте.';
+
+$lang['license'] = 'За исключением случаев, когда указано иное, содержимое этой вики предоставляется на условиях следующей лицензии:';
+$lang['licenseok'] = 'Примечание: редактируя эту страницу, вы соглашаетесь на использование своего вклада на условиях следующей лицензии:';
+
+$lang['searchmedia'] = 'Поиск по имени файла:';
+$lang['searchmedia_in'] = 'Поиск в %s';
+$lang['txt_upload'] = 'Выберите файл для загрузки';
+$lang['txt_filename'] = 'Введите имя файла в вики (необязательно)';
+$lang['txt_overwrt'] = 'Перезаписать существующий файл';
+$lang['lockedby'] = 'В данный момент заблокирован';
+$lang['lockexpire'] = 'Блокировка истекает в';
+$lang['js']['willexpire'] = 'Ваша блокировка редактирования этой страницы истекает в течение минуты.\nЧтобы избежать конфликтов и сбросить таймер блокировки, нажмите кнопку просмотра.';
+$lang['js']['notsavedyet'] = 'Несохранённые изменения будут потеряны. Вы действительно хотите продолжить?';
+$lang['js']['searchmedia'] = 'Поиск файлов';
+$lang['js']['keepopen'] = 'Не закрывать окно после выбора';
+$lang['js']['hidedetails'] = 'Скрыть детали';
+$lang['js']['mediatitle'] = 'Настройки ссылок';
+$lang['js']['mediadisplay'] = 'Тип ссылки';
+$lang['js']['mediaalign'] = 'Выравнивание';
+$lang['js']['mediasize'] = 'Размер изображения';
+$lang['js']['mediatarget'] = 'Значение target ссылки';
+$lang['js']['mediaclose'] = 'Закрыть';
+$lang['js']['mediainsert'] = 'Вставить';
+$lang['js']['mediadisplayimg'] = 'Показывать изображение.';
+$lang['js']['mediadisplaylnk'] = 'Показывать только ссылку.';
+$lang['js']['mediasmall'] = 'Малая версия';
+$lang['js']['mediamedium'] = 'Средняя версия';
+$lang['js']['medialarge'] = 'Крупная версия';
+$lang['js']['mediaoriginal'] = 'Исходная версия';
+$lang['js']['medialnk'] = 'Ссылка на подробности';
+$lang['js']['mediadirect'] = 'Прямая ссылка на оригинал';
+$lang['js']['medianolnk'] = 'Без ссылки';
+$lang['js']['medianolink'] = 'Не давать ссылку на изображение';
+$lang['js']['medialeft'] = 'Выровнять изображение по левому краю.';
+$lang['js']['mediaright'] = 'Выровнять изображение по правому краю.';
+$lang['js']['mediacenter'] = 'Выровнять изображение по центру.';
+$lang['js']['medianoalign'] = 'Не выравнивать.';
+$lang['js']['nosmblinks'] = 'Ссылка на сетевые каталоги Windows работает только из Интернет Эксплорера. Но вы можете скопировать ссылку.';
+$lang['js']['linkwiz'] = 'Мастер ссылок';
+$lang['js']['linkto'] = 'Ссылка на:';
+$lang['js']['del_confirm'] = 'Вы на самом деле желаете удалить выбранное?';
+$lang['js']['willexpire'] = 'Ваша блокировка этой страницы на редактирование истекает в течении минуты.\nЧтобы предотвратить конфликты используйте кнопку "Просмотр" для сброса таймера блокировки.';
+$lang['js']['restore_confirm'] = 'Действительно восстановить эту версию?';
+$lang['js']['media_diff'] = 'Просмотр отличий:';
+$lang['js']['media_diff_both'] = 'Рядом';
+$lang['js']['media_diff_opacity'] = 'Наложением';
+$lang['js']['media_diff_portions'] = 'Частями';
+$lang['js']['media_select'] = 'Выбрать файлы…';
+$lang['js']['media_upload_btn'] = 'Загрузить';
+$lang['js']['media_done_btn'] = 'Готово';
+$lang['js']['media_drop'] = 'Переместите файлы сюда для загрузки';
+$lang['js']['media_cancel'] = 'отменить';
+$lang['js']['media_overwrt'] = 'Перезаписать существующие файлы';
+
+$lang['rssfailed'] = 'Произошла ошибка при получении следующей новостной ленты: ';
+$lang['nothingfound'] = 'Ничего не найдено.';
+
+$lang['mediaselect'] = 'Выбор медиафайла';
+$lang['fileupload'] = 'Загрузка медиафайла';
+$lang['uploadsucc'] = 'Загрузка произведена успешно';
+$lang['uploadfail'] = 'Загрузка не удалась. Возможно, проблемы с правами доступа?';
+$lang['uploadwrong'] = 'В загрузке отказано. Файлы с таким расширением запрещены. ';
+$lang['uploadexist'] = 'Файл с таким именем существует. Загрузка не произведена.';
+$lang['uploadbadcontent'] = 'Содержание файла не соответствует расширению %s.';
+$lang['uploadspam'] = 'Загрузка заблокирована спам-фильтром.';
+$lang['uploadxss'] = 'Загрузка заблокирована по соображениям безопасности.';
+$lang['uploadsize'] = 'Загруженный файл был слишком большой. (макс. %s)';
+$lang['deletesucc'] = 'Файл "%s" был удалён.';
+$lang['deletefail'] = 'Невозможно удалить файл "%s". Проверьте права доступа к файлу.';
+$lang['mediainuse'] = 'Файл "%s" не был удалён — файл всё ещё используется.';
+$lang['namespaces'] = 'Пространства имён';
+$lang['mediafiles'] = 'Доступные файлы';
+$lang['accessdenied'] = 'Вы не можете просмотреть эту страницу.';
+$lang['mediausage'] = 'Для ссылки на этот файл используйте следующий синтаксис:';
+$lang['mediaview'] = 'Посмотреть исходный файл';
+$lang['mediaroot'] = 'корень';
+$lang['mediaupload'] = 'Здесь можно загрузить файл в текущий каталог («пространство имён»). Чтобы создать подкаталоги, добавьте их к началу имени файла («Загрузить как»). Имена подкаталогов разделяются двоеточиями. ';
+$lang['mediaextchange'] = 'Расширение изменилось: с .%s на .%s!';
+$lang['reference'] = 'Ссылки для';
+$lang['ref_inuse'] = 'Этот файл не может быть удалён, так как он используется на следующих страницах:';
+$lang['ref_hidden'] = 'Некоторые ссылки находятся на страницах, на чтение которых у вас нет прав доступа';
+
+$lang['hits'] = 'соответствий';
+$lang['quickhits'] = 'Соответствия в названиях страниц';
+$lang['toc'] = 'Содержание';
+$lang['current'] = 'текущий';
+$lang['yours'] = 'Ваша версия';
+$lang['diff'] = 'показать отличия от текущей версии';
+$lang['diff2'] = 'Показать различия между ревизиями ';
+$lang['difflink'] = 'Ссылка на это сравнение';
+$lang['diff_type'] = 'Посмотреть отличия';
+$lang['diff_inline'] = 'Встроенный';
+$lang['diff_side'] = 'Бок о бок';
+$lang['line'] = 'Строка';
+$lang['breadcrumb'] = 'Вы посетили';
+$lang['youarehere'] = 'Вы находитесь здесь';
+$lang['lastmod'] = 'Последние изменения';
+$lang['by'] = ' —';
+$lang['deleted'] = 'удалено';
+$lang['created'] = 'создано';
+$lang['restored'] = 'старая ревизия восстановлена';
+$lang['external_edit'] = 'внешнее изменение';
+$lang['summary'] = 'Сводка изменений';
+$lang['noflash'] = 'Для просмотра этого содержимого требуется <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>.';
+$lang['download'] = 'Скачать код';
+
+$lang['mail_newpage'] = 'страница добавлена:';
+$lang['mail_changed'] = 'страница изменена:';
+$lang['mail_subscribe_list'] = 'изменились страницы в пространстве имён:';
+$lang['mail_new_user'] = 'новый пользователь:';
+$lang['mail_upload'] = 'файл закачан:';
+
+$lang['changes_type'] = 'Посмотреть изменения';
+$lang['pages_changes'] = 'Страниц';
+$lang['media_changes'] = 'Медиа файлов';
+$lang['both_changes'] = 'И страниц и медиа файлов';
+
+$lang['qb_bold'] = 'Полужирный';
+$lang['qb_italic'] = 'Курсив';
+$lang['qb_underl'] = 'Подчёркнутый';
+$lang['qb_code'] = 'Текст кода';
+$lang['qb_strike'] = 'Зачёркнутый';
+$lang['qb_h1'] = 'Заголовок 1-го уровня';
+$lang['qb_h2'] = 'Заголовок 2-го уровня';
+$lang['qb_h3'] = 'Заголовок 3-го уровня';
+$lang['qb_h4'] = 'Заголовок 4-го уровня';
+$lang['qb_h5'] = 'Заголовок 5-го уровня';
+$lang['qb_h'] = 'Заголовок';
+$lang['qb_hs'] = 'Выбор заголовка';
+$lang['qb_hplus'] = 'Заголовок более высокого уровня';
+$lang['qb_hminus'] = 'Заголовок более низкого уровня (подзаголовок)';
+$lang['qb_hequal'] = 'Заголовок текущего уровня';
+$lang['qb_link'] = 'Внутренняя ссылка';
+$lang['qb_extlink'] = 'Внешняя ссылка';
+$lang['qb_hr'] = 'Разделитель';
+$lang['qb_ol'] = 'Элемент нумерованного списка';
+$lang['qb_ul'] = 'Элемент ненумерованного списка';
+$lang['qb_media'] = 'Добавить изображения или другие файлы';
+$lang['qb_sig'] = 'Вставить подпись';
+$lang['qb_smileys'] = 'Смайлики';
+$lang['qb_chars'] = 'Специальные символы';
+
+$lang['upperns'] = 'Перейти в родительское пространство имён';
+
+$lang['admin_register'] = 'Добавить пользователя';
+
+$lang['metaedit'] = 'Править метаданные';
+$lang['metasaveerr'] = 'Ошибка записи метаданных';
+$lang['metasaveok'] = 'Метаданные сохранены';
+$lang['img_backto'] = 'Вернуться к';
+$lang['img_title'] = 'Название';
+$lang['img_caption'] = 'Подпись';
+$lang['img_date'] = 'Дата';
+$lang['img_fname'] = 'Имя файла';
+$lang['img_fsize'] = 'Размер';
+$lang['img_artist'] = 'Фотограф';
+$lang['img_copyr'] = 'Авторские права';
+$lang['img_format'] = 'Формат';
+$lang['img_camera'] = 'Модель';
+$lang['img_keywords'] = 'Ключевые слова';
+$lang['img_width'] = 'Ширина';
+$lang['img_height'] = 'Высота';
+$lang['img_manager'] = 'Просмотр в media manager';
+
+$lang['subscr_subscribe_success'] = 'Добавлен %s в подписку на %s';
+$lang['subscr_subscribe_error'] = 'Невозможно добавить %s в подписку на %s';
+$lang['subscr_subscribe_noaddress'] = 'Нет адреса электронной почты, сопоставленного с вашей учётной записью. Вы не можете подписаться на рассылку';
+$lang['subscr_unsubscribe_success'] = 'Удалён %s из подписки на %s';
+$lang['subscr_unsubscribe_error'] = 'Ошибка удаления %s из подписки на %s';
+$lang['subscr_already_subscribed'] = '%s уже подписан на %s';
+$lang['subscr_not_subscribed'] = '%s не подписан на %s';
+// Manage page for subscriptions
+$lang['subscr_m_not_subscribed'] = 'Вы не подписаны на текущую страницу или пространство имён.';
+$lang['subscr_m_new_header'] = 'Добавить подписку';
+$lang['subscr_m_current_header'] = 'Текущие подписки';
+$lang['subscr_m_unsubscribe'] = 'Отменить подписку';
+$lang['subscr_m_subscribe'] = 'Подписаться';
+$lang['subscr_m_receive'] = 'Получить';
+$lang['subscr_style_every'] = 'уведомлять о каждом изменении';
+$lang['subscr_style_digest'] = 'сводка изменений по каждой странице';
+$lang['subscr_style_list'] = 'перечислять изменившиеся страницы с прошлого уведомления';
+
+/* auth.class language support */
+$lang['authmodfailed'] = 'Неправильная конфигурация аутентификации пользователя. Пожалуйста, сообщите об этом своему администратору вики.';
+$lang['authtempfail'] = 'Аутентификация пользователей временно недоступна. Если проблема продолжается какое-то время, пожалуйста, сообщите об этом своему администратору вики.';
+
+/* installer strings */
+$lang['i_chooselang'] = 'Выберите свой язык/Choose your language';
+$lang['i_installer'] = 'Установка «ДокуВики»';
+$lang['i_wikiname'] = 'Название вики';
+$lang['i_enableacl'] = 'Разрешить ограничение прав доступа (рекомендуется)';
+$lang['i_superuser'] = 'Суперпользователь';
+$lang['i_problems'] = 'Программа установки столкнулась с проблемами, перечисленными ниже. Чтобы продолжить, вам необходимо их устранить. ';
+$lang['i_modified'] = 'Из соображений безопасности эта программа запускается только на новой, неизменённой установке «ДокуВики».
+ Вам нужно либо заново распаковать скачанный пакет установки, либо обратиться к полной
+ <a href="http://www.dokuwiki.org/install">инструкции по установке «ДокуВики»</a>';
+$lang['i_funcna'] = 'Функция PHP <code>%s</code> недоступна. Может быть, она по какой-то причине заблокирована вашим хостером?';
+$lang['i_phpver'] = 'Ваша версия PHP (<code>%s</code>) ниже требуемой (<code>%s</code>). Вам необходимо обновить установленную версию PHP.';
+$lang['i_permfail'] = '<code>%s</code> недоступна для записи «ДокуВики». Вам необходимо исправить системные права доступа для этой директории!';
+$lang['i_confexists'] = '<code>%s</code> уже существует';
+$lang['i_writeerr'] = 'Не удалось создать <code>%s</code>. Вам необходимо проверить системные права доступа к файлу/директориям и создать файл вручную. ';
+$lang['i_badhash'] = 'dokuwiki.php не распознан или изменён (хэш=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> — недопустимое или пустое значение';
+$lang['i_success'] = 'Конфигурация прошла успешно. Теперь вы можете удалить файл install.php. Переходите к
+ <a href="doku.php">своей новой «ДокуВики»</a>.';
+$lang['i_failure'] = 'При записи в файлы конфигурации были обнаружены ошибки. Возможно, вам придётся исправить их вручную, прежде чем вы сможете использовать <a href="doku.php">свою новую «ДокуВики»</a>.';
+$lang['i_policy'] = 'Исходная политика прав доступа';
+$lang['i_pol0'] = 'Открытая вики (чтение, запись, закачка файлов для всех)';
+$lang['i_pol1'] = 'Общедоступная вики (чтение для всех, запись и загрузка файлов для зарегистрированных пользователей)';
+$lang['i_pol2'] = 'Закрытая вики (чтение, запись и загрузка файлов только для зарегистрированных пользователей)';
+$lang['i_retry'] = 'Повторить попытку';
+$lang['i_license'] = 'Пожалуйста, выберите тип лицензии для своей вики:';
+
+$lang['recent_global'] = 'Вы просматриваете изменения в пространстве имён <b>%s</b>. Вы можете также <a href="%s">просмотреть недавние изменения во всей вики</a>.';
+$lang['years'] = '%d лет назад';
+$lang['months'] = '%d месяц(ев) назад';
+$lang['weeks'] = '%d недель назад';
+$lang['days'] = '%d дней назад';
+$lang['hours'] = '%d час(ов) назад';
+$lang['minutes'] = '%d минут назад';
+$lang['seconds'] = '%d секунд назад';
+
+$lang['wordblock'] = 'Ваши изменения не сохранены, поскольку они содержат блокируемые слова (спам).';
+
+$lang['media_uploadtab'] = 'Загрузка';
+$lang['media_searchtab'] = 'Поиск';
+$lang['media_viewtab'] = 'Просмотр';
+$lang['media_edittab'] = 'Правка';
+$lang['media_historytab'] = 'История';
+$lang['media_sort_name'] = 'Сортировка по имени';
+$lang['media_sort_date'] = 'Сортировка по дате';
+$lang['media_upload'] = 'Загрузка в пространство имён <strong>%s</strong>.';
+$lang['media_search'] = 'Поиск в пространстве имён <strong>%s</strong>.';
+$lang['media_view'] = '%s';
+$lang['media_edit'] = 'Правка %s';
+$lang['media_meta_edited'] = 'метаданные изменены';
+$lang['media_perm_read'] = 'Извините, у Вас недостаточно прав для чтения файлов.';
+$lang['media_perm_upload'] = 'Извините, у Вас недостаточно прав для загрузки файлов.';
+$lang['media_update'] = 'Загрузить новую версию';
+$lang['media_restore'] = 'Восстановить эту версию';
+
+$lang['plugin_install_err'] = "Плагин установлен некорректно. Переименуйте папку плагина из '%s' в '%s'.";
diff --git a/inc/lang/ru/locked.txt b/inc/lang/ru/locked.txt
new file mode 100644
index 000000000..3e868ba9a
--- /dev/null
+++ b/inc/lang/ru/locked.txt
@@ -0,0 +1,3 @@
+====== Страница заблокирована ======
+
+Эта страница в данный момент заблокирована для редактирования другим пользователем. Вам придётся подождать, пока этот пользователь закончит редактирование или истечёт время блокировки.
diff --git a/inc/lang/ru/login.txt b/inc/lang/ru/login.txt
new file mode 100644
index 000000000..0a94a0b4b
--- /dev/null
+++ b/inc/lang/ru/login.txt
@@ -0,0 +1,4 @@
+====== Авторизация ======
+
+В данный момент вы не в системе. Авторизируйтесь при помощи следующей формы. //Замечание:// для работы у вас должны быть включены куки (cookies).
+
diff --git a/inc/lang/ru/mailtext.txt b/inc/lang/ru/mailtext.txt
new file mode 100644
index 000000000..53d3431a3
--- /dev/null
+++ b/inc/lang/ru/mailtext.txt
@@ -0,0 +1,17 @@
+В вашей вики была добавлена или изменена страница. Подробности:
+
+Дата : @DATE@
+Браузер : @BROWSER@
+IP-адрес : @IPADDRESS@
+Хост : @HOSTNAME@
+Старая версия : @OLDPAGE@
+Новая версия : @NEWPAGE@
+Сводка изменений : @SUMMARY@
+Пользователь : @USER@
+
+@DIFF@
+
+
+--
+Это письмо было сгенерировано «ДокуВики» по адресу
+@DOKUWIKIURL@
diff --git a/inc/lang/ru/newpage.txt b/inc/lang/ru/newpage.txt
new file mode 100644
index 000000000..ea8e35bf5
--- /dev/null
+++ b/inc/lang/ru/newpage.txt
@@ -0,0 +1,3 @@
+====== Эта страница ещё не существует ======
+
+Вы перешли по ссылке на тему, для которой ещё не создана страница. Если позволяют ваши права доступа, вы можете создать её, нажав на кнопку «Создать страницу».
diff --git a/inc/lang/ru/norev.txt b/inc/lang/ru/norev.txt
new file mode 100644
index 000000000..388d6149d
--- /dev/null
+++ b/inc/lang/ru/norev.txt
@@ -0,0 +1,4 @@
+====== Такой версии не существует ======
+
+Указанная версия страницы не существует. Нажмите на кнопку «История страницы», чтобы получить список доступных предыдущих версий этого документа.
+
diff --git a/inc/lang/ru/password.txt b/inc/lang/ru/password.txt
new file mode 100644
index 000000000..91117ca56
--- /dev/null
+++ b/inc/lang/ru/password.txt
@@ -0,0 +1,11 @@
+Здравствуйте, @FULLNAME@.
+
+Ваши данные для @TITLE@ (@DOKUWIKIURL@)
+
+Имя пользователя: @LOGIN@
+
+Пароль: @PASSWORD@
+
+--
+Это письмо было сгенерировано «ДокуВики» по адресу
+@DOKUWIKIURL@
diff --git a/inc/lang/ru/preview.txt b/inc/lang/ru/preview.txt
new file mode 100644
index 000000000..401827607
--- /dev/null
+++ b/inc/lang/ru/preview.txt
@@ -0,0 +1,4 @@
+====== Просмотр ======
+
+Здесь показано, как ваш текст будет выглядеть. Внимание: текст ещё **не сохранён.**
+
diff --git a/inc/lang/ru/pwconfirm.txt b/inc/lang/ru/pwconfirm.txt
new file mode 100644
index 000000000..9c27af752
--- /dev/null
+++ b/inc/lang/ru/pwconfirm.txt
@@ -0,0 +1,13 @@
+Здравствуйте, @FULLNAME@.
+
+Кто-то запросил новый пароль для входа в @TITLE@ по адресу @DOKUWIKIURL@
+
+Если вы не запрашивали новый пароль, просто проигнорируйте это письмо.
+
+Для подтверждения, что запрос был действительно сделан вами, пожалуйста, перейдите по следующей ссылке.
+
+@CONFIRM@
+
+--
+Это сообщение было сгенерировано «ДокуВики» по адресу
+@DOKUWIKIURL@
diff --git a/inc/lang/ru/read.txt b/inc/lang/ru/read.txt
new file mode 100644
index 000000000..fd52d1a52
--- /dev/null
+++ b/inc/lang/ru/read.txt
@@ -0,0 +1,2 @@
+Эта страница только для чтения. Вы можете посмотреть исходный текст, но не можете его изменить. Сообщите администратору, если считаете, что это неправильно.
+
diff --git a/inc/lang/ru/recent.txt b/inc/lang/ru/recent.txt
new file mode 100644
index 000000000..aa088c734
--- /dev/null
+++ b/inc/lang/ru/recent.txt
@@ -0,0 +1,5 @@
+====== Недавние изменения ======
+
+Эти страницы были изменены недавно.
+
+
diff --git a/inc/lang/ru/register.txt b/inc/lang/ru/register.txt
new file mode 100644
index 000000000..2d5d9878e
--- /dev/null
+++ b/inc/lang/ru/register.txt
@@ -0,0 +1,3 @@
+====== Регистрация нового пользователя ======
+
+Для регистрации в вики заполните все поля ниже. Обратите внимание на **правильность адреса электронной почты** — туда будет выслан пароль в том случае, если вас не просят самостоятельно ввести его здесь. Логин должен удовлетворять ограничениям для [[doku>pagename|идентификатора страницы]].
diff --git a/inc/lang/ru/registermail.txt b/inc/lang/ru/registermail.txt
new file mode 100644
index 000000000..77094e8d8
--- /dev/null
+++ b/inc/lang/ru/registermail.txt
@@ -0,0 +1,14 @@
+Был зарегистрирован новый пользователь. Подробности:
+
+Логин : @NEWUSER@
+Полное имя : @NEWNAME@
+Эл. адрес : @NEWEMAIL@
+
+Дата : @DATE@
+Браузер : @BROWSER@
+Адрес IP : @IPADDRESS@
+Хост : @HOSTNAME@
+
+--
+Это сообщение было сгенерировано «ДокуВики» по адресу
+@DOKUWIKIURL@
diff --git a/inc/lang/ru/resendpwd.txt b/inc/lang/ru/resendpwd.txt
new file mode 100644
index 000000000..3cd05049a
--- /dev/null
+++ b/inc/lang/ru/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Выслать новый пароль ======
+
+Для получения нового пароля введите требуемые данные ниже. Ваш новый пароль будет послан по адресу электронной почты, зарегистрированному на ваше имя. Указанное ниже имя должно быть вашим логином в этой вики.
diff --git a/inc/lang/ru/revisions.txt b/inc/lang/ru/revisions.txt
new file mode 100644
index 000000000..55072cd8a
--- /dev/null
+++ b/inc/lang/ru/revisions.txt
@@ -0,0 +1,3 @@
+====== История страницы ======
+
+Перед вами — история правок текущего документа. Чтобы вернуться к одной из предыдущих версий, выберите нужную, нажмите «Править страницу» и сохраните.
diff --git a/inc/lang/ru/searchpage.txt b/inc/lang/ru/searchpage.txt
new file mode 100644
index 000000000..04feb21cd
--- /dev/null
+++ b/inc/lang/ru/searchpage.txt
@@ -0,0 +1,5 @@
+====== Поиск ======
+
+Перед вами результаты поиска. Если вы не нашли то, что искали, вы можете создать новую страницу с именем, совпадающим с запросом. Чтобы сделать это, просто нажмите на кнопку «Создать страницу».
+
+===== Результаты ===== \ No newline at end of file
diff --git a/inc/lang/ru/showrev.txt b/inc/lang/ru/showrev.txt
new file mode 100644
index 000000000..596815870
--- /dev/null
+++ b/inc/lang/ru/showrev.txt
@@ -0,0 +1,2 @@
+**Это старая версия документа.**
+----
diff --git a/inc/lang/ru/stopwords.txt b/inc/lang/ru/stopwords.txt
new file mode 100644
index 000000000..a6df13902
--- /dev/null
+++ b/inc/lang/ru/stopwords.txt
@@ -0,0 +1,93 @@
+# 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
+более
+больше
+будет
+будто
+была
+было
+быть
+вдруг
+ведь
+впрочем
+всегда
+всех
+всего
+говорил
+говорила
+даже
+другой
+другая
+если
+есть
+жизнь
+жизня
+зачем
+здесь
+иногда
+кажется
+какая
+какой
+какое
+когда
+конечно
+лучше
+между
+менее
+меньше
+меня
+много
+может
+можно
+надо
+наконец
+него
+нельзя
+нибудь
+никогда
+ничего
+нужно
+один
+одна
+опять
+перед
+после
+потом
+потому
+почти
+разве
+свое
+своё
+свой
+свою
+своя
+себе
+себя
+сегодня
+сейчас
+сказал
+сказала
+сказать
+совсем
+такая
+такое
+такой
+тебя
+теперь
+тогда
+того
+тоже
+только
+тому
+хорошо
+хоть
+чего
+через
+чтоб
+чтобы
+чуть
+этого
+этой
+этим
+этот
diff --git a/inc/lang/ru/subscr_digest.txt b/inc/lang/ru/subscr_digest.txt
new file mode 100644
index 000000000..41774a4e9
--- /dev/null
+++ b/inc/lang/ru/subscr_digest.txt
@@ -0,0 +1,20 @@
+Привет.
+
+Страница @PAGE@ в вики @TITLE@ изменилась.
+Список изменений:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Старая версия: @OLDPAGE@
+Новая версия: @NEWPAGE@
+
+Чтобы отписаться от уведомлений об изменениях, войдите в вики
+@DOKUWIKIURL@ в раздел
+@SUBSCRIBE@
+и отмените подписку на страницу и/или пространство имен.
+
+--
+Это письмо создано «ДокуВики» с сайта
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ru/subscr_form.txt b/inc/lang/ru/subscr_form.txt
new file mode 100644
index 000000000..2a775c5b5
--- /dev/null
+++ b/inc/lang/ru/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Управление подписками ======
+
+Здесь вы можете управлять подписками для текущей страницы и пространства имён. \ No newline at end of file
diff --git a/inc/lang/ru/subscr_list.txt b/inc/lang/ru/subscr_list.txt
new file mode 100644
index 000000000..41e1323bc
--- /dev/null
+++ b/inc/lang/ru/subscr_list.txt
@@ -0,0 +1,17 @@
+Привет.
+
+Страницы в пространстве имён @PAGE@ в вики @TITLE@ были изменены.
+Список изменившихся страниц:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Чтобы отписаться от уведомлений об изменениях, войдите в вики
+@DOKUWIKIURL@ в раздел
+@SUBSCRIBE@
+и отмените подписку на страницу и/или пространство имён.
+
+--
+Это письмо создано «ДокуВики» с сайта
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ru/subscr_single.txt b/inc/lang/ru/subscr_single.txt
new file mode 100644
index 000000000..0e67d8f59
--- /dev/null
+++ b/inc/lang/ru/subscr_single.txt
@@ -0,0 +1,25 @@
+Привет.
+
+
+Страница @PAGE@ в вики @TITLE@ изменилась.
+Список изменений:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Дата: @DATE@
+Автор: @USER@
+
+Примечание: @SUMMARY@
+Старая версия: @OLDPAGE@
+Новая версия: @NEWPAGE@
+
+Чтобы отписаться от уведомлений об изменениях, войдите в вики
+@DOKUWIKIURL@ в раздел
+@SUBSCRIBE@
+и отмените подписку на страницу и/или пространство имён.
+
+--
+Это письмо создано «ДокуВики» с сайта
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/ru/updateprofile.txt b/inc/lang/ru/updateprofile.txt
new file mode 100644
index 000000000..b1f9f56ef
--- /dev/null
+++ b/inc/lang/ru/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Обновить профиль ======
+
+Необходимо заполнить только те поля, которые вы хотите изменить. Имя пользователя не может быть изменено.
+
+
diff --git a/inc/lang/ru/uploadmail.txt b/inc/lang/ru/uploadmail.txt
new file mode 100644
index 000000000..77f79231e
--- /dev/null
+++ b/inc/lang/ru/uploadmail.txt
@@ -0,0 +1,15 @@
+В вашу вики был закачан файл. Подробная информация:
+
+Файл : @MEDIA@
+Старая версия: @OLD@
+Дата : @DATE@
+Браузер : @BROWSER@
+Адрес IP : @IPADDRESS@
+Хост : @HOSTNAME@
+Размер : @SIZE@
+Тип MIME : @MIME@
+Пользователь : @USER@
+
+--
+Это письмо было сгенерировано «ДокуВики» по адресу
+@DOKUWIKIURL@
diff --git a/inc/lang/ru/wordblock.txt b/inc/lang/ru/wordblock.txt
new file mode 100644
index 000000000..09c663fb3
--- /dev/null
+++ b/inc/lang/ru/wordblock.txt
@@ -0,0 +1,3 @@
+====== СПАМ заблокирован ======
+
+Ваши изменения **не были** сохранены, так как они содержат одно или более запрещенных слов. Если Вы пытались добавить спам в Вики -- ай-яй-яй! Если Вы считаете, что это какая-то ошибка, обратитесь к администратору вики.
diff --git a/inc/lang/sk/admin.txt b/inc/lang/sk/admin.txt
new file mode 100644
index 000000000..510eeb9c8
--- /dev/null
+++ b/inc/lang/sk/admin.txt
@@ -0,0 +1,5 @@
+====== Administrácia ======
+
+Nižšie môžete nájsť zoznam administratívnych úloh dostupných v DokuWiki.
+
+
diff --git a/inc/lang/sk/adminplugins.txt b/inc/lang/sk/adminplugins.txt
new file mode 100644
index 000000000..64d2ca774
--- /dev/null
+++ b/inc/lang/sk/adminplugins.txt
@@ -0,0 +1 @@
+===== Ďalšie pluginy ===== \ No newline at end of file
diff --git a/inc/lang/sk/backlinks.txt b/inc/lang/sk/backlinks.txt
new file mode 100644
index 000000000..b3217d545
--- /dev/null
+++ b/inc/lang/sk/backlinks.txt
@@ -0,0 +1,3 @@
+====== Spätné odkazy ======
+
+Tu je zoznam stránok, ktoré pravdepodobne odkazujú na aktuálnu stránku.
diff --git a/inc/lang/sk/conflict.txt b/inc/lang/sk/conflict.txt
new file mode 100644
index 000000000..5dab2dbe1
--- /dev/null
+++ b/inc/lang/sk/conflict.txt
@@ -0,0 +1,5 @@
+====== Existuje novšia verzia ======
+
+Existuje novšia verzia práve upravovaného dokumentu. To sa stáva, keď niekto iný zmenil dokument, ktorý práve upravujete.
+
+Prehliadnite si nižšie uvedené rozdiely, prípadne rozdiely z obidvoch verzií ručne spojte dohromady a rozhodnite sa, ktorú verziu uchovať. Ak zvolíte ''Uložiť', bude uložená vaša verzia. V opačnom prípade stlačte ''Storno'' pre uchovanie pôvodnej verzie.
diff --git a/inc/lang/sk/denied.txt b/inc/lang/sk/denied.txt
new file mode 100644
index 000000000..6e9c98496
--- /dev/null
+++ b/inc/lang/sk/denied.txt
@@ -0,0 +1,3 @@
+====== Nepovolená akcia ======
+
+Prepáčte, ale nemáte dostatočné oprávnenie k tejto činnosti. Možno ste sa zabudli prihlásiť?
diff --git a/inc/lang/sk/diff.txt b/inc/lang/sk/diff.txt
new file mode 100644
index 000000000..0548ea5d6
--- /dev/null
+++ b/inc/lang/sk/diff.txt
@@ -0,0 +1,4 @@
+====== Rozdiely ======
+
+Tu môžete vidieť rozdiely medzi vybranou verziou a aktuálnou verziou danej stránky.
+
diff --git a/inc/lang/sk/draft.txt b/inc/lang/sk/draft.txt
new file mode 100644
index 000000000..96a4e91b2
--- /dev/null
+++ b/inc/lang/sk/draft.txt
@@ -0,0 +1,6 @@
+====== Nájdený súbor konceptu ======
+
+Vaša posledná editácia tejto stránky nebola ukončená korektne. Dokuwiki automaticky uložila počas vašej práce koncept a ten môžete teraz použiť pre pokračovanie editácie. Nižšie môžete vidieť dáta, ktoré boli uložené.
+
+Prosím, rozhodnite sa, či chcete //obnoviť// vašu poslednú editáciu, //zmazať// automaticky uložený koncept alebo //stornovať// proces editácie.
+
diff --git a/inc/lang/sk/edit.txt b/inc/lang/sk/edit.txt
new file mode 100644
index 000000000..b8d63fb72
--- /dev/null
+++ b/inc/lang/sk/edit.txt
@@ -0,0 +1 @@
+Upravte stránku a stlačte ''Uložiť''. Na stránke [[wiki:syntax]] sa môžete dozvedieť viac o Wiki syntaxi. Prosím upravujte stránky, len pokiaľ ich môžete **zdokonaliť**. Pokiaľ si chcete niečo len vyskúšať, použite [[playground:playground| pieskovisko]].
diff --git a/inc/lang/sk/editrev.txt b/inc/lang/sk/editrev.txt
new file mode 100644
index 000000000..ed15e791c
--- /dev/null
+++ b/inc/lang/sk/editrev.txt
@@ -0,0 +1 @@
+**Máte načítanú staršiu verziu dokumentu!** Pokiaľ ju uložíte, vytvoríte tým novú aktuálnu verziu.
diff --git a/inc/lang/sk/index.txt b/inc/lang/sk/index.txt
new file mode 100644
index 000000000..b4189f214
--- /dev/null
+++ b/inc/lang/sk/index.txt
@@ -0,0 +1,3 @@
+====== Index ======
+
+Tu je k dispozícii index všetkých dostupných stránok zoradených podľa [[doku>namespaces|menných priestorov]].
diff --git a/inc/lang/sk/install.html b/inc/lang/sk/install.html
new file mode 100644
index 000000000..e31d7457c
--- /dev/null
+++ b/inc/lang/sk/install.html
@@ -0,0 +1,23 @@
+<p>Táto stránka sprevádza prvou inštaláciou a konfiguráciou
+<a href="http://dokuwiki.org">Dokuwiki</a>. Viac informácií o tomto inštalátore je dostupných na jeho
+<a href="http://dokuwiki.org/installer">dokumentačnej stránke</a>.</p>
+
+<p>DokuWiki používa bežné súbory pre ukladanie wiki stránok a iných informácií
+priradených k týmto stránkam (napr. obrázkov, vyhľadávacích indexov, starých
+revízií). Ak chcete úspešne narábať s DokuWiki, <strong>musí</strong>
+mať práva pre zápis do adresárov, kde sa ukladajú tieto súbory. Tento inštalátor
+nie je schopný nastaviť prístupové práva pre adresáre. Je potrebné to urobiť
+priamo cez príkazový riadok alebo, ak využívate webhosting, cez FTP alebo vaše
+webhostingové administračné rozhranie.</p>
+
+<p>Tento inštalátor nastaví <acronym title="access control list - zoznam prístupových práv">ACL</acronym>
+konfiguráciu vašej Dokuwiki. Umožňuje vytvoriť administrátorské konto
+s prístupom do administračného menu s možnosťou inštalácie pluginov, správy
+užívateľov, správy prístupových práv k wiki stránkam a zmeny konfiguračných
+nastavení. Nie je nevyhnutné pre používanie Dokuwiki, ale umožňuje to ľahšie
+spravovať Dokuwiki.</p>
+
+<p>Skúsení užívatelia alebo užívatelia so špeciálnymi požiadavkami môžu použiť
+tieto odkazy pre bližšie informácie týkajúce sa
+<a href="http://dokuwiki.org/install">inštalačných pokynov</a>
+a <a href="http://dokuwiki.org/config">konfiguračných nastavení</a>.</p>
diff --git a/inc/lang/sk/lang.php b/inc/lang/sk/lang.php
new file mode 100644
index 000000000..117da91d4
--- /dev/null
+++ b/inc/lang/sk/lang.php
@@ -0,0 +1,313 @@
+<?php
+/**
+ * Slovak language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Ondrej Vegh <ov@vsieti.sk> with help of the scholars from Zdruzena stredna skola polygraficka in Bratislava
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Upraviť stránku';
+$lang['btn_source'] = 'Zobraziť zdroj stránky';
+$lang['btn_show'] = 'Zobraziť stránku';
+$lang['btn_create'] = 'Vytvoriť stránku';
+$lang['btn_search'] = 'Hľadať';
+$lang['btn_save'] = 'Uložiť';
+$lang['btn_preview'] = 'Náhľad';
+$lang['btn_top'] = 'Hore';
+$lang['btn_newer'] = '<< novšie';
+$lang['btn_older'] = 'staršie >>';
+$lang['btn_revs'] = 'Staršie verzie';
+$lang['btn_recent'] = 'Posledné úpravy';
+$lang['btn_upload'] = 'Nahrať';
+$lang['btn_cancel'] = 'Storno';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit'] = 'Upraviť';
+$lang['btn_login'] = 'Prihlásiť sa';
+$lang['btn_logout'] = 'Odhlásiť sa';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Aktualizovať';
+$lang['btn_delete'] = 'Zmazať';
+$lang['btn_back'] = 'Späť';
+$lang['btn_backlink'] = 'Spätné odkazy';
+$lang['btn_backtomedia'] = 'Späť na výber súboru';
+$lang['btn_subscribe'] = 'Sledovať zmeny';
+$lang['btn_profile'] = 'Aktualizovať profil';
+$lang['btn_reset'] = 'Zrušiť';
+$lang['btn_resendpwd'] = 'Poslať nové heslo';
+$lang['btn_draft'] = 'Upraviť koncept';
+$lang['btn_recover'] = 'Obnoviť koncept';
+$lang['btn_draftdel'] = 'Zmazať koncept';
+$lang['btn_revert'] = 'Obnoviť';
+$lang['btn_register'] = 'Registrovať';
+$lang['btn_apply'] = 'Použiť';
+$lang['btn_media'] = 'Správa médií';
+$lang['loggedinas'] = 'Prihlásený(á) ako';
+$lang['user'] = 'Užívateľské meno';
+$lang['pass'] = 'Heslo';
+$lang['newpass'] = 'Nové heslo';
+$lang['oldpass'] = 'Potvrď aktuálne heslo';
+$lang['passchk'] = 'Ešte raz znovu';
+$lang['remember'] = 'Zapamätaj si ma';
+$lang['fullname'] = 'Celé meno';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'Užívateľský profil';
+$lang['badlogin'] = 'Zadané užívateľské meno a heslo nie je správne.';
+$lang['minoredit'] = 'Menšie zmeny';
+$lang['draftdate'] = 'Koncept automaticky uložený';
+$lang['nosecedit'] = 'Stránka bola medzičasom zmenená, informácie o sekcii sú zastaralé a z tohto dôvodu bola nahraná celá stránka.';
+$lang['regmissing'] = 'Musíte vyplniť všetky údaje.';
+$lang['reguexists'] = 'Užívateľ s rovnakým menom je už zaregistrovaný.';
+$lang['regsuccess'] = 'Užívateľský účet bol vytvorený a heslo zaslané emailom.';
+$lang['regsuccess2'] = 'Užívateľský účet bol vytvorený.';
+$lang['regmailfail'] = 'Zdá sa, že nastala chyba pri posielaní mailu s heslom. Skúste kontaktovať správcu.';
+$lang['regbadmail'] = 'Zadaná emailová adresa nie je platná. Pokiaľ si myslíte, že to je zle, skúste kontaktovať správcu.';
+$lang['regbadpass'] = 'Zadané heslá nie sú rovnaké, zadajte ich prosím znovu.';
+$lang['regpwmail'] = 'Vaše heslo do systému DokuWiki';
+$lang['reghere'] = 'Nemáte užívateľský účet? Vytvorte si ho';
+$lang['profna'] = 'Táto wiki nepodporuje zmenu profilu';
+$lang['profnochange'] = 'Žiadne zmeny, nie je čo robiť.';
+$lang['profnoempty'] = 'Prázdne meno alebo mailová adresa nie sú povolené.';
+$lang['profchanged'] = 'Užívateľský účet úspešne zmenený.';
+$lang['pwdforget'] = 'Zabudli ste heslo? Získajte nové!';
+$lang['resendna'] = 'Táto wiki nepodporuje opätovné zasielanie hesla.';
+$lang['resendpwd'] = 'Pošli nové heslo pre';
+$lang['resendpwdmissing'] = 'Prepáčte, musíte vyplniť všetky polia.';
+$lang['resendpwdnouser'] = 'Prepáčte, nemôžeme nájsť zadaného užívateľa v databáze.';
+$lang['resendpwdbadauth'] = 'Prepáčte, tento autorizačný kód nie je platný. Uistite sa, či ste použili celý autorizačný odkaz.';
+$lang['resendpwdconfirm'] = 'Autorizačný odkaz bol zaslaný na e-mail.';
+$lang['resendpwdsuccess'] = 'Vaše nové heslo bolo zaslané na e-mail.';
+$lang['license'] = 'Ak nie je uvedené inak, obsah tejto wiki je uverejnený pod nasledujúcou licenciou:';
+$lang['licenseok'] = 'Poznámka: Zmenou tejto stránky súhlasíte s uverejnením obsahu pod nasledujúcou licenciou:';
+$lang['searchmedia'] = 'Hľadať meno súboru:';
+$lang['searchmedia_in'] = 'Hľadať v %s';
+$lang['txt_upload'] = 'Vyberte súbor ako prílohu';
+$lang['txt_filename'] = 'Uložiť ako (voliteľné)';
+$lang['txt_overwrt'] = 'Prepísať existujúci súbor';
+$lang['lockedby'] = 'Práve zamknuté:';
+$lang['lockexpire'] = 'Zámok stratí platnosť:';
+$lang['js']['willexpire'] = 'Váš zámok pre editáciu za chvíľu stratí platnosť.\nAby ste predišli konfliktom, stlačte tlačítko Náhľad a zámok sa predĺži.';
+$lang['js']['notsavedyet'] = 'Neuložené zmeny budú stratené.
+Chcete naozaj pokračovať?';
+$lang['js']['searchmedia'] = 'Hľadať súbory';
+$lang['js']['keepopen'] = 'Po vybraní súboru ponechať okno otvorené';
+$lang['js']['hidedetails'] = 'Skryť detaily';
+$lang['js']['mediatitle'] = 'Nastavenia odkazu';
+$lang['js']['mediadisplay'] = 'Typ odkazu';
+$lang['js']['mediaalign'] = 'Zarovnanie';
+$lang['js']['mediasize'] = 'Veľkosť obrázka';
+$lang['js']['mediatarget'] = 'Cieľ odkazu';
+$lang['js']['mediaclose'] = 'Zatvoriť';
+$lang['js']['mediainsert'] = 'Vložiť';
+$lang['js']['mediadisplayimg'] = 'Zobraziť obrázok.';
+$lang['js']['mediadisplaylnk'] = 'Zobraziť iba odkaz.';
+$lang['js']['mediasmall'] = 'Malý';
+$lang['js']['mediamedium'] = 'Stredný';
+$lang['js']['medialarge'] = 'Veľký';
+$lang['js']['mediaoriginal'] = 'Originál';
+$lang['js']['medialnk'] = 'Odkaz na stránku s detailným popisom';
+$lang['js']['mediadirect'] = 'Priamy odkaz na originál';
+$lang['js']['medianolnk'] = 'Žiadny odkaz';
+$lang['js']['medianolink'] = 'Bez odkazu na obrázok';
+$lang['js']['medialeft'] = 'Zarovnať obrázok vľavo.';
+$lang['js']['mediaright'] = 'Zarovnať obrázok vpravo.';
+$lang['js']['mediacenter'] = 'Zarovnať obrázok na stred.';
+$lang['js']['medianoalign'] = 'Nepoužívať zarovnanie.';
+$lang['js']['nosmblinks'] = 'Odkazovanie na zdieľané prostriedky Windows funguje len v Internet Exploreri.
+Aj napriek tomu tento odkaz môžete skopírovať a vložiť inde.';
+$lang['js']['linkwiz'] = 'Sprievodca odkazmi';
+$lang['js']['linkto'] = 'Odkaz na:';
+$lang['js']['del_confirm'] = 'Zmazať túto položku?';
+$lang['js']['restore_confirm'] = 'Skutočne obnoviť túto verziu?';
+$lang['js']['media_diff'] = 'Zobraziť rozdiely:';
+$lang['js']['media_diff_both'] = 'Vedľa seba';
+$lang['js']['media_diff_opacity'] = 'Presvitaním';
+$lang['js']['media_diff_portions'] = 'Potiahnutím';
+$lang['js']['media_select'] = 'Vybrať súbory...';
+$lang['js']['media_upload_btn'] = 'Nahrať';
+$lang['js']['media_done_btn'] = 'Hotovo';
+$lang['js']['media_drop'] = 'Pridajte súbory potiahnutím myšou';
+$lang['js']['media_cancel'] = 'odstrániť';
+$lang['js']['media_overwrt'] = 'Prepísať existujúce súbory';
+$lang['rssfailed'] = 'Nastala chyba pri vytváraní tohto RSS: ';
+$lang['nothingfound'] = 'Nič nenájdené.';
+$lang['mediaselect'] = 'Výber súboru';
+$lang['fileupload'] = 'Nahrávanie súboru';
+$lang['uploadsucc'] = 'Prenos prebehol v poriadku';
+$lang['uploadfail'] = 'Chyba pri nahrávaní. Možno kvôli zle nastaveným právam?';
+$lang['uploadwrong'] = 'Prenos súboru s takouto príponou nie je dovolený.';
+$lang['uploadexist'] = 'Súbor už existuje. Žiadna akcia.';
+$lang['uploadbadcontent'] = 'Nahraný obsah sa nezhoduje s príponou súboru %s.';
+$lang['uploadspam'] = 'Nahrávanie bolo zablokované spamovým blacklistom.';
+$lang['uploadxss'] = 'Nahrávanie bolo zablokované kvôli potenciálnemu škodlivému obsahu.';
+$lang['uploadsize'] = 'Nahraný súbor bol príliš veľký. (max %s)';
+$lang['deletesucc'] = 'Súbor "%s" bol zmazaný.';
+$lang['deletefail'] = '"%s" nie je možné zmazať - skontrolujte oprávnenia.';
+$lang['mediainuse'] = 'Súbor "%s" nebol zmazaný - je stále používaný.';
+$lang['namespaces'] = 'Menné priestory';
+$lang['mediafiles'] = 'Dostupné súbory';
+$lang['accessdenied'] = 'Nemáte oprávnenie na zobrazenie požadovanej stránky.';
+$lang['mediausage'] = 'Pre odkázanie na súbor použite nasledujúcu syntax:';
+$lang['mediaview'] = 'Zobraziť pôvodný súbor';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Nahrať súbor do aktuálneho menného priestoru. Pre vytvorenie menného podpriestoru, pridajte jeho názov na začiatok mena súboru (oddelený dvojbodkou)';
+$lang['mediaextchange'] = 'Prípona súboru bola zmenená z .%s na .%s!';
+$lang['reference'] = 'Referencie pre';
+$lang['ref_inuse'] = 'Súbor nemôže byť zmazaný, pretože je stále používaný nasledujúcimi stránkami:';
+$lang['ref_hidden'] = 'Niektoré referencie sú na stránky, pre ktoré nemáte právo na čítanie';
+$lang['hits'] = '- počet výskytov';
+$lang['quickhits'] = 'Zodpovedajúce stránky';
+$lang['toc'] = 'Obsah';
+$lang['current'] = 'aktuálne';
+$lang['yours'] = 'Vaša verzia';
+$lang['diff'] = 'Zobraziť rozdiely voči aktuálnej verzii';
+$lang['diff2'] = 'Zobraziť rozdiely medzi vybranými verziami';
+$lang['difflink'] = 'Odkaz na tento prehľad zmien';
+$lang['diff_type'] = 'Prehľad zmien:';
+$lang['diff_inline'] = 'Vnorený';
+$lang['diff_side'] = 'Vedľa seba';
+$lang['line'] = 'Riadok';
+$lang['breadcrumb'] = 'História';
+$lang['youarehere'] = 'Nachádzate sa';
+$lang['lastmod'] = 'Posledná úprava';
+$lang['by'] = 'od';
+$lang['deleted'] = 'odstránené';
+$lang['created'] = 'vytvorené';
+$lang['restored'] = 'stará verzia bola obnovená';
+$lang['external_edit'] = 'externá úprava';
+$lang['summary'] = 'Komentár k úpravám';
+$lang['noflash'] = 'Pre zobrazenie tohto obsahu potrebujete <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>.';
+$lang['download'] = 'Stiahnuť';
+$lang['mail_newpage'] = 'stránka pridaná:';
+$lang['mail_changed'] = 'stránka zmenená:';
+$lang['mail_subscribe_list'] = 'stránky zmenené v mennom priestore:';
+$lang['mail_new_user'] = 'nový užívateľ:';
+$lang['mail_upload'] = 'nahraný súbor:';
+$lang['changes_type'] = 'Prehľad zmien';
+$lang['pages_changes'] = 'Stránok';
+$lang['media_changes'] = 'Súbory';
+$lang['both_changes'] = 'Stránok spolu s média súbormi';
+$lang['qb_bold'] = 'Tučné';
+$lang['qb_italic'] = 'Kurzíva';
+$lang['qb_underl'] = 'Podčiarknutie';
+$lang['qb_code'] = 'Neformátovať (zdrojový kód)';
+$lang['qb_strike'] = 'Prečiarknutie';
+$lang['qb_h1'] = 'Nadpis 1. úrovne';
+$lang['qb_h2'] = 'Nadpis 2. úrovne';
+$lang['qb_h3'] = 'Nadpis 3. úrovne';
+$lang['qb_h4'] = 'Nadpis 4. úrovne';
+$lang['qb_h5'] = 'Nadpis 5. úrovne';
+$lang['qb_h'] = 'Nadpis';
+$lang['qb_hs'] = 'Zvoliť nadpis';
+$lang['qb_hplus'] = 'Nadpis vyššej úrovne';
+$lang['qb_hminus'] = 'Nadpis nižšej úrovne';
+$lang['qb_hequal'] = 'Nadpis predchádzajúcej úrovne';
+$lang['qb_link'] = 'Interný odkaz';
+$lang['qb_extlink'] = 'Externý odkaz';
+$lang['qb_hr'] = 'Horizontálna linka';
+$lang['qb_ol'] = 'Číslovaný zoznam';
+$lang['qb_ul'] = 'Nečíslovaný zoznam';
+$lang['qb_media'] = 'Vložiť obrázky alebo iné súbory';
+$lang['qb_sig'] = 'Vložiť podpis';
+$lang['qb_smileys'] = 'Smajlíky';
+$lang['qb_chars'] = 'Špeciálne znaky';
+$lang['upperns'] = 'návrat do nadradeného menného priestoru';
+$lang['admin_register'] = 'Pridaj nového užívateľa';
+$lang['metaedit'] = 'Upraviť metainformácie';
+$lang['metasaveerr'] = 'Zápis metainformácií zlyhal';
+$lang['metasaveok'] = 'Metainformácie uložené';
+$lang['img_backto'] = 'Späť na';
+$lang['img_title'] = 'Titul';
+$lang['img_caption'] = 'Popis';
+$lang['img_date'] = 'Dátum';
+$lang['img_fname'] = 'Názov súboru';
+$lang['img_fsize'] = 'Veľkosť';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Kopírovacie práva';
+$lang['img_format'] = 'Formát';
+$lang['img_camera'] = 'Fotoaparát';
+$lang['img_keywords'] = 'Kľúčové slová';
+$lang['img_width'] = 'Šírka';
+$lang['img_height'] = 'Výška';
+$lang['img_manager'] = 'Prezrieť v správcovi médií';
+$lang['subscr_subscribe_success'] = 'Používateľ %s bol pridaný do zoznamu hlásení o zmenách %s';
+$lang['subscr_subscribe_error'] = 'Chyba pri pridaní používateľa %s do zoznamu hlásení o zmenách %s';
+$lang['subscr_subscribe_noaddress'] = 'Vaše prihlasovacie meno nemá priradenú žiadnu email adresu, nemôžete byť pridaný do zoznamu hlásení o zmenách';
+$lang['subscr_unsubscribe_success'] = 'Používateľ %s bol odstránený zo zoznamu hlásení o zmenách %s';
+$lang['subscr_unsubscribe_error'] = 'Chyba pri odstránení používateľa %s zo zoznamu hlásení o zmenách %s';
+$lang['subscr_already_subscribed'] = 'Používateľ %s už je v zozname hlásení o zmenách %s';
+$lang['subscr_not_subscribed'] = 'Používateľ %s nie je v zozname hlásení o zmenách %s';
+$lang['subscr_m_not_subscribed'] = 'Momentálne nesledujete zmeny aktuálnej stránky alebo menného priestoru.';
+$lang['subscr_m_new_header'] = 'Pridať sledovanie zmien';
+$lang['subscr_m_current_header'] = 'Aktuálne sledované zmeny';
+$lang['subscr_m_unsubscribe'] = 'Nesledovať zmeny';
+$lang['subscr_m_subscribe'] = 'Sledovať zmeny';
+$lang['subscr_m_receive'] = 'Dostávať';
+$lang['subscr_style_every'] = 'email pri každej zmene';
+$lang['subscr_style_digest'] = 'email so zhrnutím zmien pre každú stránku (perióda %.2f dňa)';
+$lang['subscr_style_list'] = 'zoznam zmenených stránok od posledného emailu (perióda %.2f dňa)';
+$lang['authmodfailed'] = 'Užívateľská autentifikácia nie je možná. Prosím informujte správcu systému.';
+$lang['authtempfail'] = 'Užívateľská autentifikácia je dočasne nedostupná. Ak táto situácia pretrváva, prosím informujte správcu systému.';
+$lang['i_chooselang'] = 'Zvoľte váš jazyk';
+$lang['i_installer'] = 'DokuWiki inštalátor';
+$lang['i_wikiname'] = 'Názov Wiki';
+$lang['i_enableacl'] = 'Aktivovať ACL (doporučené)';
+$lang['i_superuser'] = 'Správca';
+$lang['i_problems'] = 'Inštalátor narazil na nižšie uvedené problémy. Nemôžete pokračovať, pokiaľ ich neodstránite.';
+$lang['i_modified'] = 'Z bezpečnostných dôvodov bude tento skript fungovať iba s novou, neupravenou inštaláciou Dokuwiki. Môžete buď znovu rozbaliť stiahnutý inštalačný balík alebo preštudovať <a href="http://dokuwiki.org/install"> inštalačné inštrukcie Dokuwiki</a>';
+$lang['i_funcna'] = 'PHP funkcia <code>%s</code> nie je dostupná. Je možné, že ju z určitých dôvodov zablokoval váš poskytovateľ webhostingu?';
+$lang['i_phpver'] = 'Vaša verzia PHP <code>%s</code> je nižšia ako požadovaná <code>%s</code>. Potrebujete aktualizovať Vašu inštaláciu PHP.';
+$lang['i_permfail'] = '<code>%s</code> nie je zapisovateľný pre DokuWiki. Musíte zmeniť prístupové práva pre tento adresár!';
+$lang['i_confexists'] = '<code>%s</code> už existuje';
+$lang['i_writeerr'] = 'Nie je možné vytvoriť <code>%s</code>. Potrebujete skontrolovať prístupové práva pre adresár/súbor a vytvoriť ho manuálne.';
+$lang['i_badhash'] = 'neznámy alebo zmenený súbor dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - nesprávna alebo žiadna hodnota';
+$lang['i_success'] = 'Konfigurácia bola úspešne ukončená. Teraz môžete zmazať súbor install.php. Pokračujte vo <a href="doku.php">vašej novej DokuWiki</a>.';
+$lang['i_failure'] = 'Pri zápise konfiguračného súboru nastali nejaké chyby. Potrebujete ich opraviť manuálne pred tým, ako budete môcť používať <a href="doku.php">vašu novú DokuWiki</a>.';
+$lang['i_policy'] = 'Počiatočná ACL politika';
+$lang['i_pol0'] = 'Otvorená Wiki (čítanie, zápis a nahrávanie pre každého)';
+$lang['i_pol1'] = 'Verejná Wiki (čítanie pre každého, zápis a nahrávanie pre registrovaných užívateľov)';
+$lang['i_pol2'] = 'Uzatvorená Wiki (čítanie, zápis a nahrávanie len pre registrovaných užívateľov)';
+$lang['i_retry'] = 'Skúsiť znovu';
+$lang['i_license'] = 'Vyberte licenciu, pod ktorou chcete uložiť váš obsah:';
+$lang['recent_global'] = 'Práve prehliadate zmeny v mennom priestore <b>%s</b>. Môžete si tiež pozrieť <a href="%s">aktuálne zmeny celej wiki</a>.';
+$lang['years'] = 'pred %d rokmi';
+$lang['months'] = 'pred %d mesiacmi';
+$lang['weeks'] = 'pred %d týždňami';
+$lang['days'] = 'pred %d dňami';
+$lang['hours'] = 'pred %d hodinami';
+$lang['minutes'] = 'pred %d minútami';
+$lang['seconds'] = 'pred %d sekundami';
+$lang['wordblock'] = 'Vaše zmeny neboli uložené, pretože obsahovali nepovolený text (spam).';
+$lang['media_uploadtab'] = 'Nahrať';
+$lang['media_searchtab'] = 'Hľadať';
+$lang['media_file'] = 'Súbor';
+$lang['media_viewtab'] = 'Náhľad';
+$lang['media_edittab'] = 'Upraviť';
+$lang['media_historytab'] = 'História';
+$lang['media_list_thumbs'] = 'Miniatúry';
+$lang['media_list_rows'] = 'Zoznam';
+$lang['media_sort_name'] = 'Meno';
+$lang['media_sort_date'] = 'Dátum';
+$lang['media_namespaces'] = 'Vybrať priestor';
+$lang['media_files'] = 'Súbory v %s';
+$lang['media_upload'] = 'Nahrať do %s';
+$lang['media_search'] = 'Hľadať v %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s v %s';
+$lang['media_edit'] = 'Upraviť %s';
+$lang['media_history'] = 'História %s';
+$lang['media_meta_edited'] = 'metadáta upravené';
+$lang['media_perm_read'] = 'Prepáčte, ale nemáte dostatočné oprávnenie na čítanie súborov.';
+$lang['media_perm_upload'] = 'Prepáčte, ale nemáte dostatočné oprávnenie na nahrávanie súborov.';
+$lang['media_update'] = 'Nahrať novú verziu';
+$lang['media_restore'] = 'Obnoviť túto verziu';
+$lang['plugin_install_err'] = 'Plugin nebol nainštalovaný úspešne. Premenujte adresár s pluginom \'%s\' na \'%s\'.';
diff --git a/inc/lang/sk/locked.txt b/inc/lang/sk/locked.txt
new file mode 100644
index 000000000..5063c0605
--- /dev/null
+++ b/inc/lang/sk/locked.txt
@@ -0,0 +1,3 @@
+====== Stránka je uzamknutá ======
+
+Tato stránka je práve uzamknutá pre úpravy iným užívateľom. Musíte počkať dovtedy, pokiaľ daný užívateľ dokončí svoje úpravy alebo pokiaľ tento zámok stratí platnosť.
diff --git a/inc/lang/sk/login.txt b/inc/lang/sk/login.txt
new file mode 100644
index 000000000..3bfc91037
--- /dev/null
+++ b/inc/lang/sk/login.txt
@@ -0,0 +1,3 @@
+====== Prihlásenie ======
+
+Momentálne nie ste prihlásený(á)! Prosím vložte svoje identifikačné údaje. Pre prihlásenie musíte mať zapnuté cookies.
diff --git a/inc/lang/sk/mailtext.txt b/inc/lang/sk/mailtext.txt
new file mode 100644
index 000000000..30b7f5c37
--- /dev/null
+++ b/inc/lang/sk/mailtext.txt
@@ -0,0 +1,17 @@
+Stránka vo vašej DokuWiki bola zmenená. Tu sú podrobnosti:
+
+Dátum : @DATE@
+Prehliadač : @BROWSER@
+IP adresa : @IPADDRESS@
+Adresa : @HOSTNAME@
+Stará verzia : @OLDPAGE@
+Nová verzia : @NEWPAGE@
+Komentár : @SUMMARY@
+User : @USER@
+
+@DIFF@
+
+
+--
+Táto správa bola zaslaná DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/sk/newpage.txt b/inc/lang/sk/newpage.txt
new file mode 100644
index 000000000..180d80ee1
--- /dev/null
+++ b/inc/lang/sk/newpage.txt
@@ -0,0 +1,3 @@
+====== Stránka s týmto názvom ešte neexistuje ======
+
+Odkaz vás zaviedol na stránku, ktorá ešte neexistuje. Môžete ju vytvoriť stlačením tlačítka ''Vytvoriť stránku''.
diff --git a/inc/lang/sk/norev.txt b/inc/lang/sk/norev.txt
new file mode 100644
index 000000000..f664ae496
--- /dev/null
+++ b/inc/lang/sk/norev.txt
@@ -0,0 +1,3 @@
+====== Takáto verzia neexistuje ======
+
+Zadaná verzia neexistuje. Stlačte tlačítko ''Staršie verzie'' pre zoznam starších verzií tohoto dokumentu.
diff --git a/inc/lang/sk/password.txt b/inc/lang/sk/password.txt
new file mode 100644
index 000000000..2b85e9c39
--- /dev/null
+++ b/inc/lang/sk/password.txt
@@ -0,0 +1,11 @@
+Dobrý deň,
+
+Tu sú prihlasovacie informácie pre @TITLE@ (@DOKUWIKIURL@)
+
+Meno : @FULLNAME@
+Užívateľské meno : @LOGIN@
+Heslo : @PASSWORD@
+
+--
+Táto správa bola zaslaná DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/sk/preview.txt b/inc/lang/sk/preview.txt
new file mode 100644
index 000000000..871bca371
--- /dev/null
+++ b/inc/lang/sk/preview.txt
@@ -0,0 +1,3 @@
+====== Náhľad ======
+
+Tu je náhľad, ako bude dokument vyzerať. Pozor: Súbor zatiaľ **nie je uložený**!
diff --git a/inc/lang/sk/pwconfirm.txt b/inc/lang/sk/pwconfirm.txt
new file mode 100644
index 000000000..210740da7
--- /dev/null
+++ b/inc/lang/sk/pwconfirm.txt
@@ -0,0 +1,15 @@
+Ahoj @FULLNAME@!
+
+Niekto žiadal o nové heslo pre vaše @TITLE@
+konto na @DOKUWIKIURL@
+
+Ak ste nežiadali o nové heslo, potom iba ignorujte tento mail.
+
+Pre potvrdenie, že požiadavka bola skutočne odoslaná vami,
+použite prosím nasledujúci odkaz.
+
+@CONFIRM@
+
+--
+Táto správa bola zaslaná DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/sk/read.txt b/inc/lang/sk/read.txt
new file mode 100644
index 000000000..64b7ed26e
--- /dev/null
+++ b/inc/lang/sk/read.txt
@@ -0,0 +1,2 @@
+Táto stránka je iba na čítanie. Môžete si prehliadnuť zdrojový kód, ale nemôžete ho meniť. Opýtajte sa správcu, ak si myslíte, že niečo nie je v poriadku.
+
diff --git a/inc/lang/sk/recent.txt b/inc/lang/sk/recent.txt
new file mode 100644
index 000000000..d9f7c3b9b
--- /dev/null
+++ b/inc/lang/sk/recent.txt
@@ -0,0 +1,3 @@
+====== Posledné úpravy ======
+
+Nasledujúce stránky boli nedávno zmenené.
diff --git a/inc/lang/sk/register.txt b/inc/lang/sk/register.txt
new file mode 100644
index 000000000..59c225d7c
--- /dev/null
+++ b/inc/lang/sk/register.txt
@@ -0,0 +1,3 @@
+====== Zaregistrujte sa ako nový užívateľ ======
+
+Aby ste získali užívateľský účet, vyplňte prosím všetky informácie v nasledujúcom formulári. Zadajte **platnú** mailovú adresu, na ktorú bude zaslané heslo. Užívateľské meno musí byť v platnom [[doku>pagename|formáte]] (ktorý je rovnaký ako formát názvu stránky).
diff --git a/inc/lang/sk/registermail.txt b/inc/lang/sk/registermail.txt
new file mode 100644
index 000000000..a0bf9e314
--- /dev/null
+++ b/inc/lang/sk/registermail.txt
@@ -0,0 +1,14 @@
+Nový užívateľ bol registrovaný. Tu sú detaily:
+
+Užívateľské meno : @NEWUSER@
+Celé meno : @NEWNAME@
+E-Mail : @NEWEMAIL@
+
+Dátum : @DATE@
+Prehliadač : @BROWSER@
+IP adresa : @IPADDRESS@
+Meno servera : @HOSTNAME@
+
+--
+Táto správa bola zaslaná DokuWiki
+@DOKUWIKIURL@
diff --git a/inc/lang/sk/resendpwd.txt b/inc/lang/sk/resendpwd.txt
new file mode 100644
index 000000000..143706b72
--- /dev/null
+++ b/inc/lang/sk/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Poslať nové heslo ======
+
+Zadajte prosím vaše prihlasovacie meno do formulára za účelom vygenerovania nového hesla. Autorizačný odkaz bude zaslaný na vašu zaregistrovanú email adresu. \ No newline at end of file
diff --git a/inc/lang/sk/revisions.txt b/inc/lang/sk/revisions.txt
new file mode 100644
index 000000000..ad99e7234
--- /dev/null
+++ b/inc/lang/sk/revisions.txt
@@ -0,0 +1,3 @@
+====== Staršie verzie ======
+
+Tu sú staršie verzie daného dokumentu. Pre návrat ku staršej verzii si ju zvoľte zo zoznamu nižšie, stlačte tlačidlo ''Upraviť stránku'' a uložte ju.
diff --git a/inc/lang/sk/searchpage.txt b/inc/lang/sk/searchpage.txt
new file mode 100644
index 000000000..3fdf074b7
--- /dev/null
+++ b/inc/lang/sk/searchpage.txt
@@ -0,0 +1,5 @@
+====== Vyhľadávanie ======
+
+Výsledky hľadania môžete vidieť nižšie. Pokiaľ ste nenašli, čo hľadáte, skúste požadovanú stránku sami vytvoriť stlačením tlačidla ''Vytvoriť stránku''.
+
+===== Výsledky =====
diff --git a/inc/lang/sk/showrev.txt b/inc/lang/sk/showrev.txt
new file mode 100644
index 000000000..036769694
--- /dev/null
+++ b/inc/lang/sk/showrev.txt
@@ -0,0 +1,3 @@
+**Toto je staršia verzia dokumentu!**
+----
+
diff --git a/inc/lang/sk/stopwords.txt b/inc/lang/sk/stopwords.txt
new file mode 100644
index 000000000..060ee495f
--- /dev/null
+++ b/inc/lang/sk/stopwords.txt
@@ -0,0 +1,28 @@
+#Toto je zoznam slov ignorovaných indexáciou, jedno slovo na riadok
+# Keď editujete tento súbor, uistite sa, či používate UNIXové konce riadkov (jednoduchý nový riadok)
+# Nie je potrebné vkladať slová kratšie ako 3 znaky - tie sú ignorované vždy.
+# Tento zoznam je založený na inom nájdenom na http://www.ranks.nl/stopwords/
+okolo
+tvoj
+ale
+ako
+aký
+aká
+aké
+kde
+kým
+kom
+komu
+ich
+jeho
+jej
+tvoj
+môj
+moja
+moje
+moji
+náš
+váš
+www
+
+
diff --git a/inc/lang/sk/subscr_digest.txt b/inc/lang/sk/subscr_digest.txt
new file mode 100644
index 000000000..273cc7e26
--- /dev/null
+++ b/inc/lang/sk/subscr_digest.txt
@@ -0,0 +1,20 @@
+Dobrý deň!
+
+Stránka @PAGE@ wiki @TITLE@ bola zmenená.
+Zoznam zmien:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Stará verzia: @OLDPAGE@
+Nová verzia: @NEWPAGE@
+
+Ak si neprajete zasielať tieto správy, prihláste sa do wiki
+@DOKUWIKIURL@, potom prejdite na
+@SUBSCRIBE@
+a odhláste sa z informovania o zmenách stránky alebo menného priestoru.
+
+--
+Táto správa bola zaslaná DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sk/subscr_form.txt b/inc/lang/sk/subscr_form.txt
new file mode 100644
index 000000000..1f12e9a15
--- /dev/null
+++ b/inc/lang/sk/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Sledovanie zmien ======
+
+Táto stánka umožňuje sledovať zmeny aktuálnej stránky a menného priestoru. \ No newline at end of file
diff --git a/inc/lang/sk/subscr_list.txt b/inc/lang/sk/subscr_list.txt
new file mode 100644
index 000000000..3a5bfb572
--- /dev/null
+++ b/inc/lang/sk/subscr_list.txt
@@ -0,0 +1,17 @@
+Dobrý deň!
+
+Stránky v mennom priestore @PAGE@ wiki @TITLE@ boli zmenené.
+Zoznam zmenených stránok:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Ak si neprajete zasielať tieto správy, prihláste sa do wiki
+@DOKUWIKIURL@, potom prejdite na
+@SUBSCRIBE@
+a odhláste sa z informovania o zmenách stránky alebo menného priestoru.
+
+--
+Táto správa bola zaslaná DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sk/subscr_single.txt b/inc/lang/sk/subscr_single.txt
new file mode 100644
index 000000000..3abbc40b8
--- /dev/null
+++ b/inc/lang/sk/subscr_single.txt
@@ -0,0 +1,23 @@
+Dobrý deň!
+
+Stránka @PAGE@ wiki @TITLE@ bola zmenená.
+Zoznam zmien:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Dátum : @DATE@
+Používateľ : @USER@
+Komentár: @SUMMARY@
+Stará verzia: @OLDPAGE@
+Nová verzia: @NEWPAGE@
+
+Ak si neprajete zasielať tieto správy, prihláste sa do wiki
+@DOKUWIKIURL@, potom prejdite na
+@SUBSCRIBE@
+a odhláste sa z informovania o zmenách stránky alebo menného priestoru.
+
+--
+Táto správa bola zaslaná DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sk/updateprofile.txt b/inc/lang/sk/updateprofile.txt
new file mode 100644
index 000000000..67b823dc5
--- /dev/null
+++ b/inc/lang/sk/updateprofile.txt
@@ -0,0 +1,6 @@
+====== Zmena vášho užívateľského profilu ======
+
+Potrebujete vyplniť len tie polia, ktoré chcete zmeniť. Nemôžete zmeniť prihlasovacie meno.
+
+
+
diff --git a/inc/lang/sk/uploadmail.txt b/inc/lang/sk/uploadmail.txt
new file mode 100644
index 000000000..18293799f
--- /dev/null
+++ b/inc/lang/sk/uploadmail.txt
@@ -0,0 +1,14 @@
+Súbor bol nahraný do DokuWiki. Tu sú podrobnosti:
+
+Súbor : @MEDIA@
+Dátum : @DATE@
+Prehliadač : @BROWSER@
+IP adresa : @IPADDRESS@
+Názov hostiteľa : @HOSTNAME@
+Veľkosť : @SIZE@
+MIME Typ : @MIME@
+Užívateľ : @USER@
+
+--
+Táto správa bola zaslaná DokuWiki
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sl/admin.txt b/inc/lang/sl/admin.txt
new file mode 100644
index 000000000..cee19deff
--- /dev/null
+++ b/inc/lang/sl/admin.txt
@@ -0,0 +1,3 @@
+===== Skrbništvo =====
+
+Navedene možnosti omogočajo skrbniško prilagajanje nastavitev sistema DokuWiki.
diff --git a/inc/lang/sl/adminplugins.txt b/inc/lang/sl/adminplugins.txt
new file mode 100644
index 000000000..899c854fc
--- /dev/null
+++ b/inc/lang/sl/adminplugins.txt
@@ -0,0 +1 @@
+===== Dodatni vstavki ===== \ No newline at end of file
diff --git a/inc/lang/sl/backlinks.txt b/inc/lang/sl/backlinks.txt
new file mode 100644
index 000000000..5e4d8ffa7
--- /dev/null
+++ b/inc/lang/sl/backlinks.txt
@@ -0,0 +1,3 @@
+====== Povratne povezave ======
+
+Spodaj je naveden seznam strani, ki so povezane na trenutno stran. EnoBesedne povezave niso zaznane kot povratne povezave.
diff --git a/inc/lang/sl/conflict.txt b/inc/lang/sl/conflict.txt
new file mode 100644
index 000000000..ec5b37016
--- /dev/null
+++ b/inc/lang/sl/conflict.txt
@@ -0,0 +1,5 @@
+====== Obstaja novejša različica dokumenta ======
+
+Obstaja novejša različica dokumenta, ki ga trenutno urejate. Do zapleta pride, ko drug uporabnik spremeni dokument med vašim urejanjem in ga pred vami shrani.
+
+Temeljito preglejte spodaj izpisane razlike med dokumentoma in izberite različico, ki jo želite ohraniti. V kolikor je izbrana možnost ''shrani'', bo shranjena vaša zadnja različica. Z izbiro možnosti ''prekliči'', pa bo ohranjena trenutno shranjena različica.
diff --git a/inc/lang/sl/denied.txt b/inc/lang/sl/denied.txt
new file mode 100644
index 000000000..5b5fd4d3a
--- /dev/null
+++ b/inc/lang/sl/denied.txt
@@ -0,0 +1,3 @@
+====== Ni ustreznih dovoljenj ======
+
+Za nadaljevanje opravila je treba imeti ustrezna dovoljenja. Ali ste se morda pozabili prijaviti?
diff --git a/inc/lang/sl/diff.txt b/inc/lang/sl/diff.txt
new file mode 100644
index 000000000..5cb2e3a12
--- /dev/null
+++ b/inc/lang/sl/diff.txt
@@ -0,0 +1,3 @@
+====== Primerjava izbranih različic ======
+
+Prikazane so razlike med izbrano in trenutno različico strani.
diff --git a/inc/lang/sl/draft.txt b/inc/lang/sl/draft.txt
new file mode 100644
index 000000000..b3fe4de35
--- /dev/null
+++ b/inc/lang/sl/draft.txt
@@ -0,0 +1,5 @@
+===== Zaznan je shranjen osnutek strani =====
+
+Zadnja seja te strani ni bila pravilno zaključena. Sistem DokuWiki je samodejno shranil osnutek strani, ki ga je mogoče naprej urejati. Spodaj so navedeni podatki samodejnega shranjevanja zadnje seje.
+
+Vsebino osnutka je mogoče //obnoviti// na zadnjo sejo, //izbrisati// samodejno shranjen osnutek ali pa //prekiniti// urejanje. \ No newline at end of file
diff --git a/inc/lang/sl/edit.txt b/inc/lang/sl/edit.txt
new file mode 100644
index 000000000..71d5fb02f
--- /dev/null
+++ b/inc/lang/sl/edit.txt
@@ -0,0 +1 @@
+Po koncu urejanja strani, je stran treba ''shraniti''. Navodila in podrobnosti za urejanje je mogoče najti na strani [[wiki:syntax|skladnje]]. Možnosti urejanja in pravila skladnje je mogoče varno preizkusiti v [[playground:playground|peskovniku]].
diff --git a/inc/lang/sl/editrev.txt b/inc/lang/sl/editrev.txt
new file mode 100644
index 000000000..baaacd270
--- /dev/null
+++ b/inc/lang/sl/editrev.txt
@@ -0,0 +1,2 @@
+**Naložena je stara različica dokumenta!** V kolikor staro različico shranite, bo shranjena kot najnovejša različica.
+---- \ No newline at end of file
diff --git a/inc/lang/sl/index.txt b/inc/lang/sl/index.txt
new file mode 100644
index 000000000..dd54d2bed
--- /dev/null
+++ b/inc/lang/sl/index.txt
@@ -0,0 +1,4 @@
+====== Kazalo ======
+
+Na spodnjem seznamu so izpisane vse wiki strani, ki so na voljo, razvrščene pa so po posameznih [[doku>namespaces|imenskih prostorih]].
+
diff --git a/inc/lang/sl/install.html b/inc/lang/sl/install.html
new file mode 100644
index 000000000..6fb6bead3
--- /dev/null
+++ b/inc/lang/sl/install.html
@@ -0,0 +1,20 @@
+<p>Stran je namenjena pomoči pri prvi namestitvi in nastavitvi spletišča
+<a href="http://dokuwiki.org">Dokuwiki</a>. Več podrobnosti o tem je mogoče najti na straneh dokumentacije
+<a href="http://dokuwiki.org/installer">namestitve</a>.</p>
+
+<p>Sistem DokuWiki uporablja običajne besedilne datoteke za shranjevanje
+wiki strani in drugih podrobnosti o teh straneh (npr. slike, kazalo, stare
+različice in drugo). Za pravilno delovanje <strong>mora</strong> imeti sistem DokuWiki prost
+dostop do map in datotek, zato je ključno, da so dovoljenja določena pravilno.
+Z namestilnikom ni mogoče spreminjanje dovoljenj map. To je običajno najlažje
+narediti v ukazni lupini ali pa, če spletišče Wiki gostuje na zunanjih
+strežnikih, preko nadzornika FTP povezave (npr. cPanel).</p>
+
+<p>Z namestilnikom lahko spremenite nastavitve dostopa sistema Dokuwiki
+<acronym title="access control list">ACL</acronym>, ki omogoča skrbniško prijavo in dostop do upravljanja z vstavki,
+uporabniki, dovoljenji dostopa uporabnikov do določenih strani in do nekaterih
+nastavitev. Za delovanje sistema ACL ni bistven, vendar pa močno vpliva na
+enostavnost upravljanja strani in nastavitev.</p>
+
+<p>Zahtevnejši uporabniki ali skrbniki s posebnimi zahtevami namestitve sistema
+si lahko več podrobnosti ogledajo na straneh <a href="http://dokuwiki.org/install">navodil namestitve</a> in <a href="http://dokuwiki.org/config">nastavitve</a>.</p> \ No newline at end of file
diff --git a/inc/lang/sl/lang.php b/inc/lang/sl/lang.php
new file mode 100644
index 000000000..00a349af6
--- /dev/null
+++ b/inc/lang/sl/lang.php
@@ -0,0 +1,316 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Jaka Kranjc <lynxlupodian@hotmail.com>
+ * @author Boštjan Seničar <senicar@gmail.com>
+ * @author Dejan Levec <webphp@gmail.com>
+ * @author Gregor Skumavc (grega.skumavc@gmail.com)
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Uredi stran';
+$lang['btn_source'] = 'Pokaži izvorno kodo strani';
+$lang['btn_show'] = 'Pokaži stran';
+$lang['btn_create'] = 'Ustvari stran';
+$lang['btn_search'] = 'Poišči';
+$lang['btn_save'] = 'Shrani';
+$lang['btn_preview'] = 'Predogled';
+$lang['btn_top'] = 'Nazaj na vrh';
+$lang['btn_newer'] = '<< novejši';
+$lang['btn_older'] = 'starejši >>';
+$lang['btn_revs'] = 'Stare različice';
+$lang['btn_recent'] = 'Nedavne spremembe';
+$lang['btn_upload'] = 'Pošlji';
+$lang['btn_cancel'] = 'Prekliči';
+$lang['btn_index'] = 'Kazalo';
+$lang['btn_secedit'] = 'Uredi';
+$lang['btn_login'] = 'Prijava';
+$lang['btn_logout'] = 'Odjava';
+$lang['btn_admin'] = 'Skrbništvo';
+$lang['btn_update'] = 'Posodobi';
+$lang['btn_delete'] = 'Izbriši';
+$lang['btn_back'] = 'Nazaj';
+$lang['btn_backlink'] = 'Povratne povezave';
+$lang['btn_backtomedia'] = 'Nazaj na izbiro predstavnih datotek';
+$lang['btn_subscribe'] = 'Urejanje naročnin';
+$lang['btn_profile'] = 'Posodobi profil';
+$lang['btn_reset'] = 'Ponastavi';
+$lang['btn_resendpwd'] = 'Pošlji novo geslo';
+$lang['btn_draft'] = 'Uredi osnutek';
+$lang['btn_recover'] = 'Obnovi osnutek';
+$lang['btn_draftdel'] = 'Izbriši osnutek';
+$lang['btn_revert'] = 'Povrni';
+$lang['btn_register'] = 'Prijava';
+$lang['btn_apply'] = 'Uveljavi';
+$lang['btn_media'] = 'Urejevalnik predstavnih vsebin';
+$lang['loggedinas'] = 'Prijava kot';
+$lang['user'] = 'Uporabniško ime';
+$lang['pass'] = 'Geslo';
+$lang['newpass'] = 'Novo geslo';
+$lang['oldpass'] = 'Potrdi trenutno geslo';
+$lang['passchk'] = 'Ponovi novo geslo';
+$lang['remember'] = 'Zapomni si me';
+$lang['fullname'] = 'Pravo ime';
+$lang['email'] = 'Elektronski naslov';
+$lang['profile'] = 'Uporabniški profil';
+$lang['badlogin'] = 'Uporabniško ime ali geslo je napačno.';
+$lang['minoredit'] = 'Manjše spremembe';
+$lang['draftdate'] = 'Samodejno shranjevanje osnutka je omogočeno';
+$lang['nosecedit'] = 'Stran je bila v vmesnem času spremenjena. Podatki strani so bili zastareli, zato se je celotna vsebina naložila znova.';
+$lang['regmissing'] = 'Izpolniti je treba vsa polja.';
+$lang['reguexists'] = 'Uporabnik s tem imenom že obstaja.';
+$lang['regsuccess'] = 'Uporabniški račun je uspešno ustvarjen. Geslo je bilo poslano na naveden elektronski naslov.';
+$lang['regsuccess2'] = 'Uporabniški račun je uspešno ustvarjen.';
+$lang['regmailfail'] = 'Videti je, da je prišlo do napake med pošiljanjem gesla. Stopite v stik s skrbnikom sistema!';
+$lang['regbadmail'] = 'Videti je, da je naveden elektronski naslov neveljaven - v kolikor je to napaka, stopite v stik s skrbnikom sistema.';
+$lang['regbadpass'] = 'Gesli nista enaki. Poskusite znova.';
+$lang['regpwmail'] = 'Geslo za DokuWiki';
+$lang['reghere'] = 'Nimate še računa? Vpišite se za nov račun.';
+$lang['profna'] = 'DokuWiki ne podpira spreminjanja profila.';
+$lang['profnochange'] = 'Brez sprememb.';
+$lang['profnoempty'] = 'Prazno polje elektronskega naslova ali imena ni dovoljeno.';
+$lang['profchanged'] = 'Uporabniški profil je uspešno posodobljen.';
+$lang['pwdforget'] = 'Ali ste pozabili geslo? Pridobite si novo geslo.';
+$lang['resendna'] = 'DokuWiki ne podpira možnosti ponovnega pošiljanja gesel.';
+$lang['resendpwd'] = 'Pošlji novo geslo za';
+$lang['resendpwdmissing'] = 'Izpolniti je treba vsa polja.';
+$lang['resendpwdnouser'] = 'Podanega uporabniškega imena v podatkovni zbirki ni mogoče najti.';
+$lang['resendpwdbadauth'] = 'Koda za overitev ni prava. Prepričajte se, da ste uporabili celotno povezavo za potrditev.';
+$lang['resendpwdconfirm'] = 'Povezava za potrditev računa je bila poslana na elektronski naslov.';
+$lang['resendpwdsuccess'] = 'Novo geslo je bilo poslano na elektronski naslov.';
+$lang['license'] = 'V kolikor ni posebej določeno, je vsebina Wiki strani objavljena pod pogoji dovoljenja:';
+$lang['licenseok'] = 'Opomba: z urejanjem vsebine strani, se strinjate z objavo pod pogoji dovoljenja:';
+$lang['searchmedia'] = 'Poišči ime datoteke:';
+$lang['searchmedia_in'] = 'Poišči v %s';
+$lang['txt_upload'] = 'Izberite datoteko za pošiljanje';
+$lang['txt_filename'] = 'Pošlji z imenom (izborno)';
+$lang['txt_overwrt'] = 'Prepiši obstoječo datoteko';
+$lang['lockedby'] = 'Trenutno je zaklenjeno s strani';
+$lang['lockexpire'] = 'Zaklep preteče ob';
+$lang['js']['willexpire'] = 'Zaklep za urejevanje bo pretekel čez eno minuto.\nV izogib sporom, uporabite predogled, da se merilnik časa za zaklep ponastavi.';
+$lang['js']['notsavedyet'] = 'Neshranjene spremembe bodo izgubljene.';
+$lang['js']['searchmedia'] = 'Poišči datoteke';
+$lang['js']['keepopen'] = 'Od izbiri ohrani okno odprto';
+$lang['js']['hidedetails'] = 'Skrij podrobnosti';
+$lang['js']['mediatitle'] = 'Nastavitve povezave';
+$lang['js']['mediadisplay'] = 'Vrsta povezave';
+$lang['js']['mediaalign'] = 'Poravnava';
+$lang['js']['mediasize'] = 'Velikost slike';
+$lang['js']['mediatarget'] = 'Mesto povezave';
+$lang['js']['mediaclose'] = 'Zapri';
+$lang['js']['mediainsert'] = 'Vstavi';
+$lang['js']['mediadisplayimg'] = 'Pokaži sliko.';
+$lang['js']['mediadisplaylnk'] = 'Pokaži le povezavo.';
+$lang['js']['mediasmall'] = 'Majhna različica';
+$lang['js']['mediamedium'] = 'Srednja različica';
+$lang['js']['medialarge'] = 'Velika različica';
+$lang['js']['mediaoriginal'] = 'Izvorna različica';
+$lang['js']['medialnk'] = 'Povezava na strani podrobnosti';
+$lang['js']['mediadirect'] = 'Neposredna povezava do izvorne različice';
+$lang['js']['medianolnk'] = 'Brez povezave';
+$lang['js']['medianolink'] = 'Ne poveži s sliko';
+$lang['js']['medialeft'] = 'Poravnaj sliko na levo.';
+$lang['js']['mediaright'] = 'Poravnaj sliko na desno.';
+$lang['js']['mediacenter'] = 'Poravnaj sliko na sredini.';
+$lang['js']['medianoalign'] = 'Ne uporabi poravnave.';
+$lang['js']['nosmblinks'] = 'Povezovanje do souporabnih datotek sistema Windows deluje le pri uporabi brskalnika Microsoft Internet Explorer. Povezavo je mogoče kopirati ročno.';
+$lang['js']['linkwiz'] = 'Čarovnik za povezave';
+$lang['js']['linkto'] = 'Poveži na:';
+$lang['js']['del_confirm'] = 'Ali naj se res izbrišejo izbrani predmeti?';
+$lang['js']['restore_confirm'] = 'Ali naj se koda obnovi na to različico?';
+$lang['js']['media_diff'] = 'Razlike:';
+$lang['js']['media_diff_both'] = 'Eno ob drugem';
+$lang['js']['media_diff_opacity'] = 'Prosojno';
+$lang['js']['media_select'] = 'Izbor datotek ...';
+$lang['js']['media_upload_btn'] = 'Naloži';
+$lang['js']['media_done_btn'] = 'Končano';
+$lang['js']['media_drop'] = 'Spusti datoteke za nalaganje.';
+$lang['js']['media_cancel'] = 'odstrani';
+$lang['js']['media_overwrt'] = 'Prepiši obstoječe datoteke';
+$lang['rssfailed'] = 'Prišlo je do napake med pridobivanjem vira: ';
+$lang['nothingfound'] = 'Ni najdenih predmetov.';
+$lang['mediaselect'] = 'Predstavne datoteke';
+$lang['fileupload'] = 'Pošiljanje predstavnih datotek';
+$lang['uploadsucc'] = 'Pošiljanje je bilo uspešno končano.';
+$lang['uploadfail'] = 'Pošiljanje je spodletelo. Morda so uporabljena neustrezna dovoljenja.';
+$lang['uploadwrong'] = 'Pošiljanje je zavrnjeno. Uporabljena pripona datoteke je prepovedana.';
+$lang['uploadexist'] = 'Datoteka že obstaja. Ni sprememb.';
+$lang['uploadbadcontent'] = 'Poslana datoteka se ne sklada s pripono (%s) datoteke.';
+$lang['uploadspam'] = 'Pošiljanje je bilo ustavljeno na podlagi zapisa na črnem seznamu neželenih datotek.';
+$lang['uploadxss'] = 'Pošiljanje je zaustavljeno zaradi morebitne zlonamerne vsebine.';
+$lang['uploadsize'] = 'poslana datoteka prevelika (največja dovoljena velikost je %s).';
+$lang['deletesucc'] = 'Datoteka "%s" je izbrisana.';
+$lang['deletefail'] = 'Datoteke "%s" ni mogoče izbrisati - preverite uporabniška dovoljenja.';
+$lang['mediainuse'] = 'Datoteka "%s" ni izbrisana - datoteka je še vedno v uporabi.';
+$lang['namespaces'] = 'Imenski prostori';
+$lang['mediafiles'] = 'Datoteke, ki so na voljo v';
+$lang['accessdenied'] = 'Za ogled te strani so zahtevana posebna dovoljenja.';
+$lang['mediausage'] = 'Za navajanje datoteke je treba uporabiti navedeno skladnjo:';
+$lang['mediaview'] = 'Pogled izvorne datoteke';
+$lang['mediaroot'] = 'koren';
+$lang['mediaupload'] = 'Pošiljanje datoteke v trenutni imenski prostor. Za ustvarjanje novih imenskih prostorov, jih pripnite k imenu datoteke navedene pri vnosnem polju "Naloži kot" in jih ločite z dvopičjem.';
+$lang['mediaextchange'] = 'Pripona datoteke je spremenjena iz .%s v .%s!';
+$lang['reference'] = 'Sklic za';
+$lang['ref_inuse'] = 'Datoteke ni mogoče izbrisati, saj je še vedno povezana s stranmi:';
+$lang['ref_hidden'] = 'Nekaj sklicev je navedenih na straneh, do katerih s trenutnimi dovoljenji ni mogoč dostop.';
+$lang['hits'] = 'Zadetki';
+$lang['quickhits'] = 'Ujemanje imen strani';
+$lang['toc'] = 'Kazalo';
+$lang['current'] = 'Trenutna';
+$lang['yours'] = 'Vaša različica';
+$lang['diff'] = 'Pokaži razlike s trenutno različico';
+$lang['diff2'] = 'Pokaži razlike med izbranimi različicami.';
+$lang['difflink'] = 'Poveži s tem pogledom primerjave.';
+$lang['diff_type'] = 'Razlike:';
+$lang['diff_inline'] = 'V besedilu';
+$lang['diff_side'] = 'Eno ob drugem';
+$lang['line'] = 'Vrstica';
+$lang['breadcrumb'] = 'Sled';
+$lang['youarehere'] = 'Trenutno dejavna stran';
+$lang['lastmod'] = 'Zadnja sprememba';
+$lang['by'] = 'uporabnika';
+$lang['deleted'] = 'odstranjena';
+$lang['created'] = 'ustvarjena';
+$lang['restored'] = 'povrnjena stara različica';
+$lang['external_edit'] = 'urejanje v zunanjem urejevalniku';
+$lang['summary'] = 'Povzetek urejanja';
+$lang['noflash'] = 'Za prikaz vsebine je treba namestiti <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>';
+$lang['download'] = 'Naloži izrezek';
+$lang['tools'] = 'Orodja';
+$lang['user_tools'] = 'Uporabniška orodja';
+$lang['site_tools'] = 'Orodja spletišča';
+$lang['page_tools'] = 'Orodja strani';
+$lang['skip_to_content'] = 'preskoči na vsebino';
+$lang['mail_newpage'] = '[DokuWiki] stran dodana:';
+$lang['mail_changed'] = '[DokuWiki] stran spremenjena:';
+$lang['mail_subscribe_list'] = 'strani s spremenjenim imenom:';
+$lang['mail_new_user'] = 'nov uporabnik:';
+$lang['mail_upload'] = 'naložena datoteka:';
+$lang['changes_type'] = 'Poglej spremembe';
+$lang['pages_changes'] = 'Strani';
+$lang['media_changes'] = 'Predstavne datoteke';
+$lang['both_changes'] = 'Strani in predstavne datoteke';
+$lang['qb_bold'] = 'Krepko besedilo';
+$lang['qb_italic'] = 'Ležeče besedilo';
+$lang['qb_underl'] = 'Podčrtano besedilo';
+$lang['qb_code'] = 'Oznaka kode';
+$lang['qb_strike'] = 'Prečrtano besedilo';
+$lang['qb_h1'] = 'Naslov prve ravni';
+$lang['qb_h2'] = 'Naslov druge ravni';
+$lang['qb_h3'] = 'Naslov tretje ravni';
+$lang['qb_h4'] = 'Naslov četrte ravni';
+$lang['qb_h5'] = 'Naslov pete ravni';
+$lang['qb_h'] = 'Naslov';
+$lang['qb_hs'] = 'Izberi naslov';
+$lang['qb_hplus'] = 'Naslov na višji ravni';
+$lang['qb_hminus'] = 'Naslov na nižji ravni';
+$lang['qb_hequal'] = 'Naslov na isti ravni';
+$lang['qb_link'] = 'Notranja povezava';
+$lang['qb_extlink'] = 'Zunanja povezava';
+$lang['qb_hr'] = 'Vodoravna črta';
+$lang['qb_ol'] = 'Številčna oznaka predmeta';
+$lang['qb_ul'] = 'Vrstična oznaka predmeta';
+$lang['qb_media'] = 'Dodajanje slik in drugih datotek';
+$lang['qb_sig'] = 'Vstavi podpis';
+$lang['qb_smileys'] = 'Smeški';
+$lang['qb_chars'] = 'Posebni znaki';
+$lang['upperns'] = 'skoči na nadrejeni imenski prostor';
+$lang['admin_register'] = 'Dodaj novega uporabnika';
+$lang['metaedit'] = 'Uredi metapodatke';
+$lang['metasaveerr'] = 'Zapisovanje metapodatkov je spodletelo';
+$lang['metasaveok'] = 'Metapodatki so shranjeni';
+$lang['img_backto'] = 'Nazaj na';
+$lang['img_title'] = 'Naslov';
+$lang['img_caption'] = 'Opis';
+$lang['img_date'] = 'Datum';
+$lang['img_fname'] = 'Ime datoteke';
+$lang['img_fsize'] = 'Velikost';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Avtorska pravica';
+$lang['img_format'] = 'Zapis';
+$lang['img_camera'] = 'Fotoaparat';
+$lang['img_keywords'] = 'Ključne besede';
+$lang['img_width'] = 'Širina';
+$lang['img_height'] = 'Višina';
+$lang['img_manager'] = 'Poglej v urejevalniku predstavnih vsebin';
+$lang['subscr_subscribe_success'] = 'Uporabniški račun %s je dodan na seznam naročnin na %s';
+$lang['subscr_subscribe_error'] = 'Napaka med dodajanjem %s na seznam naročnin na %s';
+$lang['subscr_subscribe_noaddress'] = 'S trenutnimi prijavnimi podatki ni povezanega elektronskega naslova, zato uporabniškega računa ni mogoče dodati na seznam naročnikov.';
+$lang['subscr_unsubscribe_success'] = 'Uporabniški račun %s je odstranjen s seznama naročnin na %s';
+$lang['subscr_unsubscribe_error'] = 'Napaka med odstranjevanjem %s s seznama naročnin na %s';
+$lang['subscr_already_subscribed'] = '%s je že naročen na %s';
+$lang['subscr_not_subscribed'] = '%s ni naročen na %s';
+$lang['subscr_m_not_subscribed'] = 'Trenutni uporabniški račun nima prijavljene naročnine na trenutno stran ali imenski prostor.';
+$lang['subscr_m_new_header'] = 'Naročanje';
+$lang['subscr_m_current_header'] = 'Trenutne naročnine';
+$lang['subscr_m_unsubscribe'] = 'Prekliči naročnino';
+$lang['subscr_m_subscribe'] = 'Prijavi naročnino';
+$lang['subscr_m_receive'] = 'Prejmi';
+$lang['subscr_style_every'] = 'elektronsko sporočilo ob vsaki spremembi';
+$lang['subscr_style_digest'] = 'strnjeno elektronsko sporočilo sprememb za vsako stran (vsakih %.2f dni)';
+$lang['subscr_style_list'] = 'seznam spremenjenih strani od zadnjega elektronskega sporočila (vsakih %.2f dni)';
+$lang['authmodfailed'] = 'Slaba nastavitev overitve uporabniškega računa. Stopite v stik s skrbnikom sistema wiki.';
+$lang['authtempfail'] = 'Potrditev uporabnika je trenutno nedostopna. Stopite v stik s skrbnikom sistema wiki.';
+$lang['i_chooselang'] = 'Izberite jezik';
+$lang['i_installer'] = 'DokuWiki namestitev';
+$lang['i_wikiname'] = 'Ime Wiki spletišča';
+$lang['i_enableacl'] = 'Omogoči ACL (priporočeno)';
+$lang['i_superuser'] = 'Skrbnik';
+$lang['i_problems'] = 'Namestilnik je naletel na težave, ki so izpisane spodaj. Namestitve ni mogoče nadaljevati, dokler težave ne bodo odpravljene.';
+$lang['i_modified'] = 'Iz varnostnih razlogov skript deluje le v novi in neprilagojeni namestitvi sistema DokuWiki. Postopek namestitve je treba začeti znova ali pa sistem namestiti ročno s pomočjo <a href="http://dokuwiki.org/install">navodil nameščanja Dokuwiki</a>.';
+$lang['i_funcna'] = 'Funkcija PHP <code>%s</code> ni na voljo. Morda je možnost na strežniku zaradi varnostnih razlogov onemogočena.';
+$lang['i_phpver'] = 'Različica PHP <code>%s</code> je nižja od zahtevane različice <code>%s</code>. Pred nadaljevanjem je treba posodobiti namestitev PHP.';
+$lang['i_permfail'] = 'Predmet <code>%s</code> ni zapisljiv. Zahtevana je sprememba dovoljenj za to mapo.';
+$lang['i_confexists'] = 'Predmet <code>%s</code> že obstaja.';
+$lang['i_writeerr'] = 'Ni mogoče ustvariti predmeta <code>%s</code>. Preveriti je treba dovoljenja datotek in map in nato ustvariti datoteko ročno.';
+$lang['i_badhash'] = 'nepoznana ali spremenjena datoteka dokuwiki.php (razpršilo=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - neveljavna ali prazna vrednost';
+$lang['i_success'] = 'Nastavitev je uspešno končana. Datoteko install.php lahko sedaj izbrišete. Nadaljujte v <a href="doku.php">novi DokuWiki</a>.';
+$lang['i_failure'] = 'Med zapisovanjem nastavitvenih datotek je prišlo do napak. Preden lahko uporabite vaš <a href="doku.php">DokuWiki</a>, jih je treba odpraviti.';
+$lang['i_policy'] = 'Začetna določila ACL';
+$lang['i_pol0'] = 'Odprt Wiki (branje, zapis, nalaganje datotek je javno za vse)';
+$lang['i_pol1'] = 'Javni Wiki (branje za vse, zapis in nalaganje datotek za prijavljene uporabnike)';
+$lang['i_pol2'] = 'Zaprt Wiki (berejo in urejajo lahko le prijavljeni uporabniki)';
+$lang['i_retry'] = 'Ponovni poskus';
+$lang['i_license'] = 'Izbor dovoljenja objave vsebine:';
+$lang['recent_global'] = 'Trenutno so prikazane spremembe znotraj imenskega prostora <b>%s</b>. Mogoče si je ogledati tudi spremembe <a href="%s">celotnega sistema Wiki</a>.';
+$lang['years'] = '%d let nazaj';
+$lang['months'] = '%d mesecev nazaj';
+$lang['weeks'] = '%d tednov nazaj';
+$lang['days'] = '%d dni nazaj';
+$lang['hours'] = '%d ur nazaj';
+$lang['minutes'] = '%d minut nazaj';
+$lang['seconds'] = '%d sekund nazaj';
+$lang['wordblock'] = 'Spremembe niso shranjene, ker je v vsebini navedeno neželeno besedilo (spam).';
+$lang['media_uploadtab'] = 'Naloži';
+$lang['media_searchtab'] = 'Poišči';
+$lang['media_file'] = 'Datoteka';
+$lang['media_viewtab'] = 'Pogled';
+$lang['media_edittab'] = 'Uredi';
+$lang['media_historytab'] = 'Zgodovina';
+$lang['media_list_thumbs'] = 'Sličice';
+$lang['media_list_rows'] = 'Vrstice';
+$lang['media_sort_name'] = 'Ime';
+$lang['media_sort_date'] = 'Datum';
+$lang['media_namespaces'] = 'Izbor imenskega prostora';
+$lang['media_files'] = 'Datoteke v %s';
+$lang['media_upload'] = 'Naloži v %s';
+$lang['media_search'] = 'Poišči v %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s pri %s';
+$lang['media_edit'] = 'Uredi %s';
+$lang['media_history'] = 'Zgodovina %s';
+$lang['media_meta_edited'] = 'metapodatki so urejeni';
+$lang['media_perm_read'] = 'Ni ustreznih dovoljenj za branje datotek.';
+$lang['media_perm_upload'] = 'Ni ustreznih dovoljenj za nalaganje datotek.';
+$lang['media_update'] = 'Naloži novo različico';
+$lang['media_restore'] = 'Obnovi to različico';
+$lang['plugin_install_err'] = 'Vstavek ni pravilno nameščen. Preimenujte mapo vstavka\'%s\' v \'%s\'.';
diff --git a/inc/lang/sl/locked.txt b/inc/lang/sl/locked.txt
new file mode 100644
index 000000000..cc693d3fa
--- /dev/null
+++ b/inc/lang/sl/locked.txt
@@ -0,0 +1,3 @@
+====== Stran je zaklenjena ======
+
+Stran je zaklenjena za urejanje. Počakati je treba, da zaklep strani poteče.
diff --git a/inc/lang/sl/login.txt b/inc/lang/sl/login.txt
new file mode 100644
index 000000000..eeae0c96c
--- /dev/null
+++ b/inc/lang/sl/login.txt
@@ -0,0 +1,3 @@
+====== Prijava ======
+
+Niste prijavljeni! Spodaj vnesite ustrezne podatke in se prijavite. Prijaviti se je mogoče le, če so omogočeni piškotki.
diff --git a/inc/lang/sl/mailtext.txt b/inc/lang/sl/mailtext.txt
new file mode 100644
index 000000000..e08d01d9e
--- /dev/null
+++ b/inc/lang/sl/mailtext.txt
@@ -0,0 +1,15 @@
+Stran na vašem DokuWiki je bila dodana ali spremenjena. Podrobnosti:
+
+Datum : @DATE@
+Brskalnik : @BROWSER@
+Naslov IP : @IPADDRESS@
+Ime gostitelja : @HOSTNAME@
+Stara različica : @OLDPAGE@
+Nova različica : @NEWPAGE@
+Povzetek urejanja: @SUMMARY@
+Uporabnik : @USER@
+
+@DIFF@
+
+--
+Sporočilo je samodejno ustvarjeno na spletišču @DOKUWIKIURL@
diff --git a/inc/lang/sl/newpage.txt b/inc/lang/sl/newpage.txt
new file mode 100644
index 000000000..2f11bbf55
--- /dev/null
+++ b/inc/lang/sl/newpage.txt
@@ -0,0 +1,3 @@
+====== Stran še ne obstaja ======
+
+Sledili ste povezavi na stran, ki še ne obstaja. Stran je mogoče ustvariti preko povezave ''Ustvari stran''.
diff --git a/inc/lang/sl/norev.txt b/inc/lang/sl/norev.txt
new file mode 100644
index 000000000..adaa22d11
--- /dev/null
+++ b/inc/lang/sl/norev.txt
@@ -0,0 +1,3 @@
+====== Neobstoječa različica strani ======
+
+Zahtevana različica strani ne obstaja. Uporabite gumb ''Stare različice'' za izpis seznama starih različic tega dokumenta.
diff --git a/inc/lang/sl/password.txt b/inc/lang/sl/password.txt
new file mode 100644
index 000000000..61929dccd
--- /dev/null
+++ b/inc/lang/sl/password.txt
@@ -0,0 +1,9 @@
+Pozdravljeni, @FULLNAME@!
+
+Spodaj so navedeni podatki za @TITLE@ na wiki spletišču @DOKUWIKIURL@
+
+Uporabniško ime: @LOGIN@
+Geslo : @PASSWORD@
+
+--
+Sporočilo je samodejno ustvarjeno na spletišču @DOKUWIKIURL@
diff --git a/inc/lang/sl/preview.txt b/inc/lang/sl/preview.txt
new file mode 100644
index 000000000..c49de6617
--- /dev/null
+++ b/inc/lang/sl/preview.txt
@@ -0,0 +1,3 @@
+====== Predogled ======
+
+Prikazan je predogled strani. Stran še ni shranjena!
diff --git a/inc/lang/sl/pwconfirm.txt b/inc/lang/sl/pwconfirm.txt
new file mode 100644
index 000000000..a621821e5
--- /dev/null
+++ b/inc/lang/sl/pwconfirm.txt
@@ -0,0 +1,11 @@
+Pozdravljeni, @FULLNAME@!
+
+S podatki vašega imena je bila poslana zahteva za pridobitev novega gesla za uporabniško ime @TITLE@ na wiki spletišču @DOKUWIKIURL@.
+
+ - V kolikor novega gesla niste zahtevali, prezrite to sporočilo.
+ - Za potrditev zahteve za pridobitev novega gesla, kliknite spodnjo povezavo.
+
+@CONFIRM@
+
+--
+Sporočilo je samodejno ustvarjeno na spletišču @DOKUWIKIURL@
diff --git a/inc/lang/sl/read.txt b/inc/lang/sl/read.txt
new file mode 100644
index 000000000..5ba9a2eb0
--- /dev/null
+++ b/inc/lang/sl/read.txt
@@ -0,0 +1,2 @@
+Stran je odprta z dovoljenji le za branje. Dovoljeno je ogledati si izvorno kodo strani, vsebine pa ni mogoče spreminjati. Za več podrobnosti stopite v stik s skrbnikom sistema.
+
diff --git a/inc/lang/sl/recent.txt b/inc/lang/sl/recent.txt
new file mode 100644
index 000000000..282a492be
--- /dev/null
+++ b/inc/lang/sl/recent.txt
@@ -0,0 +1,3 @@
+====== Nedavne spremembe ======
+
+Izpisane wiki strani so bile nedavno spremenjene.
diff --git a/inc/lang/sl/register.txt b/inc/lang/sl/register.txt
new file mode 100644
index 000000000..f1b22f933
--- /dev/null
+++ b/inc/lang/sl/register.txt
@@ -0,0 +1,3 @@
+====== Vpis novega računa ======
+
+V spodnji obrazec je treba vnesti vse zahtevane podatke za ustvarjanje novega računa. Vnesti je treba veljaven **elektronski naslov**, na katerega bo poslano geslo. Uporabniško ime mora biti veljavno [[doku>pagename|ime strani]].
diff --git a/inc/lang/sl/registermail.txt b/inc/lang/sl/registermail.txt
new file mode 100644
index 000000000..801b7d0db
--- /dev/null
+++ b/inc/lang/sl/registermail.txt
@@ -0,0 +1,14 @@
+Nov uporabniški račun je uspešno vpisan.
+Podatki računa:
+
+Uporabniško ime : @NEWUSER@
+Polno ime : @NEWNAME@
+Elektronski naslov: @NEWEMAIL@
+
+Datum : @DATE@
+Brskalnik : @BROWSER@
+Naslov IP : @IPADDRESS@
+Ime gostitelja : @HOSTNAME@
+
+--
+Sporočilo je samodejno ustvarjeno na spletišču @DOKUWIKIURL@
diff --git a/inc/lang/sl/resendpwd.txt b/inc/lang/sl/resendpwd.txt
new file mode 100644
index 000000000..8a1e614f7
--- /dev/null
+++ b/inc/lang/sl/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Pošiljanje novega gesla ======
+
+Za pridobitev novega gesla, vnesite vaše uporabniško ime ustrezno polje spodnjega obrazca. Na naveden elektronski naslov bo poslano sporočilo v katerem bo navedena povezava do strani za overjanje istovetnosti uporabnika.
diff --git a/inc/lang/sl/revisions.txt b/inc/lang/sl/revisions.txt
new file mode 100644
index 000000000..86ede9ded
--- /dev/null
+++ b/inc/lang/sl/revisions.txt
@@ -0,0 +1,3 @@
+====== Stare različice ======
+
+Prikazana je stara različica tega dokumenta. Stran je mogoče povrniti na starejšo različico tako, da stran izberete, pritisnete na povezavo ''Uredi stran'' in stran nato shranite.
diff --git a/inc/lang/sl/searchpage.txt b/inc/lang/sl/searchpage.txt
new file mode 100644
index 000000000..736a36182
--- /dev/null
+++ b/inc/lang/sl/searchpage.txt
@@ -0,0 +1,5 @@
+====== Iskanje ======
+
+Spodaj so izpisani rezultati iskanja. V kolikor rezultati niso skladni z zahtevami iskanja, je mogoče ustvariti novo stran z nazivom vaše poizvedbe preko povezave ''Uredi stran''.
+
+===== Rezultati ===== \ No newline at end of file
diff --git a/inc/lang/sl/showrev.txt b/inc/lang/sl/showrev.txt
new file mode 100644
index 000000000..838339217
--- /dev/null
+++ b/inc/lang/sl/showrev.txt
@@ -0,0 +1,2 @@
+**Stara različica tega dokumenta!**
+----
diff --git a/inc/lang/sl/stopwords.txt b/inc/lang/sl/stopwords.txt
new file mode 100644
index 000000000..8eed2daa6
--- /dev/null
+++ b/inc/lang/sl/stopwords.txt
@@ -0,0 +1,18 @@
+# To je seznam besed, ki jih ustvarjalnik kazala prezre. Seznam je sestavljen iz
+# besede, ki so zapisane vsaka v svoji vrstici. Datoteka mora biti zapisana s končnim
+# UNIX znakom vrstice. Besede krajše od treh znakov so iz kazala izločene samodejno
+# zaradi preglednosti. Seznam se s bo s časom spreminjal in dopolnjeval.
+moja
+moje
+moji
+mojo
+njegovi
+njegove
+njegovo
+njeno
+njeni
+njene
+njihova
+njihove
+njihovi
+njihovo
diff --git a/inc/lang/sl/subscr_digest.txt b/inc/lang/sl/subscr_digest.txt
new file mode 100644
index 000000000..aeb548beb
--- /dev/null
+++ b/inc/lang/sl/subscr_digest.txt
@@ -0,0 +1,19 @@
+Pozdravljeni!
+
+Strani v imenskem prostoru @PAGE@ wiki spletišča @TITLE@ so spremenjene.
+Podrobnosti sprememb so navedene spodaj.
+
+------------------------------------------------
+@DIFF@
+------------------------------------------------
+
+Stara različica: @OLDPAGE@
+Nova različica : @NEWPAGE@
+
+Za odjavo prejemanja podrobnosti sprememb, se je treba prijaviti na spletišče
+@DOKUWIKIURL@ in med možnostmi naročanja
+@SUBSCRIBE@
+odjaviti prejemanje poročil sprememb strani ali imenskega prostora.
+
+--
+Sporočilo je samodejno ustvarjeno na spletišču @DOKUWIKIURL@
diff --git a/inc/lang/sl/subscr_form.txt b/inc/lang/sl/subscr_form.txt
new file mode 100644
index 000000000..46be8c954
--- /dev/null
+++ b/inc/lang/sl/subscr_form.txt
@@ -0,0 +1,3 @@
+===== Urejanje naročnin ====
+
+Ta stran vam omogoča urejanje vaših naročnin za trenutno stran in imenski prostor. \ No newline at end of file
diff --git a/inc/lang/sl/subscr_list.txt b/inc/lang/sl/subscr_list.txt
new file mode 100644
index 000000000..253cb4104
--- /dev/null
+++ b/inc/lang/sl/subscr_list.txt
@@ -0,0 +1,16 @@
+Pozdravljeni!
+
+Strani v imenskem prostoru @PAGE@ wiki spletišča @TITLE@ so spremenjene.
+Podrobnosti sprememb so navedene spodaj.
+
+------------------------------------------------
+@DIFF@
+------------------------------------------------
+
+Za odjavo prejemanja podrobnosti sprememb, se je treba prijaviti na spletišče
+@DOKUWIKIURL@ in med možnostmi naročanja
+@SUBSCRIBE@
+odjaviti prejemanje poročil sprememb strani ali imenskega prostora.
+
+--
+Sporočilo je samodejno ustvarjeno na spletišču @DOKUWIKIURL@
diff --git a/inc/lang/sl/subscr_single.txt b/inc/lang/sl/subscr_single.txt
new file mode 100644
index 000000000..9fd64be0e
--- /dev/null
+++ b/inc/lang/sl/subscr_single.txt
@@ -0,0 +1,22 @@
+Pozdravljeni!
+
+Stran @PAGE@ na spletišču Wiki @TITLE@ je spremenjena.
+Spremenjeno je:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Datum : @DATE@
+Uporabnik : @USER@
+Povzetek urejanja: @SUMMARY@
+Stara različica : @OLDPAGE@
+Nova različica : @NEWPAGE@
+
+Preklic obveščanja o spremembah strani je mogoče določiti
+na Wiki naslovu @DOKUWIKIURL@ in z obiskom @NEWPAGE@,
+kjer se je mogoče odjaviti od spremljanja strani ali
+imenskega prostora.
+
+--
+Sporočilo je samodejno ustvarjeno na spletišču @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sl/updateprofile.txt b/inc/lang/sl/updateprofile.txt
new file mode 100644
index 000000000..5e939f2f2
--- /dev/null
+++ b/inc/lang/sl/updateprofile.txt
@@ -0,0 +1,3 @@
+===== Posodabljanje računa =====
+
+Posodobiti ali spremeniti je mogoče le nekatere podatke. Uporabniškega imena ni mogoče spremeniti. \ No newline at end of file
diff --git a/inc/lang/sl/uploadmail.txt b/inc/lang/sl/uploadmail.txt
new file mode 100644
index 000000000..0479be75f
--- /dev/null
+++ b/inc/lang/sl/uploadmail.txt
@@ -0,0 +1,14 @@
+Datoteka je bila uspešno naložena na DokuWiki spletišče.
+Podrobnosti o datoteki:
+
+Datoteka : @MEDIA@
+Datum : @DATE@
+Brskalnik : @BROWSER@
+Naslov IP : @IPADDRESS@
+Ponudnik : @HOSTNAME@
+Velikost : @SIZE@
+Vrsta MIME: @MIME@
+Uporabnik : @USER@
+
+--
+Sporočilo je samodejno ustvarjeno na spletišču @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sq/admin.txt b/inc/lang/sq/admin.txt
new file mode 100644
index 000000000..6edbf8a19
--- /dev/null
+++ b/inc/lang/sq/admin.txt
@@ -0,0 +1,3 @@
+====== Administrimi ======
+
+Poshtë është një listë e punëve administrative të disponueshme në DokuWiki. \ No newline at end of file
diff --git a/inc/lang/sq/adminplugins.txt b/inc/lang/sq/adminplugins.txt
new file mode 100644
index 000000000..f87626c8e
--- /dev/null
+++ b/inc/lang/sq/adminplugins.txt
@@ -0,0 +1 @@
+===== Plugin-e Shtesë ===== \ No newline at end of file
diff --git a/inc/lang/sq/backlinks.txt b/inc/lang/sq/backlinks.txt
new file mode 100644
index 000000000..b25df00be
--- /dev/null
+++ b/inc/lang/sq/backlinks.txt
@@ -0,0 +1,3 @@
+====== Linke të kthyeshëm ======
+
+Kjo është një listë e faqeve që duket se lidhen mbrapsht te kjo faqe aktuale. \ No newline at end of file
diff --git a/inc/lang/sq/conflict.txt b/inc/lang/sq/conflict.txt
new file mode 100644
index 000000000..9c6cc940d
--- /dev/null
+++ b/inc/lang/sq/conflict.txt
@@ -0,0 +1,5 @@
+====== Ekziston një version më i ri ======
+
+Ekziston një version më i ri i dokumentit që ju redaktuat. Kjo ndodh kur një përdorues tjetër e ndryshoi dokumentin ndërkohë që ju po e redaktonit atë.
+
+Gjeni ndryshimet e treguara më poshtë dhe pastaj vendosni se kë version doni të mbani. Nëse zgjidhni "ruaj", versioni juaj do të ruhet. Klikon "fshi" për të mbajtur versioni aktual. \ No newline at end of file
diff --git a/inc/lang/sq/denied.txt b/inc/lang/sq/denied.txt
new file mode 100644
index 000000000..03e10527f
--- /dev/null
+++ b/inc/lang/sq/denied.txt
@@ -0,0 +1,3 @@
+====== Leja Refuzohet ======
+
+Na vjen keq, ju nuk keni të drejta të mjaftueshme për të vazhduar. Mbase harruat të hyni? \ No newline at end of file
diff --git a/inc/lang/sq/diff.txt b/inc/lang/sq/diff.txt
new file mode 100644
index 000000000..ab03a283f
--- /dev/null
+++ b/inc/lang/sq/diff.txt
@@ -0,0 +1,3 @@
+====== Ndryshimet ======
+
+Kjo tregon ndryshimet midis dy versioneve të faqes. \ No newline at end of file
diff --git a/inc/lang/sq/draft.txt b/inc/lang/sq/draft.txt
new file mode 100644
index 000000000..80634a780
--- /dev/null
+++ b/inc/lang/sq/draft.txt
@@ -0,0 +1,5 @@
+====== Skedari skicë u gjend ======
+
+Sesioni juaj i fundit i redaktimit në këtë faqe nuk përfundoi me sukses. DokuWiki ruajti automatikisht një skicë gjatë punës tuaj të cilën mund ta përdorni tani për të vazhduar redaktimin tuaj. Më poshtë mund të shihni të dhënat që janë ruajtur nga sesioni juaj i fundit.
+
+Ju lutem vendosni nëse doni të //rekuperoni// sesionin tuaj të humbur të redaktimit, //fshini// skicën e ruajtur automatikisht ose //dilni// nga proçesi i redaktimit. \ No newline at end of file
diff --git a/inc/lang/sq/edit.txt b/inc/lang/sq/edit.txt
new file mode 100644
index 000000000..1f038ead7
--- /dev/null
+++ b/inc/lang/sq/edit.txt
@@ -0,0 +1 @@
+Redaktoni faqen dhe shtypni "Ruaj". Shikoni [[wiki:syntax]] për sintaksën e Wiki-t. Nëse doni të provoni disa gjëra, mësoni të hidhni hapat e parë në [[playground:playground|playground]]. \ No newline at end of file
diff --git a/inc/lang/sq/editrev.txt b/inc/lang/sq/editrev.txt
new file mode 100644
index 000000000..08792eafb
--- /dev/null
+++ b/inc/lang/sq/editrev.txt
@@ -0,0 +1,2 @@
+**Keni ngarkuar një rishikim të vjetër të dokumentit!** Nëse e ruani, do të krijoni një version të ri me këto të dhëna.
+---- \ No newline at end of file
diff --git a/inc/lang/sq/index.txt b/inc/lang/sq/index.txt
new file mode 100644
index 000000000..6daef1c30
--- /dev/null
+++ b/inc/lang/sq/index.txt
@@ -0,0 +1,3 @@
+====== Index ======
+
+Ky është një index mbi të gjitha faqet e disponueshme të renditura sipas [[doku>namespaces|namespaces]]. \ No newline at end of file
diff --git a/inc/lang/sq/install.html b/inc/lang/sq/install.html
new file mode 100644
index 000000000..f9f69f473
--- /dev/null
+++ b/inc/lang/sq/install.html
@@ -0,0 +1,8 @@
+<p>Kjo faqe ndihmon në instalimin dhe konfigurimin për herë të parë të <a href="http://dokuwiki.org">Dokuwiki-t</a>. Më shumë informacion mbi këtë installer gjendet në <a href="http://dokuwiki.org/installer">faqen e tij të dokumentimit</a>.</p>
+
+<p>Dokuwiki përdor skedarë të zakonshëm për ruajtjen e faqeve wiki dhe informacioneve të tjera të lidhura me ato faqe (psh imazhe, indekse kërkimi, rishikime të vjetra etj). Në mënyrë që të funksionojë me sukses DokuWiki <strong>duhet</strong> të ketë akses shkrimi mbi direktoritë që mbajnë këto skedarë. Ky installer nuk është në gjendje të vendosë leje mbi direktoritë. Kjo normalisht duhet bërë drejtpërdrejt nga një command shell ose nëse jeni duke përdorur hostimin, nëpërmjet FTP ose panelit të kontrollit të hostit (psh cPanel).</p>
+
+<p>Ky installer do të instalojë konfigurimin e DokuWiki-t tuaj
+për <acronym title="access control list">ACL</acronym>, që në këmbim lejon hyrje si administrator dhe akses të menusë së administrimit të DokuWiki-t për të instaluar plugin-e, menaxhuar përdoruesit, menaxhuar akses në faqet wiki dhe ndryshim të konfigurimeve. Nuk është e domosdoshme për DokuWiki-n të funksionojë, megjithatë do ta bëjë DokuWiki-n më të lehtë për tu administruar.</p>
+
+<p>Përduruesit me përvojë ose përdoruesit me kërkesa speciale për instalim duhet të përdorin këto linke për detaje mbi <a href="http://dokuwiki.org/install">instruksionet e instalimit</a> dhe <a href="http://dokuwiki.org/config">konfigurimeve</a>.</p> \ No newline at end of file
diff --git a/inc/lang/sq/lang.php b/inc/lang/sq/lang.php
new file mode 100644
index 000000000..569256b52
--- /dev/null
+++ b/inc/lang/sq/lang.php
@@ -0,0 +1,242 @@
+<?php
+/**
+ * sq language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesSq.php?view=co
+ * @author Leonard Elezi <leonard.elezi@depinfo.info>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '"';
+$lang['doublequoteclosing'] = '"';
+$lang['singlequoteopening'] = '\'';
+$lang['singlequoteclosing'] = '\'';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Redaktoni këtë faqe';
+$lang['btn_source'] = 'Trego kodin burim të faqes';
+$lang['btn_show'] = 'Trego faqen';
+$lang['btn_create'] = 'Krijo këtë faqe';
+$lang['btn_search'] = 'Kërko';
+$lang['btn_save'] = 'Ruaj';
+$lang['btn_preview'] = 'Shikim paraprak';
+$lang['btn_top'] = 'Kthehu ne krye';
+$lang['btn_newer'] = '<< më të hershme';
+$lang['btn_older'] = 'më të vonshme';
+$lang['btn_revs'] = 'Shqyrtime të vjetra';
+$lang['btn_recent'] = 'Ndryshime së fundmi';
+$lang['btn_upload'] = 'Ngarko';
+$lang['btn_cancel'] = 'Harroji';
+$lang['btn_index'] = 'Kreu';
+$lang['btn_secedit'] = 'Redaktoni';
+$lang['btn_login'] = 'Hyrje';
+$lang['btn_logout'] = 'Dalje';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Përditëso';
+$lang['btn_delete'] = 'Fshi';
+$lang['btn_back'] = 'Mbrapa';
+$lang['btn_backlink'] = 'Lidhjet këtu';
+$lang['btn_backtomedia'] = 'Mbrapa tek Përzgjedhja e Media-ve';
+$lang['btn_subscribe'] = 'Menaxho Abonimet';
+$lang['btn_profile'] = 'Përditëso Profilin';
+$lang['btn_reset'] = 'Rivendos';
+$lang['btn_resendpwd'] = 'Dërgo fjalëkalim të ri';
+$lang['btn_draft'] = 'Redakto skicën';
+$lang['btn_recover'] = 'Rekupero skicën';
+$lang['btn_draftdel'] = 'Fshi skicën';
+$lang['btn_revert'] = 'Kthe si më parë';
+$lang['btn_register'] = 'Regjsitrohuni';
+$lang['loggedinas'] = 'Regjistruar si ';
+$lang['user'] = 'Nofka e përdoruesit:';
+$lang['pass'] = 'Fjalëkalimi';
+$lang['newpass'] = 'Fjalëkalim i ri';
+$lang['oldpass'] = 'Konfirmo fjalëkalimin aktual';
+$lang['passchk'] = 'Edhe një herë';
+$lang['remember'] = 'Më mbaj mend';
+$lang['fullname'] = 'Emri i vërtetë';
+$lang['email'] = 'Adresa e email-it*';
+$lang['profile'] = 'Profili i përdoruesit';
+$lang['badlogin'] = 'Na vjen keq, emri ose fjalëkalimi është gabim.';
+$lang['minoredit'] = 'Ndryshime të Vogla';
+$lang['draftdate'] = 'Skica u ruajt automatikisht në';
+$lang['nosecedit'] = 'Faqja u ndryshua ndëwrkohë, informacioni i kwtij seksioni ishte i vjetër, u ngarkua faqja e tërë në vend të saj.';
+$lang['regmissing'] = 'Na vjen keq, duhet të plotësoni të gjitha fushat.';
+$lang['reguexists'] = 'Na vjen keq, ekziston një përdorues tjetër me të njëjtin emër.';
+$lang['regsuccess'] = 'Përdoruesi u regjistrua dhe fjalëkalimi u dërgua me email.';
+$lang['regsuccess2'] = 'Llogarija e Përdoruesit u krijua';
+$lang['regmailfail'] = 'Duket se ka ndodhur një gabim gjatë dërgimit të fjalëkalimit me e-mail. Ju lutemi kontaktoni administratorin!';
+$lang['regbadmail'] = 'Adresa email e dhënë nuk mund të pranohet sepse nuk duket e rregullt. Ju lutem fusni një adresë të rregullt ose boshatisni kutinë e shtypit.';
+$lang['regbadpass'] = 'Dy fjalëkalimet e dhëna nuk janë njësoj, ju lutemi provoni përsëri.';
+$lang['regpwmail'] = 'Fjalëkalimi juaj i DokuWiki-it.';
+$lang['reghere'] = 'Ende nuk keni llogari? Hap një';
+$lang['profna'] = 'Ky wiki nuk e lejon ndryshimin e profilit.';
+$lang['profnochange'] = 'Asnjë ndryshim, asgjë për të bërë.';
+$lang['profnoempty'] = 'Një emër bosh ose adresë email-i bosh nuk lejohet.';
+$lang['profchanged'] = 'Profili i përdoruesit u përditësua me sukses.';
+$lang['pwdforget'] = 'E harruat fjalëkalimin? Merni një të ri';
+$lang['resendna'] = 'Ky wiki nuk e lejon ridërgimin e fjalëkalimeve.';
+$lang['resendpwd'] = 'Dërgo një fjalëkalim të ri për';
+$lang['resendpwdmissing'] = 'Na vjen keq, duhet t\'i plotësoni të gjitha fushat.';
+$lang['resendpwdnouser'] = 'Na vjen keq, nuk mund ta gjejmë këtë përdorues në bazën tonë të të dhënave.';
+$lang['resendpwdbadauth'] = 'Na vjen keq, ky kod autorizimi nuk është i vlefshëm. Sigurohuni që përdoret linkun e plotë të konfirmimit.';
+$lang['resendpwdconfirm'] = 'U dërgua një link konfirmimi nëpërmjet eMail-it.';
+$lang['resendpwdsuccess'] = 'Fjalëkalimi juaj i ri u dërgua nëpërmjet eMail-it.';
+$lang['license'] = 'Përveç rasteve të përcaktuara, përmbajtja në këtë wiki është e liçnsuar nën liçensën e mëposhtme:';
+$lang['licenseok'] = 'Shënim: Duke redaktuar këtë faqe ju bini dakort të liçensoni përmbajtjen tuaj nën liçensën e mëposhtme:';
+$lang['searchmedia'] = 'Kërko emrin e skedarit:';
+$lang['searchmedia_in'] = 'Kërko në %s';
+$lang['txt_upload'] = 'Zgjidh skedarin për ngarkim';
+$lang['txt_filename'] = 'Ngarko si (alternative)';
+$lang['txt_overwrt'] = 'Zëvendëso skedarin ekzistues';
+$lang['lockedby'] = 'Kyçur momentalisht nga';
+$lang['lockexpire'] = 'Kyçi skadon në';
+$lang['js']['willexpire'] = 'Kyçi juaj për redaktimin e kësaj faqeje është duke skaduar.\nPër të shmangur konflikte përdorni butonin Shiko Paraprakisht për të rivendosur kohën e kyçjes.';
+$lang['js']['notsavedyet'] = "Ndryshimet e paruajtura do të humbasin.\nVazhdo me të vërtetë?";
+$lang['rssfailed'] = 'Ndoshi një gabim gjatë kapjes së këtij lajmi:';
+$lang['nothingfound'] = 'Nuk u gjet asgjë.';
+$lang['mediaselect'] = 'Skedarët e Medias';
+$lang['fileupload'] = 'Ngarkoje';
+$lang['uploadsucc'] = 'Ngarkim i suksesshëm';
+$lang['uploadfail'] = 'Ngarkimi dështoi. Ndoshta leje të gabuara?';
+$lang['uploadwrong'] = 'Ngarkimi u refuzua! Prapashtesa e skedarit është e ndaluar!';
+$lang['uploadexist'] = 'Skedari ekziston. Nuk u bë asgjë.';
+$lang['uploadbadcontent'] = 'Përmbajtja e ngarkimit nuk përkoi me prapshtesën e skedarit %s';
+$lang['uploadspam'] = 'Ngarkimi u bllokua nga lista e zezë e spam-eve.';
+$lang['uploadxss'] = 'Ngarkimi u bllokua për dyshim përmbajtjeje jo të sigurt.';
+$lang['uploadsize'] = 'Skedari i ngarkuar ishte tepër i madh. (maksimumi %s)';
+$lang['deletesucc'] = 'Skedari "%s" u fshi.';
+$lang['deletefail'] = '"%s" nuk mundi të fshihej. Kontrollo lejet.';
+$lang['mediainuse'] = 'Skedari "%s" nuk u fshi - është ende në përdorim.';
+$lang['namespaces'] = 'Hapësirat e Emrave';
+$lang['mediafiles'] = 'Skedarët e disponueshëm në';
+$lang['js']['searchmedia'] = 'Kërko për skedarë';
+$lang['js']['keepopen'] = 'Mbaje dritaren të hapur gjatë përzgjedhjes';
+$lang['js']['hidedetails'] = 'Fshih Detajet';
+$lang['js']['nosmblinks'] = 'Lidhja te Windows shares funksionon vetëm në Microsoft Internet Explorer. Ju prapë mund ta kopjoni dhe ngjitni linkun.';
+$lang['js']['linkwiz'] = 'Magjistari i Link';
+$lang['js']['linkto'] = 'Lidh tek:';
+$lang['js']['del_confirm'] = 'Fshiji vërtetë objektet e përzgjedhura?';
+$lang['mediausage'] = 'Përdor sintaksën e mëposhtme për të referuar këtë skedar:';
+$lang['mediaview'] = 'Shiko skedarin origjinal';
+$lang['mediaroot'] = 'rrënja';
+$lang['mediaupload'] = 'Ngarko një skedar tek hapësira e emrit aktuale këtu. Për të krijuaj nënhapësira emri, bashkangjiti ato pas emrit të skedarit "Ngarko Si" duke e ndarë me dy pika (:).';
+$lang['mediaextchange'] = 'Prapashtesa e skedarit u ndërrua nga .%s në .%s!';
+$lang['reference'] = 'Referenca për:';
+$lang['ref_inuse'] = 'Skedari nuk mund të fshihet, sepse është duke u përdorur ende nga faqet e mëposhtme:';
+$lang['ref_hidden'] = 'Disa referenca janë në faqe të cilat ju nuk keni leje t\'i lexoni.';
+$lang['hits'] = 'Pamje';
+$lang['quickhits'] = 'Emrat e faqeve që përkojnë';
+$lang['toc'] = 'Tabela e Përmbajtjeve';
+$lang['current'] = 'aktuale';
+$lang['yours'] = 'Versioni Juaj';
+$lang['diff'] = 'Trego ndryshimet nga rishikimet aktuale';
+$lang['diff2'] = 'Trego ndryshimet mes rishikimeve të përzgjedhura';
+$lang['line'] = 'Vijë';
+$lang['breadcrumb'] = 'Gjurmë';
+$lang['youarehere'] = 'Ju jeni këtu';
+$lang['lastmod'] = 'Redaktuar për herë të fundit';
+$lang['by'] = 'nga';
+$lang['deleted'] = 'u fshi';
+$lang['created'] = 'u krijua';
+$lang['restored'] = 'Kthehu tek një version i vjetër';
+$lang['external_edit'] = 'redaktim i jashtëm';
+$lang['summary'] = 'Përmbledhja redaktimit';
+$lang['noflash'] = 'Nevojitet <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> për të paraqitur këtë përmbajtje.';
+$lang['download'] = 'Shkarko Copën';
+$lang['mail_newpage'] = 'faqje u shtua:';
+$lang['mail_changed'] = 'faqja u ndryshua:';
+$lang['mail_subscribe_list'] = 'faqet u ndryshuan në hapësirën e emrave:';
+$lang['mail_new_user'] = 'përdorues i ri:';
+$lang['mail_upload'] = 'skedari u ngarkua:';
+$lang['qb_bold'] = 'Tekst i Theksuar';
+$lang['qb_italic'] = 'Tekst i Pjerrët';
+$lang['qb_underl'] = 'Tekst i Nënvijëzuar';
+$lang['qb_code'] = 'Tekst Kodi';
+$lang['qb_strike'] = 'Tekst me Vijë Mespërmes';
+$lang['qb_h1'] = 'Titull me Nivel 1';
+$lang['qb_h2'] = 'Titull me Nivel 2';
+$lang['qb_h3'] = 'Titull me Nivel 3';
+$lang['qb_h4'] = 'Titull me Nivel 4';
+$lang['qb_h5'] = 'Titull me Nivel 5';
+$lang['qb_h'] = 'Titull';
+$lang['qb_hs'] = 'Përzgjidh Titull';
+$lang['qb_hplus'] = 'Titull Më i Lartë';
+$lang['qb_hminus'] = 'Titull Më i Ulët';
+$lang['qb_hequal'] = 'Titull i të Njëjtit Nivel';
+$lang['qb_link'] = 'Lidhje e Brendshme';
+$lang['qb_extlink'] = 'Lidhje e Jashtme ';
+$lang['qb_hr'] = 'Vijë Horizontale';
+$lang['qb_ol'] = 'Listë Objektesh të Renditur';
+$lang['qb_ul'] = 'Listë Objektesh të Parenditura';
+$lang['qb_media'] = 'Shto imazhe dhe skedarë të tjerë';
+$lang['qb_sig'] = 'Fut Firmën';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Karaktere Speciale';
+$lang['upperns'] = 'kërce tek hapësira e emrit prind';
+$lang['admin_register'] = 'Shto Përdorues të Ri';
+$lang['metaedit'] = 'Redakto Metadata';
+$lang['metasaveerr'] = 'Shkrimi i metadata-ve dështoi';
+$lang['metasaveok'] = 'Metadata u ruajt';
+$lang['img_backto'] = 'Mbrapa te';
+$lang['img_title'] = 'Titulli ';
+$lang['img_caption'] = 'Titra';
+$lang['img_date'] = 'Data';
+$lang['img_fname'] = 'Emri Skedarit';
+$lang['img_fsize'] = 'Madhësia';
+$lang['img_artist'] = 'Autor';
+$lang['img_copyr'] = 'Mbajtësi i të drejtave të autorit';
+$lang['img_format'] = 'Formati';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Fjalë Kyçe';
+$lang['subscr_subscribe_success'] = 'Iu shtua %s listës së abonimeve për %s';
+$lang['subscr_subscribe_error'] = 'Gabim gjatë shtimit të %s listës së abonimeve për %s';
+$lang['subscr_subscribe_noaddress'] = 'Nuk ekziston asnjë adresë e lidhur me regjistrimin tuaj, ju nuk mund t\'i shtoheni listës së abonimeve.';
+$lang['subscr_unsubscribe_success'] = 'U hoq %s nga lista e abonimeve për %s';
+$lang['subscr_unsubscribe_error'] = 'Gabim në heqjen e %s nga lista e abonimeve për %s';
+$lang['subscr_already_subscribed'] = '%s është abonuar njëherë te %s';
+$lang['subscr_not_subscribed'] = '%s nuk është abonuar te %s';
+$lang['subscr_m_not_subscribed'] = 'Momentalisht ju nuk jeni i abonuar në faqen aktuale apo hapësirën e emrit aktual.';
+$lang['subscr_m_new_header'] = 'Shto abonim';
+$lang['subscr_m_current_header'] = 'Abonimet aktuale';
+$lang['subscr_m_unsubscribe'] = 'Fshi Abonimin';
+$lang['subscr_m_subscribe'] = 'Abonohu';
+$lang['subscr_m_receive'] = 'Mer';
+$lang['subscr_style_every'] = 'email mbi çdo ndryshim';
+$lang['subscr_style_digest'] = 'pasqyro email-e ndryshimi pér çdo faqe';
+$lang['subscr_style_list'] = 'listë e faqeve të ndryshuara që nga emaili i fundit';
+$lang['authmodfailed'] = 'Konfigurim i gabuar i autentikimit të përdoruesit. Ju lutem informoni Administratorin tuaj të Wiki-it.';
+$lang['authtempfail'] = 'Autentikimi i përdoruesve është përkohësisht i padisponueshëm. Nëse kjo gjendje vazhdon, ju lutemi të informoni Administratorin tuaj të Wiki-it.';
+$lang['i_chooselang'] = 'Zgjidhni gjuhën tuaj';
+$lang['i_installer'] = 'Installer-i DokuWiki';
+$lang['i_wikiname'] = 'Emri Wiki-it';
+$lang['i_enableacl'] = 'Aktivizo ACL (rekomanduar)';
+$lang['i_superuser'] = 'Superpërdorues';
+$lang['i_problems'] = 'Installer-i gjeti disa probleme, të shfaqura më poshtë. Nuk mund të vazhdoni derisa t\'i keni rregulluar.';
+$lang['i_modified'] = 'Për arsye sigurie ky skript do të punojë vetëm me një instalim të ri dhe të pamodifikuar DokuWiki.
+Ose duhet të ekstraktoni skedarët nga e para nga pakoja e shkarkimit ose konsultohuni me <a href="http://dokuwiki.org/install">Dokuwiki installation instructions</a>';
+$lang['i_funcna'] = 'Funksioni PHP <code>%s</code> nuk është i disponueshëm. Mbase siguruesi juaj i host-it e ka çaktivizuar për ndonjë arsye?';
+$lang['i_phpver'] = 'Versioni juaj i PHP <code>%s</code> është më i vogël se ai i duhuri <code>%s</code>. Duhet të përditësoni instalimin tuaj të PHP-së.';
+$lang['i_permfail'] = '<code>%s</code> nuk është e shkruajtshme nga DokuWiki. Duhet të rregulloni lejet e përdorimit për këtë direktori.';
+$lang['i_confexists'] = '<code>%s</code> ekziston njëherë';
+$lang['i_writeerr'] = '<code>%s</code> nuk mundi të krijohej. Duhet të kontrolloni lejet e dirkektorisë/skedarit dhe ta krijoni skedarin manualisht.';
+$lang['i_badhash'] = 'dokuwiki.php e panjohur ose e ndryshuar (hash=code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - vlerë e palejuar ose boshe';
+$lang['i_success'] = 'Konfigurimi u mbarua me sukses. Tani mund ta fshini skedarin install.php. Vazhdoni tek <a href="doku.php">DokuWiki juaj i ri.</a>.';
+$lang['i_failure'] = 'Ndodhën disa gabime gjatë shkrimit të skedarit të konfigurimit. Do t\'ju duhet t\'i rregulloni manualisht para se të përdorni <a href="doku.php">DokuWiki-in tuaj të ri.</a>.';
+$lang['i_policy'] = 'Veprimi fillestar ACL';
+$lang['i_pol0'] = 'Wiki i Hapur (lexim, shkrim, ngarkim për këdo)';
+$lang['i_pol1'] = 'Wiki Publike (lexim për këdo, shkrim dhe ngarkim për përdoruesit e regjistruar)';
+$lang['i_pol2'] = 'Wiki e Mbyllur (lexim, shkrim, ngarkim vetëm për përdoruesit e regjistruar)';
+$lang['i_retry'] = 'Provo Përsëri';
+$lang['recent_global'] = 'Momentalisht jeni duke parë ndryshimet brenda hapësirës së emrit <b>%s</b>. Gjithashtu mund <a href="%s">të shihni ndryshimet më të fundit në të gjithë wiki-n</a>.';
+$lang['years'] = '%d vite më parë';
+$lang['months'] = '%d muaj më parë';
+$lang['weeks'] = '%d javë më parë';
+$lang['days'] = '%d ditë më parë';
+$lang['hours'] = '%d orë më parë';
+$lang['minutes'] = '%d minuta më parë';
+$lang['seconds'] = '%d sekonda më parë';
diff --git a/inc/lang/sq/locked.txt b/inc/lang/sq/locked.txt
new file mode 100644
index 000000000..8c86c8be0
--- /dev/null
+++ b/inc/lang/sq/locked.txt
@@ -0,0 +1,3 @@
+====== Faqe e kyçur ======
+
+Kjo faqe është përkohësisht e kyçur për redaktim nga një përdorues tjetër. Duhet të prisni derisa ky përdorues të mbarojë redaktimin ose çelësi të skadojë. \ No newline at end of file
diff --git a/inc/lang/sq/login.txt b/inc/lang/sq/login.txt
new file mode 100644
index 000000000..843e47652
--- /dev/null
+++ b/inc/lang/sq/login.txt
@@ -0,0 +1,3 @@
+====== Hyrje ======
+
+Momentalisht nuk jeni të futur në Wiki! Futni informacionet tuaja të autentikimit më poshtë për të hyrë. Duhet t'i keni cookies të aktivizuara për të hyrë. \ No newline at end of file
diff --git a/inc/lang/sq/mailtext.txt b/inc/lang/sq/mailtext.txt
new file mode 100644
index 000000000..0746ca42c
--- /dev/null
+++ b/inc/lang/sq/mailtext.txt
@@ -0,0 +1,16 @@
+Një faqe në DokuWiki-n tuaj u shtua ose u ndryshua. Këto janë detajet:
+
+Data: @DATE@
+Shfletuesi: @BROWSER@
+Adresa IP: @IPADDRESS@
+Emri Hostit: @HOSTNAME@
+Rishikimi i vjetër: @OLDPAGE@
+Rishikimi i ri: @NEWPAGE@
+Përmbledhja redaktimit: @SUMMARY@
+Përdoruesi: @USER@
+
+@DIFF@
+
+---
+Ky email u gjenerua nga DokuWiki në
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sq/newpage.txt b/inc/lang/sq/newpage.txt
new file mode 100644
index 000000000..1db750d00
--- /dev/null
+++ b/inc/lang/sq/newpage.txt
@@ -0,0 +1,3 @@
+====== Kjo temë nuk ekziston ende ======
+
+Keni ndjekur një link për në një temë që nuk ekziston ende. Nëse ua lejojnë të drejtat, mund ta krijoni duke klikuar butonin "Krijo këtë faqe". \ No newline at end of file
diff --git a/inc/lang/sq/norev.txt b/inc/lang/sq/norev.txt
new file mode 100644
index 000000000..0e73223a9
--- /dev/null
+++ b/inc/lang/sq/norev.txt
@@ -0,0 +1,3 @@
+====== Nuk ekzistion një rishikim i tillë ======
+
+Rishikimi i specifikuar nuk ekziston. Përdor buttonin "Rishikime të vjetra" për një listë të rishikimeve të vjetra të këtij dokumenti. \ No newline at end of file
diff --git a/inc/lang/sq/password.txt b/inc/lang/sq/password.txt
new file mode 100644
index 000000000..1c8a8694a
--- /dev/null
+++ b/inc/lang/sq/password.txt
@@ -0,0 +1,10 @@
+Përshëndetje @FULLNAME@!
+
+Këtu janë të dhënat e përdoruesit për @TITLE@ në @DOKUWIKIURL@
+
+Hyrje: @LOGIN@
+Fjalëkalimi: @PASSWORD@
+
+---
+Ky email u gjenerua nga DokuWiki në
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sq/preview.txt b/inc/lang/sq/preview.txt
new file mode 100644
index 000000000..07148b842
--- /dev/null
+++ b/inc/lang/sq/preview.txt
@@ -0,0 +1,3 @@
+====== Shikim Paraprak ======
+
+Ky është një shikim paraprak i tekstit tuaj. Kujtohuni: **Nuk** është ruajtur ende! \ No newline at end of file
diff --git a/inc/lang/sq/pwconfirm.txt b/inc/lang/sq/pwconfirm.txt
new file mode 100644
index 000000000..44d6c2dfe
--- /dev/null
+++ b/inc/lang/sq/pwconfirm.txt
@@ -0,0 +1,13 @@
+Përshëndetje @FULLNAME@!
+
+Dikush kërkoi një fjalëkalim të ri për hyrjen tuaj @TITLE@ në @DOKUWIKIURL@
+
+Nëse nuk kërkuat një fjalëkalim të ri atëherë thjesht injorojeni këtë email.
+
+Për të konfirmuar që kërkesa u dërgua me të vërtetë nga ju, ju lutemi përdorni link-un e mëposhtëm.
+
+@CONFIRM@
+
+--
+Ky email u gjenerua nga DokuWiki në
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sq/read.txt b/inc/lang/sq/read.txt
new file mode 100644
index 000000000..cbb028048
--- /dev/null
+++ b/inc/lang/sq/read.txt
@@ -0,0 +1 @@
+Kjo faqe është vetëm për lexim. Mund të shihni kodin burim, por nuk mund ta ndryshoni atë. Kontaktoni administratorin nëse mendoni se kjo është e gabuar. \ No newline at end of file
diff --git a/inc/lang/sq/recent.txt b/inc/lang/sq/recent.txt
new file mode 100644
index 000000000..4b3bdf48d
--- /dev/null
+++ b/inc/lang/sq/recent.txt
@@ -0,0 +1,3 @@
+====== Ndryshimet e kohëve të fundit ======
+
+Faqet e mëposhtme janë ndryshuar së fundmi. \ No newline at end of file
diff --git a/inc/lang/sq/register.txt b/inc/lang/sq/register.txt
new file mode 100644
index 000000000..d4a3ca36b
--- /dev/null
+++ b/inc/lang/sq/register.txt
@@ -0,0 +1,3 @@
+====== Regjistrohuni si një përdorues i ri ======
+
+Plotësoni të gjitha informacionet e mëposhtme për të krijuar një llogari në këtë wiki. Sigorohuni që të jepni një **adresë email-i të vlefshme**. Nëse nuk ju kërkohet të futni një fjalëkalim këtu, një fjalëkalim i ri do t'ju dërgohet në adresën e email-it që specifikuat. Emri i hyrjes duhet të një [[doku>pagename|pagename]] e vlefshme. \ No newline at end of file
diff --git a/inc/lang/sq/registermail.txt b/inc/lang/sq/registermail.txt
new file mode 100644
index 000000000..ef90e455e
--- /dev/null
+++ b/inc/lang/sq/registermail.txt
@@ -0,0 +1,14 @@
+Një përdorues i ri u regjistrua. Këto janë detajet:
+
+Emri përdoruesit: @NEWUSER@
+Emri i plotë i përdoruesit: @NEWNAME@
+E-mail: @NEWEMAIL@
+
+Data: @DATE@
+Shfletuesi: @BROWSER@
+Adresa IP: @IPADDRESS@
+Emri Hostit: @HOSTNAME@
+
+--
+Ky email u gjenerua nga DokuWiki në
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sq/resendpwd.txt b/inc/lang/sq/resendpwd.txt
new file mode 100644
index 000000000..79d0b3e8e
--- /dev/null
+++ b/inc/lang/sq/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Dërgo fjalëkalim të ri ======
+
+Ju lutemi futni emrin tuaj të përdorimit në formën e mëposhtme për të kërkuar një fjalëkalim të ri për llogarinë tuaj në këtë wiki. Një link konfirmimi do të dërgohet në adresën tuaj të eMail-it. \ No newline at end of file
diff --git a/inc/lang/sq/revisions.txt b/inc/lang/sq/revisions.txt
new file mode 100644
index 000000000..349631ffb
--- /dev/null
+++ b/inc/lang/sq/revisions.txt
@@ -0,0 +1,3 @@
+====== Rishikime të vjetra ======
+
+Këto janë rishikimet e vjetra të dokumentit aktual. Për t'u kthyer në një rishikim të vjetër, zgjidhni nga këtu poshtë, klikoni "Redaktoni këtë faqe" dhe ruajeni atë.
diff --git a/inc/lang/sq/searchpage.txt b/inc/lang/sq/searchpage.txt
new file mode 100644
index 000000000..2f34cabb9
--- /dev/null
+++ b/inc/lang/sq/searchpage.txt
@@ -0,0 +1,5 @@
+====== Kërko ======
+
+Mund të gjeni rezultatet e kërkimit tuaj më poshtë. Nëse nuk e gjetët atë që po kërkonit, mund të krijoni ose redaktoni një faqe pas pyetjes suaj me butonin përkatës.
+
+===== Rezultate ===== \ No newline at end of file
diff --git a/inc/lang/sq/showrev.txt b/inc/lang/sq/showrev.txt
new file mode 100644
index 000000000..9c1f761dc
--- /dev/null
+++ b/inc/lang/sq/showrev.txt
@@ -0,0 +1,2 @@
+**Ky është një rishikim i vjetër i dokumentit!**
+---- \ No newline at end of file
diff --git a/inc/lang/sq/stopwords.txt b/inc/lang/sq/stopwords.txt
new file mode 100644
index 000000000..e35669410
--- /dev/null
+++ b/inc/lang/sq/stopwords.txt
@@ -0,0 +1,39 @@
+# Kjo është një listë e fjalëve që indexer-i injoron, një fjalë për rresht
+# Kur të redaktoni këtë faqe sigurohuni që të përdorni fund-rreshtash UNIX (rresht i ri i vetëm)
+# Nuk është nevoja të përfshini fjalë më të shkurtra se tre karaktere - këtë injorohen gjithsesi
+# Kjo listë bazohet mbi ato që gjenden në 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 \ No newline at end of file
diff --git a/inc/lang/sq/subscr_digest.txt b/inc/lang/sq/subscr_digest.txt
new file mode 100644
index 000000000..41404cff9
--- /dev/null
+++ b/inc/lang/sq/subscr_digest.txt
@@ -0,0 +1,20 @@
+Përshëndetje!
+
+Faqja @PAGE@ në wiki-n @TITLE@ ndryshoi.
+Këtu janë ndryshimet:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Rishikimi i vjetër: @OLDPAGE@
+Rishikimi i ri: @NEWPAGE@
+
+Për të fshirë lajmërimet e faqes, mund të hyni tek wiki në
+@DOKUWIKIURL@ pastaj vizitoni
+@SUBSCRIBE@
+dhe ç'regjistro faqen dhe/ose ndryshimet e hapësirës së emrit.
+
+--
+Ky eMail është gjeneruar nga DokuWiki në
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sq/subscr_form.txt b/inc/lang/sq/subscr_form.txt
new file mode 100644
index 000000000..7c71a4c73
--- /dev/null
+++ b/inc/lang/sq/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Menaxhimi i Abonimeve ======
+
+Kjo faqe lejon menaxhimin e abonimeve tuaja për faqen dhe hapësirën e emrit aktual. \ No newline at end of file
diff --git a/inc/lang/sq/subscr_list.txt b/inc/lang/sq/subscr_list.txt
new file mode 100644
index 000000000..cb10d4223
--- /dev/null
+++ b/inc/lang/sq/subscr_list.txt
@@ -0,0 +1,13 @@
+Përshëndetje!
+
+Faqet në hapësirën e emrit @PAGE@ të wiki-t @TITLE@ ndryshuan. Këto janë faqet e ndryshuara:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Për të fshirë lajmërimet e faqes, hyni në wiki-n tek @DOKUWIKIURL@ dhe pastaj vizitoni @SUBSCRIBE@ dhe fshini ndryshimet e faqes dhe/ose të hapësirës së emrit.
+
+--
+Ky email u gjenerua nga DokuWiki në
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sq/subscr_single.txt b/inc/lang/sq/subscr_single.txt
new file mode 100644
index 000000000..90520be4f
--- /dev/null
+++ b/inc/lang/sq/subscr_single.txt
@@ -0,0 +1,23 @@
+Përshëndetje!
+
+Faqja @PAGE@ në wiki-n @TITLE@ ndryshoi.
+Këto janë ndryshimet:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Data : @DATE@
+Përdoruesi : @USER@
+Përmbledhja redaktimit: @SUMMARY@
+Rishikimi i vjetër: @OLDPAGE@
+Rishikimi i ri: @NEWPAGE@
+
+Për të fshirë lajmërimet e faqes, hyni në wiki tek
+@DOKUWIKIURL@ dhe pastaj vizitoni
+@NEWPAGE@
+dhe fshini ndryshimet e faqes dhe/ose hapësirës së emrit.
+
+--
+Ky email u gjenerua nga DokuWiki në
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sq/updateprofile.txt b/inc/lang/sq/updateprofile.txt
new file mode 100644
index 000000000..ba76beb1f
--- /dev/null
+++ b/inc/lang/sq/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Përditësoni profilin e llogarisë tuaj ======
+
+Duhet vetëm të plotësoni ato fusha që doni të ndryshoni. Mund të mos e ndryshoni emrin tuaj të përdoruesit. \ No newline at end of file
diff --git a/inc/lang/sq/uploadmail.txt b/inc/lang/sq/uploadmail.txt
new file mode 100644
index 000000000..e7c62df15
--- /dev/null
+++ b/inc/lang/sq/uploadmail.txt
@@ -0,0 +1,14 @@
+Një skedar u ngarkua në DokuWiki-n tënd. Detajet janë:
+
+Skedar: @MEDIA@
+Data: @DATE@
+Shfletuesi: @BROWSER@
+Adresa IP: @IPADDRESS@
+Emri Hostit: @HOSTNAME@
+Madhësia: @SIZE@
+Tipi MIME: @MIME@
+Përdoruesi: @USER@
+
+---
+Ky email u gjenerua nga DokuWiki në
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sr/admin.txt b/inc/lang/sr/admin.txt
new file mode 100644
index 000000000..1e42970d3
--- /dev/null
+++ b/inc/lang/sr/admin.txt
@@ -0,0 +1,4 @@
+====== Администрација ======
+
+Изпод се налази листа доступних администраторских опција у DokuWiki-ју.
+
diff --git a/inc/lang/sr/adminplugins.txt b/inc/lang/sr/adminplugins.txt
new file mode 100644
index 000000000..02b1a0452
--- /dev/null
+++ b/inc/lang/sr/adminplugins.txt
@@ -0,0 +1 @@
+===== Остали додаци ===== \ No newline at end of file
diff --git a/inc/lang/sr/backlinks.txt b/inc/lang/sr/backlinks.txt
new file mode 100644
index 000000000..dae8d5ab2
--- /dev/null
+++ b/inc/lang/sr/backlinks.txt
@@ -0,0 +1,4 @@
+====== Повратне везе ======
+
+Ово је листа страница које имају везе ка тренутној страници.
+
diff --git a/inc/lang/sr/conflict.txt b/inc/lang/sr/conflict.txt
new file mode 100644
index 000000000..2a1427ec4
--- /dev/null
+++ b/inc/lang/sr/conflict.txt
@@ -0,0 +1,6 @@
+====== Постоји новија верзија ======
+
+Постоји новија верзија документа који сте изменили. Ово се дешава када неки други корисник измени документ док га Ви још увек мењате.
+
+Проучите разлике које су доле детаљно приказане, па након тога одлучите коју верзију желите да задржите. Ако изаберете ''сачувај'', Ваша верзија ће да буде сачувана. Ако изаберите ''поништи'', тренутна верзија ће да буде сачувана.
+
diff --git a/inc/lang/sr/denied.txt b/inc/lang/sr/denied.txt
new file mode 100644
index 000000000..b74f2b1f8
--- /dev/null
+++ b/inc/lang/sr/denied.txt
@@ -0,0 +1,4 @@
+====== Забрањен приступ ======
+
+Извините, али немате довољно права да наставите. Можда сте заборавили да се пријавите?
+
diff --git a/inc/lang/sr/diff.txt b/inc/lang/sr/diff.txt
new file mode 100644
index 000000000..39b7427ec
--- /dev/null
+++ b/inc/lang/sr/diff.txt
@@ -0,0 +1,4 @@
+====== Разлике ======
+
+Овде су приказане разлике између изабране ревизије и тренутне верзије странице.
+
diff --git a/inc/lang/sr/draft.txt b/inc/lang/sr/draft.txt
new file mode 100644
index 000000000..44affdd34
--- /dev/null
+++ b/inc/lang/sr/draft.txt
@@ -0,0 +1,5 @@
+====== Пронађена је скица датотеке ======
+
+Прошли пут кад сте покушали нешто да измените на овој страници ваше измене нису успешно сачуване. DokuWiki је аутоматски сачувао скицу вашег рада коју сада можете да искористите да бисте наставили са изменама. Испод можете да видите податке који су сачувани током ваше последње посете.
+
+Молимо вас, одаберите да ли желите да //повратите// ваше измене, //обришете// аутоматски сачувану скицу, или //поништите// цео процес измена. \ No newline at end of file
diff --git a/inc/lang/sr/edit.txt b/inc/lang/sr/edit.txt
new file mode 100644
index 000000000..2d6fa7b8e
--- /dev/null
+++ b/inc/lang/sr/edit.txt
@@ -0,0 +1,2 @@
+Измените ову страницу и притисните ''Сачувај''. Погледајте [[wiki:syntax]] за синтаксу Викија. Молим Вас, измените ову страницу само ако имате намеру да је **побољшате**. Ако желите да тестирате могућности, научите да направите своје кораке на [[playground:playground]].
+
diff --git a/inc/lang/sr/editrev.txt b/inc/lang/sr/editrev.txt
new file mode 100644
index 000000000..327902943
--- /dev/null
+++ b/inc/lang/sr/editrev.txt
@@ -0,0 +1,2 @@
+**Учитали сте стару ревизију документа!** Ако је сачувате, направићете нову верзију са овим подацима.
+----
diff --git a/inc/lang/sr/index.txt b/inc/lang/sr/index.txt
new file mode 100644
index 000000000..fe6467a1d
--- /dev/null
+++ b/inc/lang/sr/index.txt
@@ -0,0 +1,4 @@
+====== Индекс ======
+
+Овде је индекс свих доступних страница поређаних по [[doku>namespaces|именским просторима]].
+
diff --git a/inc/lang/sr/install.html b/inc/lang/sr/install.html
new file mode 100644
index 000000000..b9ab35c71
--- /dev/null
+++ b/inc/lang/sr/install.html
@@ -0,0 +1,12 @@
+<p>Ова страница ће вам помоћи у инсталацији и подешавању <a href="http://dokuwiki.org">Dokuwiki-ја</a>. Више информација о инсталацији можете пронаћи у
+<a href="http://dokuwiki.org/installer">документацији</a>.</p>
+
+<p>DokuWiki користи обичне датотеке за складиштење вики страница и осталих информација везаних за странице (слике, индекс претраге, старе преправке, итд.).
+Да би радио како треба DokuWiki као апликација <strong>мора</strong> имати могућност писања под фасциклама у којима се налазе ове датотеке. Овај програм за инсталацију нема могућност постављања дозвола за фасцикле. То се обично ради директно из командне линије или ако користите изнајмњени сервер, помоћу ФТПа или кроз Контролни панел (нпр. cPanel).</p>
+
+<p>Овај програм за инсталацију DokuWiki-а ће поставити подешавања за
+<acronym title="access control list">Права приступа</acronym>, које ће омогућити пријјављивање као администратор и приступ менију за инсталацију додатака, управљање корисницима, управљање приступом ка страницама и алтернатвна подешавања. Није неопходно да би DokuWiki радио, али ће вам олакшати администрацију.</p>
+
+<p>Искуснији корисници и корисници са посебним захтевима би требало да погледају следеће линкове са детаљним упутствима о
+<a href="http://dokuwiki.org/install">инструкцијама за инсталацију</a>
+и <a href="http://dokuwiki.org/config">подешавањима</a>.</p> \ No newline at end of file
diff --git a/inc/lang/sr/lang.php b/inc/lang/sr/lang.php
new file mode 100644
index 000000000..3b2d2939c
--- /dev/null
+++ b/inc/lang/sr/lang.php
@@ -0,0 +1,265 @@
+<?php
+/**
+ * serbian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Filip Brcic <brcha@users.sourceforge.net>
+ * @author Иван Петровић (Ivan Petrovic) <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '„';
+$lang['doublequoteclosing'] = '“';
+$lang['singlequoteopening'] = '‚';
+$lang['singlequoteclosing'] = '‘';
+$lang['apostrophe'] = '\'';
+$lang['btn_edit'] = 'Измени ову страницу';
+$lang['btn_source'] = 'Прикажи изворни код';
+$lang['btn_show'] = 'Прикажи страницу';
+$lang['btn_create'] = 'Направи ову страницу';
+$lang['btn_search'] = 'Тражи';
+$lang['btn_save'] = 'Сачувај';
+$lang['btn_preview'] = 'Прегледај';
+$lang['btn_top'] = 'Врати се на врх';
+$lang['btn_newer'] = '<< новије';
+$lang['btn_older'] = 'старије >>';
+$lang['btn_revs'] = 'Старе верзије';
+$lang['btn_recent'] = 'Скорије измене';
+$lang['btn_upload'] = 'Пошаљи';
+$lang['btn_cancel'] = 'Поништи';
+$lang['btn_index'] = 'Индекс';
+$lang['btn_secedit'] = 'Измени';
+$lang['btn_login'] = 'Пријави се';
+$lang['btn_logout'] = 'Одјави се';
+$lang['btn_admin'] = 'Администрација';
+$lang['btn_update'] = 'Ажурирај';
+$lang['btn_delete'] = 'Избриши';
+$lang['btn_back'] = 'Натраг';
+$lang['btn_backlink'] = 'Повратне везе';
+$lang['btn_backtomedia'] = 'Врати се на избор медијске датотеке';
+$lang['btn_subscribe'] = 'Пријави се на измене';
+$lang['btn_profile'] = 'Ажурирај профил';
+$lang['btn_reset'] = 'Поништи';
+$lang['btn_resendpwd'] = 'Пошаљи нову лозинку';
+$lang['btn_draft'] = 'Измени нацрт';
+$lang['btn_recover'] = 'Опорави нацрт';
+$lang['btn_draftdel'] = 'Обриши нацрт';
+$lang['btn_revert'] = 'Врати на пређашњу верзију';
+$lang['btn_register'] = 'Региструј се';
+$lang['loggedinas'] = 'Пријављен као';
+$lang['user'] = 'Корисничко име';
+$lang['pass'] = 'Лозинка';
+$lang['newpass'] = 'Нова лозинка';
+$lang['oldpass'] = 'Потврди нову лозинку';
+$lang['passchk'] = 'поново';
+$lang['remember'] = 'Запамти ме';
+$lang['fullname'] = 'Име и презиме';
+$lang['email'] = 'Е-адреса';
+$lang['profile'] = 'Кориснички профил';
+$lang['badlogin'] = 'Извините, није добро корисничко име или шифра.';
+$lang['minoredit'] = 'Мала измена';
+$lang['draftdate'] = 'Нацрт је аутоматски сачуван';
+$lang['nosecedit'] = 'Страна је у међувремену промењена, поглавље је застарело и поново се учитава цела страна.';
+$lang['regmissing'] = 'Извините, морате да попуните сва поља.';
+$lang['reguexists'] = 'Извините, корисник са истим именом већ постоји.';
+$lang['regsuccess'] = 'Корисник је направљен и лозинка је послата путем е-поште.';
+$lang['regsuccess2'] = 'Корисник је направљен.';
+$lang['regmailfail'] = 'Изгледа да је дошло до грешке приликом слања лозинке е-поштом. Молим Вас, контактирајте администратора!';
+$lang['regbadmail'] = 'Дата е-адреса није у реду - ако мислите да је ово грешка, контактирајте администратора';
+$lang['regbadpass'] = 'Две задате лозинке нису исте. Молим Вас, пробајте поново.';
+$lang['regpwmail'] = 'Ваша DokuWiki лозинка';
+$lang['reghere'] = 'Још увек немате налог? Само направите један';
+$lang['profna'] = 'Овај вики не дозвољава измену профила';
+$lang['profnochange'] = 'Нема промена.';
+$lang['profnoempty'] = 'Није дозвољено оставити празно поље имена или е-адресе.';
+$lang['profchanged'] = 'Кориснички профил је ажуриран.';
+$lang['pwdforget'] = 'Заборавили сте лозинку? Направите нову';
+$lang['resendna'] = 'Овај вики не дозвољава слање лозинки.';
+$lang['resendpwd'] = 'Пошаљи нову лозинку за';
+$lang['resendpwdmissing'] = 'Жао ми је, сва поља морају бити попуњена.';
+$lang['resendpwdnouser'] = 'Жао ми је, овај корисник не постоји у нашој бази.';
+$lang['resendpwdbadauth'] = 'Жао ми је, потврдни код није исправан. Проверите да ли сте користили комплетан потврдни линк.';
+$lang['resendpwdconfirm'] = 'Потврдни линк је постат као е-порука.';
+$lang['resendpwdsuccess'] = 'Ваша нова лозинка је послата као е-порука.';
+$lang['license'] = 'Осим где је другачије назначено, материјал на овом викију је под следећом лиценцом:';
+$lang['licenseok'] = 'Напомена: Изменом ове стране слажете се да ће ваше измене бити под следећом лиценцом:';
+$lang['searchmedia'] = 'Претражи по имену фајла';
+$lang['searchmedia_in'] = 'Претражи у %s';
+$lang['txt_upload'] = 'Изаберите датотеку за слање';
+$lang['txt_filename'] = 'Унесите вики-име (опционо)';
+$lang['txt_overwrt'] = 'Препишите тренутни фајл';
+$lang['lockedby'] = 'Тренутно закључано од стране';
+$lang['lockexpire'] = 'Закључавање истиче';
+$lang['js']['willexpire'] = 'Ваше закључавање за измену ове странице ће да истекне за један минут.\nДа би сте избегли конфликте, искористите дугме за преглед како би сте ресетовали тајмер закључавања.';
+$lang['js']['notsavedyet'] = 'Несачуване измене ће бити изгубљене.
+Да ли стварно желите да наставите?';
+$lang['js']['searchmedia'] = 'Потражи фајлове';
+$lang['js']['keepopen'] = 'Задржи отворен прозор након одабира';
+$lang['js']['hidedetails'] = 'Сакриј детаље';
+$lang['js']['mediatitle'] = 'Подешаванја везе';
+$lang['js']['mediadisplay'] = 'Тип везе';
+$lang['js']['mediaalign'] = 'Поравнање';
+$lang['js']['mediasize'] = 'Величина слике';
+$lang['js']['mediatarget'] = 'веза води ка:';
+$lang['js']['mediaclose'] = 'Затвори';
+$lang['js']['mediainsert'] = 'Убаци';
+$lang['js']['mediadisplayimg'] = 'Покажи слику';
+$lang['js']['mediadisplaylnk'] = 'Покажи само везу';
+$lang['js']['mediasmall'] = 'Мала верзија';
+$lang['js']['mediamedium'] = 'Средња верзија';
+$lang['js']['medialarge'] = 'Велика верзија';
+$lang['js']['mediaoriginal'] = 'Оригинална верзија';
+$lang['js']['medialnk'] = 'Веза ка страници са детаљима';
+$lang['js']['mediadirect'] = 'Директна веза ка оригиналу';
+$lang['js']['medianolnk'] = 'Без везе';
+$lang['js']['medianolink'] = 'Не постављај слику као везу';
+$lang['js']['medialeft'] = 'Поравнај слику на лево';
+$lang['js']['mediaright'] = 'Поравнај слику на десно';
+$lang['js']['mediacenter'] = 'Поравнај слику по средини';
+$lang['js']['medianoalign'] = 'Без поравнања';
+$lang['js']['nosmblinks'] = 'Повезивање са Windows дељеним фолдерима ради само у Мајкрософтовом Интернет Претраживачу.
+Ипак, можете да ископирате и залепите везу.';
+$lang['js']['linkwiz'] = 'Чаробњак за стварање везе';
+$lang['js']['linkto'] = 'Повежи ка:';
+$lang['js']['del_confirm'] = 'Обриши овај унос?';
+$lang['rssfailed'] = 'Дошло је до грешке приликом преузимања овог довода: ';
+$lang['nothingfound'] = 'Ништа није нађено.';
+$lang['mediaselect'] = 'Избор медијске датотеке';
+$lang['fileupload'] = 'Слање медијске датотеке';
+$lang['uploadsucc'] = 'Успешно слање';
+$lang['uploadfail'] = 'Неуспешно слање. Можда немате дозволу?';
+$lang['uploadwrong'] = 'Слање је забрањено. Овај наставак датотеке је забрањен!';
+$lang['uploadexist'] = 'Датотека већ постоји. Ништа није учињено.';
+$lang['uploadbadcontent'] = 'Материјал који шаљете не одговара %s ';
+$lang['uploadspam'] = 'Слање је блокирано јер се налазите на црној листи пошиљаоца.';
+$lang['uploadxss'] = 'Слање је блокирано јер је потенцијално малициозног садржаја.';
+$lang['uploadsize'] = 'Послата датотека је превелика. (максимум је %s)';
+$lang['deletesucc'] = 'Фајл "%s" је избрисан.';
+$lang['deletefail'] = '"%s" није могао да буде избрисан - проверите дозволе.';
+$lang['mediainuse'] = 'Фајл "%s" није избрисан - још је у употреби.';
+$lang['namespaces'] = 'Именски простори';
+$lang['mediafiles'] = 'Доступни фајлови у';
+$lang['accessdenied'] = 'Немате дозволу да видите ову страницу.';
+$lang['mediausage'] = 'Користите следећу синтаксу за референцу ка овој датотеци:';
+$lang['mediaview'] = 'Прикажи оригиналну датотеку';
+$lang['mediaroot'] = 'почетак';
+$lang['mediaupload'] = 'Пошаљи датотеку у тренутни именски простор. Да бисте направили подпросторе, предвидите их у поље „Пошаљи као“ раздвојено двотачкама.';
+$lang['mediaextchange'] = 'Наставак датотеке је промењен из .%s у .%s!';
+$lang['reference'] = 'Референце за';
+$lang['ref_inuse'] = 'Фајл не може да буде избрисан јер га још увек користе следеће странице:';
+$lang['ref_hidden'] = 'Неке референце су на страницама за које немате дозволе за читање';
+$lang['hits'] = 'Поготци';
+$lang['quickhits'] = 'Имена страница које се поклапају';
+$lang['toc'] = 'Садржај';
+$lang['current'] = 'тренутно';
+$lang['yours'] = 'Ваша верзија';
+$lang['diff'] = 'прикажи разлике до тренутне верзије';
+$lang['diff2'] = 'Прикажи разлике између одабраних ревизија';
+$lang['difflink'] = 'Постави везу ка овом компаративном приказу';
+$lang['line'] = 'Линија';
+$lang['breadcrumb'] = 'Траг';
+$lang['youarehere'] = 'Сада сте овде';
+$lang['lastmod'] = 'Последњи пут мењано';
+$lang['by'] = 'од';
+$lang['deleted'] = 'избрисано';
+$lang['created'] = 'направљено';
+$lang['restored'] = 'стара верзија повраћена';
+$lang['external_edit'] = 'спољна измена';
+$lang['summary'] = 'Сажетак измене';
+$lang['noflash'] = 'За приказивање ове врсте материјала потребан вам је <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>.';
+$lang['download'] = 'Преузми снипет';
+$lang['mail_newpage'] = 'страница додата:';
+$lang['mail_changed'] = 'страница измењена:';
+$lang['mail_subscribe_list'] = 'Странице промењене у именском простору:';
+$lang['mail_new_user'] = 'нови корисник:';
+$lang['mail_upload'] = 'послата датотека:';
+$lang['qb_bold'] = 'Мастан текст';
+$lang['qb_italic'] = 'Курзивни текст';
+$lang['qb_underl'] = 'Подвучени текст';
+$lang['qb_code'] = 'Изворни код';
+$lang['qb_strike'] = 'Прецртани текст';
+$lang['qb_h1'] = 'Наслов 1. нивоа';
+$lang['qb_h2'] = 'Наслов 2. нивоа';
+$lang['qb_h3'] = 'Наслов 3. нивоа';
+$lang['qb_h4'] = 'Наслов 4. нивоа';
+$lang['qb_h5'] = 'Наслов 5. нивоа';
+$lang['qb_h'] = 'Наслов';
+$lang['qb_hs'] = 'Одабери наслов';
+$lang['qb_hplus'] = 'Виши наслов';
+$lang['qb_hminus'] = 'Нижи наслов';
+$lang['qb_hequal'] = 'Наслов на истом нивоу';
+$lang['qb_link'] = 'Унутрашња веза';
+$lang['qb_extlink'] = 'Спољашња веза';
+$lang['qb_hr'] = 'Хоризонтална линија';
+$lang['qb_ol'] = 'Елемент уређене листе';
+$lang['qb_ul'] = 'Елемент неуређене листе';
+$lang['qb_media'] = 'Додај слике и друге фајлове';
+$lang['qb_sig'] = 'Убаци потпис';
+$lang['qb_smileys'] = 'Смешко';
+$lang['qb_chars'] = 'Посебни карактери';
+$lang['upperns'] = 'Скочи на виши именски простор';
+$lang['admin_register'] = 'Додај новог корисника';
+$lang['metaedit'] = 'Измени мета-податке';
+$lang['metasaveerr'] = 'Записивање мета-података није било успешно';
+$lang['metasaveok'] = 'Мета-подаци су сачувани';
+$lang['img_backto'] = 'Натраг на';
+$lang['img_title'] = 'Наслов';
+$lang['img_caption'] = 'Назив';
+$lang['img_date'] = 'Датум';
+$lang['img_fname'] = 'Име фајла';
+$lang['img_fsize'] = 'Величина';
+$lang['img_artist'] = 'Фотограф';
+$lang['img_copyr'] = 'Права копирања';
+$lang['img_format'] = 'Формат';
+$lang['img_camera'] = 'Камера';
+$lang['img_keywords'] = 'Кључне речи';
+$lang['subscr_subscribe_success'] = '%s је додат на списак претплатника %s';
+$lang['subscr_subscribe_error'] = 'Грешка приликом додавања %s на списак претплатника %s';
+$lang['subscr_subscribe_noaddress'] = 'Не постоји адреса повезана са вашим подацима, стога вас не можемо додати на списак претплатника.';
+$lang['subscr_unsubscribe_success'] = '%s уклоњен са списка претплатника %s';
+$lang['subscr_unsubscribe_error'] = 'Грешка приликом уклањања %s са списка претплатника %s';
+$lang['subscr_already_subscribed'] = '%s је већ претплаћен на %s';
+$lang['subscr_not_subscribed'] = '%s још није претплаћен на %s';
+$lang['subscr_m_not_subscribed'] = 'Тренутно нисте претплаћени на ову страницу или именски простор.';
+$lang['subscr_m_new_header'] = 'Додај претплату';
+$lang['subscr_m_current_header'] = 'Тренутне претплате';
+$lang['subscr_m_unsubscribe'] = 'Уклони претплату';
+$lang['subscr_m_subscribe'] = 'Претплати се';
+$lang['subscr_m_receive'] = 'Прими';
+$lang['subscr_style_every'] = 'имејл о свакој промени';
+$lang['subscr_style_digest'] = 'скраћени имејл о променама за сваку страницу (сваких %.2f дана)';
+$lang['subscr_style_list'] = 'Списак страница промењених након последњег имејла (сваких %.2f дана)';
+$lang['authmodfailed'] = 'Лоше подешена провера корисника. Молим Вас да обавестите администратора викија.';
+$lang['authtempfail'] = 'Провера корисника је тренутно недоступна. Ако се ситуација настави, молимо Вас да обавестите администратора викија.';
+$lang['i_chooselang'] = 'Одаберите језик';
+$lang['i_installer'] = 'Докувики инсталација';
+$lang['i_wikiname'] = 'Назив викија';
+$lang['i_enableacl'] = 'Укључи ';
+$lang['i_superuser'] = 'Суперкорисник';
+$lang['i_problems'] = 'Инсталација је наишла на проблеме који су навадени у тексту испод. Не можете наставити даље док их не исправите.';
+$lang['i_modified'] = 'Из сигурносних разлога ова скрипта ради само са новом Dokuwiki инсталацијом. Требало би или да опет распакујете архиву преузету са сајта или да погледате <a href="http://dokuwiki.org/install">Dokuwiki инструкције за инсталацију</a>';
+$lang['i_funcna'] = 'ПХП функција <code>%s</code> није доступна. Можда је Ваш хостинг провајдер забранио из неког разлога?';
+$lang['i_phpver'] = '<code>%s</code> Верзија Вашег ПХПа је нижа од неопходне <code>%s</code>. Требало би да надоградите ПХП инсталацију.';
+$lang['i_permfail'] = 'DokuWiki нема дозволу писања у <code>%s</code>. Потребно је да поправите дозволе за ову фасциклу!';
+$lang['i_confexists'] = '<code>%s</code> већ постоји';
+$lang['i_writeerr'] = 'Не могу да направим <code>%s</code>. Проверите дозволе а затим ручно направите ову датотеку.';
+$lang['i_badhash'] = 'dokuwiki.php није препознат или је измењен (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - недозвољена или празна вредност';
+$lang['i_success'] = 'Подешавања су завршена. Сада можете обрисати датотеку install.php. Наставите у <a href="doku.php">Ваш нови DokuWiki</a>.';
+$lang['i_failure'] = 'Појавили су се проблеми при писању датотеке са подешавањима. Требало би да их ручно исправите пре него што ћете моћи да користите <a href="doku.php">Ваш нови DokuWiki</a>.';
+$lang['i_policy'] = 'Иницијалне корисничке дозволе';
+$lang['i_pol0'] = 'Отворени вики (читање, писање, слање датотека за све)';
+$lang['i_pol1'] = 'Јавни вики (читање за све, писање и слање датотека само за регистроване кориснике)';
+$lang['i_pol2'] = 'Затворени вики (читање, писање и слање датотека само за регистроване кориснике)';
+$lang['i_retry'] = 'Понови';
+$lang['i_license'] = 'Молимо вас, одаберите лиценцу под коју желите да ставите свој садржај:';
+$lang['recent_global'] = 'Тренутно пратите промене у именском простору <b>%s</b>. Такође, можете пратити <a href="%s">прмене на целом викију</a>.';
+$lang['years'] = 'Пре %d година';
+$lang['months'] = 'Пре %d месеци';
+$lang['weeks'] = 'Пре %d недеља';
+$lang['days'] = 'Пре %d дана';
+$lang['hours'] = 'Пре %d сати';
+$lang['minutes'] = 'Пре %d минута';
+$lang['seconds'] = 'Пре %d секунди';
+$lang['wordblock'] = 'Ваше измене нису сачуване јер садрже забрањен текст (спам)';
diff --git a/inc/lang/sr/locked.txt b/inc/lang/sr/locked.txt
new file mode 100644
index 000000000..4bcc0ac5c
--- /dev/null
+++ b/inc/lang/sr/locked.txt
@@ -0,0 +1,3 @@
+====== Страница је закључана ======
+
+Ову страница је други корисник у овом тренутку закључао за измене. Мораћете да сачекате док он не заврши са изменама или не истекне закључавање.
diff --git a/inc/lang/sr/login.txt b/inc/lang/sr/login.txt
new file mode 100644
index 000000000..c2f5a6fb6
--- /dev/null
+++ b/inc/lang/sr/login.txt
@@ -0,0 +1,4 @@
+====== Пријављивање ======
+
+Тренутно нисте пријављени! Унесите Ваше информације испод да бисте се пријавили. За то је неопходно да колачићи буду омогућен.
+
diff --git a/inc/lang/sr/mailtext.txt b/inc/lang/sr/mailtext.txt
new file mode 100644
index 000000000..2ed99bf34
--- /dev/null
+++ b/inc/lang/sr/mailtext.txt
@@ -0,0 +1,17 @@
+Страница на Вашем DokuWiki-ју је додата или измењена. Ево детаља
+
+Датум : @DATE@
+Веб читач : @BROWSER@
+ИП адреса : @IPADDRESS@
+Име домаћина : @HOSTNAME@
+Стара ревизија : @OLDPAGE@
+Нова ревизија : @NEWPAGE@
+Сажетак измена : @SUMMARY@
+Корисник : @USER@
+
+@DIFF@
+
+
+--
+Ову поруку је генерисао DokuWiki са
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sr/newpage.txt b/inc/lang/sr/newpage.txt
new file mode 100644
index 000000000..40a36e6f6
--- /dev/null
+++ b/inc/lang/sr/newpage.txt
@@ -0,0 +1,3 @@
+====== Ова тема још увек не постоји ======
+
+Пратили сте везу до теме која још увек не постоји. Можете да је направите користећи дугме ''Направи ову страницу''.
diff --git a/inc/lang/sr/norev.txt b/inc/lang/sr/norev.txt
new file mode 100644
index 000000000..73f8d0b48
--- /dev/null
+++ b/inc/lang/sr/norev.txt
@@ -0,0 +1,4 @@
+====== Не постоји таква ревизија ======
+
+Задата ревизија не постоји. Искористите дугме ''Старе ревизије'' да излистате старе ревизије овог документа.
+
diff --git a/inc/lang/sr/password.txt b/inc/lang/sr/password.txt
new file mode 100644
index 000000000..114185574
--- /dev/null
+++ b/inc/lang/sr/password.txt
@@ -0,0 +1,10 @@
+Здраво @FULLNAME@!
+
+Ево Ваших података за @TITLE@ на @DOKUWIKIURL@
+
+Корисничко име : @LOGIN@
+Шифра : @PASSWORD@
+
+--
+Ову поруку је генерисао DokuWiki на
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sr/preview.txt b/inc/lang/sr/preview.txt
new file mode 100644
index 000000000..be928884f
--- /dev/null
+++ b/inc/lang/sr/preview.txt
@@ -0,0 +1,4 @@
+====== Преглед ======
+
+Ово је преглед тога како би Ваш текст изгледао. Не заборавите: он још **није сачуван**!
+
diff --git a/inc/lang/sr/pwconfirm.txt b/inc/lang/sr/pwconfirm.txt
new file mode 100644
index 000000000..35e23b75d
--- /dev/null
+++ b/inc/lang/sr/pwconfirm.txt
@@ -0,0 +1,13 @@
+Здраво @FULLNAME@!
+
+Неко је затражио нову лозинку за Ваш налог @TITLE@ на @DOKUWIKIURL@
+
+Ако то нисте Ви, само игноришите ову поруку.
+
+У супротном, да бисте потврдили захтев кликните на следећи линк:
+
+@CONFIRM@
+
+--
+Ову поруку је генерисао DokuWiki sa
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sr/read.txt b/inc/lang/sr/read.txt
new file mode 100644
index 000000000..c2d9ffff7
--- /dev/null
+++ b/inc/lang/sr/read.txt
@@ -0,0 +1,2 @@
+Ова страница је само за читање. Можете да погледате изворни код, али не можете да је мењате. Обратите се администратору ако мислите да то није уреду.
+
diff --git a/inc/lang/sr/recent.txt b/inc/lang/sr/recent.txt
new file mode 100644
index 000000000..54c0c26f0
--- /dev/null
+++ b/inc/lang/sr/recent.txt
@@ -0,0 +1,5 @@
+====== Скорије измене ======
+
+Следеће странице су биле измењене у скорије време.
+
+
diff --git a/inc/lang/sr/register.txt b/inc/lang/sr/register.txt
new file mode 100644
index 000000000..a553b7a1f
--- /dev/null
+++ b/inc/lang/sr/register.txt
@@ -0,0 +1,4 @@
+====== Региструјте се као нови корисник ======
+
+Попуните све информације испод како би сте направили нови налог на овом викију. Обавезно упишите **тачну е-адресу** - Ваша нова лозинка ће тамо бити послата. Корисничко име би требало да буде исправно [[doku>pagename|име странице]]
+
diff --git a/inc/lang/sr/registermail.txt b/inc/lang/sr/registermail.txt
new file mode 100644
index 000000000..efdcbb5c5
--- /dev/null
+++ b/inc/lang/sr/registermail.txt
@@ -0,0 +1,15 @@
+Регистрован је нови корисник. Ово су детаљи:
+
+Корисничко име: @NEWUSER@
+Име и презиме: @NEWNAME@
+Е-адреса: @NEWEMAIL@
+
+Датум: @DATE@
+Веб читач: @BROWSER@
+ИП адреса: @IPADDRESS@
+Домаћин: @HOSTNAME@
+
+
+--
+Ову поруку је генерисао DokuWiki sa
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sr/resendpwd.txt b/inc/lang/sr/resendpwd.txt
new file mode 100644
index 000000000..7f6623dbd
--- /dev/null
+++ b/inc/lang/sr/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Пошаљи нову лозинку ======
+
+Молим Вас унесите корисничко име у форму да бисте затражили нову лозинку за Ваш налог на овом викију. Потврдни линк ће бити послат на е-адресу коју сте користили на регистрацији. \ No newline at end of file
diff --git a/inc/lang/sr/revisions.txt b/inc/lang/sr/revisions.txt
new file mode 100644
index 000000000..1ca995a11
--- /dev/null
+++ b/inc/lang/sr/revisions.txt
@@ -0,0 +1,4 @@
+====== Старе ревизије ======
+
+Ово су старије ревизије тренутног документа. Да би сте повратили стару ревизију, изаберите је одоздо, кликните на ''Измени страницу'' и сачувајте је.
+
diff --git a/inc/lang/sr/searchpage.txt b/inc/lang/sr/searchpage.txt
new file mode 100644
index 000000000..010966a7c
--- /dev/null
+++ b/inc/lang/sr/searchpage.txt
@@ -0,0 +1,5 @@
+====== Претрага ======
+
+Испод можете да нађете резултате Ваше претраге. Ако нисте нашли то што сте тражили, можете да направите нову страницу названу по Вашем упиту користећи дугме ''Измени ову страницу''.
+
+===== Резултати =====
diff --git a/inc/lang/sr/showrev.txt b/inc/lang/sr/showrev.txt
new file mode 100644
index 000000000..f2aabb2cb
--- /dev/null
+++ b/inc/lang/sr/showrev.txt
@@ -0,0 +1,2 @@
+**Ово је стара верзија документа!**
+----
diff --git a/inc/lang/sr/stopwords.txt b/inc/lang/sr/stopwords.txt
new file mode 100644
index 000000000..78093e29a
--- /dev/null
+++ b/inc/lang/sr/stopwords.txt
@@ -0,0 +1,12 @@
+# Ово је листа речи које се неће индексирати, по једна реч у реду
+# Када мењате ову датотеку проверите да ли је нови ред записан по UNIX систему
+# Нема потребе уносити речи краће од 3 слова - оне се прескачу иначе
+ваш
+они
+њихов
+како
+ово
+шта
+кад
+где
+www
diff --git a/inc/lang/sr/subscr_digest.txt b/inc/lang/sr/subscr_digest.txt
new file mode 100644
index 000000000..db8416833
--- /dev/null
+++ b/inc/lang/sr/subscr_digest.txt
@@ -0,0 +1,20 @@
+Здраво!
+
+Страница @PAGE@ под Вики насловом @TITLE@ је промењена.
+Ово су промене:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Стара верзија: @OLDPAGE@
+Нова верзија: @NEWPAGE@
+
+
+Да бисте поништили обавештења о променама страница, улогујте се на Вики овде
+@DOKUWIKIURL@ а затим посетите
+@SUBSCRIBE@ и поништите обавештавање о променама страница и/или именских простора..
+
+--
+Овај имејл је направио DokuWiki на страници
+@DOKUWIKIURL@
diff --git a/inc/lang/sr/subscr_form.txt b/inc/lang/sr/subscr_form.txt
new file mode 100644
index 000000000..9bf72e424
--- /dev/null
+++ b/inc/lang/sr/subscr_form.txt
@@ -0,0 +1,3 @@
+===== Управљање претплатама =====
+
+Ова страница вам омогућава да управљате својим претплатама на страницу и именски простор на којима се налазите. \ No newline at end of file
diff --git a/inc/lang/sr/subscr_list.txt b/inc/lang/sr/subscr_list.txt
new file mode 100644
index 000000000..b3887013b
--- /dev/null
+++ b/inc/lang/sr/subscr_list.txt
@@ -0,0 +1,17 @@
+Здраво!
+
+Страница у именском простору @PAGE@ под Вики насловом @TITLE@ је промењена.
+Ово су промењене странице:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+
+Да бисте поништили обавештења о променама страница, улогујте се на Вики овде
+@DOKUWIKIURL@ а затим посетите
+@SUBSCRIBE@ и поништите обавештавање о променама страница и/или именских простора..
+
+--
+Овај имејл је направио DokuWiki на страници
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sr/subscr_single.txt b/inc/lang/sr/subscr_single.txt
new file mode 100644
index 000000000..c0ed4d87a
--- /dev/null
+++ b/inc/lang/sr/subscr_single.txt
@@ -0,0 +1,23 @@
+Здраво!
+
+Страница @PAGE@ под Вики насловом @TITLE@ је промењена.
+Ово су промене:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Датум : @DATE@
+Корисникr : @USER@
+Измени сиже: @SUMMARY@
+Стара верзија: @OLDPAGE@
+Нова верзија: @NEWPAGE@
+
+
+Да бисте поништили обавештења о променама страница, улогујте се на Бики овде
+@DOKUWIKIURL@ а затим посетите
+@SUBSCRIBE@ и поништите обавештавање о променама страница и/или именских простора..
+
+--
+Овај имејл је направио DokuWiki на страници
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sr/updateprofile.txt b/inc/lang/sr/updateprofile.txt
new file mode 100644
index 000000000..15b9955e9
--- /dev/null
+++ b/inc/lang/sr/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Ажурирање Вашег профила ======
+
+Потребно је попунити само она поља која желите да промените. Поље Корисничко име не можете да променити. \ No newline at end of file
diff --git a/inc/lang/sr/uploadmail.txt b/inc/lang/sr/uploadmail.txt
new file mode 100644
index 000000000..36b3bb31d
--- /dev/null
+++ b/inc/lang/sr/uploadmail.txt
@@ -0,0 +1,14 @@
+Нова датотека је послата на Ваш DokuWiki. Ово су њени детањи:
+
+Датотека: @MEDIA@
+Датум: @DATE@
+Веб читач: @BROWSER@
+ИП адреса: @IPADDRESS@
+Домаћин: @HOSTNAME@
+Величина: @SIZE@
+MIME тип: @MIME@
+Корисник: @USER@
+
+--
+Ову поруку је генерисао DokuWiki sa
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/sv/admin.txt b/inc/lang/sv/admin.txt
new file mode 100644
index 000000000..10887da7d
--- /dev/null
+++ b/inc/lang/sv/admin.txt
@@ -0,0 +1,4 @@
+====== Administration ======
+
+Nedan hittar du en lista över de tillgängliga administrativa uppgifterna i DokuWiki.
+
diff --git a/inc/lang/sv/adminplugins.txt b/inc/lang/sv/adminplugins.txt
new file mode 100644
index 000000000..0af37c769
--- /dev/null
+++ b/inc/lang/sv/adminplugins.txt
@@ -0,0 +1,2 @@
+
+===== Ytterligare Tillägg ===== \ No newline at end of file
diff --git a/inc/lang/sv/backlinks.txt b/inc/lang/sv/backlinks.txt
new file mode 100644
index 000000000..c907c8ecf
--- /dev/null
+++ b/inc/lang/sv/backlinks.txt
@@ -0,0 +1,3 @@
+====== Tillbakalänkar ======
+
+Detta är en lista över sidor som verkar länka tillbaka till den aktuella sidan.
diff --git a/inc/lang/sv/conflict.txt b/inc/lang/sv/conflict.txt
new file mode 100644
index 000000000..42168d1b4
--- /dev/null
+++ b/inc/lang/sv/conflict.txt
@@ -0,0 +1,6 @@
+====== Det finns en senare version ======
+
+Det finns en senare version av dokumentet du har redigerat. Detta kan hända när en annan användare redigerar dokumentet samtidigt som du.
+
+Granska skillnaderna som visas nedan noga, och välj sedan vilken version du vill behålla. Om du väljer ''spara'', så kommer din version att sparas. Välj ''avbryt'' för att behålla den nuvarande versionen.
+
diff --git a/inc/lang/sv/denied.txt b/inc/lang/sv/denied.txt
new file mode 100644
index 000000000..64d129227
--- /dev/null
+++ b/inc/lang/sv/denied.txt
@@ -0,0 +1,4 @@
+====== Åtkomst nekad ======
+
+Tyvärr, du har inte behörighet att fortsätta. Kanske har du glömt att logga in?
+
diff --git a/inc/lang/sv/diff.txt b/inc/lang/sv/diff.txt
new file mode 100644
index 000000000..9fb8c20f2
--- /dev/null
+++ b/inc/lang/sv/diff.txt
@@ -0,0 +1,4 @@
+====== Skillnader ======
+
+Här visas skillnader mellan den valda versionen och den nuvarande versionen av sidan.
+
diff --git a/inc/lang/sv/draft.txt b/inc/lang/sv/draft.txt
new file mode 100644
index 000000000..3749ad035
--- /dev/null
+++ b/inc/lang/sv/draft.txt
@@ -0,0 +1,6 @@
+====== Utkast hittat ======
+
+Din senaste redigering av sidan avslutades inte på ett korrekt sätt. DokuWiki sparade automatiskt ett utkast under tiden du arbetade, och nu kan du använda det för att fortsätta redigeringen. Nedan kan du se det innehåll som sparats från din förra session.
+
+Bestäm om du vill //återskapa// din förlorade redigeringssession, //radera// det automatiskt sparade utkastet eller //avbryta// redigeringen.
+
diff --git a/inc/lang/sv/edit.txt b/inc/lang/sv/edit.txt
new file mode 100644
index 000000000..187b11fca
--- /dev/null
+++ b/inc/lang/sv/edit.txt
@@ -0,0 +1,2 @@
+Redigera sidan och klicka ''Spara''. Se [[wiki:syntax]] för Wikisyntax. Redigera bara sidan om du kan **förbättra** den. Om du vill testa hur saker och ting fungerar, gör det på [[playground:playground|lekplatsen]].
+
diff --git a/inc/lang/sv/editrev.txt b/inc/lang/sv/editrev.txt
new file mode 100644
index 000000000..8bd1adb0a
--- /dev/null
+++ b/inc/lang/sv/editrev.txt
@@ -0,0 +1,2 @@
+**Du har hämtat en tidigare version av dokumentet!** Om du sparar den så kommer du att skapa en ny version med detta innehåll.
+----
diff --git a/inc/lang/sv/index.txt b/inc/lang/sv/index.txt
new file mode 100644
index 000000000..24d715b74
--- /dev/null
+++ b/inc/lang/sv/index.txt
@@ -0,0 +1,4 @@
+====== Innehållsförteckning ======
+
+Detta är en innehållsförteckning över alla tillgängliga sidor, sorterad efter [[doku>namespaces|namnrymder]].
+
diff --git a/inc/lang/sv/install.html b/inc/lang/sv/install.html
new file mode 100644
index 000000000..11e2eea49
--- /dev/null
+++ b/inc/lang/sv/install.html
@@ -0,0 +1,25 @@
+<p>Denna sida hjälper dig med nyinstallation och inställningar för
+<a href="http://dokuwiki.org">Dokuwiki</a>. Mer information om
+installationsprogrammet finns på dess egen
+<a href="http://dokuwiki.org/installer">dokumentationssida</a>.</p>
+
+<p>DokuWiki använder vanliga filer för att lagra wikisidor och annan
+information som här till sidorna (till exempel bilder, sökindex, gamla
+versioner, etc). För att kunna fungera
+<strong>måste</strong> DokuWiki ha skrivrättigheter i de kataloger där
+filerna ligger. Detta installationsprogram kan inte ändra rättigheter
+på kataloger. Det måste normalt göras direkt på en kommandorad, eller
+om du använder ett webbhotell, via FTP eller din leverantörs kontrollpanel
+(till exempel cPanel).</p>
+
+<p>Detta installationsprogram anpassar inställningarna i din DokuWiki för
+<acronym title="access control list">ACL</acronym> (behörighetslista), vilket i sin tur gör att
+administratören kan logga in och komma åt DokuWikis administrationsmenu för
+att installera insticksmoduler, hantera användare, hantera behörighet till
+wikisidor och ändra inställningar. ACL är inget krav för att DokuWiki ska
+fungera, men det förenklar administrationen.</p>
+
+<p>Erfarna användare, eller användare med särskilda behov, kan använda dessa
+länkar för att hitta mer detaljer om
+<a href="http://dokuwiki.org/install">installation</a>
+och <a href="http://dokuwiki.org/config">inställningar</a>.</p>
diff --git a/inc/lang/sv/lang.php b/inc/lang/sv/lang.php
new file mode 100644
index 000000000..8601829d2
--- /dev/null
+++ b/inc/lang/sv/lang.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * Swedish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Joaquim Homrighausen <joho@webbplatsen.se>
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author Tormod Johansson <tormod.otter.johansson@gmail.com>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author mikael@mallander.net
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '”';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '’';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Redigera sidan';
+$lang['btn_source'] = 'Visa källkod';
+$lang['btn_show'] = 'Visa sidan';
+$lang['btn_create'] = 'Skapa sidan';
+$lang['btn_search'] = 'Sök';
+$lang['btn_save'] = 'Spara';
+$lang['btn_preview'] = 'Granska';
+$lang['btn_top'] = 'Till början av sidan';
+$lang['btn_newer'] = '<< nyare';
+$lang['btn_older'] = 'äldre >>';
+$lang['btn_revs'] = 'Historik';
+$lang['btn_recent'] = 'Nyligen ändrat';
+$lang['btn_upload'] = 'Ladda upp';
+$lang['btn_cancel'] = 'Avbryt';
+$lang['btn_index'] = 'Index';
+$lang['btn_secedit'] = 'Redigera';
+$lang['btn_login'] = 'Logga in';
+$lang['btn_logout'] = 'Logga ut';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Uppdatera';
+$lang['btn_delete'] = 'Radera';
+$lang['btn_back'] = 'Tillbaka';
+$lang['btn_backlink'] = 'Tillbakalänkar';
+$lang['btn_backtomedia'] = 'Tillbaka till val av Mediafil';
+$lang['btn_subscribe'] = 'Prenumerera på ändringar';
+$lang['btn_profile'] = 'Uppdatera profil';
+$lang['btn_reset'] = 'Återställ';
+$lang['btn_resendpwd'] = 'Skicka nytt lösenord';
+$lang['btn_draft'] = 'Redigera utkast';
+$lang['btn_recover'] = 'Återskapa utkast';
+$lang['btn_draftdel'] = 'Radera utkast';
+$lang['btn_revert'] = 'Återställ';
+$lang['btn_register'] = 'Registrera';
+$lang['loggedinas'] = 'Inloggad som';
+$lang['user'] = 'Användarnamn';
+$lang['pass'] = 'Lösenord';
+$lang['newpass'] = 'Nytt lösenord';
+$lang['oldpass'] = 'Bekräfta nuvarande lösenord';
+$lang['passchk'] = 'en gång till';
+$lang['remember'] = 'Kom ihåg mig';
+$lang['fullname'] = 'Namn';
+$lang['email'] = 'E-post';
+$lang['profile'] = 'Användarprofil';
+$lang['badlogin'] = 'Felaktigt användarnamn eller lösenord.';
+$lang['minoredit'] = 'Små ändringar';
+$lang['draftdate'] = 'Utkast automatiskt sparat';
+$lang['nosecedit'] = 'Sidan ändrades medan du skrev, sektionsinformationen var inte uppdaterad. Laddar hela sidan istället.';
+$lang['regmissing'] = 'Du måste fylla i alla fälten.';
+$lang['reguexists'] = 'Det finns redan en användare med det användarnamnet.';
+$lang['regsuccess'] = 'Användarkontot skapat, lösenordet har skickats via e-post.';
+$lang['regsuccess2'] = 'Användarkontot skapat.';
+$lang['regmailfail'] = 'Ett fel uppstod när ditt lösenord skulle skickas via e-post. Var god kontakta administratören!';
+$lang['regbadmail'] = 'Den angivna e-postadressen verkar vara ogiltig - om du anser detta felaktigt, var god kontakta administratören';
+$lang['regbadpass'] = 'De två angivna lösenorden är inte identiska. Försök igen.';
+$lang['regpwmail'] = 'Ditt DokuWikilösenord';
+$lang['reghere'] = 'Har du inte ett konto än? Skaffa ett';
+$lang['profna'] = 'Denna wiki stödjer inte ändringar av profiler';
+$lang['profnochange'] = 'Ingenting ändrades, inget att göra.';
+$lang['profnoempty'] = 'Namn och e-postadress måste fyllas i.';
+$lang['profchanged'] = 'Användarprofilen uppdaterad.';
+$lang['pwdforget'] = 'Glömt ditt lösenord? Ordna ett nytt';
+$lang['resendna'] = 'Den här wikin stödjer inte utskick av lösenord.';
+$lang['resendpwd'] = 'Skicka nytt lösenord för';
+$lang['resendpwdmissing'] = 'Du måste fylla i alla fält.';
+$lang['resendpwdnouser'] = 'Den här användaren hittas inte i databasen.';
+$lang['resendpwdbadauth'] = 'Den här verifieringskoden är inte giltig. Kontrollera att du använde hela verifieringslänken.';
+$lang['resendpwdconfirm'] = 'En verifieringslänk har skickats med e-post.';
+$lang['resendpwdsuccess'] = 'Ditt nya lösenord har skickats med e-post.';
+$lang['license'] = 'Om inte annat angivet, innehållet i denna wiki är licensierat under följande licenser:';
+$lang['licenseok'] = 'Notera: Genom att ändra i denna sidan så accepterar du att licensiera ditt bidrag under följande licenser:';
+$lang['searchmedia'] = 'Sök efter filnamn:';
+$lang['searchmedia_in'] = 'Sök i %s';
+$lang['txt_upload'] = 'Välj fil att ladda upp';
+$lang['txt_filename'] = 'Ladda upp som (ej obligatoriskt)';
+$lang['txt_overwrt'] = 'Skriv över befintlig fil';
+$lang['lockedby'] = 'Låst av';
+$lang['lockexpire'] = 'Lås upphör att gälla';
+$lang['js']['willexpire'] = 'Ditt redigeringslås för detta dokument kommer snart att upphöra.\nFör att undvika versionskonflikter bör du förhandsgranska ditt dokument för att förlänga redigeringslåset.';
+$lang['js']['notsavedyet'] = 'Det finns ändringar som inte är sparade.
+Är du säker på att du vill fortsätta?';
+$lang['js']['searchmedia'] = 'Sök efter filer';
+$lang['js']['keepopen'] = 'Lämna fönstret öppet efter val av fil';
+$lang['js']['hidedetails'] = 'Dölj detaljer';
+$lang['js']['mediatitle'] = 'Länkinställningar';
+$lang['js']['mediadisplay'] = 'Länktyp';
+$lang['js']['mediaalign'] = 'Justering';
+$lang['js']['mediasize'] = 'Bildstorlek';
+$lang['js']['mediatarget'] = 'Länköppning';
+$lang['js']['mediaclose'] = 'Stäng';
+$lang['js']['mediadisplayimg'] = 'Visa bilden.';
+$lang['js']['mediadisplaylnk'] = 'Visa endast länken.';
+$lang['js']['mediasmall'] = 'Liten storlek';
+$lang['js']['mediamedium'] = 'Mellanstor storlek';
+$lang['js']['medialarge'] = 'Stor storlek';
+$lang['js']['mediaoriginal'] = 'Originalstorlek';
+$lang['js']['mediadirect'] = 'Direktlänk till originalet';
+$lang['js']['medianolnk'] = 'Ingen länk';
+$lang['js']['medianolink'] = 'Länka inte bilden';
+$lang['js']['medialeft'] = 'Justera bilden till vänster.';
+$lang['js']['mediaright'] = 'Justera bilden till höger.';
+$lang['js']['mediacenter'] = 'Centrera bilden.';
+$lang['js']['nosmblinks'] = 'Länkning till Windowsresurser fungerar bara med Microsofts Internet Explorer.
+Du kan fortfarande klippa och klistra in länken om du använder en annan webbläsare än MSIE.';
+$lang['js']['linkwiz'] = 'Snabbguide Länkar';
+$lang['js']['linkto'] = 'Länk till:';
+$lang['js']['del_confirm'] = 'Vill du verkligen radera?';
+$lang['rssfailed'] = 'Ett fel uppstod när detta RSS-flöde skulle hämtas: ';
+$lang['nothingfound'] = 'Inga filer hittades.';
+$lang['mediaselect'] = 'Mediafiler';
+$lang['fileupload'] = 'Ladda upp mediafiler';
+$lang['uploadsucc'] = 'Uppladdningen lyckades';
+$lang['uploadfail'] = 'Uppladdningen misslyckades, fel filskydd?';
+$lang['uploadwrong'] = 'Uppladdning nekad. Filändelsen är inte tillåten!';
+$lang['uploadexist'] = 'Filen finns redan. Ingenting gjordes.';
+$lang['uploadbadcontent'] = 'Det uppladdade innehållet stämde inte överens med filändelsen %s.';
+$lang['uploadspam'] = 'Uppladdningen stoppades av spärrlistan för spam.';
+$lang['uploadxss'] = 'Uppladdningen stoppades på grund av eventuellt skadligt innehåll.';
+$lang['uploadsize'] = 'Den uppladdade filen är för stor. (max. %s)';
+$lang['deletesucc'] = 'Filen "%s" har raderats.';
+$lang['deletefail'] = 'Kunde inte radera "%s" - kontrollera filskydd.';
+$lang['mediainuse'] = 'Filen "%s" har inte raderats - den används fortfarande.';
+$lang['namespaces'] = 'Namnrymder';
+$lang['mediafiles'] = 'Tillgängliga filer i';
+$lang['accessdenied'] = 'Du får inte läsa den här sidan.';
+$lang['mediausage'] = 'Använd följande syntax för att referera till denna fil:';
+$lang['mediaview'] = 'Visa originalfilen';
+$lang['mediaroot'] = 'rot';
+$lang['mediaupload'] = 'Här kan du ladda upp en fil till den nuvarande namnrymden. För att skapa undernamnrymder, skriv dem före filnamnet under "Ladda upp som". Separera namnrymd och filnamn med kolon.';
+$lang['mediaextchange'] = 'Filändelsen ändrad från .%s till .%s!';
+$lang['reference'] = 'Referenser till';
+$lang['ref_inuse'] = 'Filen kan inte raderas eftersom den fortfarande används av följande sidor:';
+$lang['ref_hidden'] = 'Vissa referenser är på sidor som du inte har rätt att läsa';
+$lang['hits'] = 'Träffar';
+$lang['quickhits'] = 'Matchande sidnamn';
+$lang['toc'] = 'Innehållsförteckning';
+$lang['current'] = 'aktuell';
+$lang['yours'] = 'Din version';
+$lang['diff'] = 'visa skillnader mot aktuell version';
+$lang['diff2'] = 'Visa skillnader mellan valda versioner';
+$lang['difflink'] = 'Länk till den här jämförelsesidan';
+$lang['diff_type'] = 'Visa skillnader:';
+$lang['diff_side'] = 'Sida vid sida';
+$lang['line'] = 'Rad';
+$lang['breadcrumb'] = 'Spår';
+$lang['youarehere'] = 'Här är du';
+$lang['lastmod'] = 'Senast uppdaterad';
+$lang['by'] = 'av';
+$lang['deleted'] = 'raderad';
+$lang['created'] = 'skapad';
+$lang['restored'] = 'tidigare version återställd';
+$lang['external_edit'] = 'extern redigering';
+$lang['summary'] = 'Redigeringskommentar';
+$lang['noflash'] = '<a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> behövs för att visa detta innehåll.';
+$lang['download'] = 'Ladda ner kodfragmentet';
+$lang['mail_newpage'] = 'sida tillagd:';
+$lang['mail_changed'] = 'sida ändrad:';
+$lang['mail_new_user'] = 'Ny användare:';
+$lang['mail_upload'] = 'fil uppladdad:';
+$lang['qb_bold'] = 'Fet text';
+$lang['qb_italic'] = 'Kursiv text';
+$lang['qb_underl'] = 'Understruken text';
+$lang['qb_code'] = 'Kodtext';
+$lang['qb_strike'] = 'Överstruken text';
+$lang['qb_h1'] = 'Rubrik nivå 1';
+$lang['qb_h2'] = 'Rubrik nivå 2';
+$lang['qb_h3'] = 'Rubrik nivå 3';
+$lang['qb_h4'] = 'Rubrik nivå 4';
+$lang['qb_h5'] = 'Rubrik nivå 5';
+$lang['qb_h'] = 'Rubrik';
+$lang['qb_hs'] = 'Välj Rubrik';
+$lang['qb_hplus'] = 'Större Rubrik';
+$lang['qb_hminus'] = 'Mindre Rubrik';
+$lang['qb_hequal'] = 'Rubrik samma nivå.';
+$lang['qb_link'] = 'Intern Länk';
+$lang['qb_extlink'] = 'Extern Länk';
+$lang['qb_hr'] = 'Horisontell linje';
+$lang['qb_ol'] = 'Punkt i sorterad lista';
+$lang['qb_ul'] = 'Punkt i osorterad lista';
+$lang['qb_media'] = 'Lägg till bilder och andra filer';
+$lang['qb_sig'] = 'Infoga signatur';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Specialtecken';
+$lang['upperns'] = 'hoppa till föräldernamnrymd';
+$lang['admin_register'] = 'Lägg till ny användare';
+$lang['metaedit'] = 'Redigera metadata';
+$lang['metasaveerr'] = 'Skrivning av metadata misslyckades';
+$lang['metasaveok'] = 'Metadata sparad';
+$lang['img_backto'] = 'Tillbaka till';
+$lang['img_title'] = 'Rubrik';
+$lang['img_caption'] = 'Bildtext';
+$lang['img_date'] = 'Datum';
+$lang['img_fname'] = 'Filnamn';
+$lang['img_fsize'] = 'Storlek';
+$lang['img_artist'] = 'Fotograf';
+$lang['img_copyr'] = 'Copyright';
+$lang['img_format'] = 'Format';
+$lang['img_camera'] = 'Kamera';
+$lang['img_keywords'] = 'Nyckelord';
+$lang['subscr_m_new_header'] = 'Lägg till prenumeration';
+$lang['subscr_m_current_header'] = 'Nuvarande prenumerationer';
+$lang['subscr_m_unsubscribe'] = 'Avsluta prenumeration';
+$lang['subscr_m_subscribe'] = 'Prenumerera';
+$lang['subscr_m_receive'] = 'Ta emot';
+$lang['subscr_style_every'] = 'skicka epost vid varje ändring';
+$lang['authmodfailed'] = 'Felaktiga inställningar för användarautentisering. Var vänlig meddela wikiadministratören.';
+$lang['authtempfail'] = 'Tillfälligt fel på användarautentisering. Om felet kvarstår, var vänlig meddela wikiadministratören.';
+$lang['i_chooselang'] = 'Välj språk';
+$lang['i_installer'] = 'Installation av DokuWiki';
+$lang['i_wikiname'] = 'Wikins namn';
+$lang['i_enableacl'] = 'Aktivera behörighetslistan (ACL) (rekommenderas)';
+$lang['i_superuser'] = 'Användarnamn för administratören';
+$lang['i_problems'] = 'Installationsprogrammet hittade några problem som visas nedan. Du kan inte fortsätta innan du har fixat dem.';
+$lang['i_modified'] = 'Av säkerhetsskäl fungerar det här skriptet bara med en ny och omodifierad installation av Dokuwiki.
+ Du får antingen packa upp det nedladdade paketet på nytt, eller konsultera de kompletta
+ <a href="http://dokuwiki.org/install">instruktionerna för installation av Dokuwiki</a>';
+$lang['i_funcna'] = 'PHP-funktionen <code>%s</code> är inte tillgänglig. Kanske ditt webbhotell har avaktiverat den av någon anledning?';
+$lang['i_phpver'] = 'Din PHP-version <code>%s</code> är lägre än vad som krävs <code>%s</code>. Du behöver uppgradera din PHP-installation.';
+$lang['i_permfail'] = '<code>%s</code> är inte skrivbar av DokuWiki. Du behöver ändra filskyddet på den här katalogen!';
+$lang['i_confexists'] = '<code>%s</code> finns redan';
+$lang['i_writeerr'] = 'Kan inte skapa <code>%s</code>. Kontrollera filskyddet på kataloger/filer och skapa filen manuellt.';
+$lang['i_badhash'] = 'okänd eller ändrad dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - felaktig eller blank';
+$lang['i_success'] = 'Konfigurationen avslutades utan fel. Du kan radera filen install.php nu. Fortsätt till
+ <a href="doku.php">din nya DokuWiki</a>.';
+$lang['i_failure'] = 'Fel uppstod vid skrivning av konfigurationsfilerna. Du kan behöva ordna till dem manuellt innan
+ du kan använda <a href="doku.php">din nya DokuWiki</a>.';
+$lang['i_policy'] = 'Initial ACL-policy';
+$lang['i_pol0'] = 'Öppen wiki (alla får läsa, skriva och ladda upp filer)';
+$lang['i_pol1'] = 'Publik wiki (alla får läsa, registrerade användare för skriva och ladda upp filer)';
+$lang['i_pol2'] = 'Sluten wiki (endast registrerade användare får läsa, skriva och ladda upp filer)';
+$lang['i_retry'] = 'Försök igen';
+$lang['recent_global'] = 'Du bevakar ändringar i namnrymden <b>%s</b>. Du kan också titta på <a href="%s">senaste ändringar för hela wikin</a>.';
+$lang['years'] = '%d år sedan';
+$lang['months'] = '%d månader sedan';
+$lang['weeks'] = '%d veckor sedan';
+$lang['days'] = '%d dagar sedan';
+$lang['hours'] = '%d timmar sedan';
+$lang['minutes'] = '%d minuter sedan';
+$lang['seconds'] = '%d sekunder sedan';
+$lang['wordblock'] = 'Din ändring sparades inte för att den innehåller otillåten text (spam).';
diff --git a/inc/lang/sv/locked.txt b/inc/lang/sv/locked.txt
new file mode 100644
index 000000000..cb64eaf02
--- /dev/null
+++ b/inc/lang/sv/locked.txt
@@ -0,0 +1,3 @@
+====== Sidan låst ======
+
+Den här sidan är för närvarande låst för redigering av en annan användare. Du måste vänta tills den användaren är klar med sin redigering, eller tills dess att dokumentlåset upphör att gälla.
diff --git a/inc/lang/sv/login.txt b/inc/lang/sv/login.txt
new file mode 100644
index 000000000..5f0e3b262
--- /dev/null
+++ b/inc/lang/sv/login.txt
@@ -0,0 +1,4 @@
+====== Logga in ======
+
+Du är inte inloggad! Ange ditt användarnamn och lösenord i formuläret nedan för att logga in. Stöd för cookies måste vara aktiverat i din webbläsare för att du skall kunna logga in.
+
diff --git a/inc/lang/sv/mailtext.txt b/inc/lang/sv/mailtext.txt
new file mode 100644
index 000000000..616bb4eee
--- /dev/null
+++ b/inc/lang/sv/mailtext.txt
@@ -0,0 +1,17 @@
+En sida i din DokuWiki har lagts till eller ändrats. Här är detaljerna:
+
+Datum : @DATE@
+Webbläsare : @BROWSER@
+IP-adress : @IPADDRESS@
+Datornamn : @HOSTNAME@
+Tidigare version : @OLDPAGE@
+Aktuell version : @NEWPAGE@
+Redigeringskommentar : @SUMMARY@
+Användare : @USER@
+
+@DIFF@
+
+
+--
+Detta meddelande har skapats av DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/sv/newpage.txt b/inc/lang/sv/newpage.txt
new file mode 100644
index 000000000..3e0951056
--- /dev/null
+++ b/inc/lang/sv/newpage.txt
@@ -0,0 +1,3 @@
+====== Det här ämnet finns inte ännu ======
+
+Du har följt en länk till ett ämne som inte finns ännu. Du kan skapa det genom att klicka på ''Skapa den här sidan''.
diff --git a/inc/lang/sv/norev.txt b/inc/lang/sv/norev.txt
new file mode 100644
index 000000000..46df86235
--- /dev/null
+++ b/inc/lang/sv/norev.txt
@@ -0,0 +1,4 @@
+====== Det finns ingen sådan version ======
+
+Den angivna versionen finns inte. Använd ''Historik'' för en förteckning över de versioner som finns av detta dokument.
+
diff --git a/inc/lang/sv/password.txt b/inc/lang/sv/password.txt
new file mode 100644
index 000000000..934d913d6
--- /dev/null
+++ b/inc/lang/sv/password.txt
@@ -0,0 +1,10 @@
+Hej @FULLNAME@!
+
+Här är dina användaruppgifter för @TITLE@ på @DOKUWIKIURL@
+
+Användarnamn : @LOGIN@
+Lösenord : @PASSWORD@
+
+--
+Detta meddelande har skapats av DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/sv/preview.txt b/inc/lang/sv/preview.txt
new file mode 100644
index 000000000..5c3a65341
--- /dev/null
+++ b/inc/lang/sv/preview.txt
@@ -0,0 +1,4 @@
+====== Förhandsgranskning ======
+
+Detta är en förhandstitt på hur din text kommer att se ut när den visas. Kom ihåg: Den är **inte sparad** ännu!
+
diff --git a/inc/lang/sv/pwconfirm.txt b/inc/lang/sv/pwconfirm.txt
new file mode 100644
index 000000000..541437716
--- /dev/null
+++ b/inc/lang/sv/pwconfirm.txt
@@ -0,0 +1,16 @@
+Hej @FULLNAME@!
+
+Någon har bett om ett nytt lösenord för ditt konto på @TITLE@
+(@DOKUWIKIURL@)
+
+Om det inte var du som bad om ett nytt lösenord kan du helt
+enkelt ignorera det här brevet.
+
+För att bekräfta att förfrågan verkligen kom från dig, var vänlig
+och använd följande länk.
+
+@CONFIRM@
+
+--
+Detta meddelande har skapats av DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/sv/read.txt b/inc/lang/sv/read.txt
new file mode 100644
index 000000000..5391b3ddf
--- /dev/null
+++ b/inc/lang/sv/read.txt
@@ -0,0 +1,2 @@
+Denna sida är skrivskyddad. Du kan titta på källkoden, men inte ändra den. Kontakta administratören om du anser att du bör kunna ändra sidan.
+
diff --git a/inc/lang/sv/recent.txt b/inc/lang/sv/recent.txt
new file mode 100644
index 000000000..d8c39dfa5
--- /dev/null
+++ b/inc/lang/sv/recent.txt
@@ -0,0 +1,5 @@
+====== Senaste ändringarna ======
+
+Följande sidor/dokument har nyligen uppdaterats.
+
+
diff --git a/inc/lang/sv/register.txt b/inc/lang/sv/register.txt
new file mode 100644
index 000000000..e75d2a672
--- /dev/null
+++ b/inc/lang/sv/register.txt
@@ -0,0 +1,4 @@
+====== Registrera dig som användare ======
+
+Fyll i all information som efterfrågas i formuläret nedan för att skapa ett nytt konto i denna wiki. Var särskilt noga med att ange en **giltig e-postadress** - om du inte blir ombedd att ange ett lösenord här kommer ett nytt lösenord att skickas till den adressen. Användarnamnet skall vara ett giltigt [[doku>pagename|sidnamn]].
+
diff --git a/inc/lang/sv/registermail.txt b/inc/lang/sv/registermail.txt
new file mode 100644
index 000000000..c0edc3728
--- /dev/null
+++ b/inc/lang/sv/registermail.txt
@@ -0,0 +1,14 @@
+En ny användare har registrerat sig. Här är detaljerna:
+
+Användarnamn : @NEWUSER@
+Namn : @NEWNAME@
+E-post : @NEWEMAIL@
+
+Datum : @DATE@
+Webbläsare : @BROWSER@
+IP-adress : @IPADDRESS@
+Datornamn : @HOSTNAME@
+
+--
+Detta meddelande har skapats av DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/sv/resendpwd.txt b/inc/lang/sv/resendpwd.txt
new file mode 100644
index 000000000..0757ee9dd
--- /dev/null
+++ b/inc/lang/sv/resendpwd.txt
@@ -0,0 +1,4 @@
+====== Skicka nytt lösenord ======
+
+Fyll i ditt användarnamn i formuläret nedan för att få ett nytt lösenord till ditt konto i denna wiki. En länk för verifiering kommer att skickas till din registrerade e-postadress.
+
diff --git a/inc/lang/sv/revisions.txt b/inc/lang/sv/revisions.txt
new file mode 100644
index 000000000..b9dfc5600
--- /dev/null
+++ b/inc/lang/sv/revisions.txt
@@ -0,0 +1,4 @@
+====== Historik ======
+
+Här visas tidigare versioner av detta dokument. För att återställa dokumentet till en tidigare version, välj den önskade versionen nedan, klicka på ''Redigera sida'' och spara sedan dokumentet.
+
diff --git a/inc/lang/sv/searchpage.txt b/inc/lang/sv/searchpage.txt
new file mode 100644
index 000000000..bcc88cd95
--- /dev/null
+++ b/inc/lang/sv/searchpage.txt
@@ -0,0 +1,5 @@
+====== Sök ======
+
+Nedan ser du resultatet av sökningen. Om du inte hittar det du letar efter, så kan du skapa eller redigera sidan med någon av knapparna.
+
+===== Resultat =====
diff --git a/inc/lang/sv/showrev.txt b/inc/lang/sv/showrev.txt
new file mode 100644
index 000000000..a79b30b11
--- /dev/null
+++ b/inc/lang/sv/showrev.txt
@@ -0,0 +1,2 @@
+**Detta är en gammal version av dokumentet!**
+----
diff --git a/inc/lang/sv/stopwords.txt b/inc/lang/sv/stopwords.txt
new file mode 100644
index 000000000..357659673
--- /dev/null
+++ b/inc/lang/sv/stopwords.txt
@@ -0,0 +1,129 @@
+# 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
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
+
+# Följande svenska stoppord kommer från
+# http://snowball.tartarus.org/algorithms/swedish/stop.txt. Ord kortare än tre
+# bokstäver har tagits bort (se kommentaren ovan) Se även
+# http://www.cling.gu.se/theses/2004/cl0sknub_cl0tsven.pdf. Vi behåller de
+# engelska orden eftersom det är rätt vanligt med engelska texter.
+och
+det
+att
+jag
+hon
+som
+han
+den
+med
+var
+sig
+för
+till
+men
+ett
+hade
+icke
+mig
+henne
+sin
+har
+inte
+hans
+honom
+skulle
+hennes
+där
+min
+man
+vid
+kunde
+något
+från
+när
+efter
+upp
+dem
+vara
+vad
+över
+dig
+kan
+sina
+här
+mot
+alla
+under
+någon
+eller
+allt
+mycket
+sedan
+denna
+själv
+detta
+utan
+varit
+hur
+ingen
+mitt
+bli
+blev
+oss
+din
+dessa
+några
+deras
+blir
+mina
+samma
+vilken
+sådan
+vår
+blivit
+dess
+inom
+mellan
+sådant
+varför
+varje
+vilka
+ditt
+vem
+vilket
+sitta
+sådana
+vart
+dina
+vars
+vårt
+våra
+ert
+era
+vilkas
diff --git a/inc/lang/sv/updateprofile.txt b/inc/lang/sv/updateprofile.txt
new file mode 100644
index 000000000..98ed6e33f
--- /dev/null
+++ b/inc/lang/sv/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Uppdatera din användarprofil ======
+
+Du behöver bara fylla i de fält som du vill ändra. Du kan inte ändra ditt användarnamn.
+
+
diff --git a/inc/lang/sv/uploadmail.txt b/inc/lang/sv/uploadmail.txt
new file mode 100644
index 000000000..5963adcbd
--- /dev/null
+++ b/inc/lang/sv/uploadmail.txt
@@ -0,0 +1,14 @@
+En fil har laddats upp till din DokuWiki. Här är detaljerna:
+
+Fil : @MEDIA@
+Datum : @DATE@
+Webbläsare : @BROWSER@
+IP-adress : @IPADDRESS@
+Datornamn : @HOSTNAME@
+Storlek : @SIZE@
+MIME-typ : @MIME@
+Användare : @USER@
+
+--
+Detta meddelande har skapats av DokuWiki på
+@DOKUWIKIURL@
diff --git a/inc/lang/th/admin.txt b/inc/lang/th/admin.txt
new file mode 100644
index 000000000..677e779b6
--- /dev/null
+++ b/inc/lang/th/admin.txt
@@ -0,0 +1,3 @@
+====== งานธุรการควบคุมระบบ ======
+
+ด้านล่างนี้คุณสามารถพบรายการงานควบคุมระบบทั้งหมดในโดกุวิกิ \ No newline at end of file
diff --git a/inc/lang/th/adminplugins.txt b/inc/lang/th/adminplugins.txt
new file mode 100644
index 000000000..85a6b17bd
--- /dev/null
+++ b/inc/lang/th/adminplugins.txt
@@ -0,0 +1 @@
+====== ปลั๊กอินเสริม ====== \ No newline at end of file
diff --git a/inc/lang/th/backlinks.txt b/inc/lang/th/backlinks.txt
new file mode 100644
index 000000000..fff6898d8
--- /dev/null
+++ b/inc/lang/th/backlinks.txt
@@ -0,0 +1,3 @@
+====== ลิงค์กลับ(Backlinks) ======
+
+นี่คือรายชื่อเพจที่ชี้ลิงค์กลับมายังเพจปัจจุบัน \ No newline at end of file
diff --git a/inc/lang/th/conflict.txt b/inc/lang/th/conflict.txt
new file mode 100644
index 000000000..5e786a6b3
--- /dev/null
+++ b/inc/lang/th/conflict.txt
@@ -0,0 +1,5 @@
+====== มีเนื้อหารุ่นใหม่กว่าเกิดขึ้น ======
+
+มีเอกสารรุ่นใหม่กว่าที่คุณได้แก้ไขไว้ มันเกิดขึ้นเมื่อผู้ใช้รายอื่นได้ทำการแก้ไขเอกสารในขณะที่ขณะเดียวกันกับที่คุณกำลังแก้ไขมัน
+
+ให้ตรวจสอบความแตกต่างที่แสดงไว้ด้านล่างนี้ให้ทั่วถึง, แล้วตัดสินใจว่าจะเก็บฉบับไหนไว้ ถ้าคุณเลือก "บันทึก", ฉบับของคุณจะถูกบันทึกไว้ หรือกด "ยกเลิก" เพื่อเก็บฉบับปัจจุบัน \ No newline at end of file
diff --git a/inc/lang/th/denied.txt b/inc/lang/th/denied.txt
new file mode 100644
index 000000000..88b012a67
--- /dev/null
+++ b/inc/lang/th/denied.txt
@@ -0,0 +1,3 @@
+====== ปฏิเสธสิทธิ์ ======
+
+ขออภัย คุณไม่มีสิทธิ์เพียงพอที่จะดำเนินการต่อ บางทีคุณอาจจะลืมล็อกอิน? \ No newline at end of file
diff --git a/inc/lang/th/diff.txt b/inc/lang/th/diff.txt
new file mode 100644
index 000000000..e21759e03
--- /dev/null
+++ b/inc/lang/th/diff.txt
@@ -0,0 +1,3 @@
+====== ความแตกต่าง ======
+
+นี่เป็นการแสดงความแตกต่างระหว่างเพจสองรุ่น \ No newline at end of file
diff --git a/inc/lang/th/draft.txt b/inc/lang/th/draft.txt
new file mode 100644
index 000000000..37b1841a2
--- /dev/null
+++ b/inc/lang/th/draft.txt
@@ -0,0 +1,5 @@
+====== พบไฟล์ฉบับร่าง ======
+
+เซสชั่นที่คุณแก้ไขฉบับล่าสุดในเพจนี้ไม่ถูกจัดเก็บให้สมบูรณ์ โดกุวิกิได้ทำการบันทึกฉบับร่างให้โดยอัตโนมัติในระหว่างที่คุณกำลังทำงาน อันซึ่งขณะนี้คุณอาจต้องการใช้มันเพื่อแก้ไขต่อ ด้านล่างนี้คุณจะเห็นข้อมูลที่ถูกบันทึกไว้จากการทำงานครั้งล่าสุด
+
+กรุณาตัดสินใจว่าคุณต้องการที่จะ //กู้คืน//งานฉบับที่แก้ไขล่าสุด, //ลบทิ้ง/// ตัวฉบับร่างที่ได้บันทึกอัตโนมัติไว้, //ยกเลิก// กระบวนการแก้ไขนี้ \ No newline at end of file
diff --git a/inc/lang/th/edit.txt b/inc/lang/th/edit.txt
new file mode 100644
index 000000000..81dc0000b
--- /dev/null
+++ b/inc/lang/th/edit.txt
@@ -0,0 +1 @@
+แก้ไขหน้านี้แล้วกด "บันทึก" ให้อ่าน[[wiki:syntax|ไวยกรณ์วิกิ]] สำหรับค้นหาไวยกรณ์ที่ใช้ในวิกิ และกรุณาแก้ไขเฉพาะเพจที่คุณสามารถ**ปรับปรุง**ให้มันดีขึ้นได้, ถ้าหากคุณต้องการที่จะทดสอบอะไรบางอย่าง ให้ไปลองเล่นครั้งแรกได้ใน[[playground:playground|สนามเด็กเล่น]] \ No newline at end of file
diff --git a/inc/lang/th/editrev.txt b/inc/lang/th/editrev.txt
new file mode 100644
index 000000000..28e6760d3
--- /dev/null
+++ b/inc/lang/th/editrev.txt
@@ -0,0 +1,2 @@
+**คุณได้โหลดเอาเอกสารฉบับเก่าขึ้นมา!** ถ้าคุณบันทึกมัน คุณจะสร้างเอกสารรุ่นใหม่ด้วยข้อมูลเหล่านี้
+---- \ No newline at end of file
diff --git a/inc/lang/th/index.txt b/inc/lang/th/index.txt
new file mode 100644
index 000000000..eb32a64c0
--- /dev/null
+++ b/inc/lang/th/index.txt
@@ -0,0 +1,2 @@
+====== ดัชนี ======
+นี่คือดัชนีรวมทุกเพจ เรียงตาม[[doku>namespaces|เนมสเปซ]] \ No newline at end of file
diff --git a/inc/lang/th/lang.php b/inc/lang/th/lang.php
new file mode 100644
index 000000000..4ac6d7247
--- /dev/null
+++ b/inc/lang/th/lang.php
@@ -0,0 +1,230 @@
+<?php
+/**
+ * th language file
+ *
+ * This file was initially built by fetching translations from other
+ * Wiki projects. See the @url lines below. Additional translations
+ * and fixes where done for DokuWiki by the people mentioned in the
+ * lines starting with @author
+ *
+ * @url http://svn.wikimedia.org/viewvc/mediawiki/trunk/phase3/languages/messages/MessagesTh.php?view=co
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Arthit Suriyawongkul <arthit@gmail.com>
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“ ';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'แก้ไขหน้านี้';
+$lang['btn_source'] = 'ดูโค้ด';
+$lang['btn_show'] = 'แสดงเพจ';
+$lang['btn_create'] = 'สร้างเพจนี้';
+$lang['btn_search'] = 'ค้นหา';
+$lang['btn_save'] = 'บันทึก';
+$lang['btn_preview'] = 'แสดงตัวอย่าง';
+$lang['btn_top'] = 'กลับสู่ด้านบน';
+$lang['btn_newer'] = '<< ใหม่กว่า';
+$lang['btn_older'] = 'เก่ากว่า >>';
+$lang['btn_revs'] = 'ฉบับเก่าๆ';
+$lang['btn_recent'] = 'ปรับปรุงล่าสุด';
+$lang['btn_upload'] = 'ส่งข้อมูลเข้าสู่ระบบ';
+$lang['btn_cancel'] = 'ยกเลิก';
+$lang['btn_index'] = 'ดัชนี';
+$lang['btn_secedit'] = 'แก้ไข';
+$lang['btn_login'] = 'ล็อกอิน';
+$lang['btn_logout'] = 'ล็อกเอาต์';
+$lang['btn_admin'] = 'ผู้ควบคุมระบบ';
+$lang['btn_update'] = 'ปรับปรุง';
+$lang['btn_delete'] = 'ลบ';
+$lang['btn_back'] = 'ย้อนกลับ';
+$lang['btn_backlink'] = 'หน้าที่ลิงก์มา';
+$lang['btn_backtomedia'] = 'กลับไปยังหน้าเลือกไฟล์สื่อ';
+$lang['btn_subscribe'] = 'เฝ้าดู';
+$lang['btn_unsubscribe'] = 'เลิกเฝ้าดู';
+$lang['btn_profile'] = 'แก้ข้อมูลผู้ใช้';
+$lang['btn_reset'] = 'เริ่มใหม่';
+$lang['btn_resendpwd'] = 'ลืมรหัส ส่งให้ใหม่ทางอีเมล';
+$lang['btn_draft'] = 'แก้ไขเอกสารฉบับร่าง';
+$lang['btn_recover'] = 'กู้คืนเอกสารฉบับร่าง';
+$lang['btn_draftdel'] = 'ลบเอกสารฉบับร่าง';
+$lang['btn_revert'] = 'กู้คืน';
+$lang['btn_register'] = 'สร้างบัญชีผู้ใช้';
+$lang['loggedinas'] = 'ลงชื่อเข้าใช้เป็น';
+$lang['user'] = 'ชื่อผู้ใช้:';
+$lang['pass'] = 'รหัสผ่าน';
+$lang['newpass'] = 'รหัสผ่านใหม่';
+$lang['oldpass'] = 'รหัสผ่านเดิม:';
+$lang['passchk'] = 'พิมพ์รหัสผ่านอีกครั้ง:';
+$lang['remember'] = 'จำชื่อและรหัสผ่าน';
+$lang['fullname'] = 'ชื่อจริง:';
+$lang['email'] = 'อีเมล:';
+$lang['profile'] = 'ข้อมูลส่วนตัวผู้ใช้';
+$lang['badlogin'] = 'ขัดข้อง:';
+$lang['minoredit'] = 'เป็นการแก้ไขเล็กน้อย';
+$lang['draftdate'] = 'บันทึกฉบับร่างเมื่อ';
+$lang['nosecedit'] = 'ในช่วงเวลาที่ผ่านมานี้เพจถูกแก้ไขไปแล้ว, เนื้อหาในเซคชั่นนี้ไม่ทันสมัย กรุณาโหลดเพจใหม่ทั้งหน้าแทน';
+$lang['regmissing'] = 'ขออภัย คุณต้องกรอกให้ครบทุกช่อง';
+$lang['reguexists'] = 'ชื่อบัญชีที่ใส่นั้นมีผู้อื่นได้ใช้แล้ว กรุณาเลือกชื่อผู้ใช้อื่น';
+$lang['regsuccess'] = 'ผู้ใช้ถูกสร้างแล้ว และรหัสผ่านได้ถูกส่งไปทางอีเมลแล้ว';
+$lang['regsuccess2'] = 'ชื่อบัญชีได้ถูกสร้างขึ้น';
+$lang['regmailfail'] = 'ดูเหมือนจะมีข้อผิดพลาดในการส่งรหัสผ่านทางเมล์ กรุณาติดต่อผู้ดูแลระบบ';
+$lang['regbadmail'] = 'รูปแบบอีเมลไม่ถูกต้อง ให้ใส่อีเมลให้ถูกต้องตามรูปแบบอีเมล หรือให้ทำช่องอีเมลให้ว่างแทน';
+$lang['regbadpass'] = 'รหัสผ่านที่ใส่ไม่ถูกต้อง';
+$lang['regpwmail'] = 'รหัสผ่านเข้าโดกุวิกิของคุณ';
+$lang['reghere'] = 'คุณยังไม่มีบัญชีหรือ ก็แค่สร้างขึ้นมาสักอันหนึ่ง';
+$lang['profna'] = 'วิกินี้ไม่รองรับการแก้ไขข้อมูลส่วนตัว';
+$lang['profnochange'] = 'ไม่มีการเปลี่ยนแปลงข้อมูลส่วนตัว';
+$lang['profnoempty'] = 'ไม่อนุญาติให้เว้นว่างชื่อ หรืออีเมล';
+$lang['profchanged'] = 'ปรับปรุงข้อมูลส่วนตัวผู้ใช้สำเร็จ';
+$lang['pwdforget'] = 'ลืมรหัสผ่านหรือ? เอาอันใหม่สิ';
+$lang['resendna'] = 'วิกินี้ไม่รองรับการส่งรหัสผ่านซ้ำ';
+$lang['resendpwd'] = 'ส่งรหัสผ่านใหม่ให้กับ';
+$lang['resendpwdmissing'] = 'ขออภัย, คุณต้องกรอกทุกช่อง';
+$lang['resendpwdnouser'] = 'ขออภัย, เราไม่พบผู้ใช้คนนี้ในฐานข้อมูลของเรา';
+$lang['resendpwdbadauth'] = 'ขออภัย, รหัสนี้ยังใช้ไม่ได้ กรุณาตรวจสอบว่าคุณกดลิ้งค์ยืนยันแล้ว';
+$lang['resendpwdconfirm'] = 'อีเมลยืนยันได้ถูกส่งไปที่อีเมลที่ได้ถูกเสนอ ก่อนที่อีเมลจะถูกส่งไปที่ชื่อบัญชีนั้น คุณต้องปฏิบัติตามคำแนะนำในอีเมลเพื่อยืนยันว่าหมายเลยบัญชีนั้นเป็นของคุณ';
+$lang['resendpwdsuccess'] = 'รหัสผ่านใหม่ของคุณได้ถูกส่งให้แล้วทางอีเมล';
+$lang['license'] = 'เว้นแต่จะได้แจ้งไว้เป็นอื่นใด เนื้อหาบนวิกินี้ถูกกำหนดสิทธิ์ไว้ภายใต้สัญญาอนุญาติต่อไปนี้:';
+$lang['licenseok'] = 'โปรดทราบ: เมื่อเริ่มแก้ไขหน้านี้ ถือว่าคุณตกลงให้สิทธิ์กับเนื้อหาของคุณอยู่ภายใต้สัญญาอนุญาตินี้';
+$lang['searchmedia'] = 'สืบค้นไฟล์ชื่อ:';
+$lang['searchmedia_in'] = 'สืบค้นใน %s';
+$lang['txt_upload'] = 'เลือกไฟล์ที่จะอัพโหลด';
+$lang['txt_filename'] = 'อัพโหลดเป็น(ตัวเลือก)';
+$lang['txt_overwrt'] = 'เขียนทับไฟล์ที่มีอยู่แล้ว';
+$lang['lockedby'] = 'ตอนนี้ถูกล๊อคโดย';
+$lang['lockexpire'] = 'การล๊อคจะหมดอายุเมื่อ';
+$lang['js']['willexpire'] = 'การล๊อคเพื่อแก้ไขหน้านี้กำลังจะหมดเวลาในอีก \n นาที เพื่อที่จะหลีกเลี่ยงข้อขัดแย้งให้ใช้ปุ่ม "Preview" เพื่อรีเซ็ทเวลาใหม่';
+$lang['js']['notsavedyet'] = "การแก้ไขที่ไม่ได้บันทึกจะสูญหาย \n ต้องการทำต่อจริงๆหรือ?";
+$lang['rssfailed'] = 'มีข้อผิดพลาดขณะดูดฟีดนี้';
+$lang['nothingfound'] = 'ไม่พบสิ่งใด';
+$lang['mediaselect'] = 'ไฟล์สื่อ';
+$lang['fileupload'] = 'อัปโหลด';
+$lang['uploadsucc'] = 'อัปโหลดสำเร็จ';
+$lang['uploadfail'] = 'เกิดความขัดข้องในการอัปโหลด';
+$lang['uploadwrong'] = 'การอัพโหลดถูกปฏิเสธ ส่วนขยายไฟล์นี้ต้องห้าม!';
+$lang['uploadexist'] = 'ไฟล์นี้มีอยู่แล้ว ไม่มีการบันทึกใดๆเกิดขึ้น';
+$lang['uploadbadcontent'] = 'เนื้อหาที่อัพโหลดไม่ตรงกับส่วนขยายไฟล์ %s ';
+$lang['uploadspam'] = 'การอัพโหลดถูกกีดกันจากบัญชีดำสแปม';
+$lang['uploadxss'] = 'ไฟล์นี้มีส่วนประกอบของโค้ดเอชทีเอ็มแอลหรือสคริปต์ ซึ่งอาจก่อให้เกิดความผิดพลาดในการแสดงผลของเว็บเบราว์เซอร์';
+$lang['uploadsize'] = 'ไฟล์ที่อัพโหลดใหญ่เกินไป (สูงสุด %s)';
+$lang['deletesucc'] = 'ไฟล์ "%s" ถูกลบ';
+$lang['deletefail'] = '"%s" ไม่สามารถลบได้ - ให้ตรวจสอบสิทธิ์การใช้ของคุณ';
+$lang['mediainuse'] = 'ไฟล์ "%s" ไม่ได้ถูกลบ - มันถูกใช้อยู่';
+$lang['namespaces'] = 'เนมสเปซ';
+$lang['mediafiles'] = 'มีไฟล์พร้อมใช้อยู่ใน';
+$lang['js']['searchmedia'] = 'ค้นหาไฟล์';
+$lang['js']['keepopen'] = 'เปิดหน้าต่างไว้ระหว่างที่เลือก';
+$lang['js']['hidedetails'] = 'ซ่อนรายละเอียด';
+$lang['js']['nosmblinks'] = 'เชื่อมไปยังหน้าต่างแบ่งปัน ทำงานได้กับเฉพาะไมโครซอฟท์อินเตอร์เน็ตเอ็กซโปรเรอร์(IE) คุณยังคงสามารถคัดลอกและแปะลิ้งค์ได้';
+$lang['js']['linkwiz'] = 'ลิงค์วิเศษ';
+$lang['js']['linkto'] = 'ลิงค์ไป:';
+$lang['js']['del_confirm'] = 'ต้องการลบรายการที่เลือกจริงๆหรือ?';
+$lang['mediausage'] = 'ให้ใช้ไวยกรณ์ต่อไปนี้เพื่ออ้างอิงไฟล์นี้';
+$lang['mediaview'] = 'ดูไฟล์ต้นฉบับ';
+$lang['mediaroot'] = 'ราก(รูท)';
+$lang['mediaupload'] = 'อัพโหลดไฟล์ไปยังเนมสเปซปัจจุบันจากที่นี่ หากจะสร้างเนมสเปซย่อย ให้พิมพ์ต่อข้อความของคุณหลังชื่อไฟล์ในช่อง "อัพโหลดเป็น" โดยให้คั่นด้วยโคล่อน(:)';
+$lang['mediaextchange'] = 'ส่วนขยายไฟล์ถูกเปลี่ยนจาก .%s ไปเป็น .%s!';
+$lang['reference'] = 'อ้างอิงสำหรับ';
+$lang['ref_inuse'] = 'ไม่สามารถลบไฟล์ได้ เพราะมันยังคงถูกใช้โดยเพจดังต่อไปนี้:';
+$lang['ref_hidden'] = 'มีการอ้างอิงบางรายการในเพจ คุณไม่มีสิทธิ์ในการอ่าน';
+$lang['hits'] = 'คำที่ตรงกัน';
+$lang['quickhits'] = 'ชื่อเพจที่ตรงกัน';
+$lang['toc'] = 'สารบัญ';
+$lang['current'] = 'ฉบับปัจจุบัน';
+$lang['yours'] = 'ฉบับของคุณ';
+$lang['diff'] = 'แสดงจุดแตกต่างกับฉบับปัจจุบัน';
+$lang['diff2'] = 'แสดงจุดแตกต่างระหว่างฉบับที่เลือกไว้';
+$lang['line'] = 'บรรทัด';
+$lang['breadcrumb'] = 'ตามรอย';
+$lang['youarehere'] = 'คุณอยู่ที่นี่';
+$lang['lastmod'] = 'แก้ไขครั้งล่าสุด';
+$lang['by'] = 'โดย';
+$lang['deleted'] = 'ถูกถอดออก';
+$lang['created'] = 'ถูกสร้าง';
+$lang['restored'] = 'ย้อนไปรุ่นก่อนหน้า';
+$lang['external_edit'] = 'แก้ไขภายนอก';
+$lang['summary'] = 'สรุป(หมายเหตุ)การแก้ไขนี้';
+$lang['noflash'] = 'ต้องการตัวเล่นแฟลช <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a> เพื่อแสดงผลเนื้อหานี้';
+$lang['download'] = 'ดาวน์โหลดสนิปเป็ด(Snippet)';
+$lang['mail_newpage'] = 'เพิ่มเพจแล้ว:';
+$lang['mail_changed'] = 'แก้ไขเพจแล้ว:';
+$lang['mail_new_user'] = 'ผู้ใช้คนใหม่:';
+$lang['mail_upload'] = 'ไฟล์อัพโหลดแล้ว:';
+$lang['qb_bold'] = 'ทำตัวหนา';
+$lang['qb_italic'] = 'ทำตัวเอียง';
+$lang['qb_underl'] = 'ขีดเส้นใต้ข้อความ';
+$lang['qb_code'] = 'ข้อความเป็นโค้ดโปรแกรม';
+$lang['qb_strike'] = 'ขีดฆ่าข้อความ';
+$lang['qb_h1'] = 'หัวเรื่องระดับที่ 1';
+$lang['qb_h2'] = 'หัวเรื่องระดับที่ 2';
+$lang['qb_h3'] = 'หัวเรื่องระดับที่ 3';
+$lang['qb_h4'] = 'หัวเรื่องระดับที่ 4';
+$lang['qb_h5'] = 'หัวเรื่องระดับที่ 5';
+$lang['qb_h'] = 'หัวเรื่อง';
+$lang['qb_hs'] = 'เลือกหัวเรื่อง';
+$lang['qb_hplus'] = 'หัวเรื่องที่สูงกว่า';
+$lang['qb_hminus'] = 'หัวเรื่องที่ต่ำกว่า';
+$lang['qb_hequal'] = 'หัวเรื่องระดับเดียวกัน';
+$lang['qb_link'] = 'ลิงก์ภายในเว็บ';
+$lang['qb_extlink'] = 'ลิงก์ไปที่อื่น (อย่าลืม http:// นำหน้าเสมอ)';
+$lang['qb_hr'] = 'เส้นนอน';
+$lang['qb_ol'] = 'รายการที่เรียงลำดับแล้ว';
+$lang['qb_ul'] = 'รายการที่ยังไม่ได้เรียงลำดับ';
+$lang['qb_media'] = 'เพิ่มภาพและไฟล์อื่นๆ';
+$lang['qb_sig'] = 'ลายเซ็นพร้อมลงเวลา';
+$lang['qb_smileys'] = 'ภาพแสดงอารมณ์';
+$lang['qb_chars'] = 'อักขระพิเศษ';
+$lang['upperns'] = 'กระโดดขึ้นไปยังเนมสเปซแม่';
+$lang['admin_register'] = 'สร้างบัญชีผู้ใช้';
+$lang['metaedit'] = 'แก้ไขข้อมูลเมต้า';
+$lang['metasaveerr'] = 'มีข้อผิดพลาดในการเขียนข้อมูลเมต้า';
+$lang['metasaveok'] = 'บันทึกเมต้าดาต้าแล้ว';
+$lang['img_backto'] = 'กลับไปยัง';
+$lang['img_title'] = 'ชื่อภาพ';
+$lang['img_caption'] = 'คำบรรยายภาพ';
+$lang['img_date'] = 'วันที่';
+$lang['img_fname'] = 'ชื่อไฟล์';
+$lang['img_fsize'] = 'ขนาดภาพ';
+$lang['img_artist'] = 'ผู้สร้างสรรค์';
+$lang['img_copyr'] = 'ผู้ถือลิขสิทธิ์';
+$lang['img_format'] = 'รูปแบบ';
+$lang['img_camera'] = 'กล้อง';
+$lang['img_keywords'] = 'คำหลัก';
+$lang['subscribe_success'] = 'เพิ่ม %s เข้าไปในรายชื่อสมาชิกลงทะเบียนสำหรับ %s';
+$lang['subscribe_error'] = 'มีข้อผิดพลาดในการเพิ่ม %s ในรายชื่อสมัครสมาชิกสำหรับ %s';
+$lang['subscribe_noaddress'] = 'ไม่มีที่อยู่ที่ตรงกับชื่อล็อกอินของคุณ ชื่อคุณไม่สามารถถูกเพิ่มเข้าไปในรายชื่อสมัครสมาชิก';
+$lang['unsubscribe_success'] = 'ถอด % ออกจากรายชื่อสมัครสมาชิกของ %s';
+$lang['unsubscribe_error'] = 'มีข้อผิดพลาดในการถอด %s ออกจากรายชื่อสมาชิกของ %s';
+$lang['authmodfailed'] = 'มีการกำหนดค่าสิทธิ์ผู้ใช้ไว้ไม่ดี กรุณาแจ้งผู้ดูแลระบบวิกิของคุณ';
+$lang['authtempfail'] = 'ระบบตรวจสอบสิทธิ์ผู้ใช้ไม่พร้อมใช้งานชั่วคราว หากสถานการณ์ยังไม่เปลี่ยนแปลง กรุณาแจ้งผู้ดูแลระบวิกิของคุณ';
+$lang['i_chooselang'] = 'เลือกภาษาของคุณ';
+$lang['i_installer'] = 'ตัวติดตั้งโดกุวิกิ';
+$lang['i_wikiname'] = 'ชื่อวิกิ';
+$lang['i_enableacl'] = 'เปิดระบบ ACL(แนะนำ)';
+$lang['i_superuser'] = 'ซุปเปอร์ยูสเซอร์';
+$lang['i_problems'] = 'ตัวติดตั้งพบปัญหาบางประการ ตามที่ระบุด้านล่าง คุณไม่สามารถทำต่อได้จนกว่าจะได้แก้ไขสิ่งเหล่านั้น';
+$lang['i_modified'] = 'ด้วยเหตุผลด้านความปลอดภัย สคริปต์นี้จะทำงานกับเฉพาะโดกุวิกิที่ติดตั้งใหม่หรือยังไม่ได้ดัดแปลงแก้ไข
+คุณควรเลือกระหว่างคลี่ไฟล์จากแพคเกจที่ได้ดาวน์โหลดมาอีกครั้ง หรือศึกษาจากคู่มือ
+<a href="http://dokuwiki.org/install">Dokuwiki installation instructions</a>';
+$lang['i_funcna'] = 'PHP function <code>%s</code> ไม่สามารถใช้งานได้ อาจเป็นเพราะผู้ให้บริการโฮสไม่เปิดให้ใช้งาน';
+$lang['i_phpver'] = 'PHP รุ่นที่คุณกำลังใช้งานอยู่คือ <code>%s</code> คุณจำเป็นต้องอัพเกรด PHP ให้เป็นรุ่น <code>%s</code> หรือสูงกว่า';
+$lang['i_permfail'] = '<code>%s</code> DokuWiki ไม่สามารถเขียนข้อมูลได้ ต้องตั้งค่าสิทธิ์การอนุญาตของไดเรคทอรีนี้เสียก่อน!';
+$lang['i_confexists'] = '<code>%s</code> ถูกใช้งานไปแล้ว';
+$lang['i_writeerr'] = 'ไม่สามารถสร้าง <code>%s</code>. ตรวจสอบสิทธิ์การอนุญาตของไดเรคทอรีหรือไฟล์ แล้วสร้างไฟล์ด้วยตนเอง';
+$lang['i_policy'] = 'นโยบายสิทธิ์เข้าถึง(ACL)ตั้งต้น';
+$lang['i_pol0'] = 'วิกิเปิดกว้าง (ใครก็ อ่าน, เขียน, อัพโหลดได้)';
+$lang['i_pol1'] = 'วิกิสาธารณะ (ทุกคนอ่านได้, เขียน และ อัพโหลดเฉพาะผู้ใช้ที่ลงทะเบียนแล้ว)';
+$lang['i_pol2'] = 'วิกิภายใน (อ่าน, เขียน, อัพโหลด สำหรับผู้ใช้ที่ลงทะเบียนแล้วเท่านั้น)';
+$lang['i_retry'] = 'ลองใหม่';
+$lang['years'] = '%d ปีก่อน';
+$lang['months'] = '%d เดือนก่อน';
+$lang['weeks'] = '%d สัปดาห์ก่อน';
+$lang['days'] = '%d วันก่อน';
+$lang['hours'] = '%d ชั่วโมงก่อน';
+$lang['minutes'] = '%d นาทีก่อน';
+$lang['seconds'] = '%d วินาทีก่อน';
diff --git a/inc/lang/th/locked.txt b/inc/lang/th/locked.txt
new file mode 100644
index 000000000..a198ad717
--- /dev/null
+++ b/inc/lang/th/locked.txt
@@ -0,0 +1,3 @@
+====== เพจถูกล๊อค ======
+
+เพจนี้กำลังถูกล๊อคจากการแก้ไขโดยผู้ใช้ท่านอื่น คุณต้องรอจนกว่าผู้ใช้คนนี้จะแก้ไขเสร็จ หรือการล๊อคนั้นหมดเวลา \ No newline at end of file
diff --git a/inc/lang/th/login.txt b/inc/lang/th/login.txt
new file mode 100644
index 000000000..d384c2d27
--- /dev/null
+++ b/inc/lang/th/login.txt
@@ -0,0 +1,4 @@
+====== ล็อกอิน ======
+
+คุณยังไม่ได้เข้าสู่ระบบ(ล็อกอิน)ในขณะนี้! กรอกรายละเอียดเพื่อพิสูจน์สิทธิ์ข้างล่างนี้เพื่อล็อกอิน คุณต้องเปิดคุ๊กกี้ให้ทำงานก่อนที่จะล็อกอิน
+
diff --git a/inc/lang/th/mailtext.txt b/inc/lang/th/mailtext.txt
new file mode 100644
index 000000000..a4af8a0f3
--- /dev/null
+++ b/inc/lang/th/mailtext.txt
@@ -0,0 +1,17 @@
+เพจในโดกุวิกิของคุณได้ถูกเพิ่ม หรือแก้ไข นี่คือรายละเอียด:
+
+วันที่: @DATE@
+บราวเซอร์: @BROWSER@
+ที่อยู่ไอพี: @IPADDRESS@
+ชื่อโฮสต์: @HOSTNAME@
+ฉบับเก่า: @OLDPAGE@
+ฉบับใหม่: @NEWPAGE@
+สรุปการแก้ไข: @SUMMARY@
+ผู้ใช้: @USER@
+
+@DIFF@
+
+
+--
+จดหมายนี้สร้างขึ้นโดยโดกุวิกิที่
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/th/newpage.txt b/inc/lang/th/newpage.txt
new file mode 100644
index 000000000..cab906d4c
--- /dev/null
+++ b/inc/lang/th/newpage.txt
@@ -0,0 +1,3 @@
+====== ยังไม่มีหัวข้อนี้ ======
+
+คุณได้กดลิ้งค์เข้ามายังหัวข้อที่ยังไม่ได้สร้าง ถ้าคุณได้รับอนุญาติ คุณอาจจะสร้างมันได้ด้วยการกดปุ่ม "สร้างเพจนี้" \ No newline at end of file
diff --git a/inc/lang/th/norev.txt b/inc/lang/th/norev.txt
new file mode 100644
index 000000000..9127a20c3
--- /dev/null
+++ b/inc/lang/th/norev.txt
@@ -0,0 +1,3 @@
+====== ไม่มีฉบับที่ระบุ ======
+
+ฉบับที่ระบุไม่มีอยู่จริง กรุณาใช้ปุ่ม "ฉบับเก่าๆ" เพื่อแสดงรายการรุ่นเก่าๆของเอกสารนี้ิ \ No newline at end of file
diff --git a/inc/lang/th/password.txt b/inc/lang/th/password.txt
new file mode 100644
index 000000000..5f0dcfffc
--- /dev/null
+++ b/inc/lang/th/password.txt
@@ -0,0 +1,10 @@
+สวัสดี@FULLNAME@!
+
+นี่คือข้อมูลผู้ใช้ของคุณสำหรับ @TITLE@ ที่ @DOKUWIKIURL@
+
+ล็อกอิน: @LOGIN@
+รหัสผ่าน : @PASSWORD@
+
+--
+จดหมายนี้ถูกสร้างขึ้นโดยโดกุวิกิที่
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/th/preview.txt b/inc/lang/th/preview.txt
new file mode 100644
index 000000000..caaf8ad2d
--- /dev/null
+++ b/inc/lang/th/preview.txt
@@ -0,0 +1,3 @@
+====== ดูตัวอย่าง ======
+
+นี่คือหน้าตัวอย่างของข้อความที่คุณกรอก จำไว้ว่า: มันยัง **ไม่ได้บันทึก** เก็บไว้! \ No newline at end of file
diff --git a/inc/lang/th/pwconfirm.txt b/inc/lang/th/pwconfirm.txt
new file mode 100644
index 000000000..e6ab876cf
--- /dev/null
+++ b/inc/lang/th/pwconfirm.txt
@@ -0,0 +1,14 @@
+เฮ้ @FULLNAME@!
+
+มีบางคนร้องขอรหัสผ่านใหม่สำหรับ @TITLE@ ของคุณ
+เพื่อล็อกอินที่ @DOKUWIKIURL@
+
+ถ้าคุรไม่ได้ร้องขอรหัสผ่านใหม่ ก็ไม่ต้องสนใจอีเมลนี้
+
+หากต้องการยืนยันว่านี่การร้องขอนี้ถูกส่งโดยคุณจริงๆ กรุณาใช้ลิงค์ดังต่อไปนี้
+
+@CONFIRM@
+
+--
+จดหมายนี้ถูกสร้างขึ้นโดยโดกุวิกิที่
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/th/read.txt b/inc/lang/th/read.txt
new file mode 100644
index 000000000..ac4f31290
--- /dev/null
+++ b/inc/lang/th/read.txt
@@ -0,0 +1 @@
+หน้านี้มีไว้อ่านอย่างเดียว คุณสามารถอ่านข้อความต้นฉบับ ไม่สามารถแก้ไขได้ ให้สอบถามผู้ดูแลระบบถ้าคุณคิดว่านี่คือข้อผิดพลาด \ No newline at end of file
diff --git a/inc/lang/th/recent.txt b/inc/lang/th/recent.txt
new file mode 100644
index 000000000..1655ae82b
--- /dev/null
+++ b/inc/lang/th/recent.txt
@@ -0,0 +1,3 @@
+====== การเปลี่ยนแปลงเมื่อเร็วๆนี้ ======
+
+เพจเหล่านี้ถูกเปลี่ยนแปลงเมื่อเร็วๆนี้ \ No newline at end of file
diff --git a/inc/lang/th/register.txt b/inc/lang/th/register.txt
new file mode 100644
index 000000000..ed4a40876
--- /dev/null
+++ b/inc/lang/th/register.txt
@@ -0,0 +1,3 @@
+====== ลงทะเบียนเป็นผู้ใช้หน้าใหม่ ======
+
+กรอกข้อมูลทั้งหมดด้านล่างเพื่อสร้างบัญชีใหม่ในวิกินี้ ให้แน่ใจว่าคุณให้ **ที่อยู่อีเมลที่ใช้ได้จริง** ถ้าคุณไม่ถูกถามให้กรอกรหัสผา่นที่นี่, รหัสผ่านใหม่จะถูกส่งไปยังที่อยู่ดังกล่าว ชื่อล็อกอินควรจะใช้ได้ถูกต้องตาม[[doku>pagename|pagename]]. \ No newline at end of file
diff --git a/inc/lang/th/registermail.txt b/inc/lang/th/registermail.txt
new file mode 100644
index 000000000..a96026d31
--- /dev/null
+++ b/inc/lang/th/registermail.txt
@@ -0,0 +1,14 @@
+มีผู้ใช้คนใหม่ได้ลงทะเบียน นี่คือรายละเอียด:
+
+ชื่อผู้ใช้ : @NEWUSER@
+ชื่อเต็ม : @NEWNAME@
+อีเมล : @NEWEMAIL@
+
+วันที่ : @DATE@
+บราวเซอร์ : @BROWSER@
+ที่อยู่ไอพี : @IPADDRESS@
+ชื่อโฮสต์ : @HOSTNAME@
+
+--
+จดหมายนี้ถูกสร้างขึ้นโดยโดกุวิกิที่
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/th/resendpwd.txt b/inc/lang/th/resendpwd.txt
new file mode 100644
index 000000000..1935abedd
--- /dev/null
+++ b/inc/lang/th/resendpwd.txt
@@ -0,0 +1,3 @@
+====== ส่งรหัสผ่านใหม่ ======
+
+กรุณากรอกชื่อผู้ใช้ในช่องด้านล่างเพื่อร้องขอรหัสผ่านใหม่จากบัญชีของคุณในวิกินี้ ลิงค์ยืนยันจะถูกส่งไปยังที่อยู่อีเมลที่คุณลงทะเบียนไว้ \ No newline at end of file
diff --git a/inc/lang/th/revisions.txt b/inc/lang/th/revisions.txt
new file mode 100644
index 000000000..98a49d724
--- /dev/null
+++ b/inc/lang/th/revisions.txt
@@ -0,0 +1,3 @@
+====== ฉบับเก่า ======
+
+เหล่านี้เป็นรายการฉบับเก่าของเอกสารปัจจุบัน หากต้องการคืนสภาพฉบับเก่า ให้เลือกมันจากด้านล่าง, คลิ๊ก "แก้ไขเพจนี้" แล้วจึงค่อยบันทึกมัน \ No newline at end of file
diff --git a/inc/lang/th/searchpage.txt b/inc/lang/th/searchpage.txt
new file mode 100644
index 000000000..d6399a9e9
--- /dev/null
+++ b/inc/lang/th/searchpage.txt
@@ -0,0 +1,4 @@
+====== สืบค้น ======
+คุณสามารถพบผลลัพธ์การสืบค้นของคุณด้านล่าง ถ้าคุณไม่พบสิ่งที่คนมองหา คุณสามารถเลือกที่จะสร้าง หรือแก้ไขชื่อเพจหลังจากดูผลสืบค้นแล้วด้วยปุ่มที่เหมาะสม
+
+====== ผลลัพธ์ ====== \ No newline at end of file
diff --git a/inc/lang/th/showrev.txt b/inc/lang/th/showrev.txt
new file mode 100644
index 000000000..f93869f38
--- /dev/null
+++ b/inc/lang/th/showrev.txt
@@ -0,0 +1,2 @@
+**นี่คือเอกสารรุ่น/ฉบับเก่า**
+---- \ No newline at end of file
diff --git a/inc/lang/th/updateprofile.txt b/inc/lang/th/updateprofile.txt
new file mode 100644
index 000000000..3e0a8dffd
--- /dev/null
+++ b/inc/lang/th/updateprofile.txt
@@ -0,0 +1,3 @@
+====== ปรับปรุงข้อมูลส่วนตัวของบัญชีคุณ ======
+
+คุณเพียงต้องการกรอกช่องที่ต้องการแก้ไขเหล่านี้ให้ครบ แต่ไม่สามารถเปลี่ยนชื่อผู้ใช้ได้ \ No newline at end of file
diff --git a/inc/lang/th/uploadmail.txt b/inc/lang/th/uploadmail.txt
new file mode 100644
index 000000000..026965753
--- /dev/null
+++ b/inc/lang/th/uploadmail.txt
@@ -0,0 +1,14 @@
+มีไฟล์ได้ถูกอัพโหลดเข้าไปยังโดกุวิกิของคุณ นี่คือรายละเอียด:
+
+ไฟล์: @MEDIA@
+วันที่: @DATE@
+เบราเซอร์: @BROWSER@
+ที่อยู่ไอพี: @IPADDRESS@
+ชื่อโฮสต์: @HOSTNAME@
+ขนาด: @SIZE@
+MIME Type : @MIME@
+ผู้ใช้: @USER@
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/tr/admin.txt b/inc/lang/tr/admin.txt
new file mode 100644
index 000000000..2292b6eeb
--- /dev/null
+++ b/inc/lang/tr/admin.txt
@@ -0,0 +1,3 @@
+====== Yönetim ======
+
+Aşağıda DokuWiki için yapılabilecek yönetim işleri vardır.
diff --git a/inc/lang/tr/backlinks.txt b/inc/lang/tr/backlinks.txt
new file mode 100644
index 000000000..e219a60c0
--- /dev/null
+++ b/inc/lang/tr/backlinks.txt
@@ -0,0 +1,4 @@
+====== Geri linkler ======
+
+Bu sayfaya bağlantı veren sayfaların listesi aşağıdadır.
+
diff --git a/inc/lang/tr/conflict.txt b/inc/lang/tr/conflict.txt
new file mode 100644
index 000000000..504947998
--- /dev/null
+++ b/inc/lang/tr/conflict.txt
@@ -0,0 +1,6 @@
+====== Yeni versiyon mevcut ======
+
+Değiştirdiğiniz dökümanın daha yeni bir versiyonu mevcut. Bu durum, siz dökümanı değiştirirken başka bir kullanıcının da aynı dökümanı değiştirmesi halinde olur.
+
+Aşağıda gösterilen farkları dikkatlice inceleyin, daha sonra hangi versiyonun korunacağına karar verin. Eğer ''Kaydet''i seçerseniz, sizin sürümünüz kaydedilir. Mevcut sürümü korumak için ''İptal''e tıklayın.
+
diff --git a/inc/lang/tr/denied.txt b/inc/lang/tr/denied.txt
new file mode 100644
index 000000000..04e9b8bfb
--- /dev/null
+++ b/inc/lang/tr/denied.txt
@@ -0,0 +1,4 @@
+====== Yetki Reddedildi ======
+
+Üzgünüz, devam etmek için yetkiniz yok. Giriş yapmayı unutmuş olabilir misiniz?
+
diff --git a/inc/lang/tr/diff.txt b/inc/lang/tr/diff.txt
new file mode 100644
index 000000000..72baa676b
--- /dev/null
+++ b/inc/lang/tr/diff.txt
@@ -0,0 +1,4 @@
+====== Farklar ======
+
+Bu sayfanın seçili sürümü ile mevcut sürümü arasındaki farkları gösterir.
+
diff --git a/inc/lang/tr/draft.txt b/inc/lang/tr/draft.txt
new file mode 100644
index 000000000..b1a8881b8
--- /dev/null
+++ b/inc/lang/tr/draft.txt
@@ -0,0 +1,5 @@
+====== Taslak Dosyası Bulundu ======
+
+Bu sayfadaki en son oturumunuz düzgün olarak tamamlanmamış. DokuWiki otomatik olarak bir taslak kaydetmiş olduğu için çalışmanıza devam edebilirsiniz. Aşağıda en son oturumunuzda kaydedilmiş olan taslağı görebilirsiniz.
+
+Bu taslağı //geri getirebilir//, //silebilir// veya düzenleme sürecinden //vazgeçebilirsiniz//. \ No newline at end of file
diff --git a/inc/lang/tr/edit.txt b/inc/lang/tr/edit.txt
new file mode 100644
index 000000000..4f84c4e53
--- /dev/null
+++ b/inc/lang/tr/edit.txt
@@ -0,0 +1,2 @@
+Sayfayı değiştirin ve ''Kaydete'' basın. Wiki sözdizimi için [[wiki:syntax]]'a bakınız. Lütfen sayfayı sadece eğer **geliştirebiliyorsanız** değiştirin. Eğer testler yapmak istiyorsanız, [[playground:playground|playground]] adresini kullanın.
+
diff --git a/inc/lang/tr/editrev.txt b/inc/lang/tr/editrev.txt
new file mode 100644
index 000000000..9c70fbed3
--- /dev/null
+++ b/inc/lang/tr/editrev.txt
@@ -0,0 +1,2 @@
+**Sayfanın eski bir sürümünü yüklediniz!** Eğer kaydederseniz, bu veriyle yeni bir sürüm oluşturacaksınız.
+----
diff --git a/inc/lang/tr/index.txt b/inc/lang/tr/index.txt
new file mode 100644
index 000000000..e361e8784
--- /dev/null
+++ b/inc/lang/tr/index.txt
@@ -0,0 +1,4 @@
+====== İndeks ======
+
+Bu mevcut tüm sayfaların [[doku>namespaces|isim alanlarına]] göre sıralı bir indeksidir.
+
diff --git a/inc/lang/tr/install.html b/inc/lang/tr/install.html
new file mode 100644
index 000000000..d479ca4e8
--- /dev/null
+++ b/inc/lang/tr/install.html
@@ -0,0 +1,8 @@
+<p>Bu sayfa <a href="http://dokuwiki.org">Dokuwiki</a> kurmanıza yardımcı olmaktadır. Kurulum hakkında bilgi sahibi olmak için <a href="http://dokuwiki.org/installer">bu sayfayı</a> ziyaret edebilirsiniz.</p>
+
+<p>DokuWiki wiki sayfalarını ve wiki sayfalarına ilişkin verileri (resimler, arama indeksi, geçmiş sürümler) dosyalarda tutar. DokuWikiyi sorunsuz olarak kullanmak için bu dosyaların bulunduğu dizinlere <strong>mutlaka</strong> yazma izniniz olması gereklidir. Bu kurulum betiği yazma izinlerini ayarlayamamaktadır. İzinleri shell, FTP veya kontrol paneliniz (CPanel, Plesk vs.) aracılığı ile düzenleyebilirsiniz.</p>
+
+<p>Kurulum betiği <acronym title="access control list">ACL</acronym>'yi otomatik olarak ayarlamaktadır. Böylece yönetici izinleri belirlenip, DokuWiki kullanımı kolaylaştırılmaktadır.</p>
+
+<p>Deneyimli kullanıcılar <a href="http://dokuwiki.org/install">bu sayfayı </a>
+ edebilir ve <a href="http://dokuwiki.org/config">bu sayfa yardımıyla</a> yapılandırma hakkında ekstra bilgi sahibi olabilir.</p> \ No newline at end of file
diff --git a/inc/lang/tr/lang.php b/inc/lang/tr/lang.php
new file mode 100644
index 000000000..cbadde849
--- /dev/null
+++ b/inc/lang/tr/lang.php
@@ -0,0 +1,237 @@
+<?php
+/**
+ * turkish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Selim Farsakoğlu <farsakogluselim@yahoo.de>
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Sayfayı düzenle';
+$lang['btn_source'] = 'Kaynağı göster';
+$lang['btn_show'] = 'Sayfayı göster';
+$lang['btn_create'] = 'Bu sayfayı oluştur';
+$lang['btn_search'] = 'Ara';
+$lang['btn_save'] = 'Kaydet';
+$lang['btn_preview'] = 'Önizleme';
+$lang['btn_top'] = 'Başa dön';
+$lang['btn_newer'] = '<< daha yeniler';
+$lang['btn_older'] = 'daha eskiler >>';
+$lang['btn_revs'] = 'Eski sürümler';
+$lang['btn_recent'] = 'En son değişiklikler';
+$lang['btn_upload'] = 'Yükle';
+$lang['btn_cancel'] = 'İptal';
+$lang['btn_index'] = 'İndeks';
+$lang['btn_secedit'] = 'Düzenle';
+$lang['btn_login'] = 'Giriş yap';
+$lang['btn_logout'] = 'Çıkış yap';
+$lang['btn_admin'] = 'Yönetici';
+$lang['btn_update'] = 'Güncelle';
+$lang['btn_delete'] = 'Sil';
+$lang['btn_back'] = 'Geri';
+$lang['btn_backlink'] = 'Geri linkler';
+$lang['btn_backtomedia'] = 'Çokluortam dosyası seçimine dön';
+$lang['btn_subscribe'] = 'Sayfa Değişikliklerini Bildir';
+$lang['btn_profile'] = 'Kullanıcı Bilgilerini Güncelle';
+$lang['btn_reset'] = 'Sıfırla';
+$lang['btn_resendpwd'] = 'Yeni parola gönder';
+$lang['btn_draft'] = 'Taslağı düzenle';
+$lang['btn_recover'] = 'Taslağı geri yükle';
+$lang['btn_draftdel'] = 'Taslağı sil';
+$lang['btn_revert'] = 'Geri Yükle';
+$lang['btn_register'] = 'Kayıt ol';
+$lang['loggedinas'] = 'Giriş ismi';
+$lang['user'] = 'Kullanıcı ismi';
+$lang['pass'] = 'Parola';
+$lang['newpass'] = 'Yeni Parola';
+$lang['oldpass'] = 'Kullanılan parolayı doğrula';
+$lang['passchk'] = 'Bir kez daha girin';
+$lang['remember'] = 'Beni hatırla';
+$lang['fullname'] = 'Tam isim';
+$lang['email'] = 'E-posta';
+$lang['profile'] = 'Kullanıcı Bilgileri';
+$lang['badlogin'] = 'Üzgünüz, Kullanıcı adı veya şifre yanlış oldu.';
+$lang['minoredit'] = 'Küçük Değişiklikler';
+$lang['draftdate'] = 'Taslak şu saatte otomatik kaydedildi:';
+$lang['nosecedit'] = 'Sayfa yakın zamanda değiştirilmiştir, bölüm bilgisi eski kalmıştır. Bunun için bölüm yerine tüm sayfa yüklenmiştir.';
+$lang['regmissing'] = 'Üzgünüz, tüm alanları doldurmalısınız.';
+$lang['reguexists'] = 'Üzgünüz, bu isime sahip bir kullanıcı zaten mevcut.';
+$lang['regsuccess'] = 'Kullanıcı oluşturuldu ve şifre e-posta adresine gönderildi.';
+$lang['regsuccess2'] = 'Kullanıcı oluşturuldu.';
+$lang['regmailfail'] = 'Şifrenizi e-posta ile gönderirken bir hata oluşmuş gibi görünüyor. Lütfen yönetici ile temasa geçiniz!';
+$lang['regbadmail'] = 'Verilen e-posta adresi geçersiz gibi görünüyor - bunun bir hata olduğunu düşünüyorsanız yönetici ile temasa geçiniz.';
+$lang['regbadpass'] = 'Girilen parolalar aynı değil. Lütfen tekrar deneyiniz.';
+$lang['regpwmail'] = 'DokuWiki parolanız';
+$lang['reghere'] = 'Daha hesabınız yok mu? Hemen bir tane açtırın!';
+$lang['profna'] = 'Bu wiki kullanıcı bilgilerini değiştirmeyi desteklememektedir';
+$lang['profnochange'] = 'Değişiklik yok, birşey yapılmadı.';
+$lang['profnoempty'] = 'Boş isim veya e-posta adresine izin verilmiyor.';
+$lang['profchanged'] = 'Kullanıcı bilgileri başarıyla değiştirildi.';
+$lang['pwdforget'] = 'Parolanızı mı unuttunuz? Yeni bir parola alın';
+$lang['resendna'] = 'Bu wiki parolayı tekrar göndermeyi desteklememektedir.';
+$lang['resendpwd'] = 'Yeni parolayı gönder:';
+$lang['resendpwdmissing'] = 'Üzgünüz, tüm alanları doldurmalısınız.';
+$lang['resendpwdnouser'] = 'Üzgünüz, veritabanımızda bu kullanıcıyı bulamadık.';
+$lang['resendpwdbadauth'] = 'Üzgünüz, bu doğrulama kodu doğru değil. Doğrulama linkini tam olarak kullandığınıza emin olun.';
+$lang['resendpwdconfirm'] = 'Doğrulama linki e-posta adresinize gönderildi.';
+$lang['resendpwdsuccess'] = 'Yeni parolanız e-posta adresinize gönderildi.';
+$lang['license'] = 'Aksi belirtilmediği halde, bu wikinin içeriğinin telif hakları şu lisans ile korunmaktadır:';
+$lang['licenseok'] = 'Not: Bu sayfayı değiştirerek yazınızın şu lisans ile yayınlanmasını kabul etmiş olacaksınız:';
+$lang['searchmedia'] = 'Dosya Adı Ara:';
+$lang['searchmedia_in'] = '%s içinde ara';
+$lang['txt_upload'] = 'Yüklenecek dosyayı seç';
+$lang['txt_filename'] = 'Dosya adı (zorunlu değil)';
+$lang['txt_overwrt'] = 'Mevcut dosyanın üstüne yaz';
+$lang['lockedby'] = 'Şu an şunun tarafından kilitli:';
+$lang['lockexpire'] = 'Kilitin açılma tarihi:';
+$lang['js']['willexpire'] = 'Bu sayfayı değiştirme kilidinin süresi yaklaşık bir dakika içinde geçecek.\nÇakışmaları önlemek için önizleme tuşunu kullanarak kilit sayacını sıfırla.';
+$lang['js']['notsavedyet'] = 'Kaydedilmemiş değişiklikler kaybolacak.
+Devam etmek istiyor musunuz?';
+$lang['js']['searchmedia'] = 'Dosyalar için Ara';
+$lang['js']['keepopen'] = 'Seçim yapıldığında bu pencereyi açık tut';
+$lang['js']['hidedetails'] = 'Ayrıntıları gizle';
+$lang['js']['mediatitle'] = 'Bağlantı Ayarları';
+$lang['js']['mediadisplay'] = 'Bağlantı Tipi';
+$lang['js']['mediaalign'] = 'Hizalama';
+$lang['js']['mediasize'] = 'Resim büyüklüğü';
+$lang['js']['mediatarget'] = 'Bağlantı hedefi';
+$lang['js']['mediaclose'] = 'Kapat';
+$lang['js']['mediainsert'] = 'Ekle';
+$lang['js']['mediadisplayimg'] = 'Resmi görüntüle';
+$lang['js']['mediadisplaylnk'] = 'Sadece bağlantıyı görüntüle ';
+$lang['js']['mediasmall'] = 'Küçük versiyon';
+$lang['js']['mediamedium'] = 'Orta versiyon';
+$lang['js']['medialarge'] = 'Büyük versiyon';
+$lang['js']['mediaoriginal'] = 'Orjinal versiyon';
+$lang['js']['medialnk'] = 'Detay sayfasına bağlantı';
+$lang['js']['mediadirect'] = 'Orjinal sayfaya bağlantı';
+$lang['js']['medianolnk'] = 'Bağlantı yok';
+$lang['js']['medianolink'] = 'Resme bağlantı verme';
+$lang['js']['medialeft'] = 'Resmi sola hizala';
+$lang['js']['mediaright'] = 'Resmi sağa hizala';
+$lang['js']['mediacenter'] = 'Resmi ortaya hizala';
+$lang['js']['medianoalign'] = 'Hizalama kullanma';
+$lang['js']['nosmblinks'] = 'Windows paylaşımı sadece Microsoft Internet Explorer ile çalışmaktadır. Yine de hala bağlantıyı kopyalayıp yapıştırarak kullanabilirsiniz. ';
+$lang['js']['linkwiz'] = 'Bağlantı sihirbazı';
+$lang['js']['linkto'] = 'Bağlantı:';
+$lang['js']['del_confirm'] = 'Bu girişi sil?';
+$lang['rssfailed'] = 'Bu beslemeyi çekerken hata oluştu: ';
+$lang['nothingfound'] = 'Hiçbir şey yok.';
+$lang['mediaselect'] = 'Çokluortam dosyası seçimi';
+$lang['fileupload'] = 'Çokluortam dosyası yükleme';
+$lang['uploadsucc'] = 'Yükleme tamam';
+$lang['uploadfail'] = 'Yükleme başarısız. Yetki hatası olabilir!';
+$lang['uploadwrong'] = 'Yükleme engellendi. Bu dosya uzantısına izin verilmiyor!';
+$lang['uploadexist'] = 'Dosya zaten var. Hiçbir şey yapılmadı.';
+$lang['uploadbadcontent'] = 'Yüklenen içerik %s uzantısı ile uyuşmuyor.';
+$lang['uploadspam'] = 'Yükleme işlemi spam karalistesi tarafından engellendi.';
+$lang['uploadxss'] = 'Yükleme işlemi muhtemel kötü içerik sebebiyle engellendi.';
+$lang['uploadsize'] = 'Yüklenmek istenen dosya boyutu çok büyük (en fazla %s)';
+$lang['deletesucc'] = '"%s" dosyası silindi.';
+$lang['deletefail'] = '"%s" silinemedi - yetkileri kontrol et.';
+$lang['mediainuse'] = '"%s" dosyası silinmedi, hala kullanımda.';
+$lang['namespaces'] = 'Namespaces';
+$lang['mediafiles'] = 'Şuradaki kullanıma hazır dosyalar:';
+$lang['accessdenied'] = 'Bu sayfayı görüntüleme yetkiniz bulunmamaktadır';
+$lang['mediausage'] = 'Şu ';
+$lang['mediaview'] = 'Özgün dosyayı göster';
+$lang['mediaroot'] = 'Kök dizini';
+$lang['mediaupload'] = 'Dosya bu namespace\'e yüklenir. Alt namespace oluşturmak için "Dosya adı" kısmınının başına alt namespace adını ekleyip ardından iki nokta koyun.';
+$lang['mediaextchange'] = 'Dosya uzantısı .%s\'den .%s\'e çevrildi!';
+$lang['reference'] = 'Şunun için referanslar:';
+$lang['ref_inuse'] = 'Dosya silinemiyor, çünkü şu sayfalar tarafından hala kullanılmakta:';
+$lang['ref_hidden'] = 'Bazı referanslar okuma yetkiniz olmayan sayfalarda';
+$lang['hits'] = 'tane bulundu';
+$lang['quickhits'] = 'Uyan sayfalar';
+$lang['toc'] = 'İçindekiler';
+$lang['current'] = 'mevcut';
+$lang['yours'] = 'Senin Sürümün';
+$lang['diff'] = 'Kullanılan sürüm ile farkları göster';
+$lang['diff2'] = 'Seçili sürümler arasındaki farkı göster';
+$lang['difflink'] = 'Karşılaştırma görünümüne bağlantı';
+$lang['line'] = 'Satır';
+$lang['breadcrumb'] = 'İz';
+$lang['youarehere'] = 'Buradasınız';
+$lang['lastmod'] = 'Son değiştirilme';
+$lang['by'] = 'Değiştiren:';
+$lang['deleted'] = 'silindi';
+$lang['created'] = 'oluşturuldu';
+$lang['restored'] = 'eski sürüme dönüldü';
+$lang['external_edit'] = 'Dışarıdan düzenle';
+$lang['summary'] = 'Özeti düzenle';
+$lang['noflash'] = 'Bu içeriği göstermek için <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Eklentisi</a> gerekmektedir.';
+$lang['download'] = 'Parçacığı indir';
+$lang['mail_newpage'] = 'sayfa eklenme:';
+$lang['mail_changed'] = 'sayfa değiştirilme:';
+$lang['mail_new_user'] = 'yeni kullanıcı';
+$lang['mail_upload'] = 'dosya yüklendi:';
+$lang['qb_bold'] = 'Kalın Yazı';
+$lang['qb_italic'] = 'Eğik Yazı';
+$lang['qb_underl'] = 'Altı Çizgili Yazı';
+$lang['qb_code'] = 'Kod Haline Getir';
+$lang['qb_strike'] = 'Ortası Çizilmiş Yazı';
+$lang['qb_h1'] = '1. Seviye Başlık';
+$lang['qb_h2'] = '2. Seviye Başlık';
+$lang['qb_h3'] = '3. Seviye Başlık';
+$lang['qb_h4'] = '4. Seviye Başlık';
+$lang['qb_h5'] = '5. Seviye Başlık';
+$lang['qb_h'] = 'Başlık';
+$lang['qb_hs'] = 'Başlığı seç';
+$lang['qb_hplus'] = 'Daha yüksek başlık';
+$lang['qb_link'] = 'İç Bağlantı';
+$lang['qb_extlink'] = 'Dış Bağlantı';
+$lang['qb_hr'] = 'Yatay Çizgi';
+$lang['qb_ol'] = 'Sıralı liste';
+$lang['qb_ul'] = 'Sırasız liste';
+$lang['qb_media'] = 'Resim ve başka dosyalar ekle';
+$lang['qb_sig'] = 'İmza Ekle';
+$lang['qb_smileys'] = 'Gülen Yüzler';
+$lang['qb_chars'] = 'Özel Karakterler';
+$lang['admin_register'] = 'Yeni kullanıcı ekle...';
+$lang['metaedit'] = 'Metaverileri Değiştir';
+$lang['metasaveerr'] = 'Metaveri yazma başarısız ';
+$lang['metasaveok'] = 'Metaveri kaydedildi';
+$lang['img_backto'] = 'Şuna dön:';
+$lang['img_title'] = 'Başlık';
+$lang['img_caption'] = 'Serlevha';
+$lang['img_date'] = 'Tarih';
+$lang['img_fname'] = 'Dosya Adı';
+$lang['img_fsize'] = 'Boyut';
+$lang['img_artist'] = 'Fotoğrafçı';
+$lang['img_copyr'] = 'Telif Hakkı';
+$lang['img_format'] = 'Biçim';
+$lang['img_camera'] = 'Fotoğraf Makinası';
+$lang['img_keywords'] = 'Anahtar Sözcükler';
+$lang['authmodfailed'] = 'Yanlış kullanıcı onaylama ayarı. Lütfen Wiki yöneticisine bildiriniz.';
+$lang['authtempfail'] = 'Kullanıcı doğrulama geçici olarak yapılamıyor. Eğer bu durum devam ederse lütfen Wiki yöneticine haber veriniz.';
+$lang['i_chooselang'] = 'Dili seçiniz';
+$lang['i_installer'] = 'Dokuwiki Kurulum Sihirbazı';
+$lang['i_wikiname'] = 'Wiki Adı';
+$lang['i_enableacl'] = 'ACL\'yi etkinleştir (tavsiye edilir)';
+$lang['i_superuser'] = 'Ana Kullanıcı';
+$lang['i_problems'] = 'Kurulum sihirbazı aşağıda gösterilen sorunları buldu. Bunları düzeltmeden devam etmeniz mümkün değil.';
+$lang['i_modified'] = 'Güzenlik sebebiyle bu script sadece yeni ve değiştirilmemiş bir Dokuwiki kurulumunda çalışır. Ya indirdiğiniz paketi yeniden açmalı ya da <a href="http://dokuwiki.org/install"> adresindeki Dokuwiki kurulum kılavuzu</a>na bakmalısınız.';
+$lang['i_funcna'] = '<code>%s</code> PHP fonksiyonu bulunmamaktadır. Barındırma(Hosting) hizmetinde bu özellik kapatılmış olabilir.';
+$lang['i_phpver'] = '<code>%s</code> PHP sürümü, gereken <code>%s</code> sürümünden daha düşük. PHP kurulumunu yükseltmeniz gerekmektedir.';
+$lang['i_permfail'] = '<code>%s</code> Dokuwiki tarafından yazılabilir değil. İzin ayarlarını bu klasör için düzeltmeniz gerekmektedir!';
+$lang['i_confexists'] = '<code>%s</code> zaten var';
+$lang['i_writeerr'] = '<code>%s</code> oluşturulamadı. Dosya/Klasör izin ayarlarını gözden geçirip dosyayı elle oluşturmalısınız.';
+$lang['i_badhash'] = 'dokuwiki.php tanınamadı ya da değiştirilmiş (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - Yanlış veya boş değer';
+$lang['i_success'] = 'Kurulum başarıyla tamamlandı. Şimdi install.php dosyasını silebilirsiniz. <a href="doku.php">Yeni DokuWikiniz</a>i kullanabilirsiniz.';
+$lang['i_failure'] = 'Ayar dosyalarını yazarken bazı hatalar oluştu. <a href="doku.php">Yeni DokuWikiniz</a>i kullanmadan önce bu hatalarınızı elle düzeltmeniz gerekebilir.';
+$lang['i_policy'] = 'İlk ACL ayarı';
+$lang['i_pol0'] = 'Tamamen Açık Wiki (herkes okuyabilir, yazabilir ve dosya yükleyebilir)';
+$lang['i_pol1'] = 'Açık Wiki (herkes okuyabilir, ancak sadece üye olanlar yazabilir ve dosya yükleyebilir)';
+$lang['i_pol2'] = 'Kapalı Wiki (sadece üye olanlar okuyabilir, yazabilir ve dosya yükleyebilir)';
+$lang['i_retry'] = 'Tekrar Dene';
+$lang['recent_global'] = '<b>%s</b> namespace\'i içerisinde yapılan değişiklikleri görüntülemektesiniz. Wiki\'deki tüm değişiklikleri de <a href="%s">bu adresten</a> görebilirsiniz. ';
diff --git a/inc/lang/tr/locked.txt b/inc/lang/tr/locked.txt
new file mode 100644
index 000000000..14385426e
--- /dev/null
+++ b/inc/lang/tr/locked.txt
@@ -0,0 +1,4 @@
+====== Sayfa kilitli ======
+
+Bu sayfa şu anda başka bir kullanıcının değiştirmesi için kilitli. Kilitin süresi geçene veya bu kullanıcı değiştirmeyi bitirene kadar beklemelisiniz.
+
diff --git a/inc/lang/tr/login.txt b/inc/lang/tr/login.txt
new file mode 100644
index 000000000..2ce378d00
--- /dev/null
+++ b/inc/lang/tr/login.txt
@@ -0,0 +1,4 @@
+====== Giriş ======
+
+Şu an giriş yapmış değilsiniz! Giriş yapmak için giriş bilgilerinizi aşağıya yazın. Giriş yapmak için çerezleri açmalısınız.
+
diff --git a/inc/lang/tr/mailtext.txt b/inc/lang/tr/mailtext.txt
new file mode 100644
index 000000000..7e8fc8d81
--- /dev/null
+++ b/inc/lang/tr/mailtext.txt
@@ -0,0 +1,16 @@
+DokuWikinizde bir sayfa eklendi veya değişti. Detaylar şunlar:
+
+Tarih : @DATE@
+Tarayıcı : @BROWSER@
+IP-Adresi : @IPADDRESS@
+Sunucu adı : @HOSTNAME@
+Eski Sürüm : @OLDPAGE@
+Yeni Sürüm : @NEWPAGE@
+Değiştirme Özeti : @SUMMARY@
+Kullanıcı : @USER@
+
+@DIFF@
+
+
+--
+Bu e-posta @DOKUWIKIURL@ adresindeki DokuWiki tarafından hazırlandı.
diff --git a/inc/lang/tr/newpage.txt b/inc/lang/tr/newpage.txt
new file mode 100644
index 000000000..8a47e6bf3
--- /dev/null
+++ b/inc/lang/tr/newpage.txt
@@ -0,0 +1,4 @@
+====== Bu başlık henüz mevcut değil ======
+
+Henüz mevcut olmayan bir başlığın linkiyle geldiniz. ''bu sayfayı oluştur'' tuşuna tıklayarak sayfayı oluşturabilirsiniz.
+
diff --git a/inc/lang/tr/norev.txt b/inc/lang/tr/norev.txt
new file mode 100644
index 000000000..e6f97bef2
--- /dev/null
+++ b/inc/lang/tr/norev.txt
@@ -0,0 +1,4 @@
+====== Böyle bir sürüm yok ======
+
+Belirtilen sürüm mevcut değil. Bu dökümanın eski sürümlerinin bir listesine ulaşmak için ''Eski sürümler'' tuşunu kullanın.
+
diff --git a/inc/lang/tr/password.txt b/inc/lang/tr/password.txt
new file mode 100644
index 000000000..956a786d5
--- /dev/null
+++ b/inc/lang/tr/password.txt
@@ -0,0 +1,10 @@
+Merhaba @FULLNAME@!
+
+
+@DOKUWIKIURL@ adresindeki @TITLE@ için kullanıcı bilgin şöyle:
+
+Giriş ismi : @LOGIN@
+Parola : @PASSWORD@
+
+--
+Bu e-posta @DOKUWIKIURL@ adresindeki DokuWiki tarafından hazırlandı. \ No newline at end of file
diff --git a/inc/lang/tr/preview.txt b/inc/lang/tr/preview.txt
new file mode 100644
index 000000000..71a8a42f6
--- /dev/null
+++ b/inc/lang/tr/preview.txt
@@ -0,0 +1,4 @@
+====== Önizleme ======
+
+Bu yazınızın nasıl çıkacağının bir önizlemesi. Unutma: Yazı henüz **kaydedilmedi!**
+
diff --git a/inc/lang/tr/pwconfirm.txt b/inc/lang/tr/pwconfirm.txt
new file mode 100644
index 000000000..22348bb75
--- /dev/null
+++ b/inc/lang/tr/pwconfirm.txt
@@ -0,0 +1,13 @@
+Merhaba @FULLNAME@!
+
+@DOKUWIKIURL@ adresinde kullanılan @TITLE@ hesabı için parola talebinde bulunuldu.
+
+Eğer böyle bir talebiniz olmadıysa, bu e-postayı görmezden gelebilirsiniz.
+
+Onaylamak istiyorsanız aşağıdaki linke tıklayınız.
+
+@CONFIRM@
+
+--
+Bu e-posta aşağıdaki DokuWiki tarafından otomatik olarak oluşturulmuştur.
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/tr/read.txt b/inc/lang/tr/read.txt
new file mode 100644
index 000000000..59314f152
--- /dev/null
+++ b/inc/lang/tr/read.txt
@@ -0,0 +1,2 @@
+Bu sayfa salt okunur. Kaynağı görebilirsiniz ama değiştiremezsiniz. Bunun yanlış olduğunu düşünüyorsanız yöneticiye danışın.
+
diff --git a/inc/lang/tr/recent.txt b/inc/lang/tr/recent.txt
new file mode 100644
index 000000000..99efc8fb1
--- /dev/null
+++ b/inc/lang/tr/recent.txt
@@ -0,0 +1,5 @@
+====== Son değişiklikler ======
+
+Aşağıdaki sayfalar yakın zamanda değiştirildi.
+
+
diff --git a/inc/lang/tr/register.txt b/inc/lang/tr/register.txt
new file mode 100644
index 000000000..b67e4b5c5
--- /dev/null
+++ b/inc/lang/tr/register.txt
@@ -0,0 +1,4 @@
+====== Yeni kullanıcı olarak kaydolun ======
+
+Bu wikide yeni bir hesap açmak için aşağıdaki tüm bilgileri doldurunuz. **Doğru e-posta adresi verdiğinizden** emin olun, yeni parolanız e-postanıza gönderilecek. Giriş adınız geçerli bir [[doku>pagename|sayfa adı]] olmalıdır.
+
diff --git a/inc/lang/tr/registermail.txt b/inc/lang/tr/registermail.txt
new file mode 100644
index 000000000..7754a5671
--- /dev/null
+++ b/inc/lang/tr/registermail.txt
@@ -0,0 +1,13 @@
+Yeni bir kullanıcı kayıt oldu. Ayrıntıları aşağıda listelenmiştir:
+
+Kullanıcı adı : @NEWUSER@
+İsim : @NEWNAME@
+E-posta : @NEWEMAIL@
+
+Tarih : @DATE@
+Tarayıcı : @BROWSER@
+IP Numarası : @IPADDRESS@
+Host : @HOSTNAME@
+
+--
+Bu e-posta @DOKUWIKIURL@ adresindeki DokuWiki tarafından hazırlandı. \ No newline at end of file
diff --git a/inc/lang/tr/resendpwd.txt b/inc/lang/tr/resendpwd.txt
new file mode 100644
index 000000000..1a34396ea
--- /dev/null
+++ b/inc/lang/tr/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Yeni Parola Gönderimi ======
+
+Lütfen bu wikide kullanmış olduğunuz kullanıcı adını aşağıdaki forma yazınız. Onay linki, kayıtlı e-posta adresinize gönderilecektir.
diff --git a/inc/lang/tr/revisions.txt b/inc/lang/tr/revisions.txt
new file mode 100644
index 000000000..841fba2b9
--- /dev/null
+++ b/inc/lang/tr/revisions.txt
@@ -0,0 +1,4 @@
+====== Eski sürümler ======
+
+Bunlar mevcut dökümanın daha eski sürümleridir. Eski bir sürüme çevirmek için, sürümü aşağıdan seçin, ''Sayfayı değiştir''e tıklayın ve kaydedin.
+
diff --git a/inc/lang/tr/searchpage.txt b/inc/lang/tr/searchpage.txt
new file mode 100644
index 000000000..ae6d50c77
--- /dev/null
+++ b/inc/lang/tr/searchpage.txt
@@ -0,0 +1,5 @@
+====== Arama ======
+
+Aşağıda aramanın sonuçları listelenmiştir. Aradığınız şeyi bulamadıysanız, ''Sayfayı değiştir'' tuşuna tıklayarak girdiğiniz sorgu adıyla yeni bir sayfa oluşturabilirsiniz .
+
+===== Sonuçlar =====
diff --git a/inc/lang/tr/showrev.txt b/inc/lang/tr/showrev.txt
new file mode 100644
index 000000000..4cf3d2638
--- /dev/null
+++ b/inc/lang/tr/showrev.txt
@@ -0,0 +1,2 @@
+**Bu, dökümanın eski bir sürümüdür!**
+----
diff --git a/inc/lang/tr/stopwords.txt b/inc/lang/tr/stopwords.txt
new file mode 100644
index 000000000..293067a1c
--- /dev/null
+++ b/inc/lang/tr/stopwords.txt
@@ -0,0 +1,29 @@
+# Bu indeksleyicinin yok saydığı kelimelerin bir listesidir, satır başına bir kelime yazılır
+# Bu dosyayı değiştirirken UNIX satır sonları (tek satır sonu) kullandığınız emin olun
+# 3 karakterden kısa kelimeleri eklenmesine gerek yoktur, bunlar zaten indekslenmez
+# Bu liste http://www.ranks.nl/stopwords/ altındakilerden derlenmiştir
+about
+are
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/tr/updateprofile.txt b/inc/lang/tr/updateprofile.txt
new file mode 100644
index 000000000..20b07f949
--- /dev/null
+++ b/inc/lang/tr/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Kullanıcı Bilgilerini Güncelleme ======
+
+İstediğiniz kullanıcı bilgilerini değiştirebilirsiniz. Ancak kullanıcı adınızı değiştirmeniz mümkün değildir.
diff --git a/inc/lang/tr/uploadmail.txt b/inc/lang/tr/uploadmail.txt
new file mode 100644
index 000000000..2d75345ba
--- /dev/null
+++ b/inc/lang/tr/uploadmail.txt
@@ -0,0 +1,13 @@
+Yeni dosya yüklendi. Ayrıntıları aşağıda listelenmiştir:
+
+Dosya : @MEDIA@
+Tarih : @DATE@
+Tarayıcı : @BROWSER@
+IP Adresi : @IPADDRESS@
+Host : @HOSTNAME@
+Boyut : @SIZE@
+MIME Type : @MIME@
+Kullanıcı : @USER@
+
+--
+Bu e-posta @DOKUWIKIURL@ adresindeki DokuWiki tarafından hazırlandı. \ No newline at end of file
diff --git a/inc/lang/uk/admin.txt b/inc/lang/uk/admin.txt
new file mode 100644
index 000000000..f698d937e
--- /dev/null
+++ b/inc/lang/uk/admin.txt
@@ -0,0 +1,4 @@
+====== Адміністрування ======
+
+Нижче ви можете знайти перелік адміністративних задач, що наявні в ДокуВікі.
+
diff --git a/inc/lang/uk/adminplugins.txt b/inc/lang/uk/adminplugins.txt
new file mode 100644
index 000000000..3689ccd00
--- /dev/null
+++ b/inc/lang/uk/adminplugins.txt
@@ -0,0 +1 @@
+===== Додаткові плагіни ===== \ No newline at end of file
diff --git a/inc/lang/uk/backlinks.txt b/inc/lang/uk/backlinks.txt
new file mode 100644
index 000000000..5f293e56f
--- /dev/null
+++ b/inc/lang/uk/backlinks.txt
@@ -0,0 +1,3 @@
+====== Зворотні зв'язки ======
+
+Це перелік сторінок, які, здається, посилаються на поточну сторінку.
diff --git a/inc/lang/uk/conflict.txt b/inc/lang/uk/conflict.txt
new file mode 100644
index 000000000..5a8930721
--- /dev/null
+++ b/inc/lang/uk/conflict.txt
@@ -0,0 +1,8 @@
+====== Існує більш нова версія ======
+
+Існує новіша версія документу, що ви редагували. Це може статися, коли інший користувач змінив документ під час вашого редагування.
+
+Уважно перегляньте розбіжності та вирішіть, яку версію залишити. Якщо ви натиснете
+''зберегти'', буде збережена ваша версія. Якщо натиснете ''скасувати'' --- то залишиться
+поточна версія.
+
diff --git a/inc/lang/uk/denied.txt b/inc/lang/uk/denied.txt
new file mode 100644
index 000000000..5db12e1bc
--- /dev/null
+++ b/inc/lang/uk/denied.txt
@@ -0,0 +1,4 @@
+====== Доступ заборонено ======
+
+Вибачте, але у вас не вистачає прав для продовження. Можливо ви забули увійти в систему?
+
diff --git a/inc/lang/uk/diff.txt b/inc/lang/uk/diff.txt
new file mode 100644
index 000000000..cfdf9a887
--- /dev/null
+++ b/inc/lang/uk/diff.txt
@@ -0,0 +1,4 @@
+====== Розбіжності ======
+
+Тут показані розбіжності між вибраною ревізією та поточною версією сторінки.
+
diff --git a/inc/lang/uk/draft.txt b/inc/lang/uk/draft.txt
new file mode 100644
index 000000000..f6acca8ed
--- /dev/null
+++ b/inc/lang/uk/draft.txt
@@ -0,0 +1,6 @@
+====== Знайдено чернетку ======
+
+Останнє редагування цієї сторінки не було завершено коректно. ДокуВікі автоматично зберегла чернетку під час вашої роботи. Ви можете використати чернетку для продовження редагування. Нижче ви можете побачити дані, збережені з попереднього сеансу.
+
+Будь ласка вирішить, чи ви бажаєте //відновити// останній сеанс редагування, //знищити// збережену чернетку або //скасувати// редагування.
+
diff --git a/inc/lang/uk/edit.txt b/inc/lang/uk/edit.txt
new file mode 100644
index 000000000..82dbc1a50
--- /dev/null
+++ b/inc/lang/uk/edit.txt
@@ -0,0 +1 @@
+Відредагуйте сторінку та натисніть ''Зберегти''. Використовуйте [[wiki:syntax|посібник]] з синтаксису для довідки. Будь ласка, змінюйте сторінку лише у тому випадку, коли ви можете **покращити** її. Якщо ви бажаєте щось спробувати, використовуйте спеціальну сторінку [[playground:playground]]
diff --git a/inc/lang/uk/editrev.txt b/inc/lang/uk/editrev.txt
new file mode 100644
index 000000000..aae86fa50
--- /dev/null
+++ b/inc/lang/uk/editrev.txt
@@ -0,0 +1,2 @@
+**Ви завантажили стару версію документу!** Якщо ви збережете її, ви створите нову версію з ціми даними.
+----
diff --git a/inc/lang/uk/index.txt b/inc/lang/uk/index.txt
new file mode 100644
index 000000000..0ba0d185b
--- /dev/null
+++ b/inc/lang/uk/index.txt
@@ -0,0 +1,4 @@
+====== Зміст ======
+
+Це перелік усіх доступних сторінок, упоряджених за [[doku>namespaces|просторами імен]]
+
diff --git a/inc/lang/uk/install.html b/inc/lang/uk/install.html
new file mode 100644
index 000000000..084da8662
--- /dev/null
+++ b/inc/lang/uk/install.html
@@ -0,0 +1,21 @@
+<p>Ця сторінка допомагає при першій установці та настройці <a href="http://dokuwiki.org">ДокуВікі</a>.
+Більше інформації про програму установки можна знайти на <a href="http://dokuwiki.org/installer">сторінці документації</a>.</p>
+
+<p>ДокуВікі використовую звичайні файли для зберігання сторінок вікі та іншої інформації,
+щодо цих сторінок (наприклад, зображень, індексів пошуку, старих ревізій та ін.). Для
+успішного функціонування ДокуВікі <strong>має</strong> мати права на запис для папок, що
+містять ці файли. Ця програма установки не може змінювати права доступу. Звичайно це
+робиться за допомогою інтерпретатора shell, або, якщо ви використовуєте хостинг,
+за допомогою FTP або панелі управління хостингом (наприклад cPanel).</p>
+
+<p>Ця програма установки налаштує вашу ДокуВікі для використання
+<acronym title="список контролю доступу">ACL</acronym>, що, в свою чергу,
+дозволить адміністратору входити до адміністративного меню для установки доданків,
+керування користувачами, керування правами доступу до сторінок Вікі та змін параметрів
+конфігурації. Це не є обов'язковим для роботи ДокуВікі, але зробить життя адміністратора
+значно легшим.</p>
+
+<p>Досвідчені користувачі, або користувачі, що мають особливі вимоги до налагодження, мають
+використовувати ці посилання для детальної інформації, щодо
+<a href="http://dokuwiki.org/install">інструкцій з установки</a>
+та <a href="http://dokuwiki.org/config">параметрів конфігурації</a>.</p>
diff --git a/inc/lang/uk/lang.php b/inc/lang/uk/lang.php
new file mode 100644
index 000000000..18bee589d
--- /dev/null
+++ b/inc/lang/uk/lang.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * ukrainian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oleksiy Voronin <ovoronin@gmail.com>
+ * @author serg_stetsuk@ukr.net
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko <uko@uar.net>
+ * @author Ulrikhe Lukoie <lukoie@gmail.com>
+ * @author Kate Arzamastseva pshns@ukr.net
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = 'Редагувати';
+$lang['btn_source'] = 'Показати вихідний текст';
+$lang['btn_show'] = 'Показати сторінку';
+$lang['btn_create'] = 'Створити сторінку';
+$lang['btn_search'] = 'Пошук';
+$lang['btn_save'] = 'Зберегти';
+$lang['btn_preview'] = 'Перегляд';
+$lang['btn_top'] = 'Повернутися наверх';
+$lang['btn_newer'] = '<< більш нові';
+$lang['btn_older'] = 'більш старі >>';
+$lang['btn_revs'] = 'Старі ревізії';
+$lang['btn_recent'] = 'Недавні зміни';
+$lang['btn_upload'] = 'Завантажити';
+$lang['btn_cancel'] = 'Скасувати';
+$lang['btn_index'] = 'Зміст';
+$lang['btn_secedit'] = 'Редагувати';
+$lang['btn_login'] = 'Увійти';
+$lang['btn_logout'] = 'Вийти';
+$lang['btn_admin'] = 'Керування';
+$lang['btn_update'] = 'Оновити';
+$lang['btn_delete'] = 'Знищити';
+$lang['btn_back'] = 'Назад';
+$lang['btn_backlink'] = 'Посилання сюди';
+$lang['btn_backtomedia'] = 'Назад до вибору медіа-файлу';
+$lang['btn_subscribe'] = 'Підписатися';
+$lang['btn_profile'] = 'Оновити профіль';
+$lang['btn_reset'] = 'Очистити';
+$lang['btn_resendpwd'] = 'Надіслати новий пароль';
+$lang['btn_draft'] = 'Редагувати чернетку';
+$lang['btn_recover'] = 'Відновити чернетку';
+$lang['btn_draftdel'] = 'Знищити чернетку';
+$lang['btn_revert'] = 'Відновити';
+$lang['btn_register'] = 'Реєстрація';
+$lang['loggedinas'] = 'Ви';
+$lang['user'] = 'Користувач';
+$lang['pass'] = 'Пароль';
+$lang['newpass'] = 'Новий пароль';
+$lang['oldpass'] = 'Поточний пароль';
+$lang['passchk'] = 'ще раз';
+$lang['remember'] = 'Запам\'ятати мене';
+$lang['fullname'] = 'Повне ім\'я';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'Профіль користувача';
+$lang['badlogin'] = 'Вибачте, невірне ім\'я чи пароль.';
+$lang['minoredit'] = 'Незначні зміни';
+$lang['draftdate'] = 'Чернетка збережена';
+$lang['nosecedit'] = 'Сторінку змінено, дані розділу застарілі. Завантажено сторінку повністю.';
+$lang['regmissing'] = 'Необхідно заповнити всі поля.';
+$lang['reguexists'] = 'Користувач з таким іменем вже існує.';
+$lang['regsuccess'] = 'Користувача створено. Пароль відправлено на e-mail.';
+$lang['regsuccess2'] = 'Користувача створено.';
+$lang['regmailfail'] = 'При відправленні пароля сталась помилка. Зв’яжіться з адміністратором!';
+$lang['regbadmail'] = 'Схоже, що адреса e-mail невірна - якщо ви вважаєте, що це помилка, зв’яжіться з адміністратором';
+$lang['regbadpass'] = 'Надані паролі не співпадають, спробуйте ще раз.';
+$lang['regpwmail'] = 'Пароль ДокуВікі';
+$lang['reghere'] = 'Ще не маєте облікового запису? Отримайте його негайно';
+$lang['profna'] = 'Ця Вікі не підтримує зміни профілю';
+$lang['profnochange'] = 'Немає змін, немає що робити.';
+$lang['profnoempty'] = 'Ім’я або e-mail не можуть бути пустими.';
+$lang['profchanged'] = 'Профіль успішно змінено.';
+$lang['pwdforget'] = 'Забули пароль? Отримайте новий';
+$lang['resendna'] = 'Ця Вікі не підтримує повторне відправлення пароля.';
+$lang['resendpwd'] = 'Надіслати пароль для';
+$lang['resendpwdmissing'] = 'Необхідно заповнити усі поля.';
+$lang['resendpwdnouser'] = 'Такий користувач не існує.';
+$lang['resendpwdbadauth'] = 'Код автентифікації невірний. Перевірте, чи ви використали повне посилання для підтвердження.';
+$lang['resendpwdconfirm'] = 'Посилання для підтвердження відіслано на e-mail.';
+$lang['resendpwdsuccess'] = 'Новий пароль відіслано на e-mail.';
+$lang['license'] = 'Якщо не вказано інше, вміст цієї Вікі підпадає під дію такої ліцензії:';
+$lang['licenseok'] = 'Примітка. Редагуючи ці сторінку, ви погоджуєтесь на розповсюдження інформації за такою ліцензією:';
+$lang['searchmedia'] = 'Пошук файлу:';
+$lang['searchmedia_in'] = 'Шукати у %s';
+$lang['txt_upload'] = 'Виберіть файл для завантаження';
+$lang['txt_filename'] = 'Завантажити як (не обов\'язкове)';
+$lang['txt_overwrt'] = 'Перезаписати існуючий файл';
+$lang['lockedby'] = 'Заблоковано';
+$lang['lockexpire'] = 'Блокування завершується в';
+$lang['js']['willexpire'] = 'Блокування редагування цієї сторінки закінчується через хвилину.\n Щоб уникнути конфліктів використовуйте кнопку перегляду для продовження блокування.';
+$lang['js']['notsavedyet'] = 'Незбережені зміни будуть втрачені.
+ Дійсно продовжити?';
+$lang['js']['searchmedia'] = 'Шукати файли';
+$lang['js']['keepopen'] = 'Тримати вікно відкритим під час вибору';
+$lang['js']['hidedetails'] = 'Сховати деталі';
+$lang['js']['mediatitle'] = 'Налаштунки посилання';
+$lang['js']['mediadisplay'] = 'Тип посилання';
+$lang['js']['mediaalign'] = 'Вирівнювання';
+$lang['js']['mediasize'] = 'Розмір зображення';
+$lang['js']['mediatarget'] = 'Ціль посилання';
+$lang['js']['mediaclose'] = 'Закрити';
+$lang['js']['mediainsert'] = 'Вставити';
+$lang['js']['mediadisplayimg'] = 'Показати зображення.';
+$lang['js']['mediadisplaylnk'] = 'Показати тільки посилання.';
+$lang['js']['mediasmall'] = 'Зменшена версія';
+$lang['js']['mediamedium'] = 'Середня версія';
+$lang['js']['medialarge'] = 'Велика версія';
+$lang['js']['mediaoriginal'] = 'Оригінальна версія';
+$lang['js']['medialnk'] = 'Посилання на сторінку з описом';
+$lang['js']['mediadirect'] = 'Пряме посилання на оригінал';
+$lang['js']['medianolnk'] = 'Немає посилання';
+$lang['js']['medianolink'] = 'Не посилайтеся на зображення';
+$lang['js']['medialeft'] = 'Вирівняти зображення по лівому краю.';
+$lang['js']['mediaright'] = 'Вирівняти зображення по правому краю.';
+$lang['js']['mediacenter'] = 'Вирівняти зображення по центру.';
+$lang['js']['medianoalign'] = 'Не вирівнювати зображення.';
+$lang['js']['nosmblinks'] = 'Посилання на мережеві папки працює лише в Internet Explorer.
+Ви можете скопіювати посилання і відкрити його за допомогою Internet Explorer.';
+$lang['js']['linkwiz'] = 'Чарівник посилань';
+$lang['js']['linkto'] = 'Посилання на:';
+$lang['js']['del_confirm'] = 'Дійсно знищити обрані елементи?';
+$lang['rssfailed'] = 'Виникла помилка під час отримання RSS-стрічки: ';
+$lang['nothingfound'] = 'Нічого не знайдено.';
+$lang['mediaselect'] = 'Вибір медіа-файлу';
+$lang['fileupload'] = 'Завантаження медіа-файлу';
+$lang['uploadsucc'] = 'Завантаження пройшло успішно';
+$lang['uploadfail'] = 'Помилка при завантаженні. Можливо неправильні права?';
+$lang['uploadwrong'] = 'Завантаження заборонено. Таке розширення файлу не дозволяється!';
+$lang['uploadexist'] = 'Файл вже існує. Нічого не зроблено.';
+$lang['uploadbadcontent'] = 'Завантажений вміст не відповідає розширенню %s.';
+$lang['uploadspam'] = 'Завантаження заблоковано спам-фільтром.';
+$lang['uploadxss'] = 'Завантаження заблоковано через можливість злонаміреного вмісту.';
+$lang['uploadsize'] = 'Завантажений файл надто великий (максимум %s).';
+$lang['deletesucc'] = 'Файл "%s" знищено.';
+$lang['deletefail'] = 'Неможливо знищити "%s" - перевірте права доступу.';
+$lang['mediainuse'] = '"%s" не знищено - файл використовується.';
+$lang['namespaces'] = 'Простори імен';
+$lang['mediafiles'] = 'Доступні файли';
+$lang['accessdenied'] = 'Вам не дозволено переглядати цю сторінку.';
+$lang['mediausage'] = 'Для посилання на цей файл використовуйте такий синтаксис:';
+$lang['mediaview'] = 'Переглянути початковий файл';
+$lang['mediaroot'] = 'корінь';
+$lang['mediaupload'] = 'Завантаження файлу у поточний простір імен. Щоб створити простори імен, додайте їх в початок імені файлу та розділіть двокрапками.';
+$lang['mediaextchange'] = 'Розширення файлу змінено з .%s на .%s!';
+$lang['reference'] = 'Посилання для';
+$lang['ref_inuse'] = 'Цей файл не може бути знищено, оскільки він використовується такими сторінками:';
+$lang['ref_hidden'] = 'Деякі посилання існують на сторінках, для читання яких у вас немає прав.';
+$lang['hits'] = 'Збіги';
+$lang['quickhits'] = 'Збіги у назвах сторінок';
+$lang['toc'] = 'Зміст';
+$lang['current'] = 'поточний';
+$lang['yours'] = 'Ваша версія';
+$lang['diff'] = 'показати відмінності від поточної версії';
+$lang['diff2'] = 'Показати відмінності між вибраними версіями';
+$lang['difflink'] = 'Посилання на цей список змін';
+$lang['diff_type'] = 'Переглянути відмінності:';
+$lang['diff_inline'] = 'Вбудувати';
+$lang['diff_side'] = 'Поряд';
+$lang['line'] = 'Рядок';
+$lang['breadcrumb'] = 'Відвідано';
+$lang['youarehere'] = 'Ви тут';
+$lang['lastmod'] = 'В останнє змінено';
+$lang['by'] = ' ';
+$lang['deleted'] = 'знищено';
+$lang['created'] = 'створено';
+$lang['restored'] = 'відновлено стару ревізію';
+$lang['external_edit'] = 'зовнішнє редагування';
+$lang['summary'] = 'Підсумок змін';
+$lang['noflash'] = 'Для перегляду цієї сторінки необхідно встановити <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>.';
+$lang['download'] = 'Завантажити фрагмент';
+$lang['mail_newpage'] = 'сторінку додано:';
+$lang['mail_changed'] = 'сторінку змінено:';
+$lang['mail_subscribe_list'] = 'сторінки, що змінено у просторі імен:';
+$lang['mail_new_user'] = 'новий користувач:';
+$lang['mail_upload'] = 'завантажено файл:';
+$lang['qb_bold'] = 'Напівжирний текст';
+$lang['qb_italic'] = 'Курсив';
+$lang['qb_underl'] = 'Підкреслений текст';
+$lang['qb_code'] = 'Текст коду';
+$lang['qb_strike'] = 'Закреслений текст';
+$lang['qb_h1'] = 'Заголовок 1-го рівня';
+$lang['qb_h2'] = 'Заголовок 2-го рівня';
+$lang['qb_h3'] = 'Заголовок 3-го рівня';
+$lang['qb_h4'] = 'Заголовок 4-го рівня';
+$lang['qb_h5'] = 'Заголовок 5-го рівня';
+$lang['qb_h'] = 'Заголовок';
+$lang['qb_hs'] = 'Вибрати заголовок';
+$lang['qb_hplus'] = 'Заголовок вищого рівня';
+$lang['qb_hminus'] = 'Заголовок нищого рівня';
+$lang['qb_hequal'] = 'Заголовок того ж рівня';
+$lang['qb_link'] = 'Внутрішнє посилання';
+$lang['qb_extlink'] = 'Зовнішнє посилання';
+$lang['qb_hr'] = 'Роздільник';
+$lang['qb_ol'] = 'Елемент нумерованого списку';
+$lang['qb_ul'] = 'Елемент ненумерованого списку';
+$lang['qb_media'] = 'Додати зображень та інші файли';
+$lang['qb_sig'] = 'Додати підпис';
+$lang['qb_smileys'] = 'Посмішки';
+$lang['qb_chars'] = 'Спеціальні символи';
+$lang['upperns'] = 'Перейти до батьківського простору імен';
+$lang['admin_register'] = 'Додати нового користувача';
+$lang['metaedit'] = 'Редагувати метадані';
+$lang['metasaveerr'] = 'Помилка запису метаданих';
+$lang['metasaveok'] = 'Метадані збережено';
+$lang['img_backto'] = 'Повернутися до';
+$lang['img_title'] = 'Назва';
+$lang['img_caption'] = 'Підпис';
+$lang['img_date'] = 'Дата';
+$lang['img_fname'] = 'Ім’я файлу';
+$lang['img_fsize'] = 'Розмір';
+$lang['img_artist'] = 'Фотограф';
+$lang['img_copyr'] = 'Авторські права';
+$lang['img_format'] = 'Формат';
+$lang['img_camera'] = 'Камера';
+$lang['img_keywords'] = 'Ключові слова';
+$lang['subscr_subscribe_success'] = 'Додано %s до списку підписки для %s';
+$lang['subscr_subscribe_error'] = 'Помилка при додавані %s до списку підписки для %s';
+$lang['subscr_subscribe_noaddress'] = 'Немає адреси, асоційованої з Вашим логіном, тому Ви не можете бути додані до списку підписки.';
+$lang['subscr_unsubscribe_success'] = 'Видалено %s із списку підписки для %s';
+$lang['subscr_unsubscribe_error'] = 'Помилка при видаленні %s зі списку підписки для %s';
+$lang['subscr_already_subscribed'] = '%s вже підписаний до %s';
+$lang['subscr_not_subscribed'] = '%s не підписаний до %s';
+$lang['subscr_m_not_subscribed'] = 'Ви зараз не підписані до цієї сторінки або простору імен.';
+$lang['subscr_m_new_header'] = 'Додати підписку';
+$lang['subscr_m_current_header'] = 'Поточні підписки';
+$lang['subscr_m_unsubscribe'] = 'Відписатися';
+$lang['subscr_m_subscribe'] = 'Підписатися';
+$lang['subscr_m_receive'] = 'Отримувати';
+$lang['subscr_style_every'] = 'повідомляти на пошту про кожну зміну';
+$lang['subscr_style_digest'] = 'лист з дайджестом для зміни кожної сторінки (кожні %.2f днів)';
+$lang['subscr_style_list'] = 'список змінених сторінок від часу отримання останнього листа (кожні %.2f днів)';
+$lang['authmodfailed'] = 'Неправильна настройка автентифікації користувача. Будь ласка, повідомте про це адміністратора.';
+$lang['authtempfail'] = 'Автентифікація користувача тимчасово не доступна. Якщо це буде продовжуватись, будь ласка, повідомте адміністратора.';
+$lang['i_chooselang'] = 'Виберіть мову';
+$lang['i_installer'] = 'Програма установки ДокуВікі';
+$lang['i_wikiname'] = 'Назва Вікі';
+$lang['i_enableacl'] = 'Дозволити використання ACL (рекомендовано)';
+$lang['i_superuser'] = 'Суперкористувач';
+$lang['i_problems'] = 'Програма установки знайшла декілька проблем, що вказані нижче. Ви не можете продовжити, поки не виправите їх';
+$lang['i_modified'] = 'З причин безпеки цей скрипт буде працювати тільки з новою та немодифікованою установкою ДокуВікі.
+Вам слід або ще раз розпакувати файли із завантаженого пакету, або звернутися до повної <a href="http://dokuwiki.org/install">інструкції з установки ДокуВікі</a>';
+$lang['i_funcna'] = 'Функція PHP <code>%s</code> не доступна. Можливо, хостинг-провайдер відключив її з якихось причин?';
+$lang['i_phpver'] = 'Версія PHP <code>%s</code> менша, ніж необхідно - <code>%s</code>. Необхідно оновити PHP.';
+$lang['i_permfail'] = 'ДокуВікі не має прав на запис <code>%s</code>. Необхідно змінити права доступа для цієї папки!';
+$lang['i_confexists'] = '<code>%s</code> вже існує';
+$lang['i_writeerr'] = 'Неможливо створити <code>%s</code>. Необхідно перевірити права доступа для файлу/папки та створити файл вручну.';
+$lang['i_badhash'] = 'Невпізнаний або модифікований dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - невірне або пусте значення.';
+$lang['i_success'] = 'Настройку завершено. Ми можете знищити файл install.php.
+Перейдіть до <a href="doku.php">вашої нової ДокуВікі</a>';
+$lang['i_failure'] = 'При збереженні файлу конфігурації виникли помилки. Можливо вам доведеться виправити їх самостійно
+до початку використання <a href="doku.php">вашої нової ДокуВікі</a>.';
+$lang['i_policy'] = 'Початкова політика ACL';
+$lang['i_pol0'] = 'Відкрита Вікі (читання, запис та завантаження файлів для всіх)';
+$lang['i_pol1'] = 'Публічна Вікі (читання для всіх, запис та завантаження для зареєстрованих користувачів)';
+$lang['i_pol2'] = 'Закрита Вікі (читання, запис та завантаження тільки для зареєстрованих користувачів)';
+$lang['i_retry'] = 'Повторити';
+$lang['i_license'] = 'Будь ласка, виберіть тип ліцензії, під якою Ві бажаєте опублікувати матеріал:';
+$lang['recent_global'] = 'Ви переглядаєте зміни в межах простору імен <b>%s</b>. Також можна <a href="%s">переглянути зміни в межах усієї Вікі</a>.';
+$lang['years'] = '%d років тому';
+$lang['months'] = '%d місяців тому';
+$lang['weeks'] = '%d тижнів тому';
+$lang['days'] = '%d днів тому';
+$lang['hours'] = '%d годин тому';
+$lang['minutes'] = '%d хвилин тому';
+$lang['seconds'] = '%d секунд тому';
+$lang['wordblock'] = 'Ваші зміни не збережено, тому що вони розпізнані як такі, що містять заблокований текст(спам).';
diff --git a/inc/lang/uk/locked.txt b/inc/lang/uk/locked.txt
new file mode 100644
index 000000000..367c286bf
--- /dev/null
+++ b/inc/lang/uk/locked.txt
@@ -0,0 +1,3 @@
+====== Сторінку заблоковано ======
+
+Цю сторінку заблоковано іншим користувачем для редагування. Зачекайте, поки цей користувач завершить редагування або закінчиться час блокування. \ No newline at end of file
diff --git a/inc/lang/uk/login.txt b/inc/lang/uk/login.txt
new file mode 100644
index 000000000..f45f81024
--- /dev/null
+++ b/inc/lang/uk/login.txt
@@ -0,0 +1,4 @@
+====== Вхід до вікі ======
+
+Ви не ввійшли до системи. Введіть ваші реєстраційні дані для того, щоб увійти. У вашому браузері повинні бути увімкнені файли cookies.
+
diff --git a/inc/lang/uk/mailtext.txt b/inc/lang/uk/mailtext.txt
new file mode 100644
index 000000000..5bd25c3c3
--- /dev/null
+++ b/inc/lang/uk/mailtext.txt
@@ -0,0 +1,17 @@
+Сторінка в вашому ДокуВікі була змінена. Деталі нижче:
+
+Дата : @DATE@
+Оглядач : @BROWSER@
+Адреса IP : @IPADDRESS@
+Ім'я вузла : @HOSTNAME@
+Стара ревізія: @OLDPAGE@
+Нова ревізія : @NEWPAGE@
+Підсумок змін : @SUMMARY@
+Користувач : @USER@
+
+@DIFF@
+
+
+--
+Це повідомлення було створене ДокуВікі з
+@DOKUWIKIURL@
diff --git a/inc/lang/uk/newpage.txt b/inc/lang/uk/newpage.txt
new file mode 100644
index 000000000..39cdecc35
--- /dev/null
+++ b/inc/lang/uk/newpage.txt
@@ -0,0 +1,4 @@
+====== Сторінка ще не існує ======
+
+Ви прийшли за посиланням на сторінку, що ще не існує. Якщо ваші права дозволяють, ви можете створити цю сторінку натиснувши кнопку ''Створити сторінку''.
+
diff --git a/inc/lang/uk/norev.txt b/inc/lang/uk/norev.txt
new file mode 100644
index 000000000..3c9295fce
--- /dev/null
+++ b/inc/lang/uk/norev.txt
@@ -0,0 +1,4 @@
+====== Немає такої ревізії ======
+
+Вказана ревізія не існує. Використовуйте кнопку ''Старі ревізії'', щоб отримати перелік ревізій цього документу.
+
diff --git a/inc/lang/uk/password.txt b/inc/lang/uk/password.txt
new file mode 100644
index 000000000..8597d494a
--- /dev/null
+++ b/inc/lang/uk/password.txt
@@ -0,0 +1,10 @@
+Доброго дня, @FULLNAME@!
+
+Ваші дані користувача для @TITLE@ на @DOKUWIKIURL@
+
+Login : @LOGIN@
+Password : @PASSWORD@
+
+--
+Це повідомлення було створене ДокуВікі з
+@DOKUWIKIURL@
diff --git a/inc/lang/uk/preview.txt b/inc/lang/uk/preview.txt
new file mode 100644
index 000000000..b4174c7a4
--- /dev/null
+++ b/inc/lang/uk/preview.txt
@@ -0,0 +1,4 @@
+====== Попередній перегляд ======
+
+Це попередній перегляд того, як буде виглядати ваш текст. Не забувайте, текст ще **не збережено**!
+
diff --git a/inc/lang/uk/pwconfirm.txt b/inc/lang/uk/pwconfirm.txt
new file mode 100644
index 000000000..54d7a200c
--- /dev/null
+++ b/inc/lang/uk/pwconfirm.txt
@@ -0,0 +1,13 @@
+Доброго дня, @FULLNAME@!
+
+Хтось запитав новий пароль для користувача @TITLE@ на @DOKUWIKIURL@
+
+Якщо це були не ви, ігноруйте це повідомлення.
+
+Для підтвердження, що це дійсно ви запитали новий пароль, будь ласка
+перейдіть за наступним посиланням.
+
+@CONFIRM@
+
+--
+Цей лист було надіслано за допомогою служби повідомлень DokuWiki, сайту @DOKUWIKIURL@
diff --git a/inc/lang/uk/read.txt b/inc/lang/uk/read.txt
new file mode 100644
index 000000000..59ea6a1b6
--- /dev/null
+++ b/inc/lang/uk/read.txt
@@ -0,0 +1,2 @@
+Ця сторінка доступна тільки для перегляду. Ви можете продивитися вихідний текст, але не можете змінювати його. Якщо ви вважаєте, що це не вірно, зверніться до адміністратора.
+
diff --git a/inc/lang/uk/recent.txt b/inc/lang/uk/recent.txt
new file mode 100644
index 000000000..645e3d869
--- /dev/null
+++ b/inc/lang/uk/recent.txt
@@ -0,0 +1,4 @@
+====== Останні зміни ======
+
+Вказані нижче сторінки було змінено нещодавно.
+
diff --git a/inc/lang/uk/register.txt b/inc/lang/uk/register.txt
new file mode 100644
index 000000000..8fffc002e
--- /dev/null
+++ b/inc/lang/uk/register.txt
@@ -0,0 +1,4 @@
+====== Реєстрація нового користувача ======
+
+Введіть необхідну інформацію для того, щоб створити нового користувача у цій Вікі. Переконайтеся. що ви ввели **правильну адресу e-mail** - якщо ви не ввели пароль, то новий пароль буде відіслано на цю адресу. Ім'я користувача повинно бути дозволеною [[doku>pagename|назвою сторінки]] вікі.
+
diff --git a/inc/lang/uk/registermail.txt b/inc/lang/uk/registermail.txt
new file mode 100644
index 000000000..28735ed79
--- /dev/null
+++ b/inc/lang/uk/registermail.txt
@@ -0,0 +1,13 @@
+Зареєстровано нового користувача. Перегляньте деталі:
+
+Користувач : @NEWUSER@
+Повне ім'я : @NEWNAME@
+E-Mail : @NEWEMAIL@
+
+Дата : @DATE@
+Браузер : @BROWSER@
+Адреса IP : @IPADDRESS@
+Назва хосту : @HOSTNAME@
+
+--
+Цей лист було надіслано за допомогою служби повідомлень DokuWiki, сайту @DOKUWIKIURL@
diff --git a/inc/lang/uk/resendpwd.txt b/inc/lang/uk/resendpwd.txt
new file mode 100644
index 000000000..208efad55
--- /dev/null
+++ b/inc/lang/uk/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Надіслати новий пароль ======
+
+Заповніть відомості для того, щоб отримати новий пароль у цій Вікі. Новий пароль буде надіслано на e-mail, що вказано у реєстраційних даних. Ім'я користувача повинно бути дозволеним іменем користувача Вікі.
diff --git a/inc/lang/uk/revisions.txt b/inc/lang/uk/revisions.txt
new file mode 100644
index 000000000..646de2a2f
--- /dev/null
+++ b/inc/lang/uk/revisions.txt
@@ -0,0 +1,4 @@
+====== Старі ревізії ======
+
+Це старі версії поточного документа. Для того, щоб повернутися до старої версії, виберіть її, натисніть ''Редагувати'', та збережіть сторінку.
+
diff --git a/inc/lang/uk/searchpage.txt b/inc/lang/uk/searchpage.txt
new file mode 100644
index 000000000..971c24814
--- /dev/null
+++ b/inc/lang/uk/searchpage.txt
@@ -0,0 +1,5 @@
+====== Пошук ======
+
+Дивіться результати пошуку нижче. Якщо ви не знайшли те, що ви шукали, ви можете створити або редагувати сторінку, що має таке ж ім’я, що і пошуковий запит за допомогою відповідної кнопки.
+
+===== Результати =====
diff --git a/inc/lang/uk/showrev.txt b/inc/lang/uk/showrev.txt
new file mode 100644
index 000000000..2706b35d6
--- /dev/null
+++ b/inc/lang/uk/showrev.txt
@@ -0,0 +1,2 @@
+**Це стара версія документу!**
+----
diff --git a/inc/lang/uk/stopwords.txt b/inc/lang/uk/stopwords.txt
new file mode 100644
index 000000000..288ab8e9f
--- /dev/null
+++ b/inc/lang/uk/stopwords.txt
@@ -0,0 +1,3 @@
+# Це список ігнорованих індексатором слів, одне слово в рядку
+# При редагуванні цього файлу переконайтеся, що використовуєте символи переведення рядку, як в UNIX (одиночні)
+# Слова, коротші за 3 символи включати не треба. Вони ігноруються в будь-якому випадку
diff --git a/inc/lang/uk/subscr_digest.txt b/inc/lang/uk/subscr_digest.txt
new file mode 100644
index 000000000..32379182b
--- /dev/null
+++ b/inc/lang/uk/subscr_digest.txt
@@ -0,0 +1,17 @@
+Доброго дня!
+
+Сторінку @PAGE@ у @TITLE@ було змінено.
+Зміни, які відбулися:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Стара версія: @OLDPAGE@
+Нова версія: @NEWPAGE@
+
+Щоб відмовитися від повідомлень про редагування сторінок, зайдіть під своїм ім'ям на сайт @DOKUWIKIURL@, потім відвідайте сторінку @SUBSCRIBE@
+та відпишіться від повідомлень про зміну сторінки та/або простору імен.
+
+--
+Цей лист було надіслано за допомогою служби повідомлень DokuWiki, сайту @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/uk/subscr_form.txt b/inc/lang/uk/subscr_form.txt
new file mode 100644
index 000000000..1c9d6d229
--- /dev/null
+++ b/inc/lang/uk/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Керування підписками ======
+
+Ця сторінка дозволяє Вам керувати Вашими підписками для цієї сторінки та простору імен. \ No newline at end of file
diff --git a/inc/lang/uk/subscr_list.txt b/inc/lang/uk/subscr_list.txt
new file mode 100644
index 000000000..7a538bc1f
--- /dev/null
+++ b/inc/lang/uk/subscr_list.txt
@@ -0,0 +1,14 @@
+Доброго дня!
+
+Було змінено сторінки простору імен @PAGE@ у @TITLE@.
+Зміни, які вібдулися:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Щоб відмовитися від повідомлень про редагування сторінок, зайдіть під своїм ім'ям на сайт @DOKUWIKIURL@, потім відвідайте сторінку @SUBSCRIBE@
+та відпишіться від повідомлень про зміну сторінки та/або простору імен.
+
+--
+Цей лист було надіслано за допомогою служби повідомлень DokuWiki, сайту @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/uk/subscr_single.txt b/inc/lang/uk/subscr_single.txt
new file mode 100644
index 000000000..22a06917e
--- /dev/null
+++ b/inc/lang/uk/subscr_single.txt
@@ -0,0 +1,20 @@
+Доброго часу!
+
+Сторінку @PAGE@ у @TITLE@ було змінено.
+Зміни, що відбулися:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Дата : @DATE@
+Користувач : @USER@
+Підсумок: @SUMMARY@
+Стара версія: @OLDPAGE@
+Нова версія: @NEWPAGE@
+
+Щоб відмовитися від повідомлень про редагування сторінок, зайдіть під своїм ім'ям на сайт @DOKUWIKIURL@, потім відвідайте сторінку @NEWPAGE@
+та відпишіться від повідомлень про зміну сторінки та/або простору імен.
+
+--
+Цей лист було надіслано за допомогою служби повідомлень DokuWiki, сайту @DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/uk/updateprofile.txt b/inc/lang/uk/updateprofile.txt
new file mode 100644
index 000000000..d043f99a7
--- /dev/null
+++ b/inc/lang/uk/updateprofile.txt
@@ -0,0 +1,5 @@
+====== Оновити ваш профіль ======
+
+Необхідно заповнити тільки ті поля, які ви бажаєте змінити. Ви не можете змінити ім’я користувача.
+
+
diff --git a/inc/lang/uk/uploadmail.txt b/inc/lang/uk/uploadmail.txt
new file mode 100644
index 000000000..6eb8c93c9
--- /dev/null
+++ b/inc/lang/uk/uploadmail.txt
@@ -0,0 +1,14 @@
+На вашу ДокуВікі завантажено файл. Деталі:
+
+Файл : @MEDIA@
+Дата : @DATE@
+Браузер : @BROWSER@
+IP-Адреса : @IPADDRESS@
+Назва вузла : @HOSTNAME@
+Розмір : @SIZE@
+Тип MIME : @MIME@
+Користувач : @USER@
+
+--
+Цей лист автоматично створено ДокуВікі на сайті:
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/vi/admin.txt b/inc/lang/vi/admin.txt
new file mode 100644
index 000000000..d8ac73e8c
--- /dev/null
+++ b/inc/lang/vi/admin.txt
@@ -0,0 +1,3 @@
+====== Quản lý ======
+
+Sau đây là các mục quản lý trong DokuWiki.
diff --git a/inc/lang/vi/backlinks.txt b/inc/lang/vi/backlinks.txt
new file mode 100644
index 000000000..231ab5d8c
--- /dev/null
+++ b/inc/lang/vi/backlinks.txt
@@ -0,0 +1,3 @@
+====== Nối về trước ======
+
+Đây là danh sách các trang hình như đã nối vào trang này.
diff --git a/inc/lang/vi/conflict.txt b/inc/lang/vi/conflict.txt
new file mode 100644
index 000000000..0df1ddbe4
--- /dev/null
+++ b/inc/lang/vi/conflict.txt
@@ -0,0 +1,5 @@
+====== Có phiên bản mới hơn ======
+
+Trang bạn đang biên soạn có một phiên bản mới hơn. Việc này xảy ra khi một bạn đổi trang ấy khi bạn đang biên soạn trang này.
+
+Xem kỹ những thay đổi dưới đây, rồi quyết định giữ phiên bản nào. Nếu chọn ''bảo lưu'', phiên bản của bạn được giữ lại. Bấm ''huỷ'' để giữ phiên bản kia.
diff --git a/inc/lang/vi/denied.txt b/inc/lang/vi/denied.txt
new file mode 100644
index 000000000..e70ed5d5f
--- /dev/null
+++ b/inc/lang/vi/denied.txt
@@ -0,0 +1,3 @@
+====== Không được phép vào ======
+
+Rất tiếc là bạn không được phép để tiếp tục. Bạn quen đăng nhập hay sao?
diff --git a/inc/lang/vi/diff.txt b/inc/lang/vi/diff.txt
new file mode 100644
index 000000000..10bfd0f30
--- /dev/null
+++ b/inc/lang/vi/diff.txt
@@ -0,0 +1,4 @@
+====== Khác biệt ======
+
+Đây là những khác biệt giữa phiên bạn được chọn và phiên bản hiện tại của trang này.
+
diff --git a/inc/lang/vi/edit.txt b/inc/lang/vi/edit.txt
new file mode 100644
index 000000000..b00316a7c
--- /dev/null
+++ b/inc/lang/vi/edit.txt
@@ -0,0 +1 @@
+Biên soạn trang này và bấm ''Bảo lưu''. Xem [[wiki:syntax]] về cú pháp của Wiki. Xin bạn biên soạn trang này nếu bạn có thể **cải tiến** nó. Nếu bạn muốn thí nghiệm, bạn có thể tập những bước đầu ở [[playground:playground]].
diff --git a/inc/lang/vi/editrev.txt b/inc/lang/vi/editrev.txt
new file mode 100644
index 000000000..076466c06
--- /dev/null
+++ b/inc/lang/vi/editrev.txt
@@ -0,0 +1,2 @@
+**Bạn đã nạp một phiên bản cũ của văn kiện!** Nếu bảo lưu, bạn sẽ tạo phiên bản với dữ kiện này.
+----
diff --git a/inc/lang/vi/index.txt b/inc/lang/vi/index.txt
new file mode 100644
index 000000000..708d2030d
--- /dev/null
+++ b/inc/lang/vi/index.txt
@@ -0,0 +1,3 @@
+====== Mục lục ======
+
+Đây là mục lục của tất cả các trang, xếp theo thứ tự [[doku>namespaces|namespaces]].
diff --git a/inc/lang/vi/lang.php b/inc/lang/vi/lang.php
new file mode 100644
index 000000000..361e51e84
--- /dev/null
+++ b/inc/lang/vi/lang.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * vietnamese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author James Do <jdo@myrealbox.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+
+$lang['btn_edit'] = 'Biên soạn trang này';
+$lang['btn_source'] = 'Xem mã nguồn';
+$lang['btn_show'] = 'Xem trang';
+$lang['btn_create'] = 'Tạo trang này';
+$lang['btn_search'] = 'Tìm';
+$lang['btn_save'] = 'Lưu';
+$lang['btn_preview']= 'Duyệt trước';
+$lang['btn_top'] = 'Trở lên trên';
+$lang['btn_revs'] = 'Các phiên bản cũ';
+$lang['btn_recent'] = 'Thay đổi gần đây';
+$lang['btn_upload'] = 'Tải lên';
+$lang['btn_cancel'] = 'Huỷ bỏ';
+$lang['btn_index'] = 'Mục lục';
+$lang['btn_secedit']= 'Biên soạn';
+$lang['btn_login'] = 'Đăng nhập';
+$lang['btn_logout'] = 'Thoát';
+$lang['btn_admin'] = 'Quản lý';
+$lang['btn_update'] = 'Cập nhật';
+$lang['btn_delete'] = 'Xoá';
+$lang['btn_register'] = 'Đăng ký';
+
+$lang['loggedinas'] = 'Username đang dùng';
+$lang['user'] = 'Username';
+$lang['pass'] = 'Password';
+$lang['remember'] = 'Lưu username/password lại';
+$lang['fullname'] = 'Họ và tên';
+$lang['email'] = 'E-Mail';
+$lang['badlogin'] = 'Username hoặc password không đúng.';
+
+$lang['regmissing'] = 'Bạn cần điền vào tất cả các trường';
+$lang['reguexists'] = 'Bạn khác đã dùng username này rồi.';
+$lang['regsuccess'] = 'Đã tạo username, và đã gởi password.';
+$lang['regmailfail']= 'Không gởi password được. Xin bạn liên hệ với người quản lý.';
+$lang['regbadmail'] = 'Email hình như không đúng. Xin bạn liên hệ với người quản lý.';
+$lang['regpwmail'] = 'Password DokuWiki của bạn là';
+$lang['reghere'] = 'Xin bạn đăng ký username nếu chưa có.';
+
+$lang['txt_upload'] = 'Chọn tệp để tải lên';
+$lang['txt_filename'] = 'Điền wikiname (tuỳ ý)';
+$lang['lockedby'] = 'Đang khoá bởi';
+$lang['lockexpire'] = 'Khoá sẽ hết hạn vào lúc';
+$lang['js']['willexpire'] = 'Khoá của bạn để biên soạn trang này sẽ hết hạn trong vòng 1 phút.\nĐể tránh xung đột, bạn nên bấm nút xem trước để lập lại thời gian khoá';
+
+$lang['js']['notsavedyet'] = "Hiện có những thay đổi chưa được bảo lưu, và sẽ mất.\nBạn thật sự muốn tiếp tục?";
+$lang['rssfailed'] = 'Rút nguồn này gặp phải lỗi';
+$lang['nothingfound']= 'Không tìm được gì';
+
+$lang['mediaselect'] = 'Chọn tệp media';
+$lang['fileupload'] = 'Tải lên tệp media';
+$lang['uploadsucc'] = 'Tải lên thành công';
+$lang['uploadfail'] = 'Tải lên thất bại. Có thể vì không đủ phép?';
+$lang['uploadwrong'] = 'Tải lên bị từ chối. Cấm tải loại tệp này';
+$lang['namespaces'] = 'Đề tài';
+$lang['mediafiles'] = 'Tệp có sẵn ở';
+
+$lang['hits'] = 'Trùng';
+$lang['quickhits'] = 'Trang trùng hợp';
+$lang['toc'] = 'Nội dung';
+$lang['current'] = 'hiện tại';
+$lang['yours'] = 'Phiên bản hiện tại';
+$lang['diff'] = 'cho xem khác biệt với phiên bản hiện tại';
+$lang['line'] = 'Dòng';
+$lang['breadcrumb'] = 'Trang đã xem';
+$lang['lastmod'] = 'Thời điểm thay đổi';
+$lang['by'] = 'do';
+$lang['deleted'] = 'bị xoá';
+$lang['created'] = 'được tạo ra';
+$lang['restored'] = 'phiên bản cũ đã được khôi phục';
+$lang['summary'] = 'Tóm tắt biên soạn';
+
+$lang['mail_newpage'] = 'Trang được thêm:';
+$lang['mail_changed'] = 'Trang thay đổi:';
+
+$lang['js']['nosmblinks'] = "Nối với các Windows shares chỉ có hiệu lực với Microsoft Internet Explorer.\nBạn vẫn có thể sao và chép các mốc nối.";
+
+$lang['qb_bold'] = 'Chữ đậm';
+$lang['qb_italic'] = 'Chữ nghiêng';
+$lang['qb_underl'] = 'Chữ gạch dưới';
+$lang['qb_code'] = 'Chữ mã nguồn';
+$lang['qb_h1'] = 'Đầu đề cấp 1';
+$lang['qb_h2'] = 'Đầu đề cấp 2';
+$lang['qb_h3'] = 'Đầu đề cấp 3';
+$lang['qb_h4'] = 'Đầu đề cấp 4';
+$lang['qb_h5'] = 'Đầu đề cấp 5';
+$lang['qb_link'] = 'Mốc nối nội tại';
+$lang['qb_extlink'] = 'Mốc nối ra ngoài';
+$lang['qb_hr'] = 'Gạch ngang';
+$lang['qb_ol'] = 'Điểm trong danh sách có thứ tự';
+$lang['qb_ul'] = 'Điểm trong danh sách không đánh số';
+$lang['qb_media'] = 'Thêm ảnh và tệp khác';
+$lang['qb_sig'] = 'Đặt chữ ký';
+
+$lang['js']['del_confirm']= 'Xoá mục này?';
+
+
+//Setup VIM: ex: et ts=2 :
diff --git a/inc/lang/vi/locked.txt b/inc/lang/vi/locked.txt
new file mode 100644
index 000000000..acb0981c5
--- /dev/null
+++ b/inc/lang/vi/locked.txt
@@ -0,0 +1,3 @@
+====== Trang bị khoá ======
+
+Trang này đang bị khoá để một bạn khác biên soạn. Bạn cần đợi cho đến khi nào bạn kia đã biên soạn xong, hoặc khoá hết hạn.
diff --git a/inc/lang/vi/login.txt b/inc/lang/vi/login.txt
new file mode 100644
index 000000000..4265a79df
--- /dev/null
+++ b/inc/lang/vi/login.txt
@@ -0,0 +1,3 @@
+====== Đăng nhập ======
+
+Hiện bạn chưa đăng nhập! Điền vào những chi tiết chứng minh ở phía dưới. Máy của bạn cần đặt chế độ nhận cookies để đăng nhập.
diff --git a/inc/lang/vi/mailtext.txt b/inc/lang/vi/mailtext.txt
new file mode 100644
index 000000000..3fcdf5595
--- /dev/null
+++ b/inc/lang/vi/mailtext.txt
@@ -0,0 +1,16 @@
+Một trang trên DokuWiki của bạn vừa được bổ sung hoặc thay đổi. Sau đây là chi tiết:
+
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+Old Revision: @OLDPAGE@
+New Revision: @NEWPAGE@
+Edit Summary: @SUMMARY@
+User : @USER@
+
+@DIFF@
+
+--
+This mail was generated by DokuWiki at
+@DOKUWIKIURL@
diff --git a/inc/lang/vi/newpage.txt b/inc/lang/vi/newpage.txt
new file mode 100644
index 000000000..b03bb5224
--- /dev/null
+++ b/inc/lang/vi/newpage.txt
@@ -0,0 +1,3 @@
+====== Chưa có đề tài này ======
+
+Bạn vừa nối vào một đề tài chưa có. Bạn có tạo đề tài này bằng cách bấm vào nút ''Tạo trang này''.
diff --git a/inc/lang/vi/norev.txt b/inc/lang/vi/norev.txt
new file mode 100644
index 000000000..0fa27d898
--- /dev/null
+++ b/inc/lang/vi/norev.txt
@@ -0,0 +1,3 @@
+====== Phiên bản chưa có ======
+
+Chưa có phiên bản được chỉ định. Xin bấm nút ''Phiên bản cũ'' để xem danh sách các phiên bản của văn kiện này.
diff --git a/inc/lang/vi/password.txt b/inc/lang/vi/password.txt
new file mode 100644
index 000000000..589bbf067
--- /dev/null
+++ b/inc/lang/vi/password.txt
@@ -0,0 +1,9 @@
+Thân chào bạn @FULLNAME@!
+
+Đây là chi tiết để bạn đăng nhập @TITLE@ tại @DOKUWIKIURL@:
+
+Username: @LOGIN@
+Password: @PASSWORD@
+
+--
+Điện thư này xuất phát từ DokuWiki tại @DOKUWIKIURL@.
diff --git a/inc/lang/vi/preview.txt b/inc/lang/vi/preview.txt
new file mode 100644
index 000000000..81069a2c4
--- /dev/null
+++ b/inc/lang/vi/preview.txt
@@ -0,0 +1,3 @@
+====== Xem trước ======
+
+Văn kiện của bạn sẽ thể hiện như sau. Nên nhớ: Văn kiện này **chưa được bảo lưu**!
diff --git a/inc/lang/vi/read.txt b/inc/lang/vi/read.txt
new file mode 100644
index 000000000..ffeffc7bf
--- /dev/null
+++ b/inc/lang/vi/read.txt
@@ -0,0 +1 @@
+Trang này chỉ được đọc thôi. Bạn có thể xem mã nguồn, nhưng không được thay đổi. Xin bạn hỏi người quản lý nếu không đúng.
diff --git a/inc/lang/vi/recent.txt b/inc/lang/vi/recent.txt
new file mode 100644
index 000000000..fe6628f6e
--- /dev/null
+++ b/inc/lang/vi/recent.txt
@@ -0,0 +1,3 @@
+====== Thay đổi gần đây ======
+
+Những trang sau được thay đổi gần đây.
diff --git a/inc/lang/vi/register.txt b/inc/lang/vi/register.txt
new file mode 100644
index 000000000..f7d35c84b
--- /dev/null
+++ b/inc/lang/vi/register.txt
@@ -0,0 +1,3 @@
+====== Đăng ký mới ======
+
+Xin điền vào mọi thông tin sau đây để tạo một username mới cho wiki này. Bạn cần cung cấp **e-mail chính xác** - để gởi password mới của bạn đến đấy. Username cần là một [[doku>pagename|pagename]] hợp lệ.
diff --git a/inc/lang/vi/revisions.txt b/inc/lang/vi/revisions.txt
new file mode 100644
index 000000000..943e3fff1
--- /dev/null
+++ b/inc/lang/vi/revisions.txt
@@ -0,0 +1,3 @@
+====== Phiên bản cũ ======
+
+Sau đây là các phiên bản cũ của văn kiện này. Để quây về một phiên bản cũ, chọn ở phía dưới, bấm vào ''Biên soạn trang này'' để bảo lưu.
diff --git a/inc/lang/vi/searchpage.txt b/inc/lang/vi/searchpage.txt
new file mode 100644
index 000000000..821ca9f7b
--- /dev/null
+++ b/inc/lang/vi/searchpage.txt
@@ -0,0 +1,5 @@
+====== Tìm ======
+
+Sau đây là kết quả của câu hỏi của bạn. Nếu bạn không thấy được những gì bạn đang tìm, bạn có thể một trang mới, cùng tên câu hỏi của bạn, bằng cách bấm vào nút ''Biên soạn trang này''.
+
+===== Kết quả =====
diff --git a/inc/lang/vi/showrev.txt b/inc/lang/vi/showrev.txt
new file mode 100644
index 000000000..a146f4ef3
--- /dev/null
+++ b/inc/lang/vi/showrev.txt
@@ -0,0 +1,2 @@
+**Đây là một phiên bản cũ cùa văn kiện!**
+----
diff --git a/inc/lang/zh-tw/admin.txt b/inc/lang/zh-tw/admin.txt
new file mode 100644
index 000000000..3cc10335d
--- /dev/null
+++ b/inc/lang/zh-tw/admin.txt
@@ -0,0 +1,4 @@
+====== 管理選單 ======
+
+以下為 DokuWiki 的管理設定
+
diff --git a/inc/lang/zh-tw/adminplugins.txt b/inc/lang/zh-tw/adminplugins.txt
new file mode 100644
index 000000000..fb1999269
--- /dev/null
+++ b/inc/lang/zh-tw/adminplugins.txt
@@ -0,0 +1 @@
+===== 外加插件 ===== \ No newline at end of file
diff --git a/inc/lang/zh-tw/backlinks.txt b/inc/lang/zh-tw/backlinks.txt
new file mode 100644
index 000000000..5b36728e7
--- /dev/null
+++ b/inc/lang/zh-tw/backlinks.txt
@@ -0,0 +1,4 @@
+====== 反向連結 ======
+
+這裡是引用、連結到目前頁面的頁面清單。
+
diff --git a/inc/lang/zh-tw/conflict.txt b/inc/lang/zh-tw/conflict.txt
new file mode 100644
index 000000000..4f31f665f
--- /dev/null
+++ b/inc/lang/zh-tw/conflict.txt
@@ -0,0 +1,5 @@
+====== 已存在更新版本 ======
+
+此檔案已存在更新的版本。這是因為有其他使用者在您編輯時變更了這份文件。
+
+請仔細檢查以下差異,再決定保留哪份。您可選擇「儲存」您的版本或「取消」保留目前版本。 \ No newline at end of file
diff --git a/inc/lang/zh-tw/denied.txt b/inc/lang/zh-tw/denied.txt
new file mode 100644
index 000000000..5a4d483a5
--- /dev/null
+++ b/inc/lang/zh-tw/denied.txt
@@ -0,0 +1,4 @@
+====== 權限拒絕 ======
+
+抱歉,您沒有足夠權限繼續執行。或許您忘了登入?
+
diff --git a/inc/lang/zh-tw/diff.txt b/inc/lang/zh-tw/diff.txt
new file mode 100644
index 000000000..b2b662ec3
--- /dev/null
+++ b/inc/lang/zh-tw/diff.txt
@@ -0,0 +1,4 @@
+====== 差異處 ======
+
+這裡顯示二個版本的差異處。
+
diff --git a/inc/lang/zh-tw/draft.txt b/inc/lang/zh-tw/draft.txt
new file mode 100644
index 000000000..f14702efb
--- /dev/null
+++ b/inc/lang/zh-tw/draft.txt
@@ -0,0 +1,5 @@
+====== 發現草稿檔案 ======
+
+您上次的編輯程序並未正確完成。DokuWiki 已在您編輯時自動儲存了一份草稿使您可以繼續編輯。以下是上次的編輯資料。
+
+請決定要//復原//您遺失的編輯文件,//刪除//這份草稿,或者//取消//編輯程序。
diff --git a/inc/lang/zh-tw/edit.txt b/inc/lang/zh-tw/edit.txt
new file mode 100644
index 000000000..bbe5bb8ed
--- /dev/null
+++ b/inc/lang/zh-tw/edit.txt
@@ -0,0 +1 @@
+編輯本頁並按下''儲存''即可。可在[[wiki:syntax|維基語法]]找到語法說明。請只在能讓本文品質「**更好**」時才編輯。如果只是要測試,請使用 [[playground:playground|遊樂場]]。
diff --git a/inc/lang/zh-tw/editrev.txt b/inc/lang/zh-tw/editrev.txt
new file mode 100644
index 000000000..96f9a7c6a
--- /dev/null
+++ b/inc/lang/zh-tw/editrev.txt
@@ -0,0 +1,2 @@
+**您目前載入的是本份文件的舊版!** 您如果存檔,這些資料就會被存成另一份。
+----
diff --git a/inc/lang/zh-tw/index.txt b/inc/lang/zh-tw/index.txt
new file mode 100644
index 000000000..11ec223d9
--- /dev/null
+++ b/inc/lang/zh-tw/index.txt
@@ -0,0 +1,3 @@
+====== 站台地圖 ======
+
+這個站台地圖列出了所有允許的頁面,依 [[doku>namespaces|命名空間]] 排序。
diff --git a/inc/lang/zh-tw/install.html b/inc/lang/zh-tw/install.html
new file mode 100644
index 000000000..88af0b394
--- /dev/null
+++ b/inc/lang/zh-tw/install.html
@@ -0,0 +1,8 @@
+<p>本頁面旨在幫助您完成第一次安装和配置 <a href="http://dokuwiki.org">Dokuwiki</a>。關於安裝工具的更多訊息請參閱 <a href="http://dokuwiki.org/installer">官方文檔頁面</a>。</p>
+
+<p>DokuWiki 使用普通檔案儲存維基頁面以及與頁面相關的訊息(例如:圖像,搜尋索引,修訂記錄等)。為了正常運作,DokuWiki <strong>必須</strong> 擁有針對那些路徑和檔案的寫入權限。本安裝工具無法設定目錄權限,這通常要透過命令行、FTP 或您主機上的控制台(如cPanel)進行。</p>
+
+<p>本安裝工具將設定您的 DokuWiki 用於 <acronym title="訪問控制列表">ACL</acronym> 的配置檔,它能讓管理員登入並使用「管理」功能來安裝插件、管理用户、管理訪問權限和其他配置設定。它並不是 DokuWiki 正常運作所必須,但安裝之後將更方便管理。</p>
+
+<p>有經驗的用戶或有特殊需求的用戶請參閱更詳細的 <a href="http://dokuwiki.org/install">安裝指南</a>
+和 <a href="http://dokuwiki.org/config">配置設定</a>。</p> \ No newline at end of file
diff --git a/inc/lang/zh-tw/lang.php b/inc/lang/zh-tw/lang.php
new file mode 100644
index 000000000..3a126105b
--- /dev/null
+++ b/inc/lang/zh-tw/lang.php
@@ -0,0 +1,317 @@
+<?php
+/**
+ * Chinese(Traditional) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author chinsan <chinsan@mail2000.com.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = '編修本頁';
+$lang['btn_source'] = '顯示原始碼';
+$lang['btn_show'] = '顯示頁面';
+$lang['btn_create'] = '建立此頁';
+$lang['btn_search'] = '搜尋';
+$lang['btn_save'] = '儲存';
+$lang['btn_preview'] = '預覽';
+$lang['btn_top'] = '回到頁頂';
+$lang['btn_newer'] = '<< 較新';
+$lang['btn_older'] = '較舊 >>';
+$lang['btn_revs'] = '舊版';
+$lang['btn_recent'] = '最近更新';
+$lang['btn_upload'] = '上傳';
+$lang['btn_cancel'] = '取消';
+$lang['btn_index'] = '站台地圖';
+$lang['btn_secedit'] = '改這段';
+$lang['btn_login'] = '登入';
+$lang['btn_logout'] = '登出';
+$lang['btn_admin'] = '管理選單';
+$lang['btn_update'] = '更新設定';
+$lang['btn_delete'] = '刪除';
+$lang['btn_back'] = '回上一步';
+$lang['btn_backlink'] = '反向連結';
+$lang['btn_backtomedia'] = '重新選擇圖檔';
+$lang['btn_subscribe'] = '訂閱更動通知';
+$lang['btn_profile'] = '更新個人資料';
+$lang['btn_reset'] = '資料重設';
+$lang['btn_resendpwd'] = '寄新密碼';
+$lang['btn_draft'] = '編輯草稿';
+$lang['btn_recover'] = '復原草稿';
+$lang['btn_draftdel'] = '捨棄草稿';
+$lang['btn_revert'] = '復原';
+$lang['btn_register'] = '註冊';
+$lang['btn_apply'] = '套用';
+$lang['btn_media'] = '多媒體管理器';
+$lang['loggedinas'] = '登入為';
+$lang['user'] = '帳號';
+$lang['pass'] = '密碼';
+$lang['newpass'] = '新密碼';
+$lang['oldpass'] = '目前密碼';
+$lang['passchk'] = '確認密碼';
+$lang['remember'] = '記住帳號密碼';
+$lang['fullname'] = '真實姓名';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = '使用者個人資料';
+$lang['badlogin'] = '很抱歉,您的使用者名稱或密碼可能有錯誤';
+$lang['minoredit'] = '小修改';
+$lang['draftdate'] = '草稿已自動存檔於';
+$lang['nosecedit'] = '頁面在這之間已被修改,過時的區段資料已載入全頁取代。';
+$lang['regmissing'] = '很抱歉,所有欄位都要填寫';
+$lang['reguexists'] = '很抱歉,本帳號已被註冊';
+$lang['regsuccess'] = '使用者已建立,密碼已寄發至該 email。';
+$lang['regsuccess2'] = '使用者已建立';
+$lang['regmailfail'] = '寄出密碼信似乎發生錯誤,請跟管理員聯絡!';
+$lang['regbadmail'] = '您輸入的 email 似乎不對,如果您認為是正確的,請與管理員聯絡。';
+$lang['regbadpass'] = '兩次輸入的密碼不一致,請再試一次。';
+$lang['regpwmail'] = '您的 DokuWiki 帳號密碼';
+$lang['reghere'] = '您還沒有帳號嗎?註冊一個吧。';
+$lang['profna'] = '本維基不開放修改個人資料';
+$lang['profnochange'] = '未做任何變更';
+$lang['profnoempty'] = '帳號或 email 地址不可空白!';
+$lang['profchanged'] = '個人資料已成功更新囉。';
+$lang['pwdforget'] = '忘記密碼了?索取新密碼!';
+$lang['resendna'] = '本維基不開放重寄密碼';
+$lang['resendpwd'] = '寄新密碼給';
+$lang['resendpwdmissing'] = '抱歉,您必須填寫所有欄位。';
+$lang['resendpwdnouser'] = '抱歉,資料庫內找不到這個使用者';
+$lang['resendpwdbadauth'] = '抱歉,認證碼無效。請確認您使用了完整的確認連結。';
+$lang['resendpwdconfirm'] = '確認連結已通過郵件發送給您了。';
+$lang['resendpwdsuccess'] = '您的新密碼已寄出。';
+$lang['license'] = '若未特別註明,此維基上的內容都是採用以下授權方式:';
+$lang['licenseok'] = '注意:編輯此頁面表示您已同意以下的授權方式:';
+$lang['searchmedia'] = '搜尋檔名:';
+$lang['searchmedia_in'] = '在 %s 裡搜尋';
+$lang['txt_upload'] = '請選擇要上傳的檔案';
+$lang['txt_filename'] = '請輸入要存在維基內的檔案名稱 (非必要)';
+$lang['txt_overwrt'] = '是否要覆蓋原有檔案';
+$lang['lockedby'] = '目前已被下列人員鎖定';
+$lang['lockexpire'] = '預計解除鎖定於';
+$lang['js']['willexpire'] = '本頁的編輯鎖定將在一分鐘內到期。要避免發生衝突,請按「預覽」鍵重設鎖定計時。';
+$lang['js']['notsavedyet'] = '未儲存的變更將會遺失,繼續嗎?';
+$lang['js']['searchmedia'] = '搜尋檔案';
+$lang['js']['keepopen'] = '選擇時保持視窗開啟';
+$lang['js']['hidedetails'] = '隱藏詳細內容';
+$lang['js']['mediatitle'] = '連結設定';
+$lang['js']['mediadisplay'] = '連結類型';
+$lang['js']['mediaalign'] = '校正';
+$lang['js']['mediasize'] = '圖像大小';
+$lang['js']['mediatarget'] = '連結目標';
+$lang['js']['mediaclose'] = '關閉';
+$lang['js']['mediainsert'] = '插入';
+$lang['js']['mediadisplayimg'] = '顯示此圖像';
+$lang['js']['mediadisplaylnk'] = '只顯示連結';
+$lang['js']['mediasmall'] = '小型版本';
+$lang['js']['mediamedium'] = '中型版本';
+$lang['js']['medialarge'] = '大型版本';
+$lang['js']['mediaoriginal'] = '原始版本';
+$lang['js']['medialnk'] = '連向內容頁面';
+$lang['js']['mediadirect'] = '連向原始圖片';
+$lang['js']['medianolnk'] = '不連結';
+$lang['js']['medianolink'] = '不連結圖像';
+$lang['js']['medialeft'] = '圖像靠左對齊';
+$lang['js']['mediaright'] = '圖像靠右對齊';
+$lang['js']['mediacenter'] = '圖像置中對齊';
+$lang['js']['medianoalign'] = '不對齊';
+$lang['js']['nosmblinks'] = '只有在 Microsoft IE 下才能執行「連結到 Windows shares」。
+不過您仍可複製及貼上這個連結';
+$lang['js']['linkwiz'] = '建立連結精靈';
+$lang['js']['linkto'] = '連結至:';
+$lang['js']['del_confirm'] = '確定刪除選取的項目?';
+$lang['js']['restore_confirm'] = '確定還原到這個版本?';
+$lang['js']['media_diff'] = '檢視差異:';
+$lang['js']['media_diff_both'] = '並排';
+$lang['js']['media_diff_opacity'] = '重疊';
+$lang['js']['media_diff_portions'] = '滑動';
+$lang['js']['media_select'] = '選擇檔案…';
+$lang['js']['media_upload_btn'] = '上傳';
+$lang['js']['media_done_btn'] = '完成';
+$lang['js']['media_drop'] = '拖拉檔案到此上傳';
+$lang['js']['media_cancel'] = '刪除';
+$lang['js']['media_overwrt'] = '覆蓋已存在的檔案';
+$lang['rssfailed'] = '擷取 RSS 饋送檔時發生錯誤:';
+$lang['nothingfound'] = '沒找到任何結果。';
+$lang['mediaselect'] = '媒體檔案';
+$lang['fileupload'] = '上傳媒體檔案';
+$lang['uploadsucc'] = '上傳成功';
+$lang['uploadfail'] = '上傳失敗。似乎是權限錯誤?';
+$lang['uploadwrong'] = '拒絕上傳。這個副檔名被禁止了!';
+$lang['uploadexist'] = '檔案已存在,未處理。';
+$lang['uploadbadcontent'] = '上傳檔案的內容不符合 %s 檔的副檔名';
+$lang['uploadspam'] = '這次的上傳被垃圾訊息黑名單阻檔了。';
+$lang['uploadxss'] = '這次的上傳因可能的惡意的內容而被阻檔。';
+$lang['uploadsize'] = '上傳的檔案太大了 (最大:%s)';
+$lang['deletesucc'] = '檔案 "%s" 已刪除。';
+$lang['deletefail'] = '檔案 "%s" 無法刪除,請檢查權限定。';
+$lang['mediainuse'] = '檔案 "%s" 未刪除,因為它正被使用。';
+$lang['namespaces'] = '命名空間';
+$lang['mediafiles'] = '可用的檔案有';
+$lang['accessdenied'] = '您不被允許檢視此頁面';
+$lang['mediausage'] = '使用以下的語法來連結此檔案:';
+$lang['mediaview'] = '檢視原始檔案';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = '上傳檔案至目前的命名空間。要建立次級命名空間,將其名稱加在「上傳並重命名為」檔案名的前面,並用英文冒號隔開';
+$lang['mediaextchange'] = '檔案類型已由 .%s 變更為 .%s !';
+$lang['reference'] = '引用到本頁的,合計有';
+$lang['ref_inuse'] = '此檔案無法刪除,因為它正被以下頁面使用:';
+$lang['ref_hidden'] = '一些參考內容位於您沒有讀取權限的頁面中';
+$lang['hits'] = '個符合';
+$lang['quickhits'] = '符合的頁面名稱';
+$lang['toc'] = '目錄表';
+$lang['current'] = '目前版本';
+$lang['yours'] = '您的版本';
+$lang['diff'] = '顯示與目前版本的差異';
+$lang['diff2'] = '顯示選擇版本間的差異';
+$lang['difflink'] = '連向這個比對檢視';
+$lang['diff_type'] = '檢視差異:';
+$lang['diff_inline'] = '行內';
+$lang['diff_side'] = '並排';
+$lang['line'] = '行';
+$lang['breadcrumb'] = '足跡';
+$lang['youarehere'] = '您在這裡';
+$lang['lastmod'] = '上一次變更';
+$lang['by'] = '由';
+$lang['deleted'] = '移除';
+$lang['created'] = '建立';
+$lang['restored'] = '恢復為舊版';
+$lang['external_edit'] = '外部編輯';
+$lang['summary'] = '編輯摘要';
+$lang['noflash'] = '顯示此內容需要 <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash Plugin</a>';
+$lang['download'] = '下載程式碼片段';
+$lang['mail_newpage'] = '增加的頁面:';
+$lang['mail_changed'] = '變更的頁面:';
+$lang['mail_subscribe_list'] = '命名空間中更動的頁面:';
+$lang['mail_new_user'] = '新使用者:';
+$lang['mail_upload'] = '已上傳檔案:';
+$lang['changes_type'] = '檢視最近更新類型';
+$lang['pages_changes'] = '頁面';
+$lang['media_changes'] = '多媒體檔案';
+$lang['both_changes'] = '頁面和多媒體檔案';
+$lang['qb_bold'] = '粗體';
+$lang['qb_italic'] = '斜體';
+$lang['qb_underl'] = '底線';
+$lang['qb_code'] = '程式碼';
+$lang['qb_strike'] = '刪除線';
+$lang['qb_h1'] = 'H1 標題';
+$lang['qb_h2'] = 'H2 標題';
+$lang['qb_h3'] = 'H3 標題';
+$lang['qb_h4'] = 'H4 標題';
+$lang['qb_h5'] = 'H5 標題';
+$lang['qb_h'] = '標題';
+$lang['qb_hs'] = '選擇標題';
+$lang['qb_hplus'] = '較大標題';
+$lang['qb_hminus'] = '較小標題';
+$lang['qb_hequal'] = '同等標題';
+$lang['qb_link'] = '內部連結';
+$lang['qb_extlink'] = '外部連結';
+$lang['qb_hr'] = '水平線';
+$lang['qb_ol'] = '有序列表項目';
+$lang['qb_ul'] = '無序列表項目';
+$lang['qb_media'] = '加入圖片或檔案';
+$lang['qb_sig'] = '插入簽名';
+$lang['qb_smileys'] = '表情符號';
+$lang['qb_chars'] = '特殊字元';
+$lang['upperns'] = '前往父層命名空間';
+$lang['admin_register'] = '新增使用者';
+$lang['metaedit'] = '編輯後設資料';
+$lang['metasaveerr'] = '後設資料寫入失敗';
+$lang['metasaveok'] = '後設資料已儲存';
+$lang['img_backto'] = '回上一頁';
+$lang['img_title'] = '標題';
+$lang['img_caption'] = '照片說明';
+$lang['img_date'] = '日期';
+$lang['img_fname'] = '檔名';
+$lang['img_fsize'] = '大小';
+$lang['img_artist'] = '攝影者';
+$lang['img_copyr'] = '版權';
+$lang['img_format'] = '格式';
+$lang['img_camera'] = '相機';
+$lang['img_keywords'] = '關鍵字';
+$lang['img_width'] = '寬度';
+$lang['img_height'] = '高度';
+$lang['img_manager'] = '在多媒體管理器中檢視';
+$lang['subscr_subscribe_success'] = '已將 %s 加入至 %s 的訂閱列表';
+$lang['subscr_subscribe_error'] = '將 %s 加入至 %s 的訂閱列表時發生錯誤';
+$lang['subscr_subscribe_noaddress'] = '沒有與您登入相關的地址,無法將您加入訂閱列表';
+$lang['subscr_unsubscribe_success'] = '已將 %s 移除自 %s 的訂閱列表';
+$lang['subscr_unsubscribe_error'] = '將 %s 移除自 %s 的訂閱列表時發生錯誤';
+$lang['subscr_already_subscribed'] = '%s 已經被 %s 訂閱了';
+$lang['subscr_not_subscribed'] = '%s 尚未被 %s 訂閱';
+$lang['subscr_m_not_subscribed'] = '您尚未訂閱目前的頁面或命名空間。';
+$lang['subscr_m_new_header'] = '加入訂閱';
+$lang['subscr_m_current_header'] = '目前訂閱';
+$lang['subscr_m_unsubscribe'] = '取消訂閱';
+$lang['subscr_m_subscribe'] = '訂閱';
+$lang['subscr_m_receive'] = '接收';
+$lang['subscr_style_every'] = '每次更改都發送信件';
+$lang['subscr_style_digest'] = '對每個頁面發送更改的摘要信件 (每 %.2f 天)';
+$lang['subscr_style_list'] = '自上次發信以來更改的頁面的列表 (每 %.2f 天)';
+$lang['authmodfailed'] = '帳號認證的設定不正確,請通知該維基管理員。';
+$lang['authtempfail'] = '帳號認證目前暫不提供,若本狀況持續發生的話,請通知該維基管理員。';
+$lang['i_chooselang'] = '選擇您的語系';
+$lang['i_installer'] = 'DokuWiki 安裝工具';
+$lang['i_wikiname'] = '維基名稱';
+$lang['i_enableacl'] = '啟用 ACL (建議)';
+$lang['i_superuser'] = '超級用戶';
+$lang['i_problems'] = '安裝程式發現如下的問題。您必須修正它們才能繼續。';
+$lang['i_modified'] = '出於安全考量,本腳本只能用於安裝全新且未修改的 Dokuwiki。
+您可以重新解壓下載的封包或查閱完整的<a href=\"http://dokuwiki.org/install\">Dokuwiki 安裝指南</a>';
+$lang['i_funcna'] = 'PHP 函數 <code>%s</code> 無法使用。也許您的主機供應者基於某些理由停用了它?';
+$lang['i_phpver'] = '您的 PHP 版本 <code>%s</code> 比需要的版本 <code>%s</code> 還低。您必須更新您的PHP。';
+$lang['i_permfail'] = '<code>%s</code> 無法被 DokuWiki 寫入。您必須修正該目錄的權限!';
+$lang['i_confexists'] = '<code>%s</code> 已經存在';
+$lang['i_writeerr'] = '無法建立 <code>%s</code>。您必須檢查目錄/檔案的權限並手動建立該檔案。';
+$lang['i_badhash'] = '無法辨識或被變更的 dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - 非法或空白的值';
+$lang['i_success'] = '設定已成功完成。您現在可以刪除 install.php 檔案。繼續到
+<a href="doku.php">您的新 DokuWiki</a>.';
+$lang['i_failure'] = '寫入設定檔時發生了一些錯誤。您必須在使用<a href="doku.php">您的新 Dokuwiki</a> 之前手動修正它們。';
+$lang['i_policy'] = '初步的 ACL 政策';
+$lang['i_pol0'] = '開放的維基 (任何人可讀取、寫入、上傳)';
+$lang['i_pol1'] = '公開的維基 (任何人可讀取,註冊使用者可寫入與上傳)';
+$lang['i_pol2'] = '封閉的維基 (只有註冊使用者可讀取、寫入、上傳)';
+$lang['i_retry'] = '重試';
+$lang['i_license'] = '請選擇您想要的內容發布許可協議:';
+$lang['recent_global'] = '您正在閱讀命名空間: <b>%s</b> 中的變更。您亦可觀看整個維基的<a href="%s">最近更新</a>。';
+$lang['years'] = '%d 年前';
+$lang['months'] = '%d 個月前';
+$lang['weeks'] = '%d 週前';
+$lang['days'] = '%d 天前';
+$lang['hours'] = '%d 個小時前';
+$lang['minutes'] = '%d 分鐘前';
+$lang['seconds'] = '%s 秒鐘前';
+$lang['wordblock'] = '您的更改沒有被儲存,因为它包含被阻擋的文字 (垃圾訊息)。';
+$lang['media_uploadtab'] = '上傳';
+$lang['media_searchtab'] = '搜尋';
+$lang['media_file'] = '檔案';
+$lang['media_viewtab'] = '檢視';
+$lang['media_edittab'] = '編輯';
+$lang['media_historytab'] = '歷史紀錄';
+$lang['media_list_thumbs'] = '縮圖';
+$lang['media_list_rows'] = '列表';
+$lang['media_sort_name'] = '名稱';
+$lang['media_sort_date'] = '日期';
+$lang['media_namespaces'] = '選擇命名空間';
+$lang['media_files'] = '在 %s 中的檔案';
+$lang['media_upload'] = '上傳至 %s';
+$lang['media_search'] = '在 %s 中搜尋';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s 在 %s';
+$lang['media_edit'] = '編輯 %s';
+$lang['media_history'] = '%s 的歷史紀錄';
+$lang['media_meta_edited'] = '元資料已編輯';
+$lang['media_perm_read'] = '抱歉,您沒有足夠權限讀取檔案';
+$lang['media_perm_upload'] = '抱歉,您沒有足夠權限上傳檔案。';
+$lang['media_update'] = '上傳新的版本';
+$lang['media_restore'] = '還原這個版本';
+$lang['plugin_install_err'] = '插件安裝錯誤。將插件目錄 "%s" 重新命名為 "%s"';
diff --git a/inc/lang/zh-tw/locked.txt b/inc/lang/zh-tw/locked.txt
new file mode 100644
index 000000000..e13fdc890
--- /dev/null
+++ b/inc/lang/zh-tw/locked.txt
@@ -0,0 +1,3 @@
+====== 頁面鎖定 ======
+
+本頁目前正由其他使用者編修中,您必須等他完成編輯或等鎖定時間過去。
diff --git a/inc/lang/zh-tw/login.txt b/inc/lang/zh-tw/login.txt
new file mode 100644
index 000000000..058cc5712
--- /dev/null
+++ b/inc/lang/zh-tw/login.txt
@@ -0,0 +1,5 @@
+====== 登入 ======
+
+您尚未登入,請輸入您的使用者名稱和密碼。 另外,瀏覽器需要打開 cookies 設定以進行登入。
+
+
diff --git a/inc/lang/zh-tw/mailtext.txt b/inc/lang/zh-tw/mailtext.txt
new file mode 100644
index 000000000..3b6ece377
--- /dev/null
+++ b/inc/lang/zh-tw/mailtext.txt
@@ -0,0 +1,17 @@
+您的 DokuWiki 有個新增或變動的頁面。詳細資料如下:
+
+日期 : @DATE@
+瀏覽器 : @BROWSER@
+IP位址 : @IPADDRESS@
+主機名稱 : @HOSTNAME@
+舊版本 : @OLDPAGE@
+新版本 : @NEWPAGE@
+編輯摘要 : @SUMMARY@
+使用者 : @USER@
+
+@DIFF@
+
+
+--
+本信件由以下 DokuWiki 站台產生:
+@DOKUWIKIURL@
diff --git a/inc/lang/zh-tw/newpage.txt b/inc/lang/zh-tw/newpage.txt
new file mode 100644
index 000000000..06ccd3d75
--- /dev/null
+++ b/inc/lang/zh-tw/newpage.txt
@@ -0,0 +1,3 @@
+====== 此主題不存在 ======
+
+您來到了一個未建立頁面的主題。如果權限允許,您可以用 「建立此頁」按鈕建立頁面。 \ No newline at end of file
diff --git a/inc/lang/zh-tw/norev.txt b/inc/lang/zh-tw/norev.txt
new file mode 100644
index 000000000..bd1c7a623
--- /dev/null
+++ b/inc/lang/zh-tw/norev.txt
@@ -0,0 +1,3 @@
+====== 無此版本 ======
+
+該版本的文件不存在。請用 「舊版」按鈕檢視該文件所有舊版本清單。 \ No newline at end of file
diff --git a/inc/lang/zh-tw/password.txt b/inc/lang/zh-tw/password.txt
new file mode 100644
index 000000000..5d383b528
--- /dev/null
+++ b/inc/lang/zh-tw/password.txt
@@ -0,0 +1,10 @@
+@FULLNAME@ 您好!
+
+這是您在位於 @DOKUWIKIURL@ 之 @TITLE@ 的使用者資料
+
+帳號 : @LOGIN@
+密碼 : @PASSWORD@
+
+--
+本信件由以下 DokuWiki 站台產生:
+@DOKUWIKIURL@
diff --git a/inc/lang/zh-tw/preview.txt b/inc/lang/zh-tw/preview.txt
new file mode 100644
index 000000000..c68f94819
--- /dev/null
+++ b/inc/lang/zh-tw/preview.txt
@@ -0,0 +1,4 @@
+====== 預覽 ======
+
+以下是預覽該文件的狀態。請記住:**它還沒被儲存喔**!
+
diff --git a/inc/lang/zh-tw/pwconfirm.txt b/inc/lang/zh-tw/pwconfirm.txt
new file mode 100644
index 000000000..994367980
--- /dev/null
+++ b/inc/lang/zh-tw/pwconfirm.txt
@@ -0,0 +1,13 @@
+@FULLNAME@ 您好!
+
+有人為您在 @DOKUWIKIURL@ 註冊的使用者 @TITLE@ 請求新密碼
+
+如果您沒有請求新密碼,請忽略這封郵件。
+
+要確認使用新密碼,請拜訪以下的連結。
+
+@CONFIRM@
+
+--
+本信件由以下 DokuWiki 站台產生:
+@DOKUWIKIURL@
diff --git a/inc/lang/zh-tw/read.txt b/inc/lang/zh-tw/read.txt
new file mode 100644
index 000000000..a8305611f
--- /dev/null
+++ b/inc/lang/zh-tw/read.txt
@@ -0,0 +1 @@
+本頁是唯讀的,您可以看到原始碼,但不能更動它。您如果覺得這是誤判,請詢問管理員。 \ No newline at end of file
diff --git a/inc/lang/zh-tw/recent.txt b/inc/lang/zh-tw/recent.txt
new file mode 100644
index 000000000..28314294b
--- /dev/null
+++ b/inc/lang/zh-tw/recent.txt
@@ -0,0 +1,5 @@
+====== 最近更新 ======
+
+以下的頁面是最近才更新的:
+
+
diff --git a/inc/lang/zh-tw/register.txt b/inc/lang/zh-tw/register.txt
new file mode 100644
index 000000000..0da401ccd
--- /dev/null
+++ b/inc/lang/zh-tw/register.txt
@@ -0,0 +1,4 @@
+====== 註冊新使用者 ======
+
+填寫以下資料以註冊維基帳號,請確定您提供的是**合法的 email 地址**-如果這裡沒要求您填寫密碼,您的新密碼會自動產生並寄送到該地址。登錄名稱必須是合法的[[doku>pagename|頁面名稱]]。
+
diff --git a/inc/lang/zh-tw/registermail.txt b/inc/lang/zh-tw/registermail.txt
new file mode 100644
index 000000000..489e3f9d3
--- /dev/null
+++ b/inc/lang/zh-tw/registermail.txt
@@ -0,0 +1,14 @@
+有新的使用者註冊。詳細資料如下:
+
+帳號 : @NEWUSER@
+姓名 : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+日期 : @DATE@
+瀏覽器 : @BROWSER@
+IP位址 : @IPADDRESS@
+主機名稱 : @HOSTNAME@
+
+--
+本信件由以下 DokuWiki 站台產生:
+@DOKUWIKIURL@
diff --git a/inc/lang/zh-tw/resendpwd.txt b/inc/lang/zh-tw/resendpwd.txt
new file mode 100644
index 000000000..3dbfad750
--- /dev/null
+++ b/inc/lang/zh-tw/resendpwd.txt
@@ -0,0 +1,3 @@
+====== 寄送新密碼 ======
+
+請在以下欄位輸入您的帳號,新密碼將會寄送到您註冊時填寫的 email 地址。
diff --git a/inc/lang/zh-tw/revisions.txt b/inc/lang/zh-tw/revisions.txt
new file mode 100644
index 000000000..479705b95
--- /dev/null
+++ b/inc/lang/zh-tw/revisions.txt
@@ -0,0 +1,3 @@
+====== 舊版 ======
+
+以下是該文件的舊版本。如要恢復成某個舊版次,就點下它,然後按「編修本頁」,並存檔起來就可以了。
diff --git a/inc/lang/zh-tw/searchpage.txt b/inc/lang/zh-tw/searchpage.txt
new file mode 100644
index 000000000..e0f04c433
--- /dev/null
+++ b/inc/lang/zh-tw/searchpage.txt
@@ -0,0 +1,5 @@
+====== 搜尋精靈 ======
+
+提示:您可以在下面找到您的搜尋結果。若沒找到您想要的,可按下按鈕建立或編輯和查詢關鍵字同名的頁面。
+
+===== 搜尋結果 =====
diff --git a/inc/lang/zh-tw/showrev.txt b/inc/lang/zh-tw/showrev.txt
new file mode 100644
index 000000000..306aa6ea7
--- /dev/null
+++ b/inc/lang/zh-tw/showrev.txt
@@ -0,0 +1,2 @@
+**這是本文件的舊版!**
+----
diff --git a/inc/lang/zh-tw/stopwords.txt b/inc/lang/zh-tw/stopwords.txt
new file mode 100644
index 000000000..55b67ed16
--- /dev/null
+++ b/inc/lang/zh-tw/stopwords.txt
@@ -0,0 +1,31 @@
+# 這檔是製作索引檔(index)時不要列入的關鍵字,格式為每字(詞)就使用一行。
+# 在修改時,請注意要用 UNIX 格式的換行符號(newline)處理,而非 DOS 的 CR-LR 喔
+# (如果在 MS Windows 環境使用的話,可使用 vim win32版 或 UltraEdit或其他類似編輯器修改)
+#
+# 還有,不必把小於 3 個字元(英數字元)都包括進來。
+# 目前本清單的內容是以 http://www.ranks.nl/stopwords/ 為基礎而發展的。
+about
+are
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/zh-tw/subscr_digest.txt b/inc/lang/zh-tw/subscr_digest.txt
new file mode 100644
index 000000000..a26e73050
--- /dev/null
+++ b/inc/lang/zh-tw/subscr_digest.txt
@@ -0,0 +1,19 @@
+您好!
+
+維基 @TITLE@ 的頁面 @PAGE@ 已更改。
+更改內容如下:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+舊版本:@OLDPAGE@
+新版本:@NEWPAGE@
+
+要取消頁面提醒,請登入維基 @DOKUWIKIURL@
+然後拜訪 @SUBSCRIBE@
+並取消訂閱頁面或命名空間的更改。
+
+--
+本信件由以下 DokuWiki 站台產生:
+@DOKUWIKIURL@
diff --git a/inc/lang/zh-tw/subscr_form.txt b/inc/lang/zh-tw/subscr_form.txt
new file mode 100644
index 000000000..0ad675cc8
--- /dev/null
+++ b/inc/lang/zh-tw/subscr_form.txt
@@ -0,0 +1,3 @@
+====== 訂閱管理 ======
+
+這個頁面允許您管理在目前頁面和命名空間的訂閱。 \ No newline at end of file
diff --git a/inc/lang/zh-tw/subscr_list.txt b/inc/lang/zh-tw/subscr_list.txt
new file mode 100644
index 000000000..2a1b26c6e
--- /dev/null
+++ b/inc/lang/zh-tw/subscr_list.txt
@@ -0,0 +1,16 @@
+您好!
+
+維基 @TITLE@ 的 @PAGE@ 命名空間的頁面已更改。
+更改內容如下:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+要取消頁面提醒,請登入維基 @DOKUWIKIURL@
+然後拜訪 @SUBSCRIBE@
+並取消訂閱頁面或命名空間的更改。
+
+--
+本信件由以下 DokuWiki 站台產生:
+@DOKUWIKIURL@
diff --git a/inc/lang/zh-tw/subscr_single.txt b/inc/lang/zh-tw/subscr_single.txt
new file mode 100644
index 000000000..f3c623c5c
--- /dev/null
+++ b/inc/lang/zh-tw/subscr_single.txt
@@ -0,0 +1,22 @@
+您好!
+
+維基 @TITLE@ 的頁面 @PAGE@ 已更改。
+更改內容如下:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+時間 : @DATE@
+使用者 : @USER@
+編輯摘要 : @SUMMARY@
+舊版本 : @OLDPAGE@
+新版本 : @NEWPAGE@
+
+要取消頁面提醒,請登入維基 @DOKUWIKIURL@
+然後拜訪 @NEWPAGE@
+並取消訂閱頁面或命名空間的更改。
+
+--
+本信件由以下 DokuWiki 站台產生:
+@DOKUWIKIURL@
diff --git a/inc/lang/zh-tw/updateprofile.txt b/inc/lang/zh-tw/updateprofile.txt
new file mode 100644
index 000000000..47f2ae1c4
--- /dev/null
+++ b/inc/lang/zh-tw/updateprofile.txt
@@ -0,0 +1,3 @@
+====== 更新個人資料 ======
+
+您只需變更想更新的欄位就好,帳號名稱不能變更。 \ No newline at end of file
diff --git a/inc/lang/zh-tw/uploadmail.txt b/inc/lang/zh-tw/uploadmail.txt
new file mode 100644
index 000000000..b4c1311ba
--- /dev/null
+++ b/inc/lang/zh-tw/uploadmail.txt
@@ -0,0 +1,14 @@
+有人把檔案上傳到您的 DokuWiki。詳細資料如下:
+
+檔名 : @MEDIA@
+日期 : @DATE@
+瀏覽器 : @BROWSER@
+IP位址 : @IPADDRESS@
+主機名稱 : @HOSTNAME@
+大小 : @SIZE@
+MIME類型 : @MIME@
+使用者 : @USER@
+
+--
+本信件由以下 DokuWiki 站台產生:
+@DOKUWIKIURL@
diff --git a/inc/lang/zh/admin.txt b/inc/lang/zh/admin.txt
new file mode 100644
index 000000000..bf6476e9c
--- /dev/null
+++ b/inc/lang/zh/admin.txt
@@ -0,0 +1,3 @@
+====== 管理 ======
+
+在下面您能找到 DokuWiki 中可用管理任务的列表。 \ No newline at end of file
diff --git a/inc/lang/zh/adminplugins.txt b/inc/lang/zh/adminplugins.txt
new file mode 100644
index 000000000..66cee4509
--- /dev/null
+++ b/inc/lang/zh/adminplugins.txt
@@ -0,0 +1 @@
+===== 附加插件 ===== \ No newline at end of file
diff --git a/inc/lang/zh/backlinks.txt b/inc/lang/zh/backlinks.txt
new file mode 100644
index 000000000..19e3feea6
--- /dev/null
+++ b/inc/lang/zh/backlinks.txt
@@ -0,0 +1,3 @@
+====== 反向链接 ======
+
+这里是能够反向链接到当前页面的其他页面列表。 \ No newline at end of file
diff --git a/inc/lang/zh/conflict.txt b/inc/lang/zh/conflict.txt
new file mode 100644
index 000000000..92eedf45b
--- /dev/null
+++ b/inc/lang/zh/conflict.txt
@@ -0,0 +1,5 @@
+====== 存在一个更新的版本 ======
+
+您编辑的文档存在一个更新的版本。这种情况的发生是因为在您编辑时有另一个用户更改了该文档。
+
+请仔细检查下面列出的差别,并决定保留哪个版本。如果您选择“保存”,您的版本将被保留。点击“取消”将保留当前版本。
diff --git a/inc/lang/zh/denied.txt b/inc/lang/zh/denied.txt
new file mode 100644
index 000000000..276741c40
--- /dev/null
+++ b/inc/lang/zh/denied.txt
@@ -0,0 +1,3 @@
+====== 拒绝授权 ======
+
+对不起,您没有足够权限,无法继续。也许您忘了登录? \ No newline at end of file
diff --git a/inc/lang/zh/diff.txt b/inc/lang/zh/diff.txt
new file mode 100644
index 000000000..19e8ef752
--- /dev/null
+++ b/inc/lang/zh/diff.txt
@@ -0,0 +1,3 @@
+====== 差别 ======
+
+这里会显示出您选择的修订版和当前版本之间的差别。 \ No newline at end of file
diff --git a/inc/lang/zh/draft.txt b/inc/lang/zh/draft.txt
new file mode 100644
index 000000000..615cb07bf
--- /dev/null
+++ b/inc/lang/zh/draft.txt
@@ -0,0 +1,7 @@
+====== 发现草稿 ======
+
+您在本页最后的编辑过程没有正常结束。DokuWiki 在您的编辑过程中自动保存了一份草稿,您现在可以使用它继续编辑。 下面是最后编辑时的数据。
+
+请决定您希望 //恢复// 您丢失的编辑数据,//删除// 自动保存的草稿,或者 //取消// 本编辑过程。
+
+
diff --git a/inc/lang/zh/edit.txt b/inc/lang/zh/edit.txt
new file mode 100644
index 000000000..846e89817
--- /dev/null
+++ b/inc/lang/zh/edit.txt
@@ -0,0 +1 @@
+编辑本页后请点击“保存”。请参阅 [[wiki:syntax]] 了解维基语法。只有在您能 **改进** 该页面的前提下才编辑它。如果您想尝试一些东西,请先到 [[playground:playground|playground]] 热身。 \ No newline at end of file
diff --git a/inc/lang/zh/editrev.txt b/inc/lang/zh/editrev.txt
new file mode 100644
index 000000000..82013cbbd
--- /dev/null
+++ b/inc/lang/zh/editrev.txt
@@ -0,0 +1,2 @@
+**您载入了该文档旧的修订版!** 如果您保存了它,您就会用这些数据创建一份新的修订版。
+---- \ No newline at end of file
diff --git a/inc/lang/zh/index.txt b/inc/lang/zh/index.txt
new file mode 100644
index 000000000..efb07b9e3
--- /dev/null
+++ b/inc/lang/zh/index.txt
@@ -0,0 +1,3 @@
+====== 索引 ======
+
+这是根据 [[doku>namespaces|命名空间]] 排列的所有可访问页面的索引。 \ No newline at end of file
diff --git a/inc/lang/zh/install.html b/inc/lang/zh/install.html
new file mode 100644
index 000000000..8c7a93c19
--- /dev/null
+++ b/inc/lang/zh/install.html
@@ -0,0 +1,8 @@
+<p>本页面旨在帮助您完成第一次安装和配置 <a href="http://dokuwiki.org">Dokuwiki</a>。关于安装工具的更多信息请参阅其 <a href="http://dokuwiki.org/installer">官方文档页面</a>。</p>
+
+<p>DokuWiki 使用普通的文件保存维基页面和其他与这些页面挂钩的信息(例如:图像,搜索索引,修订记录等)。为了能正常运行,DokuWiki <strong>必须</strong> 拥有针对那些路径和文件的写权限。本安装工具不能用于设置这些权限。对权限的操作通常通过命令行或使用您的网络服务提供商的 FTP 或控制面板(例如 cPanel)进行操作。</p>
+
+<p>本安装工具将设置您的 DokuWiki 配置 <acronym title="访问控制列表">ACL</acronym>,它能让管理员登录并使用“管理”功能来安装插件,管理用户,管理访问权限和其他配置设置。它并不是 DokuWiki 正常运行所必须的,但安装之后它将更方便您的管理。</p>
+
+<p>有经验的用户或有特殊需求的用户请参阅更详细的 <a href="http://dokuwiki.org/install">安装指南</a>
+和 <a href="http://dokuwiki.org/config">配置设置</a>。</p>
diff --git a/inc/lang/zh/lang.php b/inc/lang/zh/lang.php
new file mode 100644
index 000000000..8fffc5ed2
--- /dev/null
+++ b/inc/lang/zh/lang.php
@@ -0,0 +1,326 @@
+<?php
+/**
+ * Chinese(Simplified) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton <guxd@163.com>
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“';
+$lang['doublequoteclosing'] = '”';
+$lang['singlequoteopening'] = '‘';
+$lang['singlequoteclosing'] = '’';
+$lang['apostrophe'] = '’';
+$lang['btn_edit'] = '编辑本页';
+$lang['btn_source'] = '显示源文件';
+$lang['btn_show'] = '显示页面';
+$lang['btn_create'] = '创建该页面';
+$lang['btn_search'] = '搜索';
+$lang['btn_save'] = '保存';
+$lang['btn_preview'] = '预览';
+$lang['btn_top'] = '到顶部';
+$lang['btn_newer'] = '<< 较新的';
+$lang['btn_older'] = '较旧的 >>';
+$lang['btn_revs'] = '修订记录';
+$lang['btn_recent'] = '最近更改';
+$lang['btn_upload'] = '上传';
+$lang['btn_cancel'] = '取消';
+$lang['btn_index'] = '网站地图';
+$lang['btn_secedit'] = '编辑';
+$lang['btn_login'] = '登录';
+$lang['btn_logout'] = '退出';
+$lang['btn_admin'] = '管理';
+$lang['btn_update'] = '更新';
+$lang['btn_delete'] = '删除';
+$lang['btn_back'] = '返回';
+$lang['btn_backlink'] = '反向链接';
+$lang['btn_backtomedia'] = '返回到媒体文件选择工具';
+$lang['btn_subscribe'] = '订阅本页更改';
+$lang['btn_profile'] = '更新个人信息';
+$lang['btn_reset'] = '重设';
+$lang['btn_resendpwd'] = '发送新密码';
+$lang['btn_draft'] = '编辑草稿';
+$lang['btn_recover'] = '恢复草稿';
+$lang['btn_draftdel'] = '删除草稿';
+$lang['btn_revert'] = '恢复';
+$lang['btn_register'] = '注册';
+$lang['btn_apply'] = '应用';
+$lang['btn_media'] = '媒体管理器';
+$lang['loggedinas'] = '登录为';
+$lang['user'] = '用户名';
+$lang['pass'] = '密码';
+$lang['newpass'] = '请输入新密码';
+$lang['oldpass'] = '请输入当前密码';
+$lang['passchk'] = '请再输一次';
+$lang['remember'] = '记住我';
+$lang['fullname'] = '全名';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = '用户信息';
+$lang['badlogin'] = '对不起,用户名或密码错误。';
+$lang['minoredit'] = '细微修改';
+$lang['draftdate'] = '草稿自动保存于';
+$lang['nosecedit'] = '在您编辑期间本页刚被他人修改过,局部信息已过期,故载入全页。';
+$lang['regmissing'] = '对不起,您必须填写所有的区域。';
+$lang['reguexists'] = '对不起,该用户名已经存在。';
+$lang['regsuccess'] = '新用户已建立,密码将通过电子邮件发送给您。';
+$lang['regsuccess2'] = '新用户已建立';
+$lang['regmailfail'] = '发送密码邮件时产生错误。请联系管理员!';
+$lang['regbadmail'] = '您输入的邮件地址有问题——如果您认为这是系统错误,请联系管理员。';
+$lang['regbadpass'] = '您输入的密码与系统产生的不符,请重试。';
+$lang['regpwmail'] = '您的 DokuWiki 密码';
+$lang['reghere'] = '还没有账号?立即注册';
+$lang['profna'] = '本维基不支持修改个人信息';
+$lang['profnochange'] = '没有改动,不进行操作。';
+$lang['profnoempty'] = '不允许使用空的用户名或邮件地址。';
+$lang['profchanged'] = '用户信息更新成功。';
+$lang['pwdforget'] = '忘记密码?立即获取新密码';
+$lang['resendna'] = '本维基不支持二次发送密码。';
+$lang['resendpwd'] = '发送新密码给';
+$lang['resendpwdmissing'] = '对不起,您必须填写所有的区域。';
+$lang['resendpwdnouser'] = '对不起,在我们的用户数据中找不到该用户。';
+$lang['resendpwdbadauth'] = '对不起,该认证码错误。请使用完整的确认链接。';
+$lang['resendpwdconfirm'] = '确认链接已经通过邮件发送给您了。';
+$lang['resendpwdsuccess'] = '您的新密码已经通过邮件发送给您了。';
+$lang['license'] = '除额外注明的地方外,本维基上的内容按下列许可协议发布:';
+$lang['licenseok'] = '当您选择开始编辑本页,即寓示你同意将你贡献的内容按下列许可协议发布:';
+$lang['searchmedia'] = '查找文件名:';
+$lang['searchmedia_in'] = '在%s中查找';
+$lang['txt_upload'] = '选择要上传的文件';
+$lang['txt_filename'] = '上传并重命名为(可选)';
+$lang['txt_overwrt'] = '覆盖已存在的同名文件';
+$lang['lockedby'] = '目前已被下列人员锁定';
+$lang['lockexpire'] = '预计锁定解除于';
+$lang['js']['willexpire'] = '您对本页的独有编辑权将于一分钟之后解除。\n为了防止与其他人的编辑冲突,请使用预览按钮重设计时器。';
+$lang['js']['notsavedyet'] = '未保存的更改将丢失。
+真的要继续?';
+$lang['js']['searchmedia'] = '查找文件';
+$lang['js']['keepopen'] = '选中后不自动关闭窗口';
+$lang['js']['hidedetails'] = '隐藏详细信息';
+$lang['js']['mediatitle'] = '链接设置';
+$lang['js']['mediadisplay'] = '链接类型';
+$lang['js']['mediaalign'] = '对齐';
+$lang['js']['mediasize'] = '图片大小';
+$lang['js']['mediatarget'] = '链接目标';
+$lang['js']['mediaclose'] = '关闭';
+$lang['js']['mediainsert'] = '插入';
+$lang['js']['mediadisplayimg'] = '显示图片。';
+$lang['js']['mediadisplaylnk'] = '仅显示链接。';
+$lang['js']['mediasmall'] = '小尺寸';
+$lang['js']['mediamedium'] = '中等尺寸';
+$lang['js']['medialarge'] = '大尺寸';
+$lang['js']['mediaoriginal'] = '原始版本';
+$lang['js']['medialnk'] = '到详细页面的链接';
+$lang['js']['mediadirect'] = '到原始文件的直接链接';
+$lang['js']['medianolnk'] = '没有链接';
+$lang['js']['medianolink'] = '不要链接图片';
+$lang['js']['medialeft'] = '左对齐图片。';
+$lang['js']['mediaright'] = '右对齐图片。';
+$lang['js']['mediacenter'] = '居中对齐图片。';
+$lang['js']['medianoalign'] = '不使用对齐。';
+$lang['js']['nosmblinks'] = '连接到 Windows 共享功能只有在 IE 浏览器中才能正常使用。
+但您仍能复制并粘贴该链接。';
+$lang['js']['linkwiz'] = '链接向导';
+$lang['js']['linkto'] = '链接到:';
+$lang['js']['del_confirm'] = '真的要删除选中的项目吗?';
+$lang['js']['restore_confirm'] = '确实要恢复这个版本么?';
+$lang['js']['media_diff'] = '查看差异:';
+$lang['js']['media_diff_both'] = '肩并肩';
+$lang['js']['media_diff_opacity'] = '叠加';
+$lang['js']['media_diff_portions'] = '滑块';
+$lang['js']['media_select'] = '选择文件……';
+$lang['js']['media_upload_btn'] = '上传';
+$lang['js']['media_done_btn'] = '完成';
+$lang['js']['media_drop'] = '拖拽文件到此处来上传';
+$lang['js']['media_cancel'] = '删除';
+$lang['js']['media_overwrt'] = '覆盖已存在的文件';
+$lang['rssfailed'] = '获取该 RSS 信息时产生错误:';
+$lang['nothingfound'] = '什么都没有找到。';
+$lang['mediaselect'] = '媒体文件';
+$lang['fileupload'] = '上传媒体文件';
+$lang['uploadsucc'] = '上传成功';
+$lang['uploadfail'] = '上传失败。也许是上传权限错误。';
+$lang['uploadwrong'] = '上传失败。该扩展名被禁止。';
+$lang['uploadexist'] = '文件已存在。不进行操作。';
+$lang['uploadbadcontent'] = '上传的文件与扩展名 %s 不符。';
+$lang['uploadspam'] = '上传操作被垃圾信息黑名单阻止。';
+$lang['uploadxss'] = '上传操作因可能存在恶意内容而被阻止。';
+$lang['uploadsize'] = '上传的文件过大。(最大 %s)';
+$lang['deletesucc'] = '文件“%s”已经被删除。';
+$lang['deletefail'] = '无法删除“%s”- 请检查权限。';
+$lang['mediainuse'] = '文件“%s”无法删除 - 它正被使用中。';
+$lang['namespaces'] = '命名空间';
+$lang['mediafiles'] = '可用的文件';
+$lang['accessdenied'] = '您没有权限浏览此页面。';
+$lang['mediausage'] = '使用下列字符链接到该文件:';
+$lang['mediaview'] = '查看该文件';
+$lang['mediaroot'] = '根目录';
+$lang['mediaupload'] = '上传文件至当前的命名空间。要创建次级命名空间,将其名称加在“上传并重命名为”文件名的前面,并用英文冒号隔开';
+$lang['mediaextchange'] = '文件的扩展名由 .%s 改为了 .%s!';
+$lang['reference'] = '相关的';
+$lang['ref_inuse'] = '该文件无法删除,因为它正被下列页面使用:';
+$lang['ref_hidden'] = '一些相关的页面您并没有权限阅读';
+$lang['hits'] = '符合';
+$lang['quickhits'] = '匹配的页面名称';
+$lang['toc'] = '目录';
+$lang['current'] = '当前版本';
+$lang['yours'] = '您的版本';
+$lang['diff'] = '显示与当前版本的差别';
+$lang['diff2'] = '显示跟目前版本的差异';
+$lang['difflink'] = '到此差别页面的链接';
+$lang['diff_type'] = '查看差异:';
+$lang['diff_inline'] = '行内显示';
+$lang['diff_side'] = '并排显示';
+$lang['line'] = '行';
+$lang['breadcrumb'] = '您的足迹';
+$lang['youarehere'] = '您在这里';
+$lang['lastmod'] = '最后更改';
+$lang['by'] = '由';
+$lang['deleted'] = '移除';
+$lang['created'] = '创建';
+$lang['restored'] = '已恢复为旧版';
+$lang['external_edit'] = '外部编辑';
+$lang['summary'] = '编辑摘要';
+$lang['noflash'] = '需要 <a href="http://www.adobe.com/products/flashplayer/">Adobe Flash 插件</a> 来播放本内容。 ';
+$lang['download'] = '下载片段';
+$lang['mail_newpage'] = '添加页面:';
+$lang['mail_changed'] = '更改页面:';
+$lang['mail_subscribe_list'] = '命名空间中改变的页面:';
+$lang['mail_new_user'] = '新用户:';
+$lang['mail_upload'] = '已上传的文件:';
+$lang['changes_type'] = '查看何种更改';
+$lang['pages_changes'] = '页面';
+$lang['media_changes'] = '媒体文件';
+$lang['both_changes'] = '页面和媒体文件';
+$lang['qb_bold'] = '粗体';
+$lang['qb_italic'] = '斜体';
+$lang['qb_underl'] = '下划线';
+$lang['qb_code'] = '代码';
+$lang['qb_strike'] = '删除线';
+$lang['qb_h1'] = '标题 H1';
+$lang['qb_h2'] = '标题 H2 ';
+$lang['qb_h3'] = '标题 H3';
+$lang['qb_h4'] = '标题 H4';
+$lang['qb_h5'] = '标题 H5';
+$lang['qb_h'] = '标题';
+$lang['qb_hs'] = '选择标题';
+$lang['qb_hplus'] = '上级标题';
+$lang['qb_hminus'] = '下级标题';
+$lang['qb_hequal'] = '同级标题';
+$lang['qb_link'] = '内部链接';
+$lang['qb_extlink'] = '外部链接';
+$lang['qb_hr'] = '水平线';
+$lang['qb_ol'] = '数字列表项目';
+$lang['qb_ul'] = '普通列表项目';
+$lang['qb_media'] = '插入图像或其他文件';
+$lang['qb_sig'] = '插入签名';
+$lang['qb_smileys'] = '表情符号';
+$lang['qb_chars'] = '特殊字符';
+$lang['upperns'] = '跳转到父级名空间';
+$lang['admin_register'] = '添加新用户';
+$lang['metaedit'] = '编辑元数据';
+$lang['metasaveerr'] = '写入元数据失败';
+$lang['metasaveok'] = '元数据已保存';
+$lang['img_backto'] = '返回到';
+$lang['img_title'] = '标题';
+$lang['img_caption'] = '说明';
+$lang['img_date'] = '日期';
+$lang['img_fname'] = '名称';
+$lang['img_fsize'] = '大小';
+$lang['img_artist'] = '摄影师';
+$lang['img_copyr'] = '版权';
+$lang['img_format'] = '格式';
+$lang['img_camera'] = '相机';
+$lang['img_keywords'] = '关键字';
+$lang['img_width'] = '宽度';
+$lang['img_height'] = '高度';
+$lang['img_manager'] = '在媒体管理器中查看';
+$lang['subscr_subscribe_success'] = '添加 %s 到 %s 的订阅列表';
+$lang['subscr_subscribe_error'] = '添加 %s 到 %s 的订阅列表中出现错误';
+$lang['subscr_subscribe_noaddress'] = '没有与您登录信息相关联的地址,您无法被添加到订阅列表';
+$lang['subscr_unsubscribe_success'] = '%s 被移出 %s 的订阅列表';
+$lang['subscr_unsubscribe_error'] = '%s 被移出 %s 的订阅列表中出现错误';
+$lang['subscr_already_subscribed'] = '%s 已经订阅了 %s';
+$lang['subscr_not_subscribed'] = '%s 没有订阅 %s';
+$lang['subscr_m_not_subscribed'] = '您现在没有订阅当前页面或者命名空间。';
+$lang['subscr_m_new_header'] = '添加订阅';
+$lang['subscr_m_current_header'] = '当前订阅';
+$lang['subscr_m_unsubscribe'] = '退订';
+$lang['subscr_m_subscribe'] = '订阅';
+$lang['subscr_m_receive'] = '接收';
+$lang['subscr_style_every'] = '对每次更改发送邮件';
+$lang['subscr_style_digest'] = '对每个页面发送更改的摘要邮件(每 %.2f 天)';
+$lang['subscr_style_list'] = '自上封邮件以来更改的页面的列表(每 %.2f 天)';
+$lang['authmodfailed'] = '错误的用户认证设置。请通知维基管理员。';
+$lang['authtempfail'] = '用户认证暂时无法使用。如果该状态一直存在,请通知维基管理员。';
+$lang['i_chooselang'] = '选择您的语言';
+$lang['i_installer'] = 'DokuWiki 安装工具';
+$lang['i_wikiname'] = '维基名称';
+$lang['i_enableacl'] = '启用 ACL(推荐)';
+$lang['i_superuser'] = '超级用户';
+$lang['i_problems'] = '安装工具发现一些问题,已在下面列出。您必须先修复这些问题,才能继续安装。';
+$lang['i_modified'] = '由于安全上的考虑,该脚本只能用于全新且做任何改动的 Dokuwiki 安装包。
+ 您可以重新解压下载的程序包,或查阅完整的
+ <a href="http://dokuwiki.org/install">Dokuwiki 安装指南</a>';
+$lang['i_funcna'] = 'PHP 功能 <code>%s</code> 无法使用。也许您的服务器提供商因为某些原因禁用了它。';
+$lang['i_phpver'] = '您的 PHP 版本 <code>%s</code> 低于最低要求的 <code>%s</code>。您需要升级您的 PHP 版本。';
+$lang['i_permfail'] = 'DokuWiki 无法写入 <code>%s</code>。您需要修改该路径的权限设定!';
+$lang['i_confexists'] = '<code>%s</code> 已经存在';
+$lang['i_writeerr'] = '无法创建 <code>%s</code>。您需要检查该路径/文件的权限设定并手动创建该文件。';
+$lang['i_badhash'] = '无法识别的或被修改的 dokuwiki.php(值=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - 非法或空值';
+$lang['i_success'] = '配置成功完成。您现在可以删除 install.php 了。继续进入
+ <a href="doku.php">您全新的 DokuWiki</a>。';
+$lang['i_failure'] = '写入配置文件的时候产生一些错误。在使用 <a href="doku.php">您全新安装的 DokuWiki</a> 前
+ 您需要手动修复它们。';
+$lang['i_policy'] = '初始的 ACL 政策';
+$lang['i_pol0'] = '开放的维基(任何人都有读、写、上传的权限)';
+$lang['i_pol1'] = '公共的维基(任何人都有读的权限,只有注册用户才有写和上传的权限)';
+$lang['i_pol2'] = '关闭的维基(只有注册用户才有读、写、上传的权限)';
+$lang['i_retry'] = '重试';
+$lang['i_license'] = '请选择您希望的内容发布许可协议:';
+
+$lang['recent_global'] = '您当前看到的是<b>%s</b> 名称空间的变动。你还可以在<a href="%s">查看整个维基的近期变动</a>。';
+$lang['years'] = '%d年前';
+$lang['months'] = '%d月前';
+$lang['weeks'] = '%d周前';
+$lang['days'] = '%d天前';
+$lang['hours'] = '%d小时前';
+$lang['minutes'] = '%d分钟前';
+$lang['seconds'] = '%d秒前';
+$lang['wordblock'] = '您的更改没有被保存,因为它包含被屏蔽的文字(垃圾信息)。';
+$lang['media_uploadtab'] = '上传';
+$lang['media_searchtab'] = '搜索';
+$lang['media_file'] = '文件';
+$lang['media_viewtab'] = '查看';
+$lang['media_edittab'] = '编辑';
+$lang['media_historytab'] = '历史';
+$lang['media_list_thumbs'] = '缩图';
+$lang['media_list_rows'] = '列表';
+$lang['media_sort_name'] = '按名称';
+$lang['media_sort_date'] = '按日期';
+$lang['media_namespaces'] = '选择命名空间';
+$lang['media_files'] = '在 %s 中的文件';
+$lang['media_upload'] = '上传到 <strong>%s</strong> 命名空间。';
+$lang['media_search'] = '在 <strong>%s</strong> 命名空间中搜索。';
+$lang['media_view'] = '%s 在 %s';
+$lang['media_viewold'] = '%s ';
+$lang['media_edit'] = '编辑 %s';
+$lang['media_history'] = '%s 的历史纪录';
+$lang['media_meta_edited'] = '元数据已编辑';
+$lang['media_perm_read'] = '抱歉,您没有足够权限读取这些文件。';
+$lang['media_perm_upload'] = '抱歉,您没有足够权限来上传文件。';
+$lang['media_update'] = '上传新版本';
+$lang['media_restore'] = '恢复这个版本';
+$lang['plugin_install_err'] = '插件安装不正确。重命名插件目录“%s”为“%s”。';
diff --git a/inc/lang/zh/locked.txt b/inc/lang/zh/locked.txt
new file mode 100644
index 000000000..321e4a047
--- /dev/null
+++ b/inc/lang/zh/locked.txt
@@ -0,0 +1,3 @@
+====== 页面已锁定 ======
+
+本页面目前正被其他用户编辑。您要等到该用户完成编辑或锁定因过期而自动解除后才能编辑。 \ No newline at end of file
diff --git a/inc/lang/zh/login.txt b/inc/lang/zh/login.txt
new file mode 100644
index 000000000..8ff8b3846
--- /dev/null
+++ b/inc/lang/zh/login.txt
@@ -0,0 +1,3 @@
+====== 登录 ======
+
+您尚未登录!请在下方输入您的用户名和密码进行登录。 您的浏览器需要支持 Cookies 才能正常登录。
diff --git a/inc/lang/zh/mailtext.txt b/inc/lang/zh/mailtext.txt
new file mode 100644
index 000000000..311acf1b9
--- /dev/null
+++ b/inc/lang/zh/mailtext.txt
@@ -0,0 +1,17 @@
+您的 DokuWiki 中有一个页面被添加或更改了。以下是详细资料:
+
+日期 : @DATE@
+浏览器 : @BROWSER@
+IP 地址 : @IPADDRESS@
+机器名称 : @HOSTNAME@
+修订记录 : @OLDPAGE@
+最新修订 : @NEWPAGE@
+编辑摘要 : @SUMMARY@
+用户 : @USER@
+
+@DIFF@
+
+
+--
+本邮件由 DokuWiki 自动创建
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/zh/newpage.txt b/inc/lang/zh/newpage.txt
new file mode 100644
index 000000000..6f96b568d
--- /dev/null
+++ b/inc/lang/zh/newpage.txt
@@ -0,0 +1,3 @@
+====== 该主题尚不存在 ======
+
+您访问的页面并不存在。如果允许,您可以使用“创建该页面”按钮来创建它。 \ No newline at end of file
diff --git a/inc/lang/zh/norev.txt b/inc/lang/zh/norev.txt
new file mode 100644
index 000000000..3fe5aabd8
--- /dev/null
+++ b/inc/lang/zh/norev.txt
@@ -0,0 +1,3 @@
+====== 没有该修订版 ======
+
+您指定的修订版并不存在。请使用“修订记录”按钮查看本页面的修订记录列表。 \ No newline at end of file
diff --git a/inc/lang/zh/password.txt b/inc/lang/zh/password.txt
new file mode 100644
index 000000000..969297093
--- /dev/null
+++ b/inc/lang/zh/password.txt
@@ -0,0 +1,10 @@
+@FULLNAME@ 您好!
+
+这是您在 @TITLE@(@DOKUWIKIURL@)的用户资料
+用户名:@LOGIN@
+密码:@PASSWORD@
+
+--
+本邮件由 DokuWiki 自动创建
+@DOKUWIKIURL@
+
diff --git a/inc/lang/zh/preview.txt b/inc/lang/zh/preview.txt
new file mode 100644
index 000000000..dbb3de675
--- /dev/null
+++ b/inc/lang/zh/preview.txt
@@ -0,0 +1,3 @@
+====== 预览 ======
+
+这是该文件的效果预览。请记住:它**并没有被保存**!
diff --git a/inc/lang/zh/pwconfirm.txt b/inc/lang/zh/pwconfirm.txt
new file mode 100644
index 000000000..7e48751a6
--- /dev/null
+++ b/inc/lang/zh/pwconfirm.txt
@@ -0,0 +1,15 @@
+@FULLNAME@ 您好!
+
+有人请求为您在 @DOKUWIKIURL@ 注册的用户名 @TITLE@ 发送新密码
+
+如果您没有请求发送新密码,请忽略这封邮件。
+
+为了确认发送新密码请求的确来自您,请使用下面的链接。
+
+@CONFIRM@
+
+--
+本邮件由 DokuWiki 自动创建
+@DOKUWIKIURL@
+
+
diff --git a/inc/lang/zh/read.txt b/inc/lang/zh/read.txt
new file mode 100644
index 000000000..eb47765a2
--- /dev/null
+++ b/inc/lang/zh/read.txt
@@ -0,0 +1,2 @@
+本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。
+
diff --git a/inc/lang/zh/recent.txt b/inc/lang/zh/recent.txt
new file mode 100644
index 000000000..95634d037
--- /dev/null
+++ b/inc/lang/zh/recent.txt
@@ -0,0 +1,5 @@
+====== 最近更新 ======
+
+以下的页面是最近才更新的:
+
+
diff --git a/inc/lang/zh/register.txt b/inc/lang/zh/register.txt
new file mode 100644
index 000000000..7410ff1c0
--- /dev/null
+++ b/inc/lang/zh/register.txt
@@ -0,0 +1,3 @@
+====== 注册新用户 ======
+
+填写以下资料来创建一个新帐户。请确定您提供的是 **正确的 E-mail 地址** - 如果您没有被要求在这里输入密码,那么新密码将通过您的邮件地址发送给您。 用于登录的用户名必须合法,请参阅 [[doku>pagename|pagename]]。
diff --git a/inc/lang/zh/registermail.txt b/inc/lang/zh/registermail.txt
new file mode 100644
index 000000000..9647b5fad
--- /dev/null
+++ b/inc/lang/zh/registermail.txt
@@ -0,0 +1,16 @@
+新用户已创建。下面是详细信息:
+
+用户名 : @NEWUSER@
+全名 : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+日期 : @DATE@
+浏览器 : @BROWSER@
+IP 地址 : @IPADDRESS@
+机器名称 : @HOSTNAME@
+
+--
+本邮件由 DokuWiki 自动创建
+@DOKUWIKIURL@
+
+
diff --git a/inc/lang/zh/resendpwd.txt b/inc/lang/zh/resendpwd.txt
new file mode 100644
index 000000000..f98e469e6
--- /dev/null
+++ b/inc/lang/zh/resendpwd.txt
@@ -0,0 +1,5 @@
+====== 发送新密码 ======
+
+请在下列区域中输入您的用户名来获取新密码。 一封包含确认链接的邮件将发送给您注册的邮件地址。
+
+
diff --git a/inc/lang/zh/revisions.txt b/inc/lang/zh/revisions.txt
new file mode 100644
index 000000000..89d2a7857
--- /dev/null
+++ b/inc/lang/zh/revisions.txt
@@ -0,0 +1,3 @@
+====== 修订记录 ======
+
+以下是当前文档的修订记录。如果要回复到某个旧的修订版,请在下面选择它,并点击“编辑本页”,之后保存即可。 \ No newline at end of file
diff --git a/inc/lang/zh/searchpage.txt b/inc/lang/zh/searchpage.txt
new file mode 100644
index 000000000..8222e242c
--- /dev/null
+++ b/inc/lang/zh/searchpage.txt
@@ -0,0 +1,5 @@
+====== 搜索 ======
+
+下面将显示您的搜索结果。如果没有找到您想要的东西,您可以使用相应的按钮来创建或编辑该页面。
+
+===== 搜索结果 ===== \ No newline at end of file
diff --git a/inc/lang/zh/showrev.txt b/inc/lang/zh/showrev.txt
new file mode 100644
index 000000000..770fecc98
--- /dev/null
+++ b/inc/lang/zh/showrev.txt
@@ -0,0 +1,2 @@
+**这是本文档旧的修订版!**
+----
diff --git a/inc/lang/zh/stopwords.txt b/inc/lang/zh/stopwords.txt
new file mode 100644
index 000000000..bc6eb48ae
--- /dev/null
+++ b/inc/lang/zh/stopwords.txt
@@ -0,0 +1,29 @@
+# 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
+and
+you
+your
+them
+their
+com
+for
+from
+into
+how
+that
+the
+this
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/inc/lang/zh/subscr_digest.txt b/inc/lang/zh/subscr_digest.txt
new file mode 100644
index 000000000..3c73ff4c5
--- /dev/null
+++ b/inc/lang/zh/subscr_digest.txt
@@ -0,0 +1,19 @@
+您好!
+
+@TITLE@ 维基中的页面 @PAGE@ 已经更改。
+这里是更改的内容:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+旧版本:@OLDPAGE@
+新版本:@NEWPAGE@
+
+要取消页面提醒,从 @DOKUWIKIURL@ 登录维基,然后浏览
+@SUBSCRIBE@
+并退订页面以及/或者命名空间的更改。
+
+--
+本邮件由以下 DokuWiki 产生
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/zh/subscr_form.txt b/inc/lang/zh/subscr_form.txt
new file mode 100644
index 000000000..65bfd4041
--- /dev/null
+++ b/inc/lang/zh/subscr_form.txt
@@ -0,0 +1,3 @@
+====== 订阅管理 ======
+
+这个页面允许您管理在当前页面和命名空间的订阅。 \ No newline at end of file
diff --git a/inc/lang/zh/subscr_list.txt b/inc/lang/zh/subscr_list.txt
new file mode 100644
index 000000000..1fc1e213c
--- /dev/null
+++ b/inc/lang/zh/subscr_list.txt
@@ -0,0 +1,16 @@
+您好!
+
+@TITLE@ 维基中的命名空间 @PAGE@ 的页面已经更改。
+这里是更改的页面:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+要取消页面提醒,从 @DOKUWIKIURL@ 登录维基,然后浏览
+@SUBSCRIBE@
+并退订页面以及/或者命名空间的更改。
+
+--
+本邮件由以下 DokuWiki 产生
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/zh/subscr_single.txt b/inc/lang/zh/subscr_single.txt
new file mode 100644
index 000000000..7da57d570
--- /dev/null
+++ b/inc/lang/zh/subscr_single.txt
@@ -0,0 +1,22 @@
+您好!
+
+@TITLE@ 维基中的页面 @PAGE@ 已经更改。
+这里是更改的内容:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+时间:@DATE@
+用户:@USER@
+编辑摘要:@SUMMARY@
+旧版本:@OLDPAGE@
+新版本:@NEWPAGE@
+
+要取消页面提醒,从 @DOKUWIKIURL@ 登录维基,然后浏览
+@SUBSCRIBE@
+并退订页面以及/或者命名空间的更改。
+
+--
+本邮件由以下 DokuWiki 产生
+@DOKUWIKIURL@ \ No newline at end of file
diff --git a/inc/lang/zh/updateprofile.txt b/inc/lang/zh/updateprofile.txt
new file mode 100644
index 000000000..007578801
--- /dev/null
+++ b/inc/lang/zh/updateprofile.txt
@@ -0,0 +1,5 @@
+====== 更新您帐户的信息 ======
+
+您只需要填写希望更改的区域即可。您不能更改用户名。
+
+
diff --git a/inc/lang/zh/uploadmail.txt b/inc/lang/zh/uploadmail.txt
new file mode 100644
index 000000000..b820cee2b
--- /dev/null
+++ b/inc/lang/zh/uploadmail.txt
@@ -0,0 +1,20 @@
+您好!
+
+一个文件被上传到您的 DokuWiki 站点。下面是详细信息:
+
+文件名 : @MEDIA@
+日期 : @DATE@
+浏览器 : @BROWSER@
+IP 地址 : @IPADDRESS@
+主机名 : @HOSTNAME@
+大小 : @SIZE@
+MIME 类型 : @MIME@
+用户 : @USER@
+
+--
+本邮件由 DokuWiki 自动创建
+@DOKUWIKIURL@
+
+
+
+
diff --git a/inc/load.php b/inc/load.php
new file mode 100644
index 000000000..d30397f6e
--- /dev/null
+++ b/inc/load.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * Load all internal libraries and setup class autoloader
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// 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/blowfish.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/plugin.php');
+require_once(DOKU_INC.'inc/events.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/subscription.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');
+
+/**
+ * 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
+ */
+function load_autoload($name){
+ static $classes = null;
+ if(is_null($classes)) $classes = array(
+ 'DokuHTTPClient' => DOKU_INC.'inc/HTTPClient.php',
+ 'JSON' => DOKU_INC.'inc/JSON.php',
+ 'adLDAP' => DOKU_INC.'inc/adLDAP.php',
+ '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',
+ 'Doku_Event' => DOKU_INC.'inc/events.php',
+ 'Doku_Event_Handler' => DOKU_INC.'inc/events.php',
+ 'EmailAddressValidator' => DOKU_INC.'inc/EmailAddressValidator.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_IntrospectionServer' => DOKU_INC.'inc/IXR_Library.php',
+ 'Doku_Plugin_Controller'=> DOKU_INC.'inc/plugincontroller.class.php',
+ 'GeSHi' => DOKU_INC.'inc/geshi.php',
+ 'TarLib' => DOKU_INC.'inc/TarLib.class.php',
+ 'ZipLib' => DOKU_INC.'inc/ZipLib.class.php',
+ 'DokuWikiFeedCreator' => DOKU_INC.'inc/feedcreator.class.php',
+ 'Doku_Parser_Mode' => DOKU_INC.'inc/parser/parser.php',
+ 'SafeFN' => DOKU_INC.'inc/SafeFN.class.php',
+ 'Sitemapper' => DOKU_INC.'inc/Sitemapper.php',
+ 'PassHash' => DOKU_INC.'inc/PassHash.class.php',
+
+ 'DokuWiki_Action_Plugin' => DOKU_PLUGIN.'action.php',
+ 'DokuWiki_Admin_Plugin' => DOKU_PLUGIN.'admin.php',
+ 'DokuWiki_Syntax_Plugin' => DOKU_PLUGIN.'syntax.php',
+
+ );
+
+ if(isset($classes[$name])){
+ require_once($classes[$name]);
+ return;
+ }
+
+ // Plugin loading
+ if(preg_match('/^(helper|syntax|action|admin|renderer)_plugin_([^_]+)(?:_([^_]+))?$/',
+ $name, $m)) {
+ //try to load the wanted plugin file
+ // include, but be silent. Maybe some other autoloader has an idea
+ // how to load this class.
+ $c = ((count($m) === 4) ? "/{$m[3]}" : '');
+ @include DOKU_PLUGIN . "{$m[2]}/{$m[1]}$c.php";
+ return;
+ }
+}
+
diff --git a/inc/mail.php b/inc/mail.php
new file mode 100644
index 000000000..01b2895e1
--- /dev/null
+++ b/inc/mail.php
@@ -0,0 +1,318 @@
+<?php
+/**
+ * Mail functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+// 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,4}|museum|travel)');
+
+/**
+ * Prepare mailfrom replacement patterns
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function mail_setup(){
+ global $conf;
+ global $USERINFO;
+
+ $replace = array();
+
+ if(!empty($USERINFO['mail'])){
+ $replace['@MAIL@'] = $USERINFO['mail'];
+ }else{
+ $host = @parse_url(DOKU_URL,PHP_URL_HOST);
+ if(!$host) $host = 'example.com';
+ $replace['@MAIL@'] = 'noreply@'.$host;
+ }
+
+ if(!empty($_SERVER['REMOTE_USER'])){
+ $replace['@USER@'] = $_SERVER['REMOTE_USER'];
+ }else{
+ $replace['@USER@'] = 'noreply';
+ }
+
+ if(!empty($USERINFO['name'])){
+ $replace['@NAME@'] = $USERINFO['name'];
+ }else{
+ $replace['@NAME@'] = '';
+ }
+
+ $conf['mailfrom'] = str_replace(array_keys($replace),
+ array_values($replace),
+ $conf['mailfrom']);
+}
+
+/**
+ * UTF-8 autoencoding replacement for PHPs mail function
+ *
+ * Email address fields (To, From, Cc, Bcc can contain a textpart and an address
+ * like this: 'Andreas Gohr <andi@splitbrain.org>' - the text part is encoded
+ * automatically. You can seperate receivers by commas.
+ *
+ * @param string $to Receiver of the mail (multiple seperated by commas)
+ * @param string $subject Mailsubject
+ * @param string $body Messagebody
+ * @param string $from Sender address
+ * @param string $cc CarbonCopy receiver (multiple seperated by commas)
+ * @param string $bcc BlindCarbonCopy receiver (multiple seperated by commas)
+ * @param string $headers Additional Headers (seperated by MAILHEADER_EOL
+ * @param string $params Additonal Sendmail params (passed to mail())
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see mail()
+ */
+function mail_send($to, $subject, $body, $from='', $cc='', $bcc='', $headers=null, $params=null){
+
+ $message = compact('to','subject','body','from','cc','bcc','headers','params');
+ return trigger_event('MAIL_MESSAGE_SEND',$message,'_mail_send_action');
+}
+
+function _mail_send_action($data) {
+
+ // retrieve parameters from event data, $to, $subject, $body, $from, $cc, $bcc, $headers, $params
+ $to = $data['to'];
+ $subject = $data['subject'];
+ $body = $data['body'];
+
+ // add robustness in case plugin removes any of these optional values
+ $from = isset($data['from']) ? $data['from'] : '';
+ $cc = isset($data['cc']) ? $data['cc'] : '';
+ $bcc = isset($data['bcc']) ? $data['bcc'] : '';
+ $headers = isset($data['headers']) ? $data['headers'] : null;
+ $params = isset($data['params']) ? $data['params'] : null;
+
+ // discard mail request if no recipients are available
+ if(trim($to) === '' && trim($cc) === '' && trim($bcc) === '') return false;
+
+ // end additional code to support event ... original mail_send() code from here
+
+ if(defined('MAILHEADER_ASCIIONLY')){
+ $subject = utf8_deaccent($subject);
+ $subject = utf8_strip($subject);
+ }
+
+ if(!utf8_isASCII($subject)) {
+ $enc_subj = '=?UTF-8?Q?'.mail_quotedprintable_encode($subject,0).'?=';
+ // Spaces must be encoded according to rfc2047. Use the "_" shorthand
+ $enc_subj = preg_replace('/ /', '_', $enc_subj);
+
+ // quoted printable has length restriction, use base64 if needed
+ if(strlen($subject) > 74){
+ $enc_subj = '=?UTF-8?B?'.base64_encode($subject).'?=';
+ }
+
+ $subject = $enc_subj;
+ }
+
+ $header = '';
+
+ // No named recipients for To: in Windows (see FS#652)
+ $usenames = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? false : true;
+
+ $to = mail_encode_address($to,'',$usenames);
+ $header .= mail_encode_address($from,'From');
+ $header .= mail_encode_address($cc,'Cc');
+ $header .= mail_encode_address($bcc,'Bcc');
+ $header .= 'MIME-Version: 1.0'.MAILHEADER_EOL;
+ $header .= 'Content-Type: text/plain; charset=UTF-8'.MAILHEADER_EOL;
+ $header .= 'Content-Transfer-Encoding: quoted-printable'.MAILHEADER_EOL;
+ $header .= $headers;
+ $header = trim($header);
+
+ $body = mail_quotedprintable_encode($body);
+
+ if($params == null){
+ return @mail($to,$subject,$body,$header);
+ }else{
+ return @mail($to,$subject,$body,$header,$params);
+ }
+}
+
+/**
+ * Encodes an email address header
+ *
+ * Unicode characters will be deaccented and encoded
+ * quoted_printable for headers.
+ * Addresses may not contain Non-ASCII data!
+ *
+ * Example:
+ * mail_encode_address("föö <foo@bar.com>, me@somewhere.com","TBcc");
+ *
+ * @param string $string Multiple adresses separated by commas
+ * @param string $header Name of the header (To,Bcc,Cc,...)
+ * @param boolean $names Allow named Recipients?
+ */
+function mail_encode_address($string,$header='',$names=true){
+ $headers = '';
+ $parts = explode(',',$string);
+ foreach ($parts as $part){
+ $part = trim($part);
+
+ // parse address
+ if(preg_match('#(.*?)<(.*?)>#',$part,$matches)){
+ $text = trim($matches[1]);
+ $addr = $matches[2];
+ }else{
+ $addr = $part;
+ }
+
+ // skip empty ones
+ if(empty($addr)){
+ continue;
+ }
+
+ // FIXME: is there a way to encode the localpart of a emailaddress?
+ if(!utf8_isASCII($addr)){
+ msg(htmlspecialchars("E-Mail address <$addr> is not ASCII"),-1);
+ continue;
+ }
+
+ if(!mail_isvalid($addr)){
+ msg(htmlspecialchars("E-Mail address <$addr> is not valid"),-1);
+ continue;
+ }
+
+ // text was given
+ if(!empty($text) && $names){
+ // add address quotes
+ $addr = "<$addr>";
+
+ if(defined('MAILHEADER_ASCIIONLY')){
+ $text = utf8_deaccent($text);
+ $text = utf8_strip($text);
+ }
+
+ if(!utf8_isASCII($text)){
+ // put the quotes outside as in =?UTF-8?Q?"Elan Ruusam=C3=A4e"?= vs "=?UTF-8?Q?Elan Ruusam=C3=A4e?="
+ if (preg_match('/^"(.+)"$/', $text, $matches)) {
+ $text = '"=?UTF-8?Q?'.mail_quotedprintable_encode($matches[1], 0).'?="';
+ } else {
+ $text = '=?UTF-8?Q?'.mail_quotedprintable_encode($text, 0).'?=';
+ }
+ // additionally the space character should be encoded as =20 (or each
+ // word QP encoded separately).
+ // however this is needed only in mail headers, not globally in mail_quotedprintable_encode().
+ $text = str_replace(" ", "=20", $text);
+ }
+ }else{
+ $text = '';
+ }
+
+ // add to header comma seperated
+ if($headers != ''){
+ $headers .= ',';
+ if($header) $headers .= MAILHEADER_EOL.' '; // avoid overlong mail headers
+ }
+ $headers .= $text.' '.$addr;
+ }
+
+ if(empty($headers)) return null;
+
+ //if headername was given add it and close correctly
+ if($header) $headers = $header.': '.$headers.MAILHEADER_EOL;
+
+ return $headers;
+}
+
+/**
+ * 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){
+ $validator = new EmailAddressValidator;
+ $validator->allowLocalAddresses = true;
+ return $validator->check_email_address($email);
+}
+
+/**
+ * Quoted printable encoding
+ *
+ * @author umu <umuAThrz.tu-chemnitz.de>
+ * @link http://www.php.net/manual/en/function.imap-8bit.php#61216
+ */
+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]/e';
+
+ $sReplmt = 'sprintf( "=%02X", ord ( "$0" ) ) ;';
+ $sLine = preg_replace( $sRegExp, $sReplmt, $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);
+}
+
diff --git a/inc/media.php b/inc/media.php
new file mode 100644
index 000000000..66c531452
--- /dev/null
+++ b/inc/media.php
@@ -0,0 +1,2019 @@
+<?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>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+if(!defined('NL')) define('NL',"\n");
+
+/**
+ * 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>
+ */
+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>
+ */
+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);
+ }
+
+ if($meta->save()){
+ if($conf['fperm']) chmod($src, $conf['fperm']);
+
+ $new = @filemtime($src);
+ // add a log entry to the media changelog
+ addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, $lang['media_meta_edited']);
+
+ msg($lang['metasaveok'],1);
+ return $id;
+ }else{
+ msg($lang['metasaveerr'],-1);
+ return false;
+ }
+}
+
+/**
+ * Display the form to edit image meta data
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function media_metaform($id,$auth){
+ global $lang, $config_cascade;
+
+ 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();
+}
+
+/**
+ * Convenience function to check if a media file is still in use
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+function media_inuse($id) {
+ global $conf;
+ $mediareferences = array();
+ if($conf['refcheck']){
+ $mediareferences = ft_mediause($id,$conf['refshow']);
+ if(!count($mediareferences)) {
+ return false;
+ } else {
+ return $mediareferences;
+ }
+ } else {
+ return false;
+ }
+}
+
+define('DOKU_MEDIA_DELETED', 1);
+define('DOKU_MEDIA_NOT_AUTH', 2);
+define('DOKU_MEDIA_INUSE', 4);
+define('DOKU_MEDIA_EMPTY_NS', 8);
+
+/**
+ * Handles media file deletions
+ *
+ * If configured, checks for media references before deletion
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @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;
+ 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['id'] = $id;
+ $data['name'] = basename($file);
+ $data['path'] = $file;
+ $data['size'] = (@file_exists($file)) ? filesize($file) : 0;
+
+ $data['unl'] = false;
+ $data['del'] = false;
+ $evt = new Doku_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']){
+ addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE, $lang['deleted']);
+ $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
+ *
+ * @return mixed false on error, id of the new file on success
+ */
+function media_upload_xhr($ns,$auth){
+ if(!checkSecurityToken()) return false;
+
+ $id = $_GET['qqfile'];
+ list($ext,$mime,$dl) = 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 ($realSize != (int)$_SERVER["CONTENT_LENGTH"]){
+ unlink($target);
+ unlink($path);
+ return false;
+ }
+
+ $res = media_save(
+ array('name' => $path,
+ 'mime' => $mime,
+ 'ext' => $ext),
+ $ns.':'.$id,
+ (($_REQUEST['ow'] == 'checked') ? true : false),
+ $auth,
+ 'copy'
+ );
+ unlink($path);
+ if ($tmp) dir_delete($tmp);
+ 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>
+ * @return mixed false on error, id of the new file on success
+ */
+function media_upload($ns,$auth,$file=false){
+ if(!checkSecurityToken()) return false;
+ global $lang;
+
+ // get file and id
+ $id = $_POST['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,$dl) = mimetype($file['name']);
+ list($iext,$imime,$dl) = 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,
+ $_REQUEST['ow'], $auth, 'move_uploaded_file');
+ if (is_array($res)) {
+ msg($res[0], $res[1]);
+ return false;
+ }
+ return $res;
+}
+
+/**
+ * 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
+ *
+ * @triggers MEDIA_UPLOAD_FINISH
+ */
+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(create_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[0] = $file['name'];
+ $data[1] = $fn;
+ $data[2] = $id;
+ $data[3] = $file['mime'];
+ $data[4] = $overwrite;
+ $data[5] = $move;
+
+ // trigger event
+ return trigger_event('MEDIA_UPLOAD_FINISH', $data, '_media_upload_action', true);
+}
+
+/**
+ * Callback adapter for media_upload_finish()
+ * @author Michael Klier <chi@chimeric.de>
+ */
+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>
+ */
+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');
+
+ 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);
+ // add a log entry to the media changelog
+ if ($REV){
+ addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_REVERT, $lang['restored'], $REV);
+ } elseif ($overwrite) {
+ addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT);
+ } else {
+ addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created']);
+ }
+ 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;
+
+ if (!getRevisionInfo($id, $date, 8192, true)) {
+ // there was an external edit,
+ // there is no log entry for current version of file
+ if (!@file_exists(mediaMetaFN($id,'.changes'))) {
+ addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created']);
+ } else {
+ addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_EDIT);
+ }
+ }
+
+ $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?
+ */
+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;
+ }
+ }
+ }
+ if(substr($mime,0,6) == 'image/'){
+ $info = @getimagesize($file);
+ if($mime == 'image/gif' && $info[2] != 1){
+ return -1;
+ }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;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Send a notify mail on uploads
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function media_notify($id,$file,$mime,$old_rev=false){
+ global $lang;
+ global $conf;
+ global $INFO;
+ if(empty($conf['notify'])) return; //notify enabled?
+
+ $ip = clientIP();
+
+ $text = rawLocale('uploadmail');
+ $text = str_replace('@DATE@',dformat(),$text);
+ $text = str_replace('@BROWSER@',$_SERVER['HTTP_USER_AGENT'],$text);
+ $text = str_replace('@IPADDRESS@',$ip,$text);
+ $text = str_replace('@HOSTNAME@',gethostsbyaddrs($ip),$text);
+ $text = str_replace('@DOKUWIKIURL@',DOKU_URL,$text);
+ $text = str_replace('@USER@',$_SERVER['REMOTE_USER'],$text);
+ $text = str_replace('@MIME@',$mime,$text);
+ $text = str_replace('@MEDIA@',ml($id,'',true,'&',true),$text);
+ $text = str_replace('@SIZE@',filesize_h(filesize($file)),$text);
+ if ($old_rev && $conf['mediarevisions']) {
+ $text = str_replace('@OLD@', ml($id, "rev=$old_rev", true, '&', true), $text);
+ } else {
+ $text = str_replace('@OLD@', '', $text);
+ }
+
+ if(empty($conf['mailprefix'])) {
+ $subject = '['.$conf['title'].'] '.$lang['mail_upload'].' '.$id;
+ } else {
+ $subject = '['.$conf['mailprefix'].'] '.$lang['mail_upload'].' '.$id;
+ }
+
+ mail_send($conf['notify'],$subject,$text,$conf['mailfrom']);
+}
+
+/**
+ * List all files in a given Media namespace
+ */
+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);
+
+ $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;
+ }
+ }
+ if (!$fullscreenview) media_searchform($ns);
+}
+
+/**
+ * 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 $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($ext, $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, $NS;
+ $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 (isset($_REQUEST['q'])) {
+ $form->addHidden('q', $_REQUEST['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, $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'));
+}
+
+function _media_get_list_type() {
+ return _media_get_display_param('list', array('default' => 'thumbs', 'rows'));
+}
+
+function _media_get_display_param($param, $values) {
+ if (isset($_REQUEST[$param]) && in_array($_REQUEST[$param], $values)) {
+ // FIXME: Set cookie
+ return $_REQUEST[$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>
+ */
+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>
+ */
+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>
+ */
+function media_tab_search($ns,$auth=null) {
+ global $lang;
+
+ $do = $_REQUEST['mediado'];
+ $query = $_REQUEST['q'];
+ if (!$query) $query = '';
+ 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>
+ */
+function media_tab_view($image, $ns, $auth=null, $rev=false) {
+ global $lang, $conf;
+ 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>
+ */
+function media_tab_edit($image, $ns, $auth=null) {
+ global $lang;
+ if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
+
+ if ($image) {
+ list($ext, $mime) = mimetype($image);
+ if ($mime == 'image/jpeg') media_metaform($image,$auth);
+ }
+}
+
+/**
+ * Prints tab that displays mediafile revisions
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function media_tab_history($image, $ns, $auth=null) {
+ global $lang;
+ if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
+ $do = $_REQUEST['mediado'];
+
+ if ($auth >= AUTH_READ && $image) {
+ if ($do == 'diff'){
+ media_diff($image, $ns, $auth);
+ } else {
+ $first = isset($_REQUEST['first']) ? intval($_REQUEST['first']) : 0;
+ html_revisions($first, $image);
+ }
+ } else {
+ echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL;
+ }
+}
+
+/**
+ * Prints mediafile details
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function media_preview($image, $auth, $rev=false, $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>
+ */
+function media_preview_buttons($image, $auth, $rev=false) {
+ 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 $rev
+ * @param JpegMeta $meta
+ * @return array
+ */
+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
+ * @param JpegMeta $meta
+ * @param string $alt
+ * @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
+ */
+function media_file_tags($meta) {
+ global $config_cascade;
+
+ // 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(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>
+ */
+function media_details($image, $auth, $rev=false, $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;
+}
+
+/**
+ * Shows difference between two revisions of file
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function media_diff($image, $ns, $auth, $fromajax = false) {
+ global $lang;
+ global $conf;
+
+ if ($auth < AUTH_READ || !$image || !$conf['mediarevisions']) return '';
+
+ $rev1 = (int) $_REQUEST['rev'];
+
+ if(is_array($_REQUEST['rev2'])){
+ $rev1 = (int) $_REQUEST['rev2'][0];
+ $rev2 = (int) $_REQUEST['rev2'][1];
+
+ if(!$rev1){
+ $rev1 = $rev2;
+ unset($rev2);
+ }
+ }else{
+ $rev2 = (int) $_REQUEST['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 = '';
+ $revs = getRevisions($image, 0, 1, 8192, true);
+ if (file_exists(mediaFN($image, $revs[0]))) {
+ $l_rev = $revs[0];
+ } else {
+ $l_rev = '';
+ }
+ }
+
+ // prepare event data
+ $data[0] = $image;
+ $data[1] = $l_rev;
+ $data[2] = $r_rev;
+ $data[3] = $ns;
+ $data[4] = $auth;
+ $data[5] = $fromajax;
+
+ // trigger event
+ return trigger_event('MEDIA_DIFF', $data, '_media_file_diff', true);
+
+}
+
+function _media_file_diff($data) {
+ if(is_array($data) && count($data)===6) {
+ return 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>
+ */
+function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax){
+ global $lang, $config_cascade;
+
+ $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 = $_REQUEST['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
+ * @param int $l_rev
+ * @param int $r_rev
+ * @param array $l_size
+ * @param array $r_size
+ * @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
+ * @param int $rev
+ * @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($iext,$imime,$dl) = 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
+ */
+function media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort=''){
+ global $conf;
+ global $lang;
+
+ $ns = cleanID($ns);
+
+ if ($query) {
+ $evdata = array(
+ 'ns' => $ns,
+ 'data' => array(),
+ 'query' => $query
+ );
+ $evt = new Doku_Event('MEDIA_SEARCH', $evdata);
+ if ($evt->advise_before()) {
+ $dir = utf8_encodeFN(str_replace(':','/',$evdata['ns']));
+ $pattern = '/'.preg_quote($evdata['query'],'/').'/i';
+ search($evdata['data'],
+ $conf['mediadir'],
+ 'search_media',
+ array('showmsg'=>false,'pattern'=>$pattern),
+ $dir);
+ }
+
+ $data = array();
+ foreach ($evdata['data'] as $k => $v) {
+ $data[$k] = ($sort == 'date') ? $v['mtime'] : $v['id'];
+ }
+ array_multisort($data, SORT_DESC, SORT_NUMERIC, $evdata['data']);
+
+ $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
+ */
+function media_printfile($item,$auth,$jump,$display_namespace=false){
+ global $lang;
+ global $conf;
+
+ // 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,$mime,$dl) = 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 name="h_:'.$item['id'].'" class="'.$class.'">'.hsc($file).'</a> ';
+ } else {
+ echo '<a name="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;
+}
+
+function media_printicon($filename){
+ list($ext,$mime,$dl) = mimetype(mediaFN($filename),false);
+
+ if (@file_exists(DOKU_INC.'lib/images/fileicons/'.$ext.'.png')) {
+ $icon = DOKU_BASE.'lib/images/fileicons/'.$ext.'.png';
+ } else {
+ $icon = DOKU_BASE.'lib/images/fileicons/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>
+ */
+function media_printfile_thumbs($item,$auth,$jump=false,$display_namespace=false){
+ global $lang;
+ global $conf;
+
+ // 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 name="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']);
+ 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')).'" name="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">&nbsp;</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 metainfos
+ */
+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 name="l_:'.$item['id'].'" class="image thumb" href="'.
+ media_managerURL(array('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 name="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(utf8_strlen($d) > 250) $d = utf8_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>'.htmlspecialchars($t).'</strong><br />';
+ if($d) echo htmlspecialchars($d).'<br />';
+ if($t) echo '<em>'.htmlspecialchars($k).'</em>';
+ echo '</p>';
+ }
+ echo '</div>';
+}
+
+/**
+ * Build link based on the current, adding/rewriting
+ * parameters
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ * @param array $params
+ * @param string $amp - separator
+ * @return string - link
+ */
+function media_managerURL($params=false, $amp='&amp;', $abs=false, $params_array=false) {
+ global $conf;
+ global $ID;
+
+ $gets = array('do' => 'media');
+ $media_manager_params = array('tab_files', 'tab_details', 'image', 'ns', 'list', 'sort');
+ foreach ($media_manager_params as $x) {
+ if (isset($_REQUEST[$x])) $gets[$x] = $_REQUEST[$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>
+ */
+function media_uploadform($ns, $auth, $fullscreen = false){
+ global $lang, $conf;
+
+ 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 && $_REQUEST['mediado'] == 'update') {
+ $update = true;
+ $id = cleanID($_REQUEST['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;
+}
+
+/**
+ * Print the search field form
+ *
+ * @author Tobias Sarnowski <sarnowski@cosmocode.de>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+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');
+
+ if (!$fullscreen) $form->addElement('<div class="upload">' . $lang['mediasearch'] . '</div>'.NL);
+ $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>
+ */
+function media_nstree($ns){
+ global $conf;
+ global $lang;
+
+ // currently selected namespace
+ $ns = cleanID($ns);
+ if(empty($ns)){
+ global $ID;
+ $ns = dirname(str_replace(':','/',$ID));
+ if($ns == '.') $ns ='';
+ }
+ $ns = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $data = array();
+ search($data,$conf['mediadir'],'search_index',array('ns' => $ns, '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'].']'));
+
+ 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>
+ */
+function media_nstree_item($item){
+ $pos = strrpos($item['id'], ':');
+ $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0);
+ if(!$item['label']) $item['label'] = $label;
+
+ $ret = '';
+ if (!($_REQUEST['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>
+ */
+function media_nstree_li($item){
+ $class='media level'.$item['level'];
+ if($item['open']){
+ $class .= ' open';
+ $img = DOKU_BASE.'lib/images/minus.gif';
+ $alt = '&minus;';
+ }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>
+ */
+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]);
+
+ // we wont scale up to infinity
+ if($w > 2000 || $h > 2000) 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>
+ */
+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;
+ 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);
+}
+
+/**
+ * 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>
+ */
+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>
+ */
+function media_image_download($url,$file){
+ global $conf;
+ $http = new DokuHTTPClient();
+ $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>
+ */
+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>
+ */
+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>
+ */
+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
+ 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;
+
+ 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;
+}
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
diff --git a/inc/pageutils.php b/inc/pageutils.php
new file mode 100644
index 000000000..151fa5987
--- /dev/null
+++ b/inc/pageutils.php
@@ -0,0 +1,622 @@
+<?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()
+ */
+
+/**
+ * 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>
+ */
+function getID($param='id',$clean=true){
+ global $conf;
+
+ $id = isset($_REQUEST[$param]) ? $_REQUEST[$param] : null;
+
+ //construct page id from request URI
+ if(empty($id) && $conf['userewrite'] == 2){
+ $request = $_SERVER['REQUEST_URI'];
+ $script = '';
+
+ //get the script URL
+ if($conf['basedir']){
+ $relpath = '';
+ if($param != 'id') {
+ $relpath = 'lib/exe/';
+ }
+ $script = $conf['basedir'].$relpath.basename($_SERVER['SCRIPT_FILENAME']);
+
+ }elseif($_SERVER['PATH_INFO']){
+ $request = $_SERVER['PATH_INFO'];
+ }elseif($_SERVER['SCRIPT_NAME']){
+ $script = $_SERVER['SCRIPT_NAME'];
+ }elseif($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']){
+ $script = preg_replace ('/^'.preg_quote($_SERVER['DOCUMENT_ROOT'],'/').'/','',
+ $_SERVER['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'];
+ }
+ send_redirect(wl($id,'',true));
+ }
+
+ if($clean) $id = cleanID($id);
+ if(empty($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
+ * @param boolean $media DEPRECATED
+ */
+function cleanID($raw_id,$ascii=false,$media=false){
+ global $conf;
+ static $sepcharpat = null;
+
+ global $cache_cleanid;
+ $cache = & $cache_cleanid;
+
+ // check if it's already in the memory cache
+ if (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 = utf8_strtolower($id);
+
+ //alternative namespace seperator
+ $id = strtr($id,';',':');
+ if($conf['useslash']){
+ $id = strtr($id,'/',':');
+ }else{
+ $id = strtr($id,'/',$sepchar);
+ }
+
+ if($conf['deaccent'] == 2 || $ascii) $id = utf8_romanize($id);
+ if($conf['deaccent'] || $ascii) $id = utf8_deaccent($id,-1);
+
+ //remove specials
+ $id = utf8_stripspecials($id,$sepchar,'\*');
+
+ if($ascii) $id = utf8_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);
+
+ $cache[(string)$raw_id] = $id;
+ return($id);
+}
+
+/**
+ * Return namespacepart of a wiki ID
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+function noNSorNS($id) {
+ global $conf;
+
+ $p = noNS($id);
+ if ($p == $conf['start'] || $p == false) {
+ $p = curNS($id);
+ if ($p == false) {
+ return $conf['start'];
+ }
+ }
+ return $p;
+}
+
+/**
+ * Creates a XHTML valid linkid from a given headline title
+ *
+ * @param string $title The headline title
+ * @param array $check Existing IDs (title => number)
+ * @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>
+ */
+function page_exists($id,$rev='',$clean=true) {
+ 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 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.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function wikiFN($raw_id,$rev='',$clean=true){
+ global $conf;
+
+ global $cache_wikifn;
+ $cache = & $cache_wikifn;
+
+ if (isset($cache[$raw_id]) && isset($cache[$raw_id][$rev])) {
+ return $cache[$raw_id][$rev];
+ }
+
+ $id = $raw_id;
+
+ if ($clean) $id = cleanID($id);
+ $id = str_replace(':','/',$id);
+ 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[$raw_id])) { $cache[$raw_id] = array(); }
+ $cache[$raw_id][$rev] = $fn;
+ return $fn;
+}
+
+/**
+ * Returns the full path to the file for locking the page while editing.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+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>
+ */
+function mediaFN($id, $rev=''){
+ global $conf;
+ $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 textfile if local
+ * version isn't found the english one is returned
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function localeFN($id){
+ global $conf;
+ $file = DOKU_CONF.'/lang/'.$conf['lang'].'/'.$id.'.txt';
+ if(!@file_exists($file)){
+ $file = DOKU_INC.'inc/lang/'.$conf['lang'].'/'.$id.'.txt';
+ if(!@file_exists($file)){
+ //fall back to english
+ $file = DOKU_INC.'inc/lang/en/'.$id.'.txt';
+ }
+ }
+ 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://www.php.net/manual/en/function.realpath.php#57016
+ *
+ * @author <bart at mediawave dot nl>
+ */
+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{0} == '.'){
+ // normalize initial dots without a colon
+ $id = preg_replace('/^(\.+)(?=[^:\.])/','\1:',$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>
+ */
+function resolve_mediaid($ns,&$page,&$exists){
+ $page = resolve_id($ns,$page);
+ $file = mediaFN($page);
+ $exists = @file_exists($file);
+}
+
+/**
+ * Returns a full page id
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function resolve_pageid($ns,&$page,&$exists){
+ 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)
+ $file = wikiFN($page);
+
+ // 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'])){
+ // start page inside namespace
+ $page = $page.$conf['start'];
+ $exists = true;
+ }elseif(page_exists($page.noNS(cleanID($page)))){
+ // page named like the NS inside the NS
+ $page = $page.noNS(cleanID($page));
+ $exists = true;
+ }elseif(page_exists($page)){
+ // 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)){
+ $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>
+ */
+function isHiddenPage($id){
+ global $conf;
+ global $ACT;
+ if(empty($conf['hidepages'])) return false;
+ if($ACT == 'admin') return false;
+
+ if(preg_match('/'.$conf['hidepages'].'/ui',':'.$id)){
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Reverse of isHiddenPage
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+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>
+ */
+
+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
+ */
+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
+ */
+function utf8_decodeFN($file){
+ global $conf;
+ if($conf['fnencode'] == 'utf-8') return $file;
+
+ if($conf['fnencode'] == 'safe'){
+ return SafeFN::decode($file);
+ }
+
+ return urldecode($file);
+}
+
diff --git a/inc/parser/code.php b/inc/parser/code.php
new file mode 100644
index 000000000..4d94dcf4e
--- /dev/null
+++ b/inc/parser/code.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * A simple renderer that allows downloading of code and file snippets
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+if(!defined('DOKU_INC')) die('meh.');
+require_once DOKU_INC . 'inc/parser/renderer.php';
+
+class Doku_Renderer_code extends Doku_Renderer {
+ var $_codeblock=0;
+
+ /**
+ * Send the wanted code block to the browser
+ *
+ * When the correct block was found it exits the script.
+ */
+ function code($text, $language = NULL, $filename='' ) {
+ if(!$language) $language = 'txt';
+ if(!$filename) $filename = 'snippet.'.$language;
+ $filename = basename($filename);
+
+ if($this->_codeblock == $_REQUEST['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()
+ */
+ function file($text, $language = NULL, $filename='') {
+ $this->code($text, $language, $filename);
+ }
+
+ /**
+ * This should never be reached, if it is send a 404
+ */
+ function document_end() {
+ header("HTTP/1.0 404 Not Found");
+ echo '404 - Not found';
+ exit;
+ }
+
+ /**
+ * Return the format of the renderer
+ *
+ * @returns string 'code'
+ */
+ function getFormat(){
+ return 'code';
+ }
+}
diff --git a/inc/parser/handler.php b/inc/parser/handler.php
new file mode 100644
index 000000000..55b715ad9
--- /dev/null
+++ b/inc/parser/handler.php
@@ -0,0 +1,1623 @@
+<?php
+if(!defined('DOKU_INC')) die('meh.');
+if (!defined('DOKU_PARSER_EOL')) define('DOKU_PARSER_EOL',"\n"); // add this to make handling test cases simpler
+
+class Doku_Handler {
+
+ var $Renderer = NULL;
+
+ var $CallWriter = NULL;
+
+ var $calls = array();
+
+ var $status = array(
+ 'section' => false,
+ );
+
+ var $rewriteBlocks = true;
+
+ function Doku_Handler() {
+ $this->CallWriter = new Doku_Handler_CallWriter($this);
+ }
+
+ function _addCall($handler, $args, $pos) {
+ $call = array($handler,$args, $pos);
+ $this->CallWriter->writeCall($call);
+ }
+
+ function addPluginCall($plugin, $args, $state, $pos, $match) {
+ $call = array('plugin',array($plugin, $args, $state, $match), $pos);
+ $this->CallWriter->writeCall($call);
+ }
+
+ 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 Doku_Handler_Block();
+ $this->calls = $B->process($this->calls);
+ }
+
+ trigger_event('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]));
+ }
+
+ function fetch() {
+ $call = each($this->calls);
+ if ( $call ) {
+ return $call['value'];
+ }
+ return false;
+ }
+
+
+ /**
+ * Special plugin handler
+ *
+ * This handler is called for all modes starting with 'plugin_'.
+ * An additional parameter with the plugin name is passed
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function plugin($match, $state, $pos, $pluginname){
+ $data = array($match);
+ $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;
+ }
+
+ function base($match, $state, $pos) {
+ switch ( $state ) {
+ case DOKU_LEXER_UNMATCHED:
+ $this->_addCall('cdata',array($match), $pos);
+ return true;
+ break;
+ }
+ }
+
+ 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;
+ }
+
+ function notoc($match, $state, $pos) {
+ $this->_addCall('notoc',array(),$pos);
+ return true;
+ }
+
+ function nocache($match, $state, $pos) {
+ $this->_addCall('nocache',array(),$pos);
+ return true;
+ }
+
+ function linebreak($match, $state, $pos) {
+ $this->_addCall('linebreak',array(),$pos);
+ return true;
+ }
+
+ function eol($match, $state, $pos) {
+ $this->_addCall('eol',array(),$pos);
+ return true;
+ }
+
+ function hr($match, $state, $pos) {
+ $this->_addCall('hr',array(),$pos);
+ return true;
+ }
+
+ 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;
+ }
+ }
+
+ function strong($match, $state, $pos) {
+ $this->_nestingTag($match, $state, $pos, 'strong');
+ return true;
+ }
+
+ function emphasis($match, $state, $pos) {
+ $this->_nestingTag($match, $state, $pos, 'emphasis');
+ return true;
+ }
+
+ function underline($match, $state, $pos) {
+ $this->_nestingTag($match, $state, $pos, 'underline');
+ return true;
+ }
+
+ function monospace($match, $state, $pos) {
+ $this->_nestingTag($match, $state, $pos, 'monospace');
+ return true;
+ }
+
+ function subscript($match, $state, $pos) {
+ $this->_nestingTag($match, $state, $pos, 'subscript');
+ return true;
+ }
+
+ function superscript($match, $state, $pos) {
+ $this->_nestingTag($match, $state, $pos, 'superscript');
+ return true;
+ }
+
+ function deleted($match, $state, $pos) {
+ $this->_nestingTag($match, $state, $pos, 'deleted');
+ return true;
+ }
+
+
+ function footnote($match, $state, $pos) {
+// $this->_nestingTag($match, $state, $pos, 'footnote');
+ 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;
+
+ $ReWriter = new Doku_Handler_Nest($this->CallWriter,'footnote_close');
+ $this->CallWriter = & $ReWriter;
+ $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);
+ $this->CallWriter->process();
+ $ReWriter = & $this->CallWriter;
+ $this->CallWriter = & $ReWriter->CallWriter;
+ break;
+ case DOKU_LEXER_UNMATCHED:
+ $this->_addCall('cdata', array($match), $pos);
+ break;
+ }
+ return true;
+ }
+
+ function listblock($match, $state, $pos) {
+ switch ( $state ) {
+ case DOKU_LEXER_ENTER:
+ $ReWriter = new Doku_Handler_List($this->CallWriter);
+ $this->CallWriter = & $ReWriter;
+ $this->_addCall('list_open', array($match), $pos);
+ break;
+ case DOKU_LEXER_EXIT:
+ $this->_addCall('list_close', array(), $pos);
+ $this->CallWriter->process();
+ $ReWriter = & $this->CallWriter;
+ $this->CallWriter = & $ReWriter->CallWriter;
+ 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;
+ }
+
+ function unformatted($match, $state, $pos) {
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->_addCall('unformatted',array($match), $pos);
+ }
+ return true;
+ }
+
+ function php($match, $state, $pos) {
+ global $conf;
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->_addCall('php',array($match), $pos);
+ }
+ return true;
+ }
+
+ function phpblock($match, $state, $pos) {
+ global $conf;
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->_addCall('phpblock',array($match), $pos);
+ }
+ return true;
+ }
+
+ function html($match, $state, $pos) {
+ global $conf;
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->_addCall('html',array($match), $pos);
+ }
+ return true;
+ }
+
+ function htmlblock($match, $state, $pos) {
+ global $conf;
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->_addCall('htmlblock',array($match), $pos);
+ }
+ return true;
+ }
+
+ function preformatted($match, $state, $pos) {
+ switch ( $state ) {
+ case DOKU_LEXER_ENTER:
+ $ReWriter = new Doku_Handler_Preformatted($this->CallWriter);
+ $this->CallWriter = & $ReWriter;
+ $this->_addCall('preformatted_start',array(), $pos);
+ break;
+ case DOKU_LEXER_EXIT:
+ $this->_addCall('preformatted_end',array(), $pos);
+ $this->CallWriter->process();
+ $ReWriter = & $this->CallWriter;
+ $this->CallWriter = & $ReWriter->CallWriter;
+ 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;
+ }
+
+ function quote($match, $state, $pos) {
+
+ switch ( $state ) {
+
+ case DOKU_LEXER_ENTER:
+ $ReWriter = new Doku_Handler_Quote($this->CallWriter);
+ $this->CallWriter = & $ReWriter;
+ $this->_addCall('quote_start',array($match), $pos);
+ break;
+
+ case DOKU_LEXER_EXIT:
+ $this->_addCall('quote_end',array(), $pos);
+ $this->CallWriter->process();
+ $ReWriter = & $this->CallWriter;
+ $this->CallWriter = & $ReWriter->CallWriter;
+ 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;
+ }
+
+ function file($match, $state, $pos) {
+ return $this->code($match, $state, $pos, 'file');
+ }
+
+ function code($match, $state, $pos, $type='code') {
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $matches = explode('>',$match,2);
+
+ $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]);
+
+ $this->_addCall($type, $param, $pos);
+ }
+ return true;
+ }
+
+ function acronym($match, $state, $pos) {
+ $this->_addCall('acronym',array($match), $pos);
+ return true;
+ }
+
+ function smiley($match, $state, $pos) {
+ $this->_addCall('smiley',array($match), $pos);
+ return true;
+ }
+
+ function wordblock($match, $state, $pos) {
+ $this->_addCall('wordblock',array($match), $pos);
+ return true;
+ }
+
+ function entity($match, $state, $pos) {
+ $this->_addCall('entity',array($match), $pos);
+ return true;
+ }
+
+ function multiplyentity($match, $state, $pos) {
+ preg_match_all('/\d+/',$match,$matches);
+ $this->_addCall('multiplyentity',array($matches[0][0],$matches[0][1]), $pos);
+ return true;
+ }
+
+ function singlequoteopening($match, $state, $pos) {
+ $this->_addCall('singlequoteopening',array(), $pos);
+ return true;
+ }
+
+ function singlequoteclosing($match, $state, $pos) {
+ $this->_addCall('singlequoteclosing',array(), $pos);
+ return true;
+ }
+
+ function apostrophe($match, $state, $pos) {
+ $this->_addCall('apostrophe',array(), $pos);
+ return true;
+ }
+
+ function doublequoteopening($match, $state, $pos) {
+ $this->_addCall('doublequoteopening',array(), $pos);
+ return true;
+ }
+
+ function doublequoteclosing($match, $state, $pos) {
+ $this->_addCall('doublequoteclosing',array(), $pos);
+ return true;
+ }
+
+ function camelcaselink($match, $state, $pos) {
+ $this->_addCall('camelcaselink',array($match), $pos);
+ return true;
+ }
+
+ /*
+ */
+ 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 ( preg_match('/^[a-zA-Z0-9\.]+>{1}.*$/u',$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;
+ }
+
+ function filelink($match, $state, $pos) {
+ $this->_addCall('filelink',array($match, NULL), $pos);
+ return true;
+ }
+
+ function windowssharelink($match, $state, $pos) {
+ $this->_addCall('windowssharelink',array($match, NULL), $pos);
+ return true;
+ }
+
+ 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;
+ }
+
+ 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));
+
+ 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;
+ }
+
+ 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;
+ }
+
+ function emaillink($match, $state, $pos) {
+ $email = preg_replace(array('/^</','/>$/'),'',$match);
+ $this->_addCall('emaillink',array($email, NULL), $pos);
+ return true;
+ }
+
+ function table($match, $state, $pos) {
+ switch ( $state ) {
+
+ case DOKU_LEXER_ENTER:
+
+ $ReWriter = new Doku_Handler_Table($this->CallWriter);
+ $this->CallWriter = & $ReWriter;
+
+ $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);
+ $this->CallWriter->process();
+ $ReWriter = & $this->CallWriter;
+ $this->CallWriter = & $ReWriter->CallWriter;
+ 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;
+ }
+}
+
+//------------------------------------------------------------------------
+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)){
+ ($size[1]) ? $w = $size[1] : $w = NULL;
+ ($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
+ if ( preg_match('#^(https?|ftp)#i',$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;
+}
+
+//------------------------------------------------------------------------
+class Doku_Handler_CallWriter {
+
+ var $Handler;
+
+ function Doku_Handler_CallWriter(& $Handler) {
+ $this->Handler = & $Handler;
+ }
+
+ function writeCall($call) {
+ $this->Handler->calls[] = $call;
+ }
+
+ function writeCalls($calls) {
+ $this->Handler->calls = array_merge($this->Handler->calls, $calls);
+ }
+
+ // function is required, but since this call writer is first/highest in
+ // the chain it is not required to do anything
+ function finalise() {
+ unset($this->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 Doku_Handler_Nest {
+
+ var $CallWriter;
+ var $calls = array();
+
+ var $closingInstruction;
+
+ /**
+ * constructor
+ *
+ * @param object $CallWriter the renderers current call writer
+ * @param string $close closing instruction name, this is required to properly terminate the
+ * syntax mode if the document ends without a closing pattern
+ */
+ function Doku_Handler_Nest(& $CallWriter, $close="nest_close") {
+ $this->CallWriter = & $CallWriter;
+
+ $this->closingInstruction = $close;
+ }
+
+ function writeCall($call) {
+ $this->calls[] = $call;
+ }
+
+ function writeCalls($calls) {
+ $this->calls = array_merge($this->calls, $calls);
+ }
+
+ function finalise() {
+ $last_call = end($this->calls);
+ $this->writeCall(array($this->closingInstruction,array(), $last_call[2]));
+
+ $this->process();
+ $this->CallWriter->finalise();
+ unset($this->CallWriter);
+ }
+
+ 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]));
+ }
+
+ 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 if ($call[0] == 'eol') {
+ // do nothing (eol shouldn't be allowed, to counter preformatted fix in #1652 & #1699)
+ } else {
+ $this->calls[] = $call;
+ }
+ }
+}
+
+class Doku_Handler_List {
+
+ var $CallWriter;
+
+ var $calls = array();
+ var $listCalls = array();
+ var $listStack = array();
+
+ function Doku_Handler_List(& $CallWriter) {
+ $this->CallWriter = & $CallWriter;
+ }
+
+ function writeCall($call) {
+ $this->calls[] = $call;
+ }
+
+ // Probably not needed but just in case...
+ function writeCalls($calls) {
+ $this->calls = array_merge($this->calls, $calls);
+# $this->CallWriter->writeCalls($this->calls);
+ }
+
+ function finalise() {
+ $last_call = end($this->calls);
+ $this->writeCall(array('list_close',array(), $last_call[2]));
+
+ $this->process();
+ $this->CallWriter->finalise();
+ unset($this->CallWriter);
+ }
+
+ //------------------------------------------------------------------------
+ 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);
+ }
+
+ //------------------------------------------------------------------------
+ function listStart($call) {
+ $depth = $this->interpretSyntax($call[1][0], $listType);
+
+ $this->initialDepth = $depth;
+ $this->listStack[] = array($listType, $depth);
+
+ $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]);
+ }
+
+ //------------------------------------------------------------------------
+ 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]);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ function listOpen($call) {
+ $depth = $this->interpretSyntax($call[1][0], $listType);
+ $end = end($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]);
+
+ // 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);
+ }
+
+ //------------------------------------------------------------------------
+ // Getting deeper...
+ } else if ( $depth > $end[1] ) {
+
+ $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]);
+
+ $this->listStack[] = array($listType, $depth);
+
+ //------------------------------------------------------------------------
+ // Getting shallower ( $depth < $end[1] )
+ } 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]);
+
+ // Throw away the end - done
+ array_pop($this->listStack);
+
+ while (1) {
+ $end = end($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]);
+
+ } 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);
+ }
+
+ 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);
+
+ }
+
+ }
+
+ }
+ }
+
+ //------------------------------------------------------------------------
+ function listContent($call) {
+ $this->listCalls[] = $call;
+ }
+
+ //------------------------------------------------------------------------
+ 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;
+ }
+}
+
+//------------------------------------------------------------------------
+class Doku_Handler_Preformatted {
+
+ var $CallWriter;
+
+ var $calls = array();
+ var $pos;
+ var $text ='';
+
+
+
+ function Doku_Handler_Preformatted(& $CallWriter) {
+ $this->CallWriter = & $CallWriter;
+ }
+
+ function writeCall($call) {
+ $this->calls[] = $call;
+ }
+
+ // Probably not needed but just in case...
+ function writeCalls($calls) {
+ $this->calls = array_merge($this->calls, $calls);
+# $this->CallWriter->writeCalls($this->calls);
+ }
+
+ function finalise() {
+ $last_call = end($this->calls);
+ $this->writeCall(array('preformatted_end',array(), $last_call[2]));
+
+ $this->process();
+ $this->CallWriter->finalise();
+ unset($this->CallWriter);
+ }
+
+ 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;
+ }
+ }
+ }
+
+}
+
+//------------------------------------------------------------------------
+class Doku_Handler_Quote {
+
+ var $CallWriter;
+
+ var $calls = array();
+
+ var $quoteCalls = array();
+
+ function Doku_Handler_Quote(& $CallWriter) {
+ $this->CallWriter = & $CallWriter;
+ }
+
+ function writeCall($call) {
+ $this->calls[] = $call;
+ }
+
+ // Probably not needed but just in case...
+ function writeCalls($calls) {
+ $this->calls = array_merge($this->calls, $calls);
+ }
+
+ function finalise() {
+ $last_call = end($this->calls);
+ $this->writeCall(array('quote_end',array(), $last_call[2]));
+
+ $this->process();
+ $this->CallWriter->finalise();
+ unset($this->CallWriter);
+ }
+
+ function process() {
+
+ $quoteDepth = 1;
+
+ foreach ( $this->calls as $call ) {
+ switch ($call[0]) {
+
+ case 'quote_start':
+
+ $this->quoteCalls[] = array('quote_open',array(),$call[2]);
+
+ 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]);
+ }
+ } else if ( $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;
+ }
+ }
+ }
+
+ function getDepth($marker) {
+ preg_match('/>{1,}/', $marker, $matches);
+ $quoteLength = strlen($matches[0]);
+ return $quoteLength;
+ }
+}
+
+//------------------------------------------------------------------------
+class Doku_Handler_Table {
+
+ var $CallWriter;
+
+ var $calls = array();
+ var $tableCalls = array();
+ var $maxCols = 0;
+ var $maxRows = 1;
+ var $currentCols = 0;
+ var $firstCell = false;
+ var $lastCellType = 'tablecell';
+
+ function Doku_Handler_Table(& $CallWriter) {
+ $this->CallWriter = & $CallWriter;
+ }
+
+ function writeCall($call) {
+ $this->calls[] = $call;
+ }
+
+ // Probably not needed but just in case...
+ function writeCalls($calls) {
+ $this->calls = array_merge($this->calls, $calls);
+ }
+
+ function finalise() {
+ $last_call = end($this->calls);
+ $this->writeCall(array('table_end',array(), $last_call[2]));
+
+ $this->process();
+ $this->CallWriter->finalise();
+ unset($this->CallWriter);
+ }
+
+ //------------------------------------------------------------------------
+ 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);
+ }
+
+ function tableStart($call) {
+ $this->tableCalls[] = array('table_open',$call[1],$call[2]);
+ $this->tableCalls[] = array('tablerow_open',array(),$call[2]);
+ $this->firstCell = true;
+ }
+
+ function tableEnd($call) {
+ $this->tableCalls[] = array('table_close',$call[1],$call[2]);
+ $this->finalizeTable();
+ }
+
+ function tableRowOpen($call) {
+ $this->tableCalls[] = $call;
+ $this->currentCols = 0;
+ $this->firstCell = true;
+ $this->lastCellType = 'tablecell';
+ $this->maxRows++;
+ }
+
+ function tableRowClose($call) {
+ // 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;
+ }
+ }
+ $this->tableCalls[] = array('tablerow_close', array(), $call[2]);
+
+ if ( $this->currentCols > $this->maxCols ) {
+ $this->maxCols = $this->currentCols;
+ }
+ }
+
+ function tableCell($call) {
+ 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++;
+ }
+
+ function tableDefault($call) {
+ $this->tableCalls[] = $call;
+ }
+
+ 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();
+
+ // 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 '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;
+ 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->tableCells[$key][1][1] = '';
+ continue;
+ }
+ $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
+ while (++$lastCell < $this->maxCols) {
+ array_splice($this->tableCalls, $key, 0, array(
+ array('tablecell_open', array(1, null, 1), $call[2]),
+ array('cdata', array(''), $call[2]),
+ array('tablecell_close', array(), $call[2])));
+ $key += 3;
+ }
+
+ 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);
+ }
+}
+
+
+/**
+ * Handler for paragraphs
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+class Doku_Handler_Block {
+ var $calls = array();
+ var $skipEol = false;
+
+ // Blocks these should not be inside paragraphs
+ var $blockOpen = array(
+ 'header',
+ 'listu_open','listo_open','listitem_open','listcontent_open',
+ 'table_open','tablerow_open','tablecell_open','tableheader_open',
+ 'quote_open',
+ 'code','file','hr','preformatted','rss',
+ 'htmlblock','phpblock',
+ 'footnote_open',
+ );
+
+ var $blockClose = array(
+ 'header',
+ 'listu_close','listo_close','listitem_close','listcontent_close',
+ 'table_close','tablerow_close','tablecell_close','tableheader_close',
+ 'quote_close',
+ 'code','file','hr','preformatted','rss',
+ 'htmlblock','phpblock',
+ 'footnote_close',
+ );
+
+ // Stacks can contain paragraphs
+ var $stackOpen = array(
+ 'section_open',
+ );
+
+ var $stackClose = array(
+ 'section_close',
+ );
+
+
+ /**
+ * Constructor. Adds loaded syntax plugins to the block and stack
+ * arrays
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function Doku_Handler_Block(){
+ 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;
+ }
+ }
+ }
+
+ 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>
+ */
+ 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],DOKU_PARSER_EOL);
+ $this->calls[] = array('p_close',array(), $pos);
+ }
+
+ $this->inParagraph = false;
+ $this->skipEol = true;
+ }
+
+ 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
+ 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>
+ */
+ 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(DOKU_PARSER_EOL), $call[2]));
+ }
+ }
+ continue;
+ }
+ /* normal */
+ $this->addCall($call);
+ $this->skipEol = false;
+ }
+ // close last paragraph
+ $call = end($this->calls);
+ $this->closeParagraph($call[2]);
+ return $this->calls;
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/parser/lexer.php b/inc/parser/lexer.php
new file mode 100644
index 000000000..b5bcb9612
--- /dev/null
+++ b/inc/parser/lexer.php
@@ -0,0 +1,600 @@
+<?php
+/**
+* Author Markus Baker: http://www.lastcraft.com
+* Version adapted from Simple Test: http://sourceforge.net/projects/simpletest/
+* For an intro to the Lexer see:
+* http://www.phppatterns.com/index.php/article/articleview/106/1/2/
+* @author Marcus Baker
+* @package Doku
+* @subpackage Lexer
+* @version $Id: lexer.php,v 1.1 2005/03/23 23:14:09 harryf Exp $
+*/
+
+/**
+* Init path constant
+*/
+if(!defined('DOKU_INC')) die('meh.');
+
+/**#@+
+ * lexer mode constant
+ */
+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);
+/**#@-*/
+
+/**
+ * Compounded regular expression. Any of
+ * the contained patterns could match and
+ * when one does it's label is returned.
+ * @package Doku
+ * @subpackage Lexer
+ */
+class Doku_LexerParallelRegex {
+ var $_patterns;
+ var $_labels;
+ var $_regex;
+ var $_case;
+
+ /**
+ * Constructor. Starts with no patterns.
+ * @param boolean $case True for case sensitive, false
+ * for insensitive.
+ * @access public
+ */
+ function Doku_LexerParallelRegex($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 string $label Label of regex to be returned
+ * on a match. Label must be ASCII
+ * @access 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 boolean True on success.
+ * @access 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);
+ 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.
+ * @access public
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ 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.
+ * @param array $patterns List of patterns in order.
+ * @access private
+ */
+ 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.
+ * @access private
+ */
+ function _getPerlMatchingFlags() {
+ return ($this->_case ? "msS" : "msSi");
+ }
+}
+
+/**
+ * States for a stack machine.
+ * @package Lexer
+ * @subpackage Lexer
+ */
+class Doku_LexerStateStack {
+ var $_stack;
+
+ /**
+ * Constructor. Starts in named state.
+ * @param string $start Starting state name.
+ * @access public
+ */
+ function Doku_LexerStateStack($start) {
+ $this->_stack = array($start);
+ }
+
+ /**
+ * Accessor for current state.
+ * @return string State.
+ * @access 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.
+ * @access public
+ */
+ function enter($state) {
+ array_push($this->_stack, $state);
+ }
+
+ /**
+ * Leaves the current state and reverts
+ * to the previous one.
+ * @return boolean False if we drop off
+ * the bottom of the list.
+ * @access public
+ */
+ function leave() {
+ if (count($this->_stack) == 1) {
+ return false;
+ }
+ array_pop($this->_stack);
+ return true;
+ }
+}
+
+/**
+ * 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.
+ * @package Doku
+ * @subpackage Lexer
+ */
+class Doku_Lexer {
+ var $_regexes;
+ var $_parser;
+ var $_mode;
+ var $_mode_handlers;
+ var $_case;
+
+ /**
+ * Sets up the lexer in case insensitive matching
+ * by default.
+ * @param Doku_Parser $parser Handling strategy by
+ * reference.
+ * @param string $start Starting handler.
+ * @param boolean $case True for case sensitive.
+ * @access public
+ */
+ function Doku_Lexer(&$parser, $start = "accept", $case = false) {
+ $this->_case = $case;
+ $this->_regexes = array();
+ $this->_parser = &$parser;
+ $this->_mode = new Doku_LexerStateStack($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.
+ * @access public
+ */
+ function addPattern($pattern, $mode = "accept") {
+ if (! isset($this->_regexes[$mode])) {
+ $this->_regexes[$mode] = new Doku_LexerParallelRegex($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.
+ * @access public
+ */
+ function addEntryPattern($pattern, $mode, $new_mode) {
+ if (! isset($this->_regexes[$mode])) {
+ $this->_regexes[$mode] = new Doku_LexerParallelRegex($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.
+ * @access public
+ */
+ function addExitPattern($pattern, $mode) {
+ if (! isset($this->_regexes[$mode])) {
+ $this->_regexes[$mode] = new Doku_LexerParallelRegex($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.
+ * @access public
+ */
+ function addSpecialPattern($pattern, $mode, $special) {
+ if (! isset($this->_regexes[$mode])) {
+ $this->_regexes[$mode] = new Doku_LexerParallelRegex($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.
+ * @access 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.
+ * @access public
+ */
+ function parse($raw) {
+ if (! isset($this->_parser)) {
+ 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->_invokeParser($raw, DOKU_LEXER_UNMATCHED, $pos);
+ }
+
+ /**
+ * 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 string $mode Mode after match. A boolean
+ * false mode causes no change.
+ * @param int $pos Current byte index location in raw doc
+ * thats being parsed
+ * @return boolean False if there was any error
+ * from the parser.
+ * @access private
+ */
+ function _dispatchTokens($unmatched, $matched, $mode = false, $initialPos, $matchPos) {
+ if (! $this->_invokeParser($unmatched, DOKU_LEXER_UNMATCHED, $initialPos) ){
+ return false;
+ }
+ if ($this->_isModeEnd($mode)) {
+ if (! $this->_invokeParser($matched, DOKU_LEXER_EXIT, $matchPos)) {
+ return false;
+ }
+ return $this->_mode->leave();
+ }
+ if ($this->_isSpecialMode($mode)) {
+ $this->_mode->enter($this->_decodeSpecial($mode));
+ if (! $this->_invokeParser($matched, DOKU_LEXER_SPECIAL, $matchPos)) {
+ return false;
+ }
+ return $this->_mode->leave();
+ }
+ if (is_string($mode)) {
+ $this->_mode->enter($mode);
+ return $this->_invokeParser($matched, DOKU_LEXER_ENTER, $matchPos);
+ }
+ return $this->_invokeParser($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.
+ * @access private
+ */
+ 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.
+ * @access private
+ */
+ 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.
+ * @access private
+ */
+ 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
+ * @access private
+ */
+ function _invokeParser($content, $is_match, $pos) {
+ if (($content === "") || ($content === false)) {
+ return true;
+ }
+ $handler = $this->_mode->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->_parser->$handler($content, $is_match, $pos, $plugin);
+ }
+
+ return $this->_parser->$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 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.
+ * @access private
+ */
+ function _reduce(&$raw) {
+ if (! isset($this->_regexes[$this->_mode->getCurrent()])) {
+ return false;
+ }
+ if ($raw === "") {
+ return true;
+ }
+ if ($action = $this->_regexes[$this->_mode->getCurrent()]->split($raw, $split)) {
+ list($unparsed, $match, $raw) = $split;
+ return array($unparsed, $match, $action);
+ }
+ return true;
+ }
+}
+
+/**
+* Escapes regex characters other than (, ) and /
+* @TODO
+*/
+function Doku_Lexer_Escape($str) {
+ //$str = addslashes($str);
+ $chars = array(
+ '/\\\\/',
+ '/\./',
+ '/\+/',
+ '/\*/',
+ '/\?/',
+ '/\[/',
+ '/\^/',
+ '/\]/',
+ '/\$/',
+ '/\{/',
+ '/\}/',
+ '/\=/',
+ '/\!/',
+ '/\</',
+ '/\>/',
+ '/\|/',
+ '/\:/'
+ );
+
+ $escaped = array(
+ '\\\\\\\\',
+ '\.',
+ '\+',
+ '\*',
+ '\?',
+ '\[',
+ '\^',
+ '\]',
+ '\$',
+ '\{',
+ '\}',
+ '\=',
+ '\!',
+ '\<',
+ '\>',
+ '\|',
+ '\:'
+ );
+ return preg_replace($chars, $escaped, $str);
+}
+
+//Setup VIM: ex: et ts=4 sw=4 :
diff --git a/inc/parser/metadata.php b/inc/parser/metadata.php
new file mode 100644
index 000000000..136c37531
--- /dev/null
+++ b/inc/parser/metadata.php
@@ -0,0 +1,485 @@
+<?php
+/**
+ * Renderer for metadata
+ *
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+if(!defined('DOKU_INC')) die('meh.');
+
+if ( !defined('DOKU_LF') ) {
+ // Some whitespace to help View > Source
+ define ('DOKU_LF',"\n");
+}
+
+if ( !defined('DOKU_TAB') ) {
+ // Some whitespace to help View > Source
+ define ('DOKU_TAB',"\t");
+}
+
+require_once DOKU_INC . 'inc/parser/renderer.php';
+
+/**
+ * The Renderer
+ */
+class Doku_Renderer_metadata extends Doku_Renderer {
+
+ var $doc = '';
+ var $meta = array();
+ var $persistent = array();
+
+ var $headers = array();
+ var $capture = true;
+ var $store = '';
+ var $firstimage = '';
+
+ function getFormat(){
+ return 'metadata';
+ }
+
+ function document_start(){
+ global $ID;
+
+ $this->headers = array();
+
+ // external pages are missing create date
+ if(!$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;
+ }
+
+ 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) > 500)
+ $this->doc = utf8_substr($this->doc, 0, 500).'…';
+ $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));
+ }
+
+ }
+
+ 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
+ );
+ }
+
+ }
+
+ 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
+ if ($this->capture && ($level > 1)) $this->doc .= DOKU_LF.$text.DOKU_LF;
+ }
+
+ function section_open($level){}
+ function section_close(){}
+
+ function cdata($text){
+ if ($this->capture) $this->doc .= $text;
+ }
+
+ function p_open(){
+ if ($this->capture) $this->doc .= DOKU_LF;
+ }
+
+ function p_close(){
+ if ($this->capture){
+ if (strlen($this->doc) > 250) $this->capture = false;
+ else $this->doc .= DOKU_LF;
+ }
+ }
+
+ function linebreak(){
+ if ($this->capture) $this->doc .= DOKU_LF;
+ }
+
+ function hr(){
+ if ($this->capture){
+ if (strlen($this->doc) > 250) $this->capture = false;
+ else $this->doc .= DOKU_LF.'----------'.DOKU_LF;
+ }
+ }
+
+ function strong_open(){}
+ function strong_close(){}
+
+ function emphasis_open(){}
+ function emphasis_close(){}
+
+ function underline_open(){}
+ function underline_close(){}
+
+ function monospace_open(){}
+ function monospace_close(){}
+
+ function subscript_open(){}
+ function subscript_close(){}
+
+ function superscript_open(){}
+ function superscript_close(){}
+
+ function deleted_open(){}
+ function deleted_close(){}
+
+ /**
+ * 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>
+ */
+ function footnote_open() {
+ if ($this->capture){
+ // 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
+ */
+ function footnote_close() {
+ if ($this->capture){
+ // restore old content
+ $this->doc = $this->store;
+ $this->store = '';
+ }
+ }
+
+ function listu_open(){
+ if ($this->capture) $this->doc .= DOKU_LF;
+ }
+
+ function listu_close(){
+ if ($this->capture && (strlen($this->doc) > 250)) $this->capture = false;
+ }
+
+ function listo_open(){
+ if ($this->capture) $this->doc .= DOKU_LF;
+ }
+
+ function listo_close(){
+ if ($this->capture && (strlen($this->doc) > 250)) $this->capture = false;
+ }
+
+ function listitem_open($level){
+ if ($this->capture) $this->doc .= str_repeat(DOKU_TAB, $level).'* ';
+ }
+
+ function listitem_close(){
+ if ($this->capture) $this->doc .= DOKU_LF;
+ }
+
+ function listcontent_open(){}
+ function listcontent_close(){}
+
+ function unformatted($text){
+ if ($this->capture) $this->doc .= $text;
+ }
+
+ function php($text){}
+
+ function phpblock($text){}
+
+ function html($text){}
+
+ function htmlblock($text){}
+
+ function preformatted($text){
+ if ($this->capture) $this->doc .= $text;
+ }
+
+ function file($text, $lang = null, $file = null){
+ if ($this->capture){
+ $this->doc .= DOKU_LF.$text;
+ if (strlen($this->doc) > 250) $this->capture = false;
+ else $this->doc .= DOKU_LF;
+ }
+ }
+
+ function quote_open(){
+ if ($this->capture) $this->doc .= DOKU_LF.DOKU_TAB.'"';
+ }
+
+ function quote_close(){
+ if ($this->capture){
+ $this->doc .= '"';
+ if (strlen($this->doc) > 250) $this->capture = false;
+ else $this->doc .= DOKU_LF;
+ }
+ }
+
+ function code($text, $language = NULL, $file = null){
+ if ($this->capture){
+ $this->doc .= DOKU_LF.$text;
+ if (strlen($this->doc) > 250) $this->capture = false;
+ else $this->doc .= DOKU_LF;
+ }
+ }
+
+ function acronym($acronym){
+ if ($this->capture) $this->doc .= $acronym;
+ }
+
+ function smiley($smiley){
+ if ($this->capture) $this->doc .= $smiley;
+ }
+
+ function entity($entity){
+ if ($this->capture) $this->doc .= $entity;
+ }
+
+ function multiplyentity($x, $y){
+ if ($this->capture) $this->doc .= $x.'×'.$y;
+ }
+
+ function singlequoteopening(){
+ global $lang;
+ if ($this->capture) $this->doc .= $lang['singlequoteopening'];
+ }
+
+ function singlequoteclosing(){
+ global $lang;
+ if ($this->capture) $this->doc .= $lang['singlequoteclosing'];
+ }
+
+ function apostrophe() {
+ global $lang;
+ if ($this->capture) $this->doc .= $lang['apostrophe'];
+ }
+
+ function doublequoteopening(){
+ global $lang;
+ if ($this->capture) $this->doc .= $lang['doublequoteopening'];
+ }
+
+ function doublequoteclosing(){
+ global $lang;
+ if ($this->capture) $this->doc .= $lang['doublequoteclosing'];
+ }
+
+ function camelcaselink($link) {
+ $this->internallink($link, $link);
+ }
+
+ function locallink($hash, $name = NULL){}
+
+ /**
+ * keep track of internal links in $this->meta['relation']['references']
+ */
+ function internallink($id, $name = NULL){
+ global $ID;
+
+ if(is_array($name))
+ $this->_firstimage($name['src']);
+
+ $default = $this->_simpleTitle($id);
+
+ // first resolve and clean up the $id
+ resolve_pageid(getNS($ID), $id, $exists);
+ list($page, $hash) = 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;
+ }
+ }
+
+ function externallink($url, $name = NULL){
+ if(is_array($name))
+ $this->_firstimage($name['src']);
+
+ if ($this->capture){
+ $this->doc .= $this->_getLinkTitle($name, '<' . $url . '>');
+ }
+ }
+
+ function interwikilink($match, $name = NULL, $wikiName, $wikiUri){
+ if(is_array($name))
+ $this->_firstimage($name['src']);
+
+ if ($this->capture){
+ list($wikiUri, $hash) = explode('#', $wikiUri, 2);
+ $name = $this->_getLinkTitle($name, $wikiUri);
+ $this->doc .= $name;
+ }
+ }
+
+ function windowssharelink($url, $name = NULL){
+ if(is_array($name))
+ $this->_firstimage($name['src']);
+
+ if ($this->capture){
+ if ($name) $this->doc .= $name;
+ else $this->doc .= '<'.$url.'>';
+ }
+ }
+
+ function emaillink($address, $name = NULL){
+ if(is_array($name))
+ $this->_firstimage($name['src']);
+
+ if ($this->capture){
+ if ($name) $this->doc .= $name;
+ else $this->doc .= '<'.$address.'>';
+ }
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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'];
+ }
+
+ function table_open($maxcols = NULL, $numrows = NULL){}
+ function table_close(){}
+
+ function tablerow_open(){}
+ function tablerow_close(){}
+
+ function tableheader_open($colspan = 1, $align = NULL, $rowspan = 1){}
+ function tableheader_close(){}
+
+ function tablecell_open($colspan = 1, $align = NULL, $rowspan = 1){}
+ function tablecell_close(){}
+
+ //----------------------------------------------------------
+ // Utils
+
+ /**
+ * Removes any Namespace from the given name but keeps
+ * casing and special chars
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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;
+ }
+
+ /**
+ * Creates a linkid from a headline
+ *
+ * @param string $title The headline title
+ * @param boolean $create Create a new unique ID?
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _headerToLink($title, $create=false) {
+ if($create){
+ return sectionID($title,$this->headers);
+ }else{
+ $check = false;
+ return sectionID($title,$check);
+ }
+ }
+
+ /**
+ * Construct a title and handle images in titles
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+ function _getLinkTitle($title, $default, $id=NULL) {
+ global $conf;
+
+ $isImage = false;
+ if (is_null($title)){
+ if (useHeading('content') && $id){
+ $heading = p_get_first_heading($id,METADATA_DONT_RENDER);
+ if ($heading) return $heading;
+ }
+ return $default;
+ } else if (is_string($title)){
+ return $title;
+ } else if (is_array($title)){
+ if($title['title']) return '['.$title['title'].']';
+ }
+ }
+
+ function _firstimage($src){
+ if($this->firstimage) return;
+ global $ID;
+
+ list($src,$hash) = explode('#',$src,2);
+ if(!preg_match('/^https?:\/\//i',$src)){
+ resolve_mediaid(getNS($ID),$src, $exists);
+ }
+ if(preg_match('/.(jpe?g|gif|png)$/i',$src)){
+ $this->firstimage = $src;
+ }
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/parser/parser.php b/inc/parser/parser.php
new file mode 100644
index 000000000..68d4e4569
--- /dev/null
+++ b/inc/parser/parser.php
@@ -0,0 +1,959 @@
+<?php
+if(!defined('DOKU_INC')) die('meh.');
+require_once DOKU_INC . 'inc/parser/lexer.php';
+require_once DOKU_INC . 'inc/parser/handler.php';
+
+
+/**
+ * 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')
+);
+
+//-------------------------------------------------------------------
+
+/**
+* Sets up the Lexer with modes and points it to the Handler
+* For an intro to the Lexer see: wiki:parser
+*/
+class Doku_Parser {
+
+ var $Handler;
+
+ var $Lexer;
+
+ var $modes = array();
+
+ var $connected = false;
+
+ function addBaseMode(& $BaseMode) {
+ $this->modes['base'] = & $BaseMode;
+ if ( !$this->Lexer ) {
+ $this->Lexer = new Doku_Lexer($this->Handler,'base', true);
+ }
+ $this->modes['base']->Lexer = & $this->Lexer;
+ }
+
+ /**
+ * PHP preserves order of associative elements
+ * Mode sequence is important
+ */
+ function addMode($name, & $Mode) {
+ if ( !isset($this->modes['base']) ) {
+ $this->addBaseMode(new Doku_Parser_Mode_base());
+ }
+ $Mode->Lexer = & $this->Lexer;
+ $this->modes[$name] = & $Mode;
+ }
+
+ 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;
+ }
+
+ function parse($doc) {
+ if ( $this->Lexer ) {
+ $this->connectModes();
+ // Normalize CRs and pad doc
+ $doc = "\n".str_replace("\r\n","\n",$doc)."\n";
+ $this->Lexer->parse($doc);
+ $this->Handler->_finalize();
+ return $this->Handler->calls;
+ } else {
+ return false;
+ }
+ }
+
+}
+
+//-------------------------------------------------------------------
+/**
+ * This class and all the subclasses below are
+ * used to reduce the effort required to register
+ * modes with the Lexer. For performance these
+ * could all be eliminated later perhaps, or
+ * the Parser could be serialized to a file once
+ * all modes are registered
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+*/
+class Doku_Parser_Mode {
+
+ var $Lexer;
+
+ var $allowedModes = array();
+
+ // returns a number used to determine in which order modes are added
+ function getSort() {
+ trigger_error('getSort() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ // Called before any calls to connectTo
+ function preConnect() {}
+
+ // Connects the mode
+ function connectTo($mode) {}
+
+ // Called after all calls to connectTo
+ function postConnect() {}
+
+ function accepts($mode) {
+ return in_array($mode, (array) $this->allowedModes );
+ }
+
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_base extends Doku_Parser_Mode {
+
+ function Doku_Parser_Mode_base() {
+ 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']
+ );
+ }
+
+ function getSort() {
+ return 0;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_footnote extends Doku_Parser_Mode {
+
+ function Doku_Parser_Mode_footnote() {
+ 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)]);
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern(
+ '\x28\x28(?=.*\x29\x29)',$mode,'footnote'
+ );
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern(
+ '\x29\x29','footnote'
+ );
+ }
+
+ function getSort() {
+ return 150;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_header extends Doku_Parser_Mode {
+
+ 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'
+ );
+ }
+
+ function getSort() {
+ return 50;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_notoc extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('~~NOTOC~~',$mode,'notoc');
+ }
+
+ function getSort() {
+ return 30;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_nocache extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('~~NOCACHE~~',$mode,'nocache');
+ }
+
+ function getSort() {
+ return 40;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_linebreak extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('\x5C{2}(?:[ \t]|(?=\n))',$mode,'linebreak');
+ }
+
+ function getSort() {
+ return 140;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_eol extends Doku_Parser_Mode {
+
+ 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');
+ }
+
+ function getSort() {
+ return 370;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_hr extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('\n[ \t]*-{4,}[ \t]*(?=\n)',$mode,'hr');
+ }
+
+ function getSort() {
+ return 160;
+ }
+}
+
+//-------------------------------------------------------------------
+/**
+ * This class sets the markup for bold (=strong),
+ * italic (=emphasis), underline etc.
+ */
+class Doku_Parser_Mode_formatting extends Doku_Parser_Mode {
+ var $type;
+
+ var $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
+ ),
+ );
+
+ function Doku_Parser_Mode_formatting($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']
+ );
+ }
+
+ 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
+ );
+ }
+
+ function postConnect() {
+
+ $this->Lexer->addExitPattern(
+ $this->formatting[$this->type]['exit'],
+ $this->type
+ );
+
+ }
+
+ function getSort() {
+ return $this->formatting[$this->type]['sort'];
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_listblock extends Doku_Parser_Mode {
+
+ function Doku_Parser_Mode_listblock() {
+ global $PARSER_MODES;
+
+ $this->allowedModes = array_merge (
+ $PARSER_MODES['formatting'],
+ $PARSER_MODES['substition'],
+ $PARSER_MODES['disabled'],
+ $PARSER_MODES['protected'] #XXX new
+ );
+
+ // $this->allowedModes[] = 'footnote';
+ }
+
+ 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');
+
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern('\n','listblock');
+ }
+
+ function getSort() {
+ return 10;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_table extends Doku_Parser_Mode {
+
+ function Doku_Parser_Mode_table() {
+ global $PARSER_MODES;
+
+ $this->allowedModes = array_merge (
+ $PARSER_MODES['formatting'],
+ $PARSER_MODES['substition'],
+ $PARSER_MODES['disabled'],
+ $PARSER_MODES['protected']
+ );
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern('\n\^',$mode,'table');
+ $this->Lexer->addEntryPattern('\n\|',$mode,'table');
+ }
+
+ 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');
+ }
+
+ function getSort() {
+ return 60;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_unformatted extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern('<nowiki>(?=.*</nowiki>)',$mode,'unformatted');
+ $this->Lexer->addEntryPattern('%%(?=.*%%)',$mode,'unformattedalt');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern('</nowiki>','unformatted');
+ $this->Lexer->addExitPattern('%%','unformattedalt');
+ $this->Lexer->mapHandler('unformattedalt','unformatted');
+ }
+
+ function getSort() {
+ return 170;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_php extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern('<php>(?=.*</php>)',$mode,'php');
+ $this->Lexer->addEntryPattern('<PHP>(?=.*</PHP>)',$mode,'phpblock');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern('</php>','php');
+ $this->Lexer->addExitPattern('</PHP>','phpblock');
+ }
+
+ function getSort() {
+ return 180;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_html extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern('<html>(?=.*</html>)',$mode,'html');
+ $this->Lexer->addEntryPattern('<HTML>(?=.*</HTML>)',$mode,'htmlblock');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern('</html>','html');
+ $this->Lexer->addExitPattern('</HTML>','htmlblock');
+ }
+
+ function getSort() {
+ return 190;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_preformatted extends Doku_Parser_Mode {
+
+ 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');
+
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern('\n','preformatted');
+ }
+
+ function getSort() {
+ return 20;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_code extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern('<code(?=.*</code>)',$mode,'code');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern('</code>','code');
+ }
+
+ function getSort() {
+ return 200;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_file extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern('<file(?=.*</file>)',$mode,'file');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern('</file>','file');
+ }
+
+ function getSort() {
+ return 210;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_quote extends Doku_Parser_Mode {
+
+ function Doku_Parser_Mode_quote() {
+ global $PARSER_MODES;
+
+ $this->allowedModes = array_merge (
+ $PARSER_MODES['formatting'],
+ $PARSER_MODES['substition'],
+ $PARSER_MODES['disabled'],
+ $PARSER_MODES['protected'] #XXX new
+ );
+ #$this->allowedModes[] = 'footnote';
+ #$this->allowedModes[] = 'preformatted';
+ #$this->allowedModes[] = 'unformatted';
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern('\n>{1,}',$mode,'quote');
+ }
+
+ function postConnect() {
+ $this->Lexer->addPattern('\n>{1,}','quote');
+ $this->Lexer->addExitPattern('\n','quote');
+ }
+
+ function getSort() {
+ return 220;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_acronym extends Doku_Parser_Mode {
+ // A list
+ var $acronyms = array();
+ var $pattern = '';
+
+ function Doku_Parser_Mode_acronym($acronyms) {
+ usort($acronyms,array($this,'_compare'));
+ $this->acronyms = $acronyms;
+ }
+
+ function preConnect() {
+ if(!count($this->acronyms)) return;
+
+ $bound = '[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]';
+ $acronyms = array_map('Doku_Lexer_Escape',$this->acronyms);
+ $this->pattern = '(?<=^|'.$bound.')(?:'.join('|',$acronyms).')(?='.$bound.')';
+ }
+
+ function connectTo($mode) {
+ if(!count($this->acronyms)) return;
+
+ if ( strlen($this->pattern) > 0 ) {
+ $this->Lexer->addSpecialPattern($this->pattern,$mode,'acronym');
+ }
+ }
+
+ function getSort() {
+ return 240;
+ }
+
+ /**
+ * sort callback to order by string length descending
+ */
+ function _compare($a,$b) {
+ $a_len = strlen($a);
+ $b_len = strlen($b);
+ if ($a_len > $b_len) {
+ return -1;
+ } else if ($a_len < $b_len) {
+ return 1;
+ }
+
+ return 0;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_smiley extends Doku_Parser_Mode {
+ // A list
+ var $smileys = array();
+ var $pattern = '';
+
+ function Doku_Parser_Mode_smiley($smileys) {
+ $this->smileys = $smileys;
+ }
+
+ function preConnect() {
+ if(!count($this->smileys) || $this->pattern != '') return;
+
+ $sep = '';
+ foreach ( $this->smileys as $smiley ) {
+ $this->pattern .= $sep.'(?<=\W|^)'.Doku_Lexer_Escape($smiley).'(?=\W|$)';
+ $sep = '|';
+ }
+ }
+
+ function connectTo($mode) {
+ if(!count($this->smileys)) return;
+
+ if ( strlen($this->pattern) > 0 ) {
+ $this->Lexer->addSpecialPattern($this->pattern,$mode,'smiley');
+ }
+ }
+
+ function getSort() {
+ return 230;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_wordblock extends Doku_Parser_Mode {
+ // A list
+ var $badwords = array();
+ var $pattern = '';
+
+ function Doku_Parser_Mode_wordblock($badwords) {
+ $this->badwords = $badwords;
+ }
+
+ function preConnect() {
+
+ if ( count($this->badwords) == 0 || $this->pattern != '') {
+ return;
+ }
+
+ $sep = '';
+ foreach ( $this->badwords as $badword ) {
+ $this->pattern .= $sep.'(?<=\b)(?i)'.Doku_Lexer_Escape($badword).'(?-i)(?=\b)';
+ $sep = '|';
+ }
+
+ }
+
+ function connectTo($mode) {
+ if ( strlen($this->pattern) > 0 ) {
+ $this->Lexer->addSpecialPattern($this->pattern,$mode,'wordblock');
+ }
+ }
+
+ function getSort() {
+ return 250;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_entity extends Doku_Parser_Mode {
+ // A list
+ var $entities = array();
+ var $pattern = '';
+
+ function Doku_Parser_Mode_entity($entities) {
+ $this->entities = $entities;
+ }
+
+ function preConnect() {
+ if(!count($this->entities) || $this->pattern != '') return;
+
+ $sep = '';
+ foreach ( $this->entities as $entity ) {
+ $this->pattern .= $sep.Doku_Lexer_Escape($entity);
+ $sep = '|';
+ }
+ }
+
+ function connectTo($mode) {
+ if(!count($this->entities)) return;
+
+ if ( strlen($this->pattern) > 0 ) {
+ $this->Lexer->addSpecialPattern($this->pattern,$mode,'entity');
+ }
+ }
+
+ function getSort() {
+ return 260;
+ }
+}
+
+//-------------------------------------------------------------------
+// Implements the 640x480 replacement
+class Doku_Parser_Mode_multiplyentity extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+
+ $this->Lexer->addSpecialPattern(
+ '(?<=\b)(?:[1-9]|\d{2,})[xX]\d+(?=\b)',$mode,'multiplyentity'
+ );
+
+ }
+
+ function getSort() {
+ return 270;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_quotes extends Doku_Parser_Mode {
+
+ 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'
+ );
+
+
+ }
+
+ function getSort() {
+ return 280;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_camelcaselink extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '\b[A-Z]+[a-z]+[A-Z][A-Za-z]*\b',$mode,'camelcaselink'
+ );
+ }
+
+ function getSort() {
+ return 290;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_internallink extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ // Word boundaries?
+ $this->Lexer->addSpecialPattern("\[\[(?:(?:[^[\]]*?\[.*?\])|.*?)\]\]",$mode,'internallink');
+ }
+
+ function getSort() {
+ return 300;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_media extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ // Word boundaries?
+ $this->Lexer->addSpecialPattern("\{\{[^\}]+\}\}",$mode,'media');
+ }
+
+ function getSort() {
+ return 320;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_rss extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern("\{\{rss>[^\}]+\}\}",$mode,'rss');
+ }
+
+ function getSort() {
+ return 310;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_externallink extends Doku_Parser_Mode {
+ var $schemes = array();
+ var $patterns = array();
+
+ 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[] = '\b(?i)www?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
+ $this->patterns[] = '\b(?i)ftp?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
+ }
+
+ function connectTo($mode) {
+
+ foreach ( $this->patterns as $pattern ) {
+ $this->Lexer->addSpecialPattern($pattern,$mode,'externallink');
+ }
+ }
+
+ function getSort() {
+ return 330;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_filelink extends Doku_Parser_Mode {
+
+ var $pattern;
+
+ function preConnect() {
+
+ $ltrs = '\w';
+ $gunk = '/\#~:.?+=&%@!\-';
+ $punc = '.:?\-;,';
+ $host = $ltrs.$punc;
+ $any = $ltrs.$gunk.$punc;
+
+ $this->pattern = '\b(?i)file(?-i)://['.$any.']+?['.
+ $punc.']*[^'.$any.']';
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ $this->pattern,$mode,'filelink');
+ }
+
+ function getSort() {
+ return 360;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_windowssharelink extends Doku_Parser_Mode {
+
+ var $pattern;
+
+ function preConnect() {
+ $this->pattern = "\\\\\\\\\w+?(?:\\\\[\w$]+)+";
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ $this->pattern,$mode,'windowssharelink');
+ }
+
+ function getSort() {
+ return 350;
+ }
+}
+
+//-------------------------------------------------------------------
+class Doku_Parser_Mode_emaillink extends Doku_Parser_Mode {
+
+ function connectTo($mode) {
+ // pattern below is defined in inc/mail.php
+ $this->Lexer->addSpecialPattern('<'.PREG_PATTERN_VALID_EMAIL.'>',$mode,'emaillink');
+ }
+
+ function getSort() {
+ return 340;
+ }
+}
+
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/parser/renderer.php b/inc/parser/renderer.php
new file mode 100644
index 000000000..7002fd0cb
--- /dev/null
+++ b/inc/parser/renderer.php
@@ -0,0 +1,322 @@
+<?php
+/**
+ * Renderer output base class
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+if(!defined('DOKU_INC')) die('meh.');
+require_once DOKU_INC . 'inc/plugin.php';
+require_once DOKU_INC . 'inc/pluginutils.php';
+
+/**
+ * An empty renderer, produces no output
+ *
+ * Inherits from DokuWiki_Plugin for giving additional functions to render plugins
+ */
+class Doku_Renderer extends DokuWiki_Plugin {
+ var $info = array(
+ 'cache' => true, // may the rendered result cached?
+ 'toc' => true, // render the TOC?
+ );
+
+ // keep some config options
+ var $acronyms = array();
+ var $smileys = array();
+ var $badwords = array();
+ var $entities = array();
+ var $interwiki = array();
+
+ // allows renderer to be used again, clean out any per-use values
+ function reset() {
+ }
+
+ function nocache() {
+ $this->info['cache'] = false;
+ }
+
+ function notoc() {
+ $this->info['toc'] = false;
+ }
+
+ /**
+ * Returns the format produced by this renderer.
+ *
+ * Has to be overidden by decendend classes
+ */
+ function getFormat(){
+ trigger_error('getFormat() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ /**
+ * Allow the plugin to prevent DokuWiki from reusing an instance
+ *
+ * @return bool false if the plugin has to be instantiated
+ */
+ function isSingleton() {
+ return false;
+ }
+
+
+ //handle plugin rendering
+ function plugin($name,$data){
+ $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
+ */
+ 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]);
+ }
+ }
+ }
+
+ // 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.
+ function nest_close() {}
+
+ function document_start() {}
+
+ function document_end() {}
+
+ function render_TOC() { return ''; }
+
+ function toc_additem($id, $text, $level) {}
+
+ function header($text, $level, $pos) {}
+
+ function section_open($level) {}
+
+ function section_close() {}
+
+ function cdata($text) {}
+
+ function p_open() {}
+
+ function p_close() {}
+
+ function linebreak() {}
+
+ function hr() {}
+
+ function strong_open() {}
+
+ function strong_close() {}
+
+ function emphasis_open() {}
+
+ function emphasis_close() {}
+
+ function underline_open() {}
+
+ function underline_close() {}
+
+ function monospace_open() {}
+
+ function monospace_close() {}
+
+ function subscript_open() {}
+
+ function subscript_close() {}
+
+ function superscript_open() {}
+
+ function superscript_close() {}
+
+ function deleted_open() {}
+
+ function deleted_close() {}
+
+ function footnote_open() {}
+
+ function footnote_close() {}
+
+ function listu_open() {}
+
+ function listu_close() {}
+
+ function listo_open() {}
+
+ function listo_close() {}
+
+ function listitem_open($level) {}
+
+ function listitem_close() {}
+
+ function listcontent_open() {}
+
+ function listcontent_close() {}
+
+ function unformatted($text) {}
+
+ function php($text) {}
+
+ function phpblock($text) {}
+
+ function html($text) {}
+
+ function htmlblock($text) {}
+
+ function preformatted($text) {}
+
+ function quote_open() {}
+
+ function quote_close() {}
+
+ function file($text, $lang = null, $file = null ) {}
+
+ function code($text, $lang = null, $file = null ) {}
+
+ function acronym($acronym) {}
+
+ function smiley($smiley) {}
+
+ function wordblock($word) {}
+
+ function entity($entity) {}
+
+ // 640x480 ($x=640, $y=480)
+ function multiplyentity($x, $y) {}
+
+ function singlequoteopening() {}
+
+ function singlequoteclosing() {}
+
+ function apostrophe() {}
+
+ function doublequoteopening() {}
+
+ function doublequoteclosing() {}
+
+ // $link like 'SomePage'
+ function camelcaselink($link) {}
+
+ function locallink($hash, $name = NULL) {}
+
+ // $link like 'wiki:syntax', $title could be an array (media)
+ function internallink($link, $title = NULL) {}
+
+ // $link is full URL with scheme, $title could be an array (media)
+ function externallink($link, $title = NULL) {}
+
+ function rss ($url,$params) {}
+
+ // $link is the original link - probably not much use
+ // $wikiName is an indentifier for the wiki
+ // $wikiUri is the URL fragment to append to some known URL
+ function interwikilink($link, $title = NULL, $wikiName, $wikiUri) {}
+
+ // Link to file on users OS, $title could be an array (media)
+ function filelink($link, $title = NULL) {}
+
+ // Link to a Windows share, , $title could be an array (media)
+ function windowssharelink($link, $title = NULL) {}
+
+// function email($address, $title = NULL) {}
+ function emaillink($address, $name = NULL) {}
+
+ function internalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
+ $height=NULL, $cache=NULL, $linking=NULL) {}
+
+ function externalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
+ $height=NULL, $cache=NULL, $linking=NULL) {}
+
+ function internalmedialink (
+ $src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL
+ ) {}
+
+ function externalmedialink(
+ $src,$title=NULL,$align=NULL,$width=NULL,$height=NULL,$cache=NULL
+ ) {}
+
+ function table_open($maxcols = null, $numrows = null, $pos = null){}
+
+ function table_close($pos = null){}
+
+ function tablerow_open(){}
+
+ function tablerow_close(){}
+
+ function tableheader_open($colspan = 1, $align = NULL, $rowspan = 1){}
+
+ function tableheader_close(){}
+
+ function tablecell_open($colspan = 1, $align = NULL, $rowspan = 1){}
+
+ function tablecell_close(){}
+
+
+ // util functions follow, you probably won't need to reimplement them
+
+
+ /**
+ * Removes any Namespace from the given name but keeps
+ * casing and special chars
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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;
+
+ $name = strtr($name,';',':');
+ if($conf['useslash']){
+ $name = strtr($name,'/',':');
+ }
+
+ return noNSorNS($name);
+ }
+
+ /**
+ * Resolve an interwikilink
+ */
+ function _resolveInterWiki(&$shortcut,$reference){
+ //get interwiki URL
+ if ( isset($this->interwiki[$shortcut]) ) {
+ $url = $this->interwiki[$shortcut];
+ } else {
+ // Default to Google I'm feeling lucky
+ $url = 'http://www.google.com/search?q={URL}&amp;btnI=lucky';
+ $shortcut = 'go';
+ }
+
+ //split into hash and url part
+ list($reference,$hash) = explode('#',$reference,2);
+
+ //replace placeholder
+ if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#',$url)){
+ //use placeholders
+ $url = str_replace('{URL}',rawurlencode($reference),$url);
+ $url = str_replace('{NAME}',$reference,$url);
+ $parsed = parse_url($reference);
+ if(!$parsed['port']) $parsed['port'] = 80;
+ $url = str_replace('{SCHEME}',$parsed['scheme'],$url);
+ $url = str_replace('{HOST}',$parsed['host'],$url);
+ $url = str_replace('{PORT}',$parsed['port'],$url);
+ $url = str_replace('{PATH}',$parsed['path'],$url);
+ $url = str_replace('{QUERY}',$parsed['query'],$url);
+ }else{
+ //default
+ $url = $url.rawurlencode($reference);
+ }
+ if($hash) $url .= '#'.rawurlencode($hash);
+
+ return $url;
+ }
+}
+
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php
new file mode 100644
index 000000000..8d1eb24c1
--- /dev/null
+++ b/inc/parser/xhtml.php
@@ -0,0 +1,1232 @@
+<?php
+/**
+ * Renderer for XHTML output
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+if(!defined('DOKU_INC')) die('meh.');
+
+if ( !defined('DOKU_LF') ) {
+ // Some whitespace to help View > Source
+ define ('DOKU_LF',"\n");
+}
+
+if ( !defined('DOKU_TAB') ) {
+ // Some whitespace to help View > Source
+ define ('DOKU_TAB',"\t");
+}
+
+require_once DOKU_INC . 'inc/parser/renderer.php';
+require_once DOKU_INC . 'inc/html.php';
+
+/**
+ * The Renderer
+ */
+class Doku_Renderer_xhtml extends Doku_Renderer {
+
+ // @access public
+ var $doc = ''; // will contain the whole document
+ var $toc = array(); // will contain the Table of Contents
+
+ private $sectionedits = array(); // A stack of section edit data
+
+ var $headers = array();
+ var $footnotes = array();
+ var $lastlevel = 0;
+ var $node = array(0,0,0,0,0);
+ var $store = '';
+
+ var $_counter = array(); // used as global counter, introduced for table classes
+ var $_codeblock = 0; // counts the code and file blocks, used to provide download links
+
+ /**
+ * Register a new edit section range
+ *
+ * @param $type string The section type identifier
+ * @param $title string The section title
+ * @param $start int The byte position for the edit start
+ * @return string A marker class for the starting HTML element
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+ public function startSectionEdit($start, $type, $title = null) {
+ static $lastsecid = 0;
+ $this->sectionedits[] = array(++$lastsecid, $start, $type, $title);
+ return 'sectionedit' . $lastsecid;
+ }
+
+ /**
+ * Finish an edit section range
+ *
+ * @param $end int 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) {
+ list($id, $start, $type, $title) = array_pop($this->sectionedits);
+ if (!is_null($end) && $end <= $start) {
+ return;
+ }
+ $this->doc .= "<!-- EDIT$id " . strtoupper($type) . ' ';
+ if (!is_null($title)) {
+ $this->doc .= '"' . str_replace('"', '', $title) . '" ';
+ }
+ $this->doc .= "[$start-" . (is_null($end) ? '' : $end) . '] -->';
+ }
+
+ function getFormat(){
+ return 'xhtml';
+ }
+
+
+ function document_start() {
+ //reset some internals
+ $this->toc = array();
+ $this->headers = array();
+ }
+
+ function document_end() {
+ // Finish open section edits.
+ while (count($this->sectionedits) > 0) {
+ if ($this->sectionedits[count($this->sectionedits) - 1][1] <= 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;
+
+ $id = 0;
+ foreach ( $this->footnotes as $footnote ) {
+ $id++; // the number of the current 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.'" name="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+1).'" id="fn__'.($ref+1).'" name="fn__'.($ref+1).'" class="fn_bot">';
+ $this->doc .= ($ref+1).')</a></sup> '.DOKU_LF;
+ }
+ }
+
+ // add footnote markup and close this footnote
+ $this->doc .= $footnote;
+ $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);
+ }
+
+ 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);
+ }
+ }
+
+ function header($text, $level, $pos) {
+ global $conf;
+
+ if(!$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][2] === 'section') {
+ $this->finishSectionEdit($pos - 1);
+ }
+
+ // write the header
+ $this->doc .= DOKU_LF.'<h'.$level;
+ if ($level <= $conf['maxseclevel']) {
+ $this->doc .= ' class="' . $this->startSectionEdit($pos, 'section', $text) . '"';
+ }
+ $this->doc .= '><a name="'.$hid.'" id="'.$hid.'">';
+ $this->doc .= $this->_xmlEntities($text);
+ $this->doc .= "</a></h$level>".DOKU_LF;
+ }
+
+ function section_open($level) {
+ $this->doc .= '<div class="level' . $level . '">' . DOKU_LF;
+ }
+
+ function section_close() {
+ $this->doc .= DOKU_LF.'</div>'.DOKU_LF;
+ }
+
+ function cdata($text) {
+ $this->doc .= $this->_xmlEntities($text);
+ }
+
+ function p_open() {
+ $this->doc .= DOKU_LF.'<p>'.DOKU_LF;
+ }
+
+ function p_close() {
+ $this->doc .= DOKU_LF.'</p>'.DOKU_LF;
+ }
+
+ function linebreak() {
+ $this->doc .= '<br/>'.DOKU_LF;
+ }
+
+ function hr() {
+ $this->doc .= '<hr />'.DOKU_LF;
+ }
+
+ function strong_open() {
+ $this->doc .= '<strong>';
+ }
+
+ function strong_close() {
+ $this->doc .= '</strong>';
+ }
+
+ function emphasis_open() {
+ $this->doc .= '<em>';
+ }
+
+ function emphasis_close() {
+ $this->doc .= '</em>';
+ }
+
+ function underline_open() {
+ $this->doc .= '<em class="u">';
+ }
+
+ function underline_close() {
+ $this->doc .= '</em>';
+ }
+
+ function monospace_open() {
+ $this->doc .= '<code>';
+ }
+
+ function monospace_close() {
+ $this->doc .= '</code>';
+ }
+
+ function subscript_open() {
+ $this->doc .= '<sub>';
+ }
+
+ function subscript_close() {
+ $this->doc .= '</sub>';
+ }
+
+ function superscript_open() {
+ $this->doc .= '<sup>';
+ }
+
+ function superscript_close() {
+ $this->doc .= '</sup>';
+ }
+
+ function deleted_open() {
+ $this->doc .= '<del>';
+ }
+
+ 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>
+ */
+ 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
+ */
+ function footnote_close() {
+
+ // 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
+ $id = count($this->footnotes)+1;
+ $this->footnotes[count($this->footnotes)] = $footnote;
+ } else {
+ // seen this one before, translate the index to an id and save a placeholder
+ $i++;
+ $id = count($this->footnotes)+1;
+ $this->footnotes[count($this->footnotes)] = "@@FNT".($i);
+ }
+
+ // output the footnote reference and link
+ $this->doc .= '<sup><a href="#fn__'.$id.'" name="fnt__'.$id.'" id="fnt__'.$id.'" class="fn_top">'.$id.')</a></sup>';
+ }
+
+ function listu_open() {
+ $this->doc .= '<ul>'.DOKU_LF;
+ }
+
+ function listu_close() {
+ $this->doc .= '</ul>'.DOKU_LF;
+ }
+
+ function listo_open() {
+ $this->doc .= '<ol>'.DOKU_LF;
+ }
+
+ function listo_close() {
+ $this->doc .= '</ol>'.DOKU_LF;
+ }
+
+ function listitem_open($level) {
+ $this->doc .= '<li class="level'.$level.'">';
+ }
+
+ function listitem_close() {
+ $this->doc .= '</li>'.DOKU_LF;
+ }
+
+ function listcontent_open() {
+ $this->doc .= '<div class="li">';
+ }
+
+ function listcontent_close() {
+ $this->doc .= '</div>'.DOKU_LF;
+ }
+
+ function unformatted($text) {
+ $this->doc .= $this->_xmlEntities($text);
+ }
+
+ /**
+ * Execute PHP code if allowed
+ *
+ * @param string $wrapper html element to wrap result if $conf['phpok'] is okff
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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);
+ }
+ }
+
+ function phpblock($text) {
+ $this->php($text, 'pre');
+ }
+
+ /**
+ * Insert HTML if allowed
+ *
+ * @param string $wrapper html element to wrap result if $conf['htmlok'] is okff
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function html($text, $wrapper='code') {
+ global $conf;
+
+ if($conf['htmlok']){
+ $this->doc .= $text;
+ } else {
+ $this->doc .= p_xhtml_cached_geshi($text, 'html4strict', $wrapper);
+ }
+ }
+
+ function htmlblock($text) {
+ $this->html($text, 'pre');
+ }
+
+ function quote_open() {
+ $this->doc .= '<blockquote><div class="no">'.DOKU_LF;
+ }
+
+ function quote_close() {
+ $this->doc .= '</div></blockquote>'.DOKU_LF;
+ }
+
+ function preformatted($text) {
+ $this->doc .= '<pre class="code">' . trim($this->_xmlEntities($text),"\n\r") . '</pre>'. DOKU_LF;
+ }
+
+ function file($text, $language=null, $filename=null) {
+ $this->_highlight('file',$text,$language,$filename);
+ }
+
+ function code($text, $language=null, $filename=null) {
+ $this->_highlight('code',$text,$language,$filename);
+ }
+
+ /**
+ * Use GeSHi to highlight language syntax in code and file blocks
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _highlight($type, $text, $language=null, $filename=null) {
+ global $conf;
+ global $ID;
+ global $lang;
+
+ if($filename){
+ // add icon
+ list($ext) = mimetype($filename,false);
+ $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext);
+ $class = 'mediafile mf_'.$class;
+
+ $this->doc .= '<dl class="'.$type.'">'.DOKU_LF;
+ $this->doc .= '<dt><a href="'.exportlink($ID,'code',array('codeblock'=>$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 ( is_null($language) ) {
+ $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, '').'</pre>'.DOKU_LF;
+ }
+
+ if($filename){
+ $this->doc .= '</dd></dl>'.DOKU_LF;
+ }
+
+ $this->_codeblock++;
+ }
+
+ function acronym($acronym) {
+
+ if ( array_key_exists($acronym, $this->acronyms) ) {
+
+ $title = $this->_xmlEntities($this->acronyms[$acronym]);
+
+ $this->doc .= '<acronym title="'.$title
+ .'">'.$this->_xmlEntities($acronym).'</acronym>';
+
+ } else {
+ $this->doc .= $this->_xmlEntities($acronym);
+ }
+ }
+
+ function smiley($smiley) {
+ if ( array_key_exists($smiley, $this->smileys) ) {
+ $title = $this->_xmlEntities($this->smileys[$smiley]);
+ $this->doc .= '<img src="'.DOKU_BASE.'lib/images/smileys/'.$this->smileys[$smiley].
+ '" class="middle" alt="'.
+ $this->_xmlEntities($smiley).'" />';
+ } else {
+ $this->doc .= $this->_xmlEntities($smiley);
+ }
+ }
+
+ /*
+ * not used
+ function wordblock($word) {
+ if ( array_key_exists($word, $this->badwords) ) {
+ $this->doc .= '** BLEEP **';
+ } else {
+ $this->doc .= $this->_xmlEntities($word);
+ }
+ }
+ */
+
+ function entity($entity) {
+ if ( array_key_exists($entity, $this->entities) ) {
+ $this->doc .= $this->entities[$entity];
+ } else {
+ $this->doc .= $this->_xmlEntities($entity);
+ }
+ }
+
+ function multiplyentity($x, $y) {
+ $this->doc .= "$x&times;$y";
+ }
+
+ function singlequoteopening() {
+ global $lang;
+ $this->doc .= $lang['singlequoteopening'];
+ }
+
+ function singlequoteclosing() {
+ global $lang;
+ $this->doc .= $lang['singlequoteclosing'];
+ }
+
+ function apostrophe() {
+ global $lang;
+ $this->doc .= $lang['apostrophe'];
+ }
+
+ function doublequoteopening() {
+ global $lang;
+ $this->doc .= $lang['doublequoteopening'];
+ }
+
+ function doublequoteclosing() {
+ global $lang;
+ $this->doc .= $lang['doublequoteclosing'];
+ }
+
+ /**
+ */
+ function camelcaselink($link) {
+ $this->internallink($link,$link);
+ }
+
+
+ function locallink($hash, $name = NULL){
+ global $ID;
+ $name = $this->_getLinkTitle($name, $hash, $isImage);
+ $hash = $this->_headerToLink($hash);
+ $title = $ID.' &crarr;';
+ $this->doc .= '<a href="#'.$hash.'" title="'.$title.'" class="wikilink1">';
+ $this->doc .= $name;
+ $this->doc .= '</a>';
+ }
+
+ /**
+ * 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>
+ */
+ 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);
+
+ $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'] = '';
+ // highlight link to current page
+ if ($id == $INFO['id']) {
+ $link['pre'] = '<span class="curid">';
+ $link['suf'] = '</span>';
+ }
+ $link['more'] = '';
+ $link['class'] = $class;
+ $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);
+ }
+ }
+
+ function externallink($url, $name = NULL) {
+ 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){
+ $this->doc .= $name;
+ return;
+ }
+
+ // set class
+ if ( !$isImage ) {
+ $class='urlextern';
+ } else {
+ $class='media';
+ }
+
+ //prepare for formating
+ $link['target'] = $conf['target']['extern'];
+ $link['style'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = '';
+ $link['class'] = $class;
+ $link['url'] = $url;
+
+ $link['name'] = $name;
+ $link['title'] = $this->_xmlEntities($url);
+ if($conf['relnofollow']) $link['more'] .= ' rel="nofollow"';
+
+ //output formatted
+ $this->doc .= $this->_formatLink($link);
+ }
+
+ /**
+ */
+ function interwikilink($match, $name = NULL, $wikiName, $wikiUri) {
+ global $conf;
+
+ $link = array();
+ $link['target'] = $conf['target']['interwiki'];
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = '';
+ $link['name'] = $this->_getLinkTitle($name, $wikiUri, $isImage);
+
+ //get interwiki URL
+ $url = $this->_resolveInterWiki($wikiName,$wikiUri);
+
+ 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 ){
+ $link['target'] = $conf['target']['wiki'];
+ }
+
+ $link['url'] = $url;
+ $link['title'] = htmlspecialchars($link['url']);
+
+ //output formatted
+ $this->doc .= $this->_formatLink($link);
+ }
+
+ /**
+ */
+ function windowssharelink($url, $name = NULL) {
+ global $conf;
+ global $lang;
+ //simple setup
+ $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
+ $this->doc .= $this->_formatLink($link);
+ }
+
+ function emaillink($address, $name = NULL) {
+ 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
+ $this->doc .= $this->_formatLink($link);
+ }
+
+ function internalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
+ $height=NULL, $cache=NULL, $linking=NULL) {
+ global $ID;
+ list($src,$hash) = explode('#',$src,2);
+ resolve_mediaid(getNS($ID),$src, $exists);
+
+ $noLink = false;
+ $render = ($linking == 'linkonly') ? false : true;
+ $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render);
+
+ list($ext,$mime,$dl) = mimetype($src,false);
+ if(substr($mime,0,5) == 'image' && $render){
+ $link['url'] = ml($src,array('id'=>$ID,'cache'=>$cache),($linking=='direct'));
+ }elseif($mime == 'application/x-shockwave-flash' && $render){
+ // don't link flash 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),true);
+ }
+
+ if($hash) $link['url'] .= '#'.$hash;
+
+ //markup non existing files
+ if (!$exists) {
+ $link['class'] .= ' wikilink2';
+ }
+
+ //output formatted
+ if ($linking == 'nolink' || $noLink) $this->doc .= $link['name'];
+ else $this->doc .= $this->_formatLink($link);
+ }
+
+ function externalmedia ($src, $title=NULL, $align=NULL, $width=NULL,
+ $height=NULL, $cache=NULL, $linking=NULL) {
+ list($src,$hash) = explode('#',$src,2);
+ $noLink = false;
+ $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,$dl) = 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' && $render){
+ // don't link flash 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 ($linking == 'nolink' || $noLink) $this->doc .= $link['name'];
+ else $this->doc .= $this->_formatLink($link);
+ }
+
+ /**
+ * Renders an RSS feed
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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 (!defined('DOKU_E_LEVEL')) { error_reporting($elvl); }
+
+ //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(),
+ htmlspecialchars_decode($item->get_title()));
+ }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'].' '.$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>';
+ }
+
+ // $numrows not yet implemented
+ function table_open($maxcols = null, $numrows = null, $pos = null){
+ global $lang;
+ // initialize the row counter used for classes
+ $this->_counter['row_counter'] = 0;
+ $class = 'table';
+ if ($pos !== null) {
+ $class .= ' ' . $this->startSectionEdit($pos, 'table');
+ }
+ $this->doc .= '<div class="' . $class . '"><table class="inline">' .
+ DOKU_LF;
+ }
+
+ function table_close($pos = null){
+ $this->doc .= '</table></div>'.DOKU_LF;
+ if ($pos !== null) {
+ $this->finishSectionEdit($pos);
+ }
+ }
+
+ function tablerow_open(){
+ // initialize the cell counter used for classes
+ $this->_counter['cell_counter'] = 0;
+ $class = 'row' . $this->_counter['row_counter']++;
+ $this->doc .= DOKU_TAB . '<tr class="'.$class.'">' . DOKU_LF . DOKU_TAB . DOKU_TAB;
+ }
+
+ function tablerow_close(){
+ $this->doc .= DOKU_LF . DOKU_TAB . '</tr>' . DOKU_LF;
+ }
+
+ function tableheader_open($colspan = 1, $align = NULL, $rowspan = 1){
+ $class = 'class="col' . $this->_counter['cell_counter']++;
+ if ( !is_null($align) ) {
+ $class .= ' '.$align.'align';
+ }
+ $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 .= '>';
+ }
+
+ function tableheader_close(){
+ $this->doc .= '</th>';
+ }
+
+ function tablecell_open($colspan = 1, $align = NULL, $rowspan = 1){
+ $class = 'class="col' . $this->_counter['cell_counter']++;
+ if ( !is_null($align) ) {
+ $class .= ' '.$align.'align';
+ }
+ $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 .= '>';
+ }
+
+ function tablecell_close(){
+ $this->doc .= '</td>';
+ }
+
+ //----------------------------------------------------------
+ // Utils
+
+ /**
+ * Build a link
+ *
+ * Assembles all parts defined in $link returns HTML for the link
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ 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="'.$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>
+ */
+ function _media ($src, $title=NULL, $align=NULL, $width=NULL,
+ $height=NULL, $cache=NULL, $render = true) {
+
+ $ret = '';
+
+ list($ext,$mime,$dl) = 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($cap){
+ $title = $this->_xmlEntities($cap);
+ }
+ }
+ if (!$render) {
+ // if the picture is not supposed to be rendered
+ // return the title of the picture
+ if (!$title) {
+ // just show the sourcename
+ $title = $this->_xmlEntities(basename(noNS($src)));
+ }
+ return $title;
+ }
+ //add image tag
+ $ret .= '<img src="'.ml($src,array('w'=>$width,'h'=>$height,'cache'=>$cache)).'"';
+ $ret .= ' class="media'.$align.'"';
+
+ // make left/right alignment for no-CSS view work (feeds)
+ if($align == 'right') $ret .= ' align="right"';
+ if($align == 'left') $ret .= ' align="left"';
+
+ 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($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 = 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(basename(noNS($src)));
+ }
+
+ return $ret;
+ }
+
+ function _xmlEntities($string) {
+ return htmlspecialchars($string,ENT_QUOTES,'UTF-8');
+ }
+
+ /**
+ * Creates a linkid from a headline
+ *
+ * @param string $title The headline title
+ * @param boolean $create Create a new unique ID?
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _headerToLink($title,$create=false) {
+ if($create){
+ return sectionID($title,$this->headers);
+ }else{
+ $check = false;
+ return sectionID($title,$check);
+ }
+ }
+
+ /**
+ * Construct a title and handle images in titles
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+ function _getLinkTitle($title, $default, & $isImage, $id=NULL, $linktype='content') {
+ global $conf;
+
+ $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 ($heading) {
+ return $this->_xmlEntities($heading);
+ }
+ }
+ return $this->_xmlEntities($default);
+ } else {
+ return $this->_xmlEntities($title);
+ }
+ }
+
+ /**
+ * Returns an HTML code for images used in link titles
+ *
+ * @todo Resolve namespace on internal images
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _imageTitle($img) {
+ global $ID;
+
+ // some fixes on $img['src']
+ // see internalmedia() and externalmedia()
+ list($img['src'],$hash) = explode('#',$img['src'],2);
+ if ($img['type'] == 'internalmedia') {
+ resolve_mediaid(getNS($ID),$img['src'],$exists);
+ }
+
+ return $this->_media($img['src'],
+ $img['title'],
+ $img['align'],
+ $img['width'],
+ $img['height'],
+ $img['cache']);
+ }
+
+ /**
+ * _getMediaLinkConf is a helperfunction to internalmedia() and externalmedia()
+ * which returns a basic link to a media.
+ *
+ * @author Pierre Spring <pierre.spring@liip.ch>
+ * @param string $src
+ * @param string $title
+ * @param string $align
+ * @param string $width
+ * @param string $height
+ * @param string $cache
+ * @param string $render
+ * @access protected
+ * @return array
+ */
+ 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'];
+ $link['title'] = $this->_xmlEntities($src);
+ $link['name'] = $this->_media($src, $title, $align, $width, $height, $cache, $render);
+
+ return $link;
+ }
+
+
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/parser/xhtmlsummary.php b/inc/parser/xhtmlsummary.php
new file mode 100644
index 000000000..95f86cbef
--- /dev/null
+++ b/inc/parser/xhtmlsummary.php
@@ -0,0 +1,90 @@
+<?php
+if(!defined('DOKU_INC')) die('meh.');
+require_once DOKU_INC . 'inc/parser/xhtml.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
+ var $sum_paragraphs = 0;
+ var $sum_capture = true;
+ var $sum_inSection = false;
+ var $sum_summary = '';
+ var $sum_pageTitle = false;
+
+ function document_start() {
+ $this->doc .= DOKU_LF.'<div>'.DOKU_LF;
+ }
+
+ function document_end() {
+ $this->doc = $this->sum_summary;
+ $this->doc .= DOKU_LF.'</div>'.DOKU_LF;
+ }
+
+ // FIXME not supported anymore
+ function toc_open() {
+ $this->sum_summary .= $this->doc;
+ }
+
+ // FIXME not supported anymore
+ function toc_close() {
+ $this->doc = '';
+ }
+
+ 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;
+ }
+
+ function section_open($level) {
+ if ( $this->sum_capture ) {
+ $this->sum_inSection = true;
+ }
+ }
+
+ function section_close() {
+ if ( $this->sum_capture && $this->sum_inSection ) {
+ $this->sum_summary .= $this->doc;
+ $this->sum_capture = false;
+ }
+ }
+
+ function p_open() {
+ if ( $this->sum_capture && $this->sum_paragraphs < 2 ) {
+ $this->sum_paragraphs++;
+ }
+ parent :: p_open();
+ }
+
+ 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/inc/parserutils.php b/inc/parserutils.php
new file mode 100644
index 000000000..9384929bf
--- /dev/null
+++ b/inc/parserutils.php
@@ -0,0 +1,777 @@
+<?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>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * 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>
+ */
+function p_wiki_xhtml($id, $rev='', $excuse=true){
+ $file = wikiFN($id,$rev);
+ $ret = '';
+
+ //ensure $id is in global $ID (needed for parsing)
+ global $ID;
+ $keep = $ID;
+ $ID = $id;
+
+ if($rev){
+ if(@file_exists($file)){
+ $ret = p_render('xhtml',p_get_instructions(io_readWikiPage($file,$id,$rev)),$info); //no caching on old revisions
+ }elseif($excuse){
+ $ret = p_locale_xhtml('norev');
+ }
+ }else{
+ if(@file_exists($file)){
+ $ret = p_cached_output($file,'xhtml',$id);
+ }elseif($excuse){
+ $ret = p_locale_xhtml('newpage');
+ }
+ }
+
+ //restore ID (just in case)
+ $ID = $keep;
+
+ return $ret;
+}
+
+/**
+ * Returns starting summary for a page (e.g. the first few
+ * paragraphs), marked up in XHTML.
+ *
+ * If $excuse is true an explanation is returned if the file
+ * wasn't found
+ *
+ * @param string wiki page id
+ * @param reference populated with page title from heading or page id
+ * @deprecated
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+function p_wiki_xhtml_summary($id, &$title, $rev='', $excuse=true){
+ $file = wikiFN($id,$rev);
+ $ret = '';
+
+ //ensure $id is in global $ID (needed for parsing)
+ global $ID;
+ $keep = $ID;
+ $ID = $id;
+
+ if($rev){
+ if(@file_exists($file)){
+ //no caching on old revisions
+ $ins = p_get_instructions(io_readWikiPage($file,$id,$rev));
+ }elseif($excuse){
+ $ret = p_locale_xhtml('norev');
+ //restore ID (just in case)
+ $ID = $keep;
+ return $ret;
+ }
+
+ }else{
+
+ if(@file_exists($file)){
+ // The XHTML for a summary is not cached so use the instruction cache
+ $ins = p_cached_instructions($file);
+ }elseif($excuse){
+ $ret = p_locale_xhtml('newpage');
+ //restore ID (just in case)
+ $ID = $keep;
+ return $ret;
+ }
+ }
+
+ $ret = p_render('xhtmlsummary',$ins,$info);
+
+ if ( $info['sum_pagetitle'] ) {
+ $title = $info['sum_pagetitle'];
+ } else {
+ $title = $id;
+ }
+
+ $ID = $keep;
+ return $ret;
+}
+
+/**
+ * Returns the specified local text in parsed format
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function p_locale_xhtml($id){
+ //fetch parsed locale
+ $html = p_cached_output(localeFN($id));
+ return $html;
+}
+
+/**
+ * *** DEPRECATED ***
+ *
+ * use p_cached_output()
+ *
+ * Returns the given file parsed to XHTML
+ *
+ * Uses and creates a cachefile
+ *
+ * @deprecated
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @todo rewrite to use mode instead of hardcoded XHTML
+ */
+function p_cached_xhtml($file){
+ return p_cached_output($file);
+}
+
+/**
+ * Returns the given file parsed into the requested output format
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+function p_cached_output($file, $format='xhtml', $id='') {
+ global $conf;
+
+ $cache = new cache_renderer($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); //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>
+ */
+function p_cached_instructions($file,$cacheonly=false,$id='') {
+ global $conf;
+ static $run = null;
+ if(is_null($run)) $run = array();
+
+ $cache = new cache_instructions($id, $file);
+
+ if ($cacheonly || $cache->useCache() || isset($run[$file])) {
+ 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>
+ */
+function p_get_instructions($text){
+
+ $modes = p_get_parsermodes();
+
+ // Create the parser
+ $Parser = new Doku_Parser();
+
+ // Add the Handler
+ $Parser->Handler = new Doku_Handler();
+
+ //add modes to parser
+ foreach($modes as $mode){
+ $Parser->addMode($mode['mode'],$mode['obj']);
+ }
+
+ // Do the parsing
+ trigger_event('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 cache_renderer($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) {
+ ++$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
+ $cachefile->storeCache(time());
+ } elseif ($meta != $old_meta) {
+ 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){
+ $meta['current'][$key][$subkey] = !empty($meta['current'][$key][$subkey]) ? array_merge($meta['current'][$key][$subkey], $subvalue) : $subvalue;
+ if ($persistent)
+ $meta['persistent'][$key][$subkey] = !empty($meta['persistent'][$key][$subkey]) ? array_merge($meta['persistent'][$key][$subkey], $subvalue) : $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_merge($meta['current'][$key],$value) : $value;
+
+ if ($persistent) {
+ $meta['persistent'][$key] = !empty($meta['persistent'][$key]) ? array_merge($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>
+ */
+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>
+ */
+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 Doku_Event('PARSER_METADATA_RENDER', $orig);
+ if ($evt->advise_before()) {
+
+ require_once DOKU_INC."inc/parser/metadata.php";
+
+ // 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>
+ */
+function p_get_parsermodes(){
+ global $conf;
+
+ //reuse old data
+ static $modes = null;
+ if($modes != null){
+ 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){
+ 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 = "Doku_Parser_Mode_$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 Doku_Parser_Mode_formatting($m);
+ $modes[] = array(
+ 'sort' => $obj->getSort(),
+ 'mode' => $m,
+ 'obj' => $obj
+ );
+ }
+
+ // add modes which need files
+ $obj = new Doku_Parser_Mode_smiley(array_keys(getSmileys()));
+ $modes[] = array('sort' => $obj->getSort(), 'mode' => 'smiley','obj' => $obj );
+ $obj = new Doku_Parser_Mode_acronym(array_keys(getAcronyms()));
+ $modes[] = array('sort' => $obj->getSort(), 'mode' => 'acronym','obj' => $obj );
+ $obj = new Doku_Parser_Mode_entity(array_keys(getEntities()));
+ $modes[] = array('sort' => $obj->getSort(), 'mode' => 'entity','obj' => $obj );
+
+ // add optional camelcase mode
+ if($conf['camelcase']){
+ $obj = new Doku_Parser_Mode_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>
+ */
+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>
+ */
+function p_render($mode,$instructions,&$info){
+ if(is_null($instructions)) return '';
+
+ $Renderer =& p_get_renderer($mode);
+ if (is_null($Renderer)) return null;
+
+ $Renderer->reset();
+
+ $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
+ call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]);
+ }
+
+ //set info array
+ $info = $Renderer->info;
+
+ // Post process and return the output
+ $data = array($mode,& $Renderer->doc);
+ trigger_event('RENDERER_CONTENT_POSTPROCESS',$data);
+ return $Renderer->doc;
+}
+
+function & p_get_renderer($mode) {
+ global $conf, $plugin_controller;
+
+ $rname = !empty($conf['renderer_'.$mode]) ? $conf['renderer_'.$mode] : $mode;
+ $rclass = "Doku_Renderer_$rname";
+
+ if( class_exists($rclass) ) {
+ return new $rclass();
+ }
+
+ // try default renderer first:
+ $file = DOKU_INC."inc/parser/$rname.php";
+ if(@file_exists($file)){
+ require_once $file;
+
+ if ( !class_exists($rclass) ) {
+ trigger_error("Unable to resolve render class $rclass",E_USER_WARNING);
+ msg("Renderer '$rname' for $mode not valid",-1);
+ return null;
+ }
+ $Renderer = new $rclass();
+ }else{
+ // Maybe a plugin/component is available?
+ list($plugin, $component) = $plugin_controller->_splitName($rname);
+ if (!$plugin_controller->isdisabled($plugin)){
+ $Renderer =& $plugin_controller->load('renderer',$rname);
+ }
+
+ if(is_null($Renderer)){
+ msg("No renderer '$rname' found for mode '$mode'",-1);
+ return null;
+ }
+ }
+
+ return $Renderer;
+}
+
+/**
+ * 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
+ *
+ * @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
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function p_xhtml_cached_geshi($code, $language, $wrapper='pre') {
+ global $conf, $config_cascade;
+ $language = strtolower($language);
+
+ // remove any leading or trailing blank lines
+ $code = preg_replace('/^\s*?\n|\s*?\n$/','',$code);
+
+ $cache = getCacheName($language.$code,".code");
+ $ctime = @filemtime($cache);
+ if($ctime && !$_REQUEST['purge'] &&
+ $ctime > filemtime(DOKU_INC.'inc/geshi.php') && // geshi changed
+ $ctime > @filemtime(DOKU_INC.'inc/geshi/'.$language.'.php') && // language syntax definition changed
+ $ctime > filemtime(reset($config_cascade['main']['default']))){ // dokuwiki changed
+ $highlighted_code = io_readFile($cache, false);
+
+ } else {
+
+ $geshi = new GeSHi($code, $language, DOKU_INC . 'inc/geshi');
+ $geshi->set_encoding('utf-8');
+ $geshi->enable_classes();
+ $geshi->set_header_type(GESHI_HEADER_PRE);
+ $geshi->set_link_target($conf['target']['extern']);
+
+ // 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/inc/plugin.php b/inc/plugin.php
new file mode 100644
index 000000000..ec94433b6
--- /dev/null
+++ b/inc/plugin.php
@@ -0,0 +1,259 @@
+<?php
+/**
+ * DokuWiki Plugin base class
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+
+/**
+ * Do not inherit directly from this class, instead inherit from the specialized
+ * ones in lib/plugin
+ */
+class DokuWiki_Plugin {
+
+ var $localised = false; // set to true by setupLocale() after loading language dependent strings
+ var $lang = array(); // array to hold language dependent strings, best accessed via ->getLang()
+ var $configloaded = false; // set to true by loadConfig() after loading plugin configuration variables
+ var $conf = array(); // array to hold plugin settings, best accessed via ->getConf()
+
+ /**
+ * General Info
+ *
+ * Needs to return a associative array with the following values:
+ *
+ * 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)
+ */
+ 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 />This is a bug in the '.
+ $parts[2].' plugin and should be reported to the '.
+ 'plugin author.',-1);
+ return array(
+ 'date' => '0000-00-00',
+ 'name' => $parts[2].' plugin',
+ );
+ }
+
+ // plugin introspection methods
+ // extract from class name, format = <plugin type>_plugin_<name>[_<component name>]
+ function getPluginType() {
+ list($t) = explode('_', get_class($this), 2);
+ return $t;
+ }
+ function getPluginName() {
+ list($t, $p, $n) = explode('_', get_class($this), 4);
+ return $n;
+ }
+ function getPluginComponent() {
+ list($t, $p, $n, $c) = explode('_', get_class($this), 4);
+ return (isset($c)?$c:'');
+ }
+
+ // localisation methods
+ /**
+ * getLang($id)
+ * use this function to 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 $id id of the string to be retrieved
+ * @return string string in appropriate language or english if not available
+ */
+ function getLang($id) {
+ if (!$this->localised) $this->setupLocale();
+
+ return (isset($this->lang[$id]) ? $this->lang[$id] : '');
+ }
+
+ /**
+ * locale_xhtml($id)
+ *
+ * retrieve a language dependent file and pass to xhtml renderer for display
+ * plugin equivalent of p_locale_xhtml()
+ *
+ * @param $id id of language dependent wiki page
+ * @return string parsed contents of the wiki page in xhtml format
+ */
+ function locale_xhtml($id) {
+ return p_cached_output($this->localFN($id));
+ }
+
+ /**
+ * localFN($id)
+ * prepends appropriate path for a language dependent filename
+ * plugin equivalent of localFN()
+ */
+ function localFN($id) {
+ global $conf;
+ $plugin = $this->getPluginName();
+ $file = DOKU_CONF.'/plugin_lang/'.$plugin.'/'.$conf['lang'].'/'.$id.'.txt';
+ if (!@file_exists($file)){
+ $file = DOKU_PLUGIN.$plugin.'/lang/'.$conf['lang'].'/'.$id.'.txt';
+ if(!@file_exists($file)){
+ //fall back to english
+ $file = DOKU_PLUGIN.$plugin.'/lang/en/'.$id.'.txt';
+ }
+ }
+ return $file;
+ }
+
+ /**
+ * setupLocale()
+ * reads all the plugins language dependent strings into $this->lang
+ * this function is automatically called by getLang()
+ */
+ function setupLocale() {
+ if ($this->localised) return;
+
+ global $conf; // 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');
+ if ($conf['lang'] != 'en') @include($path.$conf['lang'].'/lang.php');
+
+ $this->lang = $lang;
+ $this->localised = true;
+ }
+
+ // configuration methods
+ /**
+ * getConf($setting)
+ *
+ * use this function to access plugin configuration variables
+ */
+ function getConf($setting){
+
+ if (!$this->configloaded){ $this->loadConfig(); }
+
+ return $this->conf[$setting];
+ }
+
+ /**
+ * loadConfig()
+ * merges the plugin's default settings with any local settings
+ * this function is automatically called through getConf()
+ */
+ 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
+ */
+ function readDefaultSettings() {
+
+ $path = DOKU_PLUGIN.$this->getPluginName().'/conf/';
+ $conf = array();
+
+ if (@file_exists($path.'default.php')) {
+ include($path.'default.php');
+ }
+
+ return $conf;
+ }
+
+ /**
+ * Loads a given helper plugin (if enabled)
+ *
+ * @author Esther Brunner <wikidesign@gmail.com>
+ *
+ * @param $name name of plugin to load
+ * @param $msg message to display in case the plugin is not available
+ *
+ * @return object helper plugin object
+ */
+ function loadHelper($name, $msg){
+ if (!plugin_isdisabled($name)){
+ $obj =& plugin_load('helper',$name);
+ }else{
+ $obj = null;
+ }
+ if (is_null($obj) && $msg) msg("Helper plugin $name is not available or invalid.",-1);
+ return $obj;
+ }
+
+ // standard functions for outputing email addresses and links
+ // use these to avoid having to duplicate code to produce links in line with the installation configuration
+
+ /**
+ * email
+ * standardised function to generate an email link according to obfuscation settings
+ */
+ 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>";
+ }
+
+ /**
+ * external_link
+ * standardised function to generate an external link according to conf settings
+ */
+ 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>";
+ }
+
+ /**
+ * output text string through the parser, allows dokuwiki markup to be used
+ * very ineffecient for small pieces of data - try not to use
+ */
+ function render($text, $format='xhtml') {
+ return p_render($format, p_get_instructions($text),$info);
+ }
+
+ /**
+ * Allow the plugin to prevent DokuWiki from reusing an instance
+ *
+ * @return bool false if the plugin has to be instantiated
+ */
+ function isSingleton() {
+ return true;
+ }
+
+ // deprecated functions
+ function plugin_localFN($id) { return $this->localFN($id); }
+ function plugin_locale_xhtml($id) { return $this->locale_xhtml($id); }
+ function plugin_email($e, $n='', $c='', $m='') { return $this->email($e, $n, $c, $m); }
+ function plugin_link($l, $t='', $c='', $to='', $m='') { return $this->external_link($l, $t, $c, $to, $m); }
+ function plugin_render($t, $f='xhtml') { return $this->render($t, $f); }
+}
diff --git a/inc/plugincontroller.class.php b/inc/plugincontroller.class.php
new file mode 100644
index 000000000..734331c94
--- /dev/null
+++ b/inc/plugincontroller.class.php
@@ -0,0 +1,286 @@
+<?php
+/**
+ * Class to encapsulate access to dokuwiki plugins
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+
+// plugin related constants
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+
+class Doku_Plugin_Controller {
+
+ var $list_bytype = array();
+ var $tmp_plugins = array();
+ var $plugin_cascade = array('default'=>array(),'local'=>array(),'protected'=>array());
+ var $last_local_config_file = '';
+
+ /**
+ * Populates the master list of plugins
+ */
+ 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
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function getList($type='',$all=false){
+
+ // request the complete list
+ if (!$type) {
+ return $all ? array_keys($this->tmp_plugins) : array_keys(array_filter($this->tmp_plugins));
+ }
+
+ if (!isset($this->list_bytype[$type]['enabled'])) {
+ $this->list_bytype[$type]['enabled'] = $this->_getListByType($type,true);
+ }
+ if ($all && !isset($this->list_bytype[$type]['disabled'])) {
+ $this->list_bytype[$type]['disabled'] = $this->_getListByType($type,false);
+ }
+
+ return $all ? array_merge($this->list_bytype[$type]['enabled'],$this->list_bytype[$type]['disabled']) : $this->list_bytype[$type]['enabled'];
+ }
+
+ /**
+ * Loads the given plugin and creates an object of it
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @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 objectreference the plugin object or null on failure
+ */
+ function load($type,$name,$new=false,$disabled=false){
+
+ //we keep all loaded plugins available in global scope for reuse
+ global $DOKU_PLUGINS;
+ global $lang;
+
+ list($plugin,$component) = $this->_splitName($name);
+
+ // check if disabled
+ if(!$disabled && $this->isdisabled($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;
+ } else {
+ return $DOKU_PLUGINS[$type][$name];
+ }
+ }
+
+ //construct class and instantiate
+ if (!class_exists($class, true)) {
+
+ # the plugin might be in the wrong directory
+ $dir = $this->get_directory($plugin);
+ $inf = confToHash(DOKU_PLUGIN."$dir/plugin.info.txt");
+ if($inf['base'] && $inf['base'] != $plugin){
+ msg(sprintf($lang['plugin_install_err'],hsc($plugin),hsc($inf['base'])),-1);
+ }
+ return null;
+ }
+
+ $DOKU_PLUGINS[$type][$name] = new $class;
+ return $DOKU_PLUGINS[$type][$name];
+ }
+
+ function isdisabled($plugin) {
+ return empty($this->tmp_plugins[$plugin]);
+ }
+
+ function disable($plugin) {
+ if(array_key_exists($plugin,$this->plugin_cascade['protected'])) return false;
+ $this->tmp_plugins[$plugin] = 0;
+ return $this->saveList();
+ }
+
+ function enable($plugin) {
+ if(array_key_exists($plugin,$this->plugin_cascade['protected'])) return false;
+ $this->tmp_plugins[$plugin] = 1;
+ return $this->saveList();
+ }
+
+ function get_directory($plugin) {
+ return $plugin;
+ }
+
+ 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 (substr($plugin,-9) == '.disabled') {
+ // the plugin was disabled by rc2009-01-26
+ // disabling mechanism was changed back very soon again
+ // to keep everything simple we just skip the plugin completely
+ } elseif (@file_exists(DOKU_PLUGIN.$plugin.'/disabled')) {
+ // treat this as a default disabled plugin(over-rideable by the plugin manager)
+ // deprecated 2011-09-10 (usage of disabled files)
+ if (empty($this->plugin_cascade['local'][$plugin])) {
+ $all_plugins[$plugin] = 0;
+ } else {
+ $all_plugins[$plugin] = 1;
+ }
+ $this->plugin_cascade['default'][$plugin] = 0;
+
+ } elseif ((array_key_exists($plugin,$this->tmp_plugins) && $this->tmp_plugins[$plugin] == 0) ||
+ ($plugin === 'plugin' && isset($conf['pluginmanager']) && !$conf['pluginmanager'])){
+ $all_plugins[$plugin] = 0;
+
+ } elseif ((array_key_exists($plugin,$this->tmp_plugins) && $this->tmp_plugins[$plugin] == 1)) {
+ $all_plugins[$plugin] = 1;
+ } else {
+ $all_plugins[$plugin] = 1;
+ }
+ }
+ $this->tmp_plugins = $all_plugins;
+ if (!file_exists($this->last_local_config_file)) {
+ $this->saveList(true);
+ }
+ }
+ }
+
+ protected function checkRequire($files) {
+ $plugins = array();
+ foreach($files as $file) {
+ if(file_exists($file)) {
+ @include_once($file);
+ }
+ }
+ return $plugins;
+ }
+
+ function getCascade() {
+ return $this->plugin_cascade;
+ }
+
+ /**
+ * Save the current list of plugins
+ */
+ function saveList($forceSave = false) {
+ global $conf;
+
+ if (empty($this->tmp_plugins)) return false;
+
+ // Rebuild list of local settings
+ $local_plugins = $this->rebuildLocal();
+ if($local_plugins != $this->plugin_cascade['local'] || $forceSave) {
+ $file = $this->last_local_config_file;
+ $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, unless having a 'disabled' file in their plugin folder.\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 ($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'])
+ */
+ function rebuildLocal() {
+ //assign to local variable to avoid overwriting
+ $backup = $this->tmp_plugins;
+ //Can't do anything about protected one so rule them out completely
+ $local_default = array_diff_key($backup,$this->plugin_cascade['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->plugin_cascade['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->plugin_cascade['default']));
+ }
+
+ /**
+ * Build the list of plugins and cascade
+ *
+ */
+ function loadConfig() {
+ global $config_cascade;
+ foreach(array('default','protected') as $type) {
+ if(array_key_exists($type,$config_cascade['plugins']))
+ $this->plugin_cascade[$type] = $this->checkRequire($config_cascade['plugins'][$type]);
+ }
+ $local = $config_cascade['plugins']['local'];
+ $this->last_local_config_file = array_pop($local);
+ $this->plugin_cascade['local'] = $this->checkRequire(array($this->last_local_config_file));
+ if(is_array($local)) {
+ $this->plugin_cascade['default'] = array_merge($this->plugin_cascade['default'],$this->checkRequire($local));
+ }
+ $this->tmp_plugins = array_merge($this->plugin_cascade['default'],$this->plugin_cascade['local'],$this->plugin_cascade['protected']);
+ }
+
+ function _getListByType($type, $enabled) {
+ $master_list = $enabled ? array_keys(array_filter($this->tmp_plugins)) : array_keys(array_filter($this->tmp_plugins,array($this,'negate')));
+
+ $plugins = array();
+ foreach ($master_list as $plugin) {
+ $dir = $this->get_directory($plugin);
+
+ if (@file_exists(DOKU_PLUGIN."$dir/$type.php")){
+ $plugins[] = $plugin;
+ } else {
+ if ($dp = @opendir(DOKU_PLUGIN."$dir/$type/")) {
+ while (false !== ($component = readdir($dp))) {
+ if (substr($component,0,1) == '.' || strtolower(substr($component, -4)) != ".php") continue;
+ if (is_file(DOKU_PLUGIN."$dir/$type/$component")) {
+ $plugins[] = $plugin.'_'.substr($component, 0, -4);
+ }
+ }
+ closedir($dp);
+ }
+ }
+ }
+
+ return $plugins;
+ }
+
+ function _splitName($name) {
+ if (array_search($name, array_keys($this->tmp_plugins)) === false) {
+ return explode('_',$name,2);
+ }
+
+ return array($name,'');
+ }
+ function negate($input) {
+ return !(bool) $input;
+ }
+}
diff --git a/inc/pluginutils.php b/inc/pluginutils.php
new file mode 100644
index 000000000..53cfedf82
--- /dev/null
+++ b/inc/pluginutils.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Utilities for handling plugins
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// plugin related constants
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+
+/**
+ * Original plugin functions, remain for backwards compatibility
+ */
+function plugin_list($type='',$all=false) {
+ global $plugin_controller;
+ return $plugin_controller->getList($type,$all);
+}
+function plugin_load($type,$name,$new=false,$disabled=false) {
+ global $plugin_controller;
+ return $plugin_controller->load($type,$name,$new,$disabled);
+}
+function plugin_isdisabled($plugin) {
+ global $plugin_controller;
+ return $plugin_controller->isdisabled($plugin);
+}
+function plugin_enable($plugin) {
+ global $plugin_controller;
+ return $plugin_controller->enable($plugin);
+}
+function plugin_disable($plugin) {
+ global $plugin_controller;
+ return $plugin_controller->disable($plugin);
+}
+function plugin_directory($plugin) {
+ global $plugin_controller;
+ return $plugin_controller->get_directory($plugin);
+}
+function plugin_getcascade() {
+ global $plugin_controller;
+ return $plugin_controller->getCascade();
+}
diff --git a/inc/search.php b/inc/search.php
new file mode 100644
index 000000000..a26ae4808
--- /dev/null
+++ b/inc/search.php
@@ -0,0 +1,610 @@
+<?php
+/**
+ * DokuWiki search functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * recurse direcory
+ *
+ * This function recurses into a given base directory
+ * and calls the supplied function for each file and directory
+ *
+ * @param array ref $data The results of the search are stored here
+ * @param string $base Where to start the search
+ * @param callback $func Callback (function name or arayy with object,method)
+ * @param string $dir Current directory beyond $base
+ * @param int $lvl Recursion Level
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function search(&$data,$base,$func,$opts,$dir='',$lvl=1,$sort=false){
+ $dirs = array();
+ $files = array();
+ $filepaths = array();
+
+ //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 ($sort == 'date') {
+ @array_multisort(array_map('filemtime', $filepaths), SORT_NUMERIC, SORT_DESC, $files);
+ } else {
+ sort($files);
+ }
+ sort($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);
+ }
+ }
+ //now handle the files
+ foreach($files as $file){
+ call_user_func_array($func, array(&$data,$base,$file,'f',$lvl,$opts));
+ }
+}
+
+/**
+ * Wrapper around call_user_func_array.
+ *
+ * @deprecated
+ */
+function search_callback($func,&$data,$base,$file,$type,$lvl,$opts){
+ return call_user_func_array($func, array(&$data,$base,$file,$type,$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:
+ *
+ * &$data - Reference to the result data structure
+ * $base - Base usually $conf['datadir']
+ * $file - current file or directory relative to $base
+ * $type - Type either 'd' for directory or 'f' for file
+ * $lvl - Current recursion depht
+ * $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>
+ */
+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>
+ */
+function search_index(&$data,$base,$file,$type,$lvl,$opts){
+ global $conf;
+ $opts = array(
+ 'pagesonly' => true,
+ 'listdirs' => true,
+ 'listfiles' => !$opts['nofiles'],
+ 'sneakyacl' => $conf['sneaky_index'],
+ // Hacky, should rather use recmatch
+ 'depth' => preg_match('#^'.$file.'(/|$)#','/'.$opts['ns']) ? 0 : -1
+ );
+
+ return search_universal($data, $base, $file, $type, $lvl, $opts);
+}
+
+/**
+ * List all namespaces
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function search_media(&$data,$base,$file,$type,$lvl,$opts){
+
+ //we do nothing with directories
+ if($type == 'd') {
+ if(!$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(!$opts['skipacl'] && $info['perm'] < AUTH_READ){
+ return false;
+ }
+
+ //check pattern filter
+ if($opts['pattern'] && !@preg_match($opts['pattern'], $info['id'])){
+ return false;
+ }
+
+ $info['file'] = 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($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>
+ */
+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>
+ */
+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>
+ */
+function search_allpages(&$data,$base,$file,$type,$lvl,$opts){
+ //we do nothing with directories
+ if($type == 'd'){
+ if(!$opts['depth']) return true; // recurse forever
+ $parts = explode('/',ltrim($file,'/'));
+ if(count($parts) == $opts['depth']) return false; // depth reached
+ return true;
+ }
+
+ //only search txt files
+ if(substr($file,-4) != '.txt') return true;
+
+ $item['id'] = pathID($file);
+ if(!$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($opts['hash']){
+ $item['hash'] = md5(trim(rawWiki($item['id'])));
+ }
+
+ $data[] = $item;
+ return true;
+}
+
+/**
+ * Search for backlinks to a given page
+ *
+ * $opts['ns'] namespace of the page
+ * $opts['name'] name of the page without namespace
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @deprecated Replaced by ft_backlinks()
+ */
+function search_backlinks(&$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;
+
+ //absolute search id
+ $sid = cleanID($opts['ns'].':'.$opts['name']);
+
+ //current id and namespace
+ $cid = pathID($file);
+ $cns = getNS($cid);
+
+ //check ACL
+ if(auth_quickaclcheck($cid) < AUTH_READ){
+ return false;
+ }
+
+ //fetch instructions
+ $instructions = p_cached_instructions($base.$file,true);
+ if(is_null($instructions)) return false;
+
+ global $conf;
+ //check all links for match
+ foreach($instructions as $ins){
+ if($ins[0] == 'internallink' || ($conf['camelcase'] && $ins[0] == 'camelcaselink') ){
+ $mid = $ins[1][0];
+ resolve_pageid($cns,$mid,$exists); //exists is not used
+ if($mid == $sid){
+ //we have a match - finish
+ $data[]['id'] = $cid;
+ break;
+ }
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Fulltextsearch
+ *
+ * $opts['query'] is the search query
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @deprecated - fulltext indexer is used instead
+ */
+function search_fulltext(&$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;
+
+ //check ACL
+ $id = pathID($file);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return false;
+ }
+
+ //create regexp from queries
+ $poswords = array();
+ $negwords = array();
+ $qpreg = preg_split('/\s+/',$opts['query']);
+
+ foreach($qpreg as $word){
+ switch(substr($word,0,1)){
+ case '-':
+ if(strlen($word) > 1){ // catch single '-'
+ array_push($negwords,preg_quote(substr($word,1),'#'));
+ }
+ break;
+ case '+':
+ if(strlen($word) > 1){ // catch single '+'
+ array_push($poswords,preg_quote(substr($word,1),'#'));
+ }
+ break;
+ default:
+ array_push($poswords,preg_quote($word,'#'));
+ break;
+ }
+ }
+
+ // a search without any posword is useless
+ if (!count($poswords)) return true;
+
+ $reg = '^(?=.*?'.join(')(?=.*?',$poswords).')';
+ $reg .= count($negwords) ? '((?!'.join('|',$negwords).').)*$' : '.*$';
+ search_regex($data,$base,$file,$reg,$poswords);
+ return true;
+ }
+
+ /**
+ * Reference search
+ * This fuction searches for existing references to a given media file
+ * and returns an array with the found pages. It doesn't pay any
+ * attention to ACL permissions to find every reference. The caller
+ * must check if the user has the appropriate rights to see the found
+ * page and eventually have to prevent the result from displaying.
+ *
+ * @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 char $type Type either 'd' for directory or 'f' for file
+ * @param int $lvl Current recursion depht
+ * @param mixed $opts option array as given to search()
+ *
+ * $opts['query'] is the demanded media file name
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+function search_reference(&$data,$base,$file,$type,$lvl,$opts){
+ global $conf;
+
+ //we do nothing with directories
+ if($type == 'd') return true;
+
+ //only search txt files
+ if(substr($file,-4) != '.txt') return true;
+
+ //we finish after 'cnt' references found. The return value
+ //'false' will skip subdirectories to speed search up.
+ $cnt = $conf['refshow'] > 0 ? $conf['refshow'] : 1;
+ if(count($data) >= $cnt) return false;
+
+ $reg = '\{\{ *\:?'.$opts['query'].' *(\|.*)?\}\}';
+ search_regex($data,$base,$file,$reg,array($opts['query']));
+ return true;
+}
+
+/* ------------- helper functions below -------------- */
+
+/**
+ * fulltext search helper
+ * searches a text file with a given regular expression
+ * no ACL checks are performed. This have to be done by
+ * the caller if necessary.
+ *
+ * @param array $data reference to array for results
+ * @param string $base base directory
+ * @param string $file file name to search in
+ * @param string $reg regular expression to search for
+ * @param array $words words that should be marked in the results
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ *
+ * @deprecated - fulltext indexer is used instead
+ */
+function search_regex(&$data,$base,$file,$reg,$words){
+
+ //get text
+ $text = io_readfile($base.'/'.$file);
+ //lowercase text (u modifier does not help with case)
+ $lctext = utf8_strtolower($text);
+
+ //do the fulltext search
+ $matches = array();
+ if($cnt = preg_match_all('#'.$reg.'#usi',$lctext,$matches)){
+ //this is not the best way for snippet generation but the fastest I could find
+ $q = $words[0]; //use first word for snippet creation
+ $p = utf8_strpos($lctext,$q);
+ $f = $p - 100;
+ $l = utf8_strlen($q) + 200;
+ if($f < 0) $f = 0;
+ $snippet = '<span class="search_sep"> ... </span>'.
+ htmlspecialchars(utf8_substr($text,$f,$l)).
+ '<span class="search_sep"> ... </span>';
+ $mark = '('.join('|', $words).')';
+ $snippet = preg_replace('#'.$mark.'#si','<strong class="search_hit">\\1</strong>',$snippet);
+
+ $data[] = array(
+ 'id' => pathID($file),
+ 'count' => preg_match_all('#'.$mark.'#usi',$lctext,$matches),
+ 'poswords' => join(' ',$words),
+ 'snippet' => $snippet,
+ );
+ }
+
+ return true;
+}
+
+
+/**
+ * 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>
+ */
+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
+ */
+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
+ * keeptxt bool keep .txt extension for IDs
+ * listfiles bool include files in listing
+ * listdirs bool include namespaces in listing
+ * pagesonly bool restrict files to pages
+ * skipacl bool do not check for READ permission
+ * sneakyacl bool don't recurse into nonreadable dirs
+ * hash bool create MD5 hash for files
+ * meta bool return file metadata
+ * filematch string match files against this regexp
+ * idmatch string match full ID against this regexp
+ * dirmatch string match directory against this regexp when adding
+ * nsmatch string match namespace against this regexp when adding
+ * recmatch string match directory against this regexp when recursing
+ * showmsg bool warn about non-ID files
+ * showhidden bool show hidden files too
+ * firsthead bool return first heading for pages
+ *
+ * @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' || $opts['keeptxt']));
+ if($item['id'] != cleanID($item['id'])){
+ if($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(!$opts['depth']){
+ $return = true; // recurse forever
+ }else{
+ $depth = substr_count($file,'/');
+ if($depth >= $opts['depth']){
+ $return = false; // depth reached
+ }else{
+ $return = true;
+ }
+ }
+ if($return && !preg_match('/'.$opts['recmatch'].'/',$file)){
+ $return = false; // doesn't match
+ }
+ }
+
+ // check ACL
+ if(!$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(!$opts['listdirs']) return $return;
+ if(!$opts['skipacl'] && $opts['sneakyacl'] && $item['perm'] < AUTH_READ) return false; //neither list nor recurse
+ if($opts['dirmatch'] && !preg_match('/'.$opts['dirmatch'].'/',$file)) return $return;
+ if($opts['nsmatch'] && !preg_match('/'.$opts['nsmatch'].'/',$item['ns'])) return $return;
+ }else{
+ if(!$opts['listfiles']) return $return;
+ if(!$opts['skipacl'] && $item['perm'] < AUTH_READ) return $return;
+ if($opts['pagesonly'] && (substr($file,-4) != '.txt')) return $return;
+ if(!$opts['showhidden'] && isHiddenPage($item['id'])) return $return;
+ if($opts['filematch'] && !preg_match('/'.$opts['filematch'].'/',$file)) return $return;
+ if($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($opts['meta']){
+ $item['file'] = 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($opts['hash']) $item['hash'] = md5(io_readFile($base.'/'.$file,false));
+ if($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/inc/subscription.php b/inc/subscription.php
new file mode 100644
index 000000000..c94f17ad0
--- /dev/null
+++ b/inc/subscription.php
@@ -0,0 +1,394 @@
+<?php
+/**
+ * Utilities for handling (email) subscriptions
+ *
+ * The public interface of this file consists of the functions
+ * - subscription_find
+ * - subscription_send_digest
+ * - subscription_send_list
+ * - subscription_set
+ * - get_info_subscribed
+ * - subscription_addresslist
+ * - subscription_lock
+ * - subscription_unlock
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+/**
+ * Get the name of the metafile tracking subscriptions to target page or
+ * namespace
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_filename($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);
+}
+
+/**
+ * Lock subscription info for an ID
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_lock_filename ($id){
+ global $conf;
+ return $conf['lockdir'].'/_subscr_' . md5($id) . '.lock';
+}
+
+function subscription_lock($id) {
+ global $conf;
+ $lock = subscription_lock_filename($id);
+
+ 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($conf['dperm']) chmod($lock, $conf['dperm']);
+ return true;
+}
+
+/**
+ * Unlock subscription info for an ID
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_unlock($id) {
+ $lockf = subscription_lock_filename($id);
+ return @rmdir($lockf);
+}
+
+/**
+ * Set subscription information
+ *
+ * Allows to set subscription information for permanent storage in meta files.
+ * Subscriptions consist of a target object, a subscribing user, a subscribe
+ * style and optional data.
+ * A subscription may be deleted by specifying an empty subscribe style.
+ * Only one subscription per target and user is allowed.
+ * The function returns false on error, otherwise true. Note that no error is
+ * returned if a subscription should be deleted but the user is not subscribed
+ * and the subscription meta file exists.
+ *
+ * @param string $user The subscriber or unsubscriber
+ * @param string $page The target object (page or namespace), specified by
+ * id; Namespaces are identified by a trailing colon.
+ * @param string $style The subscribe style; DokuWiki currently implements
+ * “every”, “digest”, and “list”.
+ * @param string $data An optional data blob
+ * @param bool $overwrite Whether an existing subscription may be overwritten
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_set($user, $page, $style, $data = null,
+ $overwrite = false) {
+ global $lang;
+ if (is_null($style)) {
+ // Delete subscription.
+ $file = subscription_filename($page);
+ if (!@file_exists($file)) {
+ msg(sprintf($lang['subscr_not_subscribed'], $user,
+ prettyprint_id($page)), -1);
+ return false;
+ }
+
+ // io_deleteFromFile does not return false if no line matched.
+ return io_deleteFromFile($file,
+ subscription_regex(array('user' => auth_nameencode($user))),
+ true);
+ }
+
+ // Delete subscription if one exists and $overwrite is true. If $overwrite
+ // is false, fail.
+ $subs = subscription_find($page, array('user' => $user));
+ if (count($subs) > 0 && array_pop(array_keys($subs)) === $page) {
+ if (!$overwrite) {
+ msg(sprintf($lang['subscr_already_subscribed'], $user,
+ prettyprint_id($page)), -1);
+ return false;
+ }
+ // Fail if deletion failed, else continue.
+ if (!subscription_set($user, $page, null)) {
+ return false;
+ }
+ }
+
+ $file = subscription_filename($page);
+ $content = auth_nameencode($user) . ' ' . $style;
+ if (!is_null($data)) {
+ $content .= ' ' . $data;
+ }
+ return io_saveFile($file, $content . "\n", true);
+}
+
+/**
+ * Recursively search for matching subscriptions
+ *
+ * This function searches all relevant subscription files for a page or
+ * namespace.
+ *
+ * @param string $page The target object’s (namespace or page) id
+ * @param array $pre A hash of predefined values
+ *
+ * @see function subscription_regex for $pre documentation
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_find($page, $pre) {
+ // Construct list of files which may contain relevant subscriptions.
+ $filenames = array(':' => subscription_filename(':'));
+ do {
+ $filenames[$page] = subscription_filename($page);
+ $page = getNS(rtrim($page, ':')) . ':';
+ } while ($page !== ':');
+
+ // Handle files.
+ $matches = array();
+ foreach ($filenames as $cur_page => $filename) {
+ if (!@file_exists($filename)) {
+ continue;
+ }
+ $subscriptions = file($filename);
+ foreach ($subscriptions as $subscription) {
+ if (strpos($subscription, ' ') === false) {
+ // This is an old subscription file.
+ $subscription = trim($subscription) . " every\n";
+ }
+
+ list($user, $rest) = explode(' ', $subscription, 2);
+ $subscription = rawurldecode($user) . " " . $rest;
+
+ if (preg_match(subscription_regex($pre), $subscription,
+ $line_matches) === 0) {
+ continue;
+ }
+ $match = array_slice($line_matches, 1);
+ if (!isset($matches[$cur_page])) {
+ $matches[$cur_page] = array();
+ }
+ $matches[$cur_page][] = $match;
+ }
+ }
+ return array_reverse($matches);
+}
+
+/**
+ * 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>
+ */
+function get_info_subscribed() {
+ global $ID;
+ global $conf;
+ if (!$conf['subscribers']) {
+ return false;
+ }
+
+ $subs = subscription_find($ID, array('user' => $_SERVER['REMOTE_USER']));
+ if (count($subs) === 0) {
+ return false;
+ }
+
+ $_ret = array();
+ foreach ($subs as $target => $subs_data) {
+ $new = array('target' => $target,
+ 'style' => $subs_data[0][0]);
+ if (count($subs_data[0]) > 1) {
+ $new['data'] = $subs_data[0][1];
+ }
+ $_ret[] = $new;
+ }
+
+ return $_ret;
+}
+
+/**
+ * Construct a regular expression parsing a subscription definition line
+ *
+ * @param array $pre A hash of predefined values; “user”, “style”, and
+ * “data” may be set to limit the results to
+ * subscriptions matching these parameters. If
+ * “escaped” is true, these fields are inserted into the
+ * regular expression without escaping.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_regex($pre = array()) {
+ if (!isset($pre['escaped']) || $pre['escaped'] === false) {
+ $pre = array_map('preg_quote_cb', $pre);
+ }
+ foreach (array('user', 'style', 'data') as $key) {
+ if (!isset($pre[$key])) {
+ $pre[$key] = '(\S+)';
+ }
+ }
+ return '/^' . $pre['user'] . '(?: ' . $pre['style'] .
+ '(?: ' . $pre['data'] . ')?)?$/';
+}
+
+/**
+ * Return a string with the email addresses of all the
+ * users subscribed to a page
+ *
+ * This is the default action for COMMON_NOTIFY_ADDRESSLIST.
+ *
+ * @param array $data Containing $id (the page id), $self (whether the author
+ * should be notified, $addresslist (current email address
+ * list)
+ *
+ * @author Steven Danz <steven-danz@kc.rr.com>
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_addresslist(&$data){
+ global $conf;
+ global $auth;
+
+ $id = $data['id'];
+ $self = $data['self'];
+ $addresslist = $data['addresslist'];
+
+ if (!$conf['subscribers'] || $auth === null) {
+ return '';
+ }
+ $pres = array('style' => 'every', 'escaped' => true);
+ if (!$self && isset($_SERVER['REMOTE_USER'])) {
+ $pres['user'] = '((?!' . preg_quote_cb($_SERVER['REMOTE_USER']) .
+ '(?: |$))\S+)';
+ }
+ $subs = subscription_find($id, $pres);
+ $emails = array();
+ foreach ($subs as $by_targets) {
+ foreach ($by_targets as $sub) {
+ $info = $auth->getUserData($sub[0]);
+ if ($info === false) continue;
+ $level = auth_aclcheck($id, $sub[0], $info['grps']);
+ if ($level >= AUTH_READ) {
+ if (strcasecmp($info['mail'], $conf['notify']) != 0) {
+ $emails[$sub[0]] = $info['mail'];
+ }
+ }
+ }
+ }
+ $data['addresslist'] = trim($addresslist . ',' . implode(',', $emails), ',');
+}
+
+/**
+ * Send a digest mail
+ *
+ * Sends a digest mail showing a bunch of changes.
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param array $id The ID
+ * @param int $lastupdate Time of the last notification
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_send_digest($subscriber_mail, $id, $lastupdate) {
+ $n = 0;
+ do {
+ $rev = getRevisions($id, $n++, 1);
+ $rev = (count($rev) > 0) ? $rev[0] : null;
+ } while (!is_null($rev) && $rev > $lastupdate);
+
+ $replaces = array('NEWPAGE' => wl($id, '', true, '&'),
+ 'SUBSCRIBE' => wl($id, array('do' => 'subscribe'), true, '&'));
+ if (!is_null($rev)) {
+ $subject = 'changed';
+ $replaces['OLDPAGE'] = wl($id, "rev=$rev", true, '&');
+ $df = new Diff(explode("\n", rawWiki($id, $rev)),
+ explode("\n", rawWiki($id)));
+ $dformat = new UnifiedDiffFormatter();
+ $replaces['DIFF'] = $dformat->format($df);
+ } else {
+ $subject = 'newpage';
+ $replaces['OLDPAGE'] = 'none';
+ $replaces['DIFF'] = rawWiki($id);
+ }
+ subscription_send($subscriber_mail, $replaces, $subject, $id,
+ 'subscr_digest');
+}
+
+/**
+ * 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
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_send_list($subscriber_mail, $ids, $ns_id) {
+ if (count($ids) === 0) return;
+ global $conf;
+ $list = '';
+ foreach ($ids as $id) {
+ $list .= '* ' . wl($id, array(), true) . NL;
+ }
+ subscription_send($subscriber_mail,
+ array('DIFF' => rtrim($list),
+ 'SUBSCRIBE' => wl($ns_id . $conf['start'],
+ array('do' => 'subscribe'),
+ true, '&')),
+ 'subscribe_list',
+ prettyprint_id($ns_id),
+ 'subscr_list');
+}
+
+/**
+ * Helper function for sending a mail
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param array $replaces Predefined parameters used to parse the
+ * template
+ * @param string $subject The lang id of the mail subject (without the
+ * prefix “mail_”)
+ * @param string $id The page or namespace id
+ * @param string $template The name of the mail template
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function subscription_send($subscriber_mail, $replaces, $subject, $id, $template) {
+ global $conf;
+
+ $text = rawLocale($template);
+ $replaces = array_merge($replaces, array('TITLE' => $conf['title'],
+ 'DOKUWIKIURL' => DOKU_URL,
+ 'PAGE' => $id));
+
+ foreach ($replaces as $key => $substitution) {
+ $text = str_replace('@'.strtoupper($key).'@', $substitution, $text);
+ }
+
+ global $lang;
+ $subject = $lang['mail_' . $subject] . ' ' . $id;
+ mail_send('', '['.$conf['title'].'] '. $subject, $text,
+ $conf['mailfrom'], '', $subscriber_mail);
+}
diff --git a/inc/template.php b/inc/template.php
new file mode 100644
index 000000000..c23fd14c1
--- /dev/null
+++ b/inc/template.php
@@ -0,0 +1,1613 @@
+<?php
+/**
+ * DokuWiki template functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * Returns the path to the given template, uses
+ * default one if the custom version doesn't exist.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function template($tpl){
+ global $conf;
+
+ if(@is_readable(DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$tpl))
+ return DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$tpl;
+
+ return DOKU_INC.'lib/tpl/default/'.$tpl;
+}
+
+
+/**
+ * Convenience function to access template dir from local FS
+ *
+ * This replaces the deprecated DOKU_TPLINC constant
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_incdir(){
+ global $conf;
+ return DOKU_INC.'lib/tpl/'.$conf['template'].'/';
+}
+
+/**
+ * Convenience function to access template dir from web
+ *
+ * This replaces the deprecated DOKU_TPL constant
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_basedir(){
+ global $conf;
+ return DOKU_BASE.'lib/tpl/'.$conf['template'].'/';
+}
+
+/**
+ * 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>
+ */
+function tpl_content($prependTOC=true) {
+ global $ACT;
+ global $INFO;
+ $INFO['prependTOC'] = $prependTOC;
+
+ ob_start();
+ trigger_event('TPL_ACT_RENDER',$ACT,'tpl_content_core');
+ $html_output = ob_get_clean();
+ trigger_event('TPL_CONTENT_DISPLAY',$html_output,'ptln');
+
+ return !empty($html_output);
+}
+
+function tpl_content_core(){
+ global $ACT;
+ global $TEXT;
+ global $PRE;
+ global $SUF;
+ global $SUM;
+ global $IDX;
+
+ switch($ACT){
+ case 'show':
+ html_show();
+ break;
+ case 'locked':
+ html_locked();
+ case 'edit':
+ case 'recover':
+ html_edit();
+ break;
+ case 'preview':
+ html_edit();
+ html_show($TEXT);
+ break;
+ case 'draft':
+ html_draft();
+ break;
+ case 'search':
+ html_search();
+ break;
+ case 'revisions':
+ $first = isset($_REQUEST['first']) ? intval($_REQUEST['first']) : 0;
+ html_revisions($first);
+ break;
+ case 'diff':
+ html_diff();
+ break;
+ case 'recent':
+ if (is_array($_REQUEST['first'])) {
+ $_REQUEST['first'] = array_keys($_REQUEST['first']);
+ $_REQUEST['first'] = $_REQUEST['first'][0];
+ }
+ $first = is_numeric($_REQUEST['first']) ? intval($_REQUEST['first']) : 0;
+ $show_changes = $_REQUEST['show_changes'];
+ html_recent($first, $show_changes);
+ break;
+ case 'index':
+ html_index($IDX); #FIXME can this be pulled from globals? is it sanitized correctly?
+ break;
+ case 'backlink':
+ html_backlinks();
+ break;
+ case 'conflict':
+ html_conflict(con($PRE,$TEXT,$SUF),$SUM);
+ html_diff(con($PRE,$TEXT,$SUF),false);
+ break;
+ case 'login':
+ html_login();
+ break;
+ case 'register':
+ html_register();
+ break;
+ case 'resendpwd':
+ html_resendpwd();
+ break;
+ case 'denied':
+ print p_locale_xhtml('denied');
+ break;
+ case 'profile' :
+ html_updateprofile();
+ break;
+ case 'admin':
+ tpl_admin();
+ break;
+ case 'subscribe':
+ tpl_subscribe();
+ break;
+ case 'media':
+ tpl_media();
+ break;
+ default:
+ $evt = new Doku_Event('TPL_ACT_UNKNOWN',$ACT);
+ if ($evt->advise_before())
+ msg("Failed to handle command: ".hsc($ACT),-1);
+ $evt->advise_after();
+ unset($evt);
+ 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>
+ */
+function tpl_toc($return=false){
+ global $TOC;
+ global $ACT;
+ global $ID;
+ global $REV;
+ global $INFO;
+ global $conf;
+ $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, false, METADATA_RENDER_USING_CACHE);
+ if(isset($meta['internal']['toc'])){
+ $tocok = $meta['internal']['toc'];
+ }else{
+ $tocok = true;
+ }
+ $toc = $meta['description']['tableofcontents'];
+ if(!$tocok || !is_array($toc) || !$conf['tocminheads'] || count($toc) < $conf['tocminheads']){
+ $toc = array();
+ }
+ }elseif($ACT == 'admin'){
+ // try to load admin plugin TOC FIXME: duplicates code from tpl_admin
+ $plugin = null;
+ if (!empty($_REQUEST['page'])) {
+ $pluginlist = plugin_list('admin');
+ if (in_array($_REQUEST['page'], $pluginlist)) {
+ // attempt to load the plugin
+ $plugin =& plugin_load('admin',$_REQUEST['page']);
+ }
+ }
+ if ( ($plugin !== null) &&
+ (!$plugin->forAdminOnly() || $INFO['isadmin']) ){
+ $toc = $plugin->getTOC();
+ $TOC = $toc; // avoid later rebuild
+ }
+ }
+
+ trigger_event('TPL_TOC_RENDER', $toc, null, false);
+ $html = html_TOC($toc);
+ if($return) return $html;
+ echo $html;
+}
+
+/**
+ * Handle the admin page contents
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_admin(){
+ global $INFO;
+ global $TOC;
+
+ $plugin = null;
+ if (!empty($_REQUEST['page'])) {
+ $pluginlist = plugin_list('admin');
+
+ if (in_array($_REQUEST['page'], $pluginlist)) {
+
+ // attempt to load the plugin
+ $plugin =& plugin_load('admin',$_REQUEST['page']);
+ }
+ }
+
+ if ($plugin !== null){
+ if(!is_array($TOC)) $TOC = $plugin->getTOC(); //if TOC wasn't requested yet
+ if($INFO['prependTOC']) tpl_toc();
+ $plugin->html();
+ }else{
+ html_admin();
+ }
+ return true;
+}
+
+/**
+ * Print the correct HTML meta headers
+ *
+ * This has to go into the head section of your template.
+ *
+ * @triggers TPL_METAHEADER_OUTPUT
+ * @param boolean $alt Should feeds and alternative format links be added?
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_metaheaders($alt=true){
+ global $ID;
+ global $REV;
+ global $INFO;
+ global $JSINFO;
+ global $ACT;
+ global $QUERY;
+ global $lang;
+ global $conf;
+ $it=2;
+
+ // prepare the head array
+ $head = array();
+
+ // prepare seed for js and css
+ $tseed = 0;
+ $depends = getConfigFiles('main');
+ foreach($depends as $f) {
+ $time = @filemtime($f);
+ if($time > $tseed) $tseed = $time;
+ }
+
+ // the usual stuff
+ $head['meta'][] = array( 'name'=>'generator', 'content'=>'DokuWiki');
+ $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($alt){
+ $head['link'][] = array( 'rel'=>'alternate', 'type'=>'application/rss+xml',
+ 'title'=>'Recent Changes', 'href'=>DOKU_BASE.'feed.php');
+ $head['link'][] = array( 'rel'=>'alternate', 'type'=>'application/rss+xml',
+ 'title'=>'Current Namespace',
+ 'href'=>DOKU_BASE.'feed.php?mode=list&ns='.$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($ACT == 'search'){
+ $head['link'][] = array( 'rel'=>'alternate', 'type'=>'application/rss+xml',
+ 'title'=>'Search Result',
+ 'href'=>DOKU_BASE.'feed.php?mode=search&q='.$QUERY);
+ }
+
+ if(actionOK('export_xhtml')){
+ $head['link'][] = array( 'rel'=>'alternate', 'type'=>'text/html', 'title'=>'Plain HTML',
+ 'href'=>exportlink($ID, 'xhtml', '', false, '&'));
+ }
+
+ if(actionOK('export_raw')){
+ $head['link'][] = array( 'rel'=>'alternate', 'type'=>'text/plain', 'title'=>'Wiki Markup',
+ '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']){
+ $head['meta'][] = array( 'name'=>'robots', 'content'=>'index,follow');
+ }else{
+ $head['meta'][] = array( 'name'=>'robots', 'content'=>'noindex,nofollow');
+ }
+ $head['link'][] = array( 'rel'=>'canonical', 'href'=>wl($ID,'',true,'&') );
+ }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'){
+ // date of modification
+ if($REV){
+ $head['meta'][] = array( 'name'=>'date', 'content'=>date('Y-m-d\TH:i:sO',$REV));
+ }else{
+ $head['meta'][] = array( 'name'=>'date', 'content'=>date('Y-m-d\TH:i:sO',$INFO['lastmod']));
+ }
+
+ // 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', 'media'=>'screen', 'type'=>'text/css',
+ 'href'=>DOKU_BASE.'lib/exe/css.php?t='.$conf['template'].'&tseed='.$tseed);
+ $head['link'][] = array('rel'=>'stylesheet', 'media'=>'all', 'type'=>'text/css',
+ 'href'=>DOKU_BASE.'lib/exe/css.php?s=all&t='.$conf['template'].'&tseed='.$tseed);
+ $head['link'][] = array('rel'=>'stylesheet', 'media'=>'print', 'type'=>'text/css',
+ 'href'=>DOKU_BASE.'lib/exe/css.php?s=print&t='.$conf['template'].'&tseed='.$tseed);
+
+ // make $INFO and other vars available to JavaScripts
+ $json = new JSON();
+ $script = "var NS='".$INFO['namespace']."';";
+ if($conf['useacl'] && $_SERVER['REMOTE_USER']){
+ $script .= "var SIG='".toolbar_signature()."';";
+ }
+ $script .= 'var JSINFO = '.$json->encode($JSINFO).';';
+ $head['script'][] = array( 'type'=>'text/javascript', '_data'=> $script);
+
+ // load external javascript
+ $head['script'][] = array( 'type'=>'text/javascript', 'charset'=>'utf-8', '_data'=>'',
+ 'src'=>DOKU_BASE.'lib/exe/js.php'.'?tseed='.$tseed);
+
+ // trigger event here
+ trigger_event('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 the body data in the special
+ * attribute '_data'. This field will NOT BE ESCAPED automatically.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function _tpl_metaheaders_action($data){
+ foreach($data as $tag => $inst){
+ foreach($inst as $attr){
+ echo '<',$tag,' ',buildAttributes($attr);
+ if(isset($attr['_data']) || $tag == 'script'){
+ if($tag == 'script' && $attr['_data'])
+ $attr['_data'] = "<!--//--><![CDATA[//><!--\n".
+ $attr['_data'].
+ "\n//--><!]]>";
+
+ echo '>',$attr['_data'],'</',$tag,'>';
+ }else{
+ echo '/>';
+ }
+ echo "\n";
+ }
+ }
+}
+
+/**
+ * Print a link
+ *
+ * Just builds a link.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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>
+ */
+function tpl_pagelink($id,$name=null){
+ print html_wikilink($id,$name);
+ 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>
+ */
+function tpl_getparent($id){
+ global $conf;
+ $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
+ */
+function tpl_button($type,$return=false){
+ $data = tpl_get_action($type);
+ if ($data === false) {
+ return false;
+ } elseif (!is_array($data)) {
+ $out = sprintf($data, 'button');
+ } else {
+ 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
+ */
+function tpl_actionlink($type,$pre='',$suf='',$inner='',$return=false){
+ global $lang;
+ $data = tpl_get_action($type);
+ if ($data === false) {
+ return false;
+ } elseif (!is_array($data)) {
+ $out = sprintf($data, 'link');
+ } else {
+ extract($data);
+ if (strpos($id, '#') === 0) {
+ $linktarget = $id;
+ } else {
+ $linktarget = wl($id, $params);
+ }
+ $caption = $lang['btn_' . $type];
+ $akey = $addTitle = '';
+ if($accesskey){
+ $akey = 'accesskey="'.$accesskey.'" ';
+ $addTitle = ' ['.strtoupper($accesskey).']';
+ }
+ $out = tpl_link($linktarget, $pre.(($inner)?$inner:$caption).$suf,
+ 'class="action ' . $type . '" ' .
+ $akey . 'rel="nofollow" ' .
+ 'title="' . hsc($caption).$addTitle . '"', 1);
+ }
+ if ($return) return $out;
+ echo $out;
+ return true;
+}
+
+/**
+ * Check the actions and get data for buttons and links
+ *
+ * Available actions are
+ *
+ * edit - edit/create/show/draft
+ * history - old revisions
+ * recent - recent changes
+ * login - login/logout - if ACL enabled
+ * profile - user profile (if logged in)
+ * index - The index
+ * admin - admin page - if enough rights
+ * top - back to top
+ * back - back to parent - if available
+ * backlink - links to the list of backlinks
+ * subscribe/subscription- subscribe/unsubscribe
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Adrian Lang <mail@adrianlang.de>
+ */
+function tpl_get_action($type) {
+ global $ID;
+ global $INFO;
+ global $REV;
+ global $ACT;
+ global $conf;
+ global $auth;
+
+ // check disabled actions and fix the badly named ones
+ if($type == 'history') $type='revisions';
+ if(!actionOK($type)) return false;
+
+ $accesskey = null;
+ $id = $ID;
+ $method = 'get';
+ $params = array('do' => $type);
+ switch($type){
+ case 'edit':
+ // most complicated type - we need to decide on current action
+ if($ACT == 'show' || $ACT == 'search'){
+ $method = 'post';
+ if($INFO['writable']){
+ $accesskey = 'e';
+ if(!empty($INFO['draft'])) {
+ $type = 'draft';
+ $params['do'] = 'draft';
+ } else {
+ $params['rev'] = $REV;
+ if(!$INFO['exists']){
+ $type = 'create';
+ }
+ }
+ }else{
+ if(!actionOK('source')) return false; //pseudo action
+ $params['rev'] = $REV;
+ $type = 'source';
+ $accesskey = 'v';
+ }
+ }else{
+ $params = '';
+ $type = 'show';
+ $accesskey = 'v';
+ }
+ break;
+ case 'revisions':
+ $type = 'revs';
+ $accesskey = 'o';
+ break;
+ case 'recent':
+ $accesskey = 'r';
+ break;
+ case 'index':
+ $accesskey = 'x';
+ break;
+ case 'top':
+ $accesskey = 'x';
+ $params = '';
+ $id = '#dokuwiki__top';
+ break;
+ case 'back':
+ $parent = tpl_getparent($ID);
+ if (!$parent) {
+ return false;
+ }
+ $id = $parent;
+ $params = '';
+ $accesskey = 'b';
+ break;
+ case 'login':
+ $params['sectok'] = getSecurityToken();
+ if(isset($_SERVER['REMOTE_USER'])){
+ if (!actionOK('logout')) {
+ return false;
+ }
+ $params['do'] = 'logout';
+ $type = 'logout';
+ }
+ break;
+ case 'register':
+ if($_SERVER['REMOTE_USER']){
+ return false;
+ }
+ break;
+ case 'resendpwd':
+ if($_SERVER['REMOTE_USER']){
+ return false;
+ }
+ break;
+ case 'admin':
+ if(!$INFO['ismanager']){
+ return false;
+ }
+ break;
+ case 'revert':
+ if(!$INFO['ismanager'] || !$REV || !$INFO['writable']) {
+ return false;
+ }
+ $params['rev'] = $REV;
+ $params['sectok'] = getSecurityToken();
+ break;
+ case 'subscription':
+ $type = 'subscribe';
+ $params['do'] = 'subscribe';
+ case 'subscribe':
+ if(!$_SERVER['REMOTE_USER']){
+ return false;
+ }
+ break;
+ case 'backlink':
+ break;
+ case 'profile':
+ if(!isset($_SERVER['REMOTE_USER'])){
+ return false;
+ }
+ break;
+ case 'media':
+ break;
+ default:
+ return '[unknown %s type]';
+ break;
+ }
+ return compact('accesskey', 'type', 'id', 'method', 'params');
+}
+
+/**
+ * Wrapper around tpl_button() and tpl_actionlink()
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+function tpl_action($type,$link=0,$wrapper=false,$return=false,$pre='',$suf='',$inner='') {
+ $out = '';
+ if ($link) $out .= tpl_actionlink($type,$pre,$suf,$inner,1);
+ else $out .= tpl_button($type,1);
+ 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>
+ */
+function tpl_searchform($ajax=true,$autocomplete=true){
+ global $lang;
+ global $ACT;
+ global $QUERY;
+
+ // don't print the search form if search action has been disabled
+ if (!actionOk('search')) return false;
+
+ print '<form action="'.wl().'" accept-charset="utf-8" class="search" id="dw__search" method="get"><div class="no">';
+ print '<input type="hidden" name="do" value="search" />';
+ print '<input type="text" ';
+ if($ACT == 'search') print 'value="'.htmlspecialchars($QUERY).'" ';
+ if(!$autocomplete) print 'autocomplete="off" ';
+ print 'id="qsearch__in" accesskey="f" name="id" class="edit" title="[F]" />';
+ print '<input type="submit" value="'.$lang['btn_search'].'" class="button" title="'.$lang['btn_search'].'" />';
+ if($ajax) print '<div id="qsearch__out" class="ajax_qsearch JSpopup"></div>';
+ print '</div></form>';
+ return true;
+}
+
+/**
+ * Print the breadcrumbs trace
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_breadcrumbs($sep='&bull;'){
+ global $lang;
+ global $conf;
+
+ //check if enabled
+ if(!$conf['breadcrumbs']) return false;
+
+ $crumbs = breadcrumbs(); //setup crumb trace
+
+ //reverse crumborder in right-to-left mode, add RLM character to fix heb/eng display mixups
+ if($lang['direction'] == 'rtl') {
+ $crumbs = array_reverse($crumbs,true);
+ $crumbs_sep = ' &#8207;<span class="bcsep">'.$sep.'</span>&#8207; ';
+ } else {
+ $crumbs_sep = ' <span class="bcsep">'.$sep.'</span> ';
+ }
+
+ //render crumbs, highlight the last one
+ print '<span class="bchead">'.$lang['breadcrumb'].':</span>';
+ $last = count($crumbs);
+ $i = 0;
+ foreach ($crumbs as $id => $name){
+ $i++;
+ echo $crumbs_sep;
+ if ($i == $last) print '<span class="curid">';
+ tpl_link(wl($id),hsc($name),'class="breadcrumbs" title="'.$id.'"');
+ if ($i == $last) print '</span>';
+ }
+ return true;
+}
+
+/**
+ * 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
+ */
+function tpl_youarehere($sep=' &raquo; '){
+ global $conf;
+ global $ID;
+ global $lang;
+
+ // check if enabled
+ if(!$conf['youarehere']) return false;
+
+ $parts = explode(':', $ID);
+ $count = count($parts);
+
+ echo '<span class="bchead">'.$lang['youarehere'].': </span>';
+
+ // always print the startpage
+ tpl_pagelink(':'.$conf['start']);
+
+ // 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
+ echo $sep;
+ tpl_pagelink($page);
+ }
+
+ // print current page, skipping start page, skipping for namespace index
+ resolve_pageid('',$page,$exists);
+ if(isset($page) && $page==$part.$parts[$i]) return;
+ $page = $part.$parts[$i];
+ if($page == $conf['start']) return;
+ echo $sep;
+ tpl_pagelink($page);
+ return true;
+}
+
+/**
+ * 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>
+ */
+function tpl_userinfo(){
+ global $lang;
+ global $INFO;
+ if(isset($_SERVER['REMOTE_USER'])){
+ print $lang['loggedinas'].': '.hsc($INFO['userinfo']['name']).' ('.hsc($_SERVER['REMOTE_USER']).')';
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Print some info about the current page
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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(fullpath($conf['olddir']).'/','',$fn);
+ }else{
+ $fn = str_replace(fullpath($conf['datadir']).'/','',$fn);
+ }
+ }
+ $fn = utf8_decodeFN($fn);
+ $date = dformat($INFO['lastmod']);
+
+ // print it
+ if($INFO['exists']){
+ $out = '';
+ $out .= $fn;
+ $out .= ' &middot; ';
+ $out .= $lang['lastmod'];
+ $out .= ': ';
+ $out .= $date;
+ if($INFO['editor']){
+ $out .= ' '.$lang['by'].' ';
+ $out .= editorinfo($INFO['editor']);
+ }else{
+ $out .= ' ('.$lang['external_edit'].')';
+ }
+ if($INFO['locked']){
+ $out .= ' &middot; ';
+ $out .= $lang['lockedby'];
+ $out .= ': ';
+ $out .= editorinfo($INFO['locked']);
+ }
+ 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>
+ */
+function tpl_pagetitle($id=null, $ret=false){
+ global $conf;
+ if(is_null($id)){
+ global $ID;
+ $id = $ID;
+ }
+
+ $name = $id;
+ if (useHeading('navigation')) {
+ $title = p_get_first_heading($id);
+ if ($title) $name = $title;
+ }
+
+ if ($ret) {
+ return hsc($name);
+ } else {
+ print hsc($name);
+ 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>
+ */
+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 = $meta->getField($tags);
+ if($info == false) return $alt;
+ return $info;
+}
+
+/**
+ * Prints the image with a link to the full sized version
+ *
+ * Only allowed in: detail.php
+ *
+ * @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
+ */
+function tpl_img($maxwidth=0,$maxheight=0,$link=true,$params=null){
+ global $IMG;
+ $w = tpl_img_getTag('File.Width');
+ $h = 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'=>$_REQUEST['cache']),true,'&');
+ $src=ml($IMG,array('cache'=>$_REQUEST['cache'],'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 trigger_event('TPL_IMG_DISPLAY',$data,'_tpl_img_action',true);
+}
+
+/**
+ * Default action for TPL_IMG_DISPLAY
+ */
+function _tpl_img_action($data, $param=NULL) {
+ 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
+ */
+function tpl_indexerWebBug(){
+ global $ID;
+ global $INFO;
+ if(!$INFO['exists']) return false;
+
+ $p = array();
+ $p['src'] = DOKU_BASE.'lib/exe/indexer.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;
+}
+
+// configuration methods
+/**
+ * tpl_getConf($id)
+ *
+ * use this function to access template configuration variables
+ */
+function tpl_getConf($id){
+ 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;
+ }
+ }
+
+ return $conf['tpl'][$tpl][$id];
+}
+
+/**
+ * tpl_loadConfig()
+ * reads all template configuration variables
+ * this function is automatically called by tpl_getConf()
+ */
+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
+ */
+function tpl_getLang($id){
+ static $lang = array();
+
+ if (count($lang) === 0){
+ $path = tpl_incdir().'lang/';
+
+ $lang = array();
+
+ global $conf; // definitely don't invoke "global $lang"
+ // don't include once
+ @include($path.'en/lang.php');
+ if ($conf['lang'] != 'en') @include($path.$conf['lang'].'/lang.php');
+ }
+
+ return $lang[$id];
+}
+
+/**
+ * prints the "main content" in the mediamanger 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
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_mediaContent($fromajax=false){
+ global $IMG;
+ global $AUTH;
+ global $INUSE;
+ global $NS;
+ global $JUMPTO;
+
+ if(is_array($_REQUEST['do'])){
+ $do = array_shift(array_keys($_REQUEST['do']));
+ }else{
+ $do = $_REQUEST['do'];
+ }
+ if(in_array($do,array('save','cancel'))) $do = '';
+
+ if(!$do){
+ if($_REQUEST['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 Doku_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);
+ }elseif($do == 'searchlist'){
+ media_searchlist($_REQUEST['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;
+
+ $opened_tab = $_REQUEST['tab_files'];
+ if (!$opened_tab || !in_array($opened_tab, array('files', 'upload', 'search'))) $opened_tab = 'files';
+ if ($_REQUEST['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>'.$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>
+ */
+function tpl_mediaFileDetails($image, $rev){
+ global $AUTH, $NS, $conf, $DEL, $lang;
+
+ $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;
+ if (isset($NS) && getNS($image) != $NS) return '';
+ $do = $_REQUEST['mediado'];
+
+ $opened_tab = $_REQUEST['tab_details'];
+
+ $tab_array = array('view');
+ list($ext, $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 ($_REQUEST['edit']) $opened_tab = 'edit';
+ if ($do == 'restore') $opened_tab = 'view';
+
+ media_tabs_details($image, $opened_tab);
+
+ echo '<div class="panelHeader"><h3>';
+ list($ext,$mime,$dl) = mimetype($image,false);
+ $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext);
+ $class = 'select mediafile mf_'.$class;
+ $tabTitle = '<strong class="'.$class.'">'.$image.'</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, $AUTH, $rev);
+
+ } elseif ($opened_tab == 'edit' && !$removed) {
+ media_tab_edit($image, $NS, $AUTH);
+
+ } elseif ($opened_tab == 'history' && $conf['mediarevisions']) {
+ media_tab_history($image,$NS,$AUTH);
+ }
+
+ echo '</div>'.NL;
+}
+
+/**
+ * prints the namespace tree in the mediamanger 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>
+ */
+function tpl_actiondropdown($empty='',$button='&gt;'){
+ global $ID;
+ global $INFO;
+ global $REV;
+ global $ACT;
+ global $conf;
+ global $lang;
+ global $auth;
+
+ echo '<form action="' . DOKU_SCRIPT . '" method="post" accept-charset="utf-8">';
+ echo '<div class="no">';
+ echo '<input type="hidden" name="id" value="'.$ID.'" />';
+ if($REV) echo '<input type="hidden" name="rev" value="'.$REV.'" />';
+ echo '<input type="hidden" name="sectok" value="'.getSecurityToken().'" />';
+
+ echo '<select name="do" class="edit quickselect">';
+ echo '<option value="">'.$empty.'</option>';
+
+ echo '<optgroup label="'.$lang['page_tools'].'">';
+ $act = tpl_get_action('edit');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+
+ $act = tpl_get_action('revert');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+
+ $act = tpl_get_action('revisions');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+
+ $act = tpl_get_action('backlink');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+
+ $act = tpl_get_action('subscribe');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+ echo '</optgroup>';
+
+ echo '<optgroup label="'.$lang['site_tools'].'">';
+ $act = tpl_get_action('recent');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+
+ $act = tpl_get_action('media');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+
+ $act = tpl_get_action('index');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+ echo '</optgroup>';
+
+ echo '<optgroup label="'.$lang['user_tools'].'">';
+ $act = tpl_get_action('login');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+
+ $act = tpl_get_action('register');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+
+ $act = tpl_get_action('profile');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+
+ $act = tpl_get_action('admin');
+ if($act) echo '<option value="'.$act['params']['do'].'">'.$lang['btn_'.$act['type']].'</option>';
+ echo '</optgroup>';
+
+ echo '</select>';
+ echo '<input type="submit" value="'.$button.'" />';
+ echo '</div>';
+ echo '</form>';
+}
+
+/**
+ * Print a informational line about the used license
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $img - print image? (|button|badge)
+ * @param bool $return - when true don't print, but return HTML
+ */
+function tpl_license($img='badge',$imgonly=false,$return=false){
+ global $license;
+ global $conf;
+ global $lang;
+ if(!$conf['license']) return '';
+ if(!is_array($license[$conf['license']])) return '';
+ $lic = $license[$conf['license']];
+
+ $out = '<div class="license">';
+ if($img){
+ $src = license_img($img);
+ if($src){
+ $out .= '<a href="'.$lic['url'].'" rel="license"';
+ if($conf['target']['extern']) $out .= ' target="'.$conf['target']['extern'].'"';
+ $out .= '><img src="'.DOKU_BASE.$src.'" class="medialeft lic'.$img.'" alt="'.$lic['name'].'" /></a> ';
+ }
+ }
+ if(!$imgonly) {
+ $out .= $lang['license'];
+ $out .= ' <a href="'.$lic['url'].'" rel="license" class="urlextern"';
+ if($conf['target']['extern']) $out .= ' target="'.$conf['target']['extern'].'"';
+ $out .= '>'.$lic['name'].'</a>';
+ }
+ $out .= '</div>';
+
+ if($return) return $out;
+ echo $out;
+}
+
+
+/**
+ * Includes the rendered XHTML of a given page
+ *
+ * This function is useful to populate sidebars or similar features in a
+ * template
+ */
+function tpl_include_page($pageid,$print=true){
+ global $ID;
+ global $TOC;
+ $oldid = $ID;
+ $oldtoc = $TOC;
+ $html = p_wiki_xhtml($pageid,'',false);
+ $ID = $oldid;
+ $TOC = $oldtoc;
+
+ if(!$print) return $html;
+ echo $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(){
+ 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 array $search locations to look at
+ * @param bool $abs if to use absolute URL
+ * @param arrayref $imginfo filled with getimagesize()
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_getMediaFile($search, $abs=false, &$imginfo=null){
+ // 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;
+ }
+
+ // 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;
+}
+
+/**
+ * Returns icon from data/media root directory if it exists, otherwise
+ * the one in the template's image directory.
+ *
+ * @deprecated Use tpl_getMediaFile() instead
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+function tpl_getFavicon($abs=false, $fileName='favicon.ico') {
+ $look = array(":wiki:$fileName", ":$fileName", "images/$fileName");
+ return tpl_getMediaFile($look, $abs);
+}
+
+/**
+ * Returns <link> tag for various icon types (favicon|mobile|generic)
+ *
+ * @param array $types - list of icon types to display (favicon|mobile|generic)
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+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.ico');
+ $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 $DEL, $NS, $IMG, $AUTH, $JUMPTO, $REV, $lang, $fullscreen, $conf;
+ $fullscreen = true;
+ require_once DOKU_INC.'lib/exe/mediamanager.php';
+
+ if ($_REQUEST['image']) $image = cleanID($_REQUEST['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;
+}
+
+//Setup VIM: ex: et ts=4 :
+
diff --git a/inc/toolbar.php b/inc/toolbar.php
new file mode 100644
index 000000000..02172510e
--- /dev/null
+++ b/inc/toolbar.php
@@ -0,0 +1,255 @@
+<?php
+/**
+ * Editing toolbar functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) die('meh.');
+
+/**
+ * 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 Doku_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' => 'c',
+ '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' => explode(' ','À à Á á  â à ã Ä ä Ǎ ǎ Ă ă Å å Ā ā Ą ą Æ æ Ć ć Ç ç Č č Ĉ ĉ Ċ ċ Ð đ ð Ď ď È è É é Ê ê Ë ë Ě ě Ē ē Ė ė Ę ę Ģ ģ Ĝ ĝ Ğ ğ Ġ ġ Ĥ ĥ Ì ì Í í Î î Ï ï Ǐ ǐ Ī ī İ ı Į į Ĵ ĵ Ķ ķ Ĺ ĺ Ļ ļ Ľ ľ Ł ł Ŀ ŀ Ń ń Ñ ñ Ņ ņ Ň ň Ò ò Ó ó Ô ô Õ õ Ö ö Ǒ ǒ Ō ō Ő ő Œ œ Ø ø Ŕ ŕ Ŗ ŗ Ř ř Ś ś Ş ş Š š Ŝ ŝ Ţ ţ Ť ť Ù ù Ú ú Û û Ü ü Ǔ ǔ Ŭ ŭ Ū ū Ů ů ǖ ǘ ǚ ǜ Ų ų Ű ű Ŵ ŵ Ý ý Ÿ ÿ Ŷ ŷ Ź ź Ž ž Ż ż Þ þ ß Ħ ħ ¿ ¡ ¢ £ ¤ ¥ € ¦ § ª ¬ ¯ ° ± ÷ ‰ ¼ ½ ¾ ¹ ² ³ µ ¶ † ‡ · • º ∀ ∂ ∃ Ə ə ∅ ∇ ∈ ∉ ∋ ∏ ∑ ‾ − ∗ × ⁄ √ ∝ ∞ ∠ ∧ ∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ ≥ ⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ◊ ℘ ℑ ℜ ℵ ♠ ♣ ♥ ♦ α β Γ γ Δ δ ε ζ η Θ θ ι κ Λ λ μ Ξ ξ Π π ρ Σ σ Τ τ υ Φ φ χ Ψ ψ Ω ω ★ ☆ ☎ ☚ ☛ ☜ ☝ ☞ ☟ ☹ ☺ ✔ ✘ „ “ ” ‚ ‘ ’ « » ‹ › — – … ← ↑ → ↓ ↔ ⇐ ⇑ ⇒ ⇓ ⇔ © ™ ® ′ ″ [ ] { } ~ ( ) % § $ # | @'),
+ '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
+ $json = new JSON();
+ 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;
+
+ $sig = $conf['signature'];
+ $sig = strftime($sig);
+ $sig = str_replace('@USER@',$_SERVER['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',addslashes($sig));
+ return $sig;
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/inc/utf8.php b/inc/utf8.php
new file mode 100644
index 000000000..9d0d17f78
--- /dev/null
+++ b/inc/utf8.php
@@ -0,0 +1,1624 @@
+<?php
+/**
+ * UTF8 helper functions
+ *
+ * @license LGPL 2.1 (http://www.gnu.org/copyleft/lesser.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+/**
+ * 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);
+ }
+}
+
+if(UTF8_MBSTRING){ mb_internal_encoding('UTF-8'); }
+
+if(!function_exists('utf8_isASCII')){
+ /**
+ * Checks if a string contains 7bit ASCII only
+ *
+ * @author Andreas Haerter <andreas.haerter@dev.mail-node.com>
+ */
+ function utf8_isASCII($str){
+ return (preg_match('/(?:[^\x00-\x7F])/', $str) !== 1);
+ }
+}
+
+if(!function_exists('utf8_strip')){
+ /**
+ * Strips all highbyte chars
+ *
+ * Returns a pure ASCII7 string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function utf8_strip($str){
+ $ascii = '';
+ $len = strlen($str);
+ for($i=0; $i<$len; $i++){
+ if(ord($str{$i}) <128){
+ $ascii .= $str{$i};
+ }
+ }
+ return $ascii;
+ }
+}
+
+if(!function_exists('utf8_check')){
+ /**
+ * Tries to detect if a string is in Unicode encoding
+ *
+ * @author <bmorel@ssi.fr>
+ * @link http://www.php.net/manual/en/function.utf8-encode.php
+ */
+ function utf8_check($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;
+ }
+}
+
+if(!function_exists('utf8_strlen')){
+ /**
+ * 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.
+ *
+ * @author <chernyshevsky at hotmail dot com>
+ * @see strlen()
+ * @see utf8_decode()
+ */
+ function utf8_strlen($string){
+ return strlen(utf8_decode($string));
+ }
+}
+
+if(!function_exists('utf8_substr')){
+ /**
+ * UTF-8 aware alternative to substr
+ *
+ * Return part of a string given character offset (and optionally length)
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param string
+ * @param integer number of UTF-8 characters offset (from left)
+ * @param integer (optional) length in UTF-8 characters from offset
+ * @return mixed string or false if failure
+ */
+ function utf8_substr($str, $offset, $length = null) {
+ if(UTF8_MBSTRING){
+ if( $length === null ){
+ return mb_substr($str, $offset);
+ }else{
+ 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 (!is_null($length)) $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 = strlen(utf8_decode($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 (is_null($length)) {
+ $length_pattern = '(.*)$'; // the rest of the string
+ } else {
+
+ if (!isset($strlen)) $strlen = strlen(utf8_decode($str)); // see notes
+ if ($offset > $strlen) return ''; // another trivial case
+
+ if ($length > 0) {
+
+ $length = min($strlen-$offset, $length); // reduce any length that would go passed the end of the string
+
+ $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];
+ }
+}
+
+if(!function_exists('utf8_substr_replace')){
+ /**
+ * Unicode aware replacement for substr_replace()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see substr_replace()
+ */
+ function utf8_substr_replace($string, $replacement, $start , $length=0 ){
+ $ret = '';
+ if($start>0) $ret .= utf8_substr($string, 0, $start);
+ $ret .= $replacement;
+ $ret .= utf8_substr($string, $start+$length);
+ return $ret;
+ }
+}
+
+if(!function_exists('utf8_ltrim')){
+ /**
+ * Unicode aware replacement for ltrim()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see ltrim()
+ * @return string
+ */
+ function utf8_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);
+ }
+}
+
+if(!function_exists('utf8_rtrim')){
+ /**
+ * Unicode aware replacement for rtrim()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see rtrim()
+ * @return string
+ */
+ function utf8_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);
+ }
+}
+
+if(!function_exists('utf8_trim')){
+ /**
+ * Unicode aware replacement for trim()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see trim()
+ * @return string
+ */
+ function utf8_trim($str,$charlist='') {
+ if($charlist == '') return trim($str);
+
+ return utf8_ltrim(utf8_rtrim($str,$charlist),$charlist);
+ }
+}
+
+if(!function_exists('utf8_strtolower')){
+ /**
+ * This is a unicode aware replacement for strtolower()
+ *
+ * Uses mb_string extension if available
+ *
+ * @author Leo Feyer <leo@typolight.org>
+ * @see strtolower()
+ * @see utf8_strtoupper()
+ */
+ function utf8_strtolower($string){
+ if(UTF8_MBSTRING) return mb_strtolower($string,'utf-8');
+
+ global $UTF8_UPPER_TO_LOWER;
+ return strtr($string,$UTF8_UPPER_TO_LOWER);
+ }
+}
+
+if(!function_exists('utf8_strtoupper')){
+ /**
+ * This is a unicode aware replacement for strtoupper()
+ *
+ * Uses mb_string extension if available
+ *
+ * @author Leo Feyer <leo@typolight.org>
+ * @see strtoupper()
+ * @see utf8_strtoupper()
+ */
+ function utf8_strtoupper($string){
+ if(UTF8_MBSTRING) return mb_strtoupper($string,'utf-8');
+
+ global $UTF8_LOWER_TO_UPPER;
+ return strtr($string,$UTF8_LOWER_TO_UPPER);
+ }
+}
+
+if(!function_exists('utf8_ucfirst')){
+ /**
+ * UTF-8 aware alternative to ucfirst
+ * Make a string's first character uppercase
+ *
+ * @author Harry Fuecks
+ * @param string
+ * @return string with first character as upper case (if applicable)
+ */
+ function utf8_ucfirst($str){
+ switch ( utf8_strlen($str) ) {
+ case 0:
+ return '';
+ case 1:
+ return utf8_strtoupper($str);
+ default:
+ preg_match('/^(.{1})(.*)$/us', $str, $matches);
+ return utf8_strtoupper($matches[1]).$matches[2];
+ }
+ }
+}
+
+if(!function_exists('utf8_ucwords')){
+ /**
+ * UTF-8 aware alternative to ucwords
+ * Uppercase the first character of each word in a string
+ *
+ * @author Harry Fuecks
+ * @param string
+ * @return string with first char of each word uppercase
+ * @see http://www.php.net/ucwords
+ */
+ function utf8_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://www.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, 'utf8_ucwords_callback',$str);
+ }
+
+ /**
+ * Callback function for preg_replace_callback call in utf8_ucwords
+ * You don't need to call this yourself
+ *
+ * @author Harry Fuecks
+ * @param array of matches corresponding to a single word
+ * @return string with first char of the word in uppercase
+ * @see utf8_ucwords
+ * @see utf8_strtoupper
+ */
+ function utf8_ucwords_callback($matches) {
+ $leadingws = $matches[2];
+ $ucfirst = utf8_strtoupper($matches[3]);
+ $ucword = utf8_substr_replace(ltrim($matches[0]),$ucfirst,0,1);
+ return $leadingws . $ucword;
+ }
+}
+
+if(!function_exists('utf8_deaccent')){
+ /**
+ * 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>
+ */
+ function utf8_deaccent($string,$case=0){
+ if($case <= 0){
+ global $UTF8_LOWER_ACCENTS;
+ $string = strtr($string,$UTF8_LOWER_ACCENTS);
+ }
+ if($case >= 0){
+ global $UTF8_UPPER_ACCENTS;
+ $string = strtr($string,$UTF8_UPPER_ACCENTS);
+ }
+ return $string;
+ }
+}
+
+if(!function_exists('utf8_romanize')){
+ /**
+ * Romanize a non-latin string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function utf8_romanize($string){
+ if(utf8_isASCII($string)) return $string; //nothing to do
+
+ global $UTF8_ROMANIZATION;
+ return strtr($string,$UTF8_ROMANIZATION);
+ }
+}
+
+if(!function_exists('utf8_stripspecials')){
+ /**
+ * 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)
+ */
+ function utf8_stripspecials($string,$repl='',$additional=''){
+ global $UTF8_SPECIAL_CHARS;
+ global $UTF8_SPECIAL_CHARS2;
+
+ static $specials = null;
+ if(is_null($specials)){
+ #$specials = preg_quote(unicode_to_utf8($UTF8_SPECIAL_CHARS), '/');
+ $specials = preg_quote($UTF8_SPECIAL_CHARS2, '/');
+ }
+
+ return preg_replace('/['.$additional.'\x00-\x19'.$specials.']/u',$repl,$string);
+ }
+}
+
+if(!function_exists('utf8_strpos')){
+ /**
+ * This is an Unicode aware replacement for strpos
+ *
+ * @author Leo Feyer <leo@typolight.org>
+ * @see strpos()
+ * @param string
+ * @param string
+ * @param integer
+ * @return integer
+ */
+ function utf8_strpos($haystack, $needle, $offset=0){
+ $comp = 0;
+ $length = null;
+
+ while (is_null($length) || $length < $offset) {
+ $pos = strpos($haystack, $needle, $offset + $comp);
+
+ if ($pos === false)
+ return false;
+
+ $length = utf8_strlen(substr($haystack, 0, $pos));
+
+ if ($length < $offset)
+ $comp = $pos - $length;
+ }
+
+ return $length;
+ }
+}
+
+if(!function_exists('utf8_tohtml')){
+ /**
+ * Encodes UTF-8 characters to HTML entities
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author <vpribish at shopping dot com>
+ * @link http://www.php.net/manual/en/function.utf8-decode.php
+ */
+ function utf8_tohtml ($str) {
+ $ret = '';
+ foreach (utf8_to_unicode($str) as $cp) {
+ if ($cp < 0x80)
+ $ret .= chr($cp);
+ elseif ($cp < 0x100)
+ $ret .= "&#$cp;";
+ else
+ $ret .= '&#x'.dechex($cp).';';
+ }
+ return $ret;
+ }
+}
+
+if(!function_exists('utf8_unhtml')){
+ /**
+ * 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(utf8_unhtml($s)) -> "&#38;&#38;"
+ * utf8_unhtml(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 Flag controlling decoding of named entities.
+ * @return UTF-8 encoded string with numeric (and named) entities replaced.
+ */
+ function utf8_unhtml($str, $entities=null) {
+ static $decoder = null;
+ if (is_null($decoder))
+ $decoder = new utf8_entity_decoder();
+ if (is_null($entities))
+ return preg_replace_callback('/(&#([Xx])?([0-9A-Za-z]+);)/m',
+ 'utf8_decode_numeric', $str);
+ else
+ return preg_replace_callback('/&(#)?([Xx])?([0-9A-Za-z]+);/m',
+ array(&$decoder, 'decode'), $str);
+ }
+}
+
+if(!function_exists('utf8_decode_numeric')){
+ function utf8_decode_numeric($ent) {
+ switch ($ent[2]) {
+ case 'X':
+ case 'x':
+ $cp = hexdec($ent[3]);
+ break;
+ default:
+ $cp = intval($ent[3]);
+ break;
+ }
+ return unicode_to_utf8(array($cp));
+ }
+}
+
+if(!class_exists('utf8_entity_decoder')){
+ class utf8_entity_decoder {
+ var $table;
+ function utf8_entity_decoder() {
+ $table = get_html_translation_table(HTML_ENTITIES);
+ $table = array_flip($table);
+ $this->table = array_map(array(&$this,'makeutf8'), $table);
+ }
+ function makeutf8($c) {
+ return unicode_to_utf8(array(ord($c)));
+ }
+ function decode($ent) {
+ if ($ent[1] == '#') {
+ return utf8_decode_numeric($ent);
+ } elseif (array_key_exists($ent[0],$this->table)) {
+ return $this->table[$ent[0]];
+ } else {
+ return $ent[0];
+ }
+ }
+ }
+}
+
+if(!function_exists('utf8_to_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>
+ * @param string UTF-8 encoded string
+ * @param boolean Check for invalid sequences?
+ * @return mixed array of unicode code points or false if UTF-8 invalid
+ * @see unicode_to_utf8
+ * @link http://hsivonen.iki.fi/php-utf8/
+ * @link http://sourceforge.net/projects/phputf8/
+ */
+ function utf8_to_unicode($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;
+ }
+}
+
+if(!function_exists('unicode_to_utf8')){
+ /**
+ * 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 of unicode code points representing a string
+ * @param boolean Check for invalid sequences?
+ * @return mixed 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/
+ */
+ function unicode_to_utf8($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;
+ }
+ }
+
+ $result = ob_get_contents();
+ ob_end_clean();
+ return $result;
+ }
+}
+
+if(!function_exists('utf8_to_utf16be')){
+ /**
+ * UTF-8 to UTF-16BE conversion.
+ *
+ * Maybe really UCS-2 without mb_string due to utf8_to_unicode limits
+ */
+ function utf8_to_utf16be(&$str, $bom = false) {
+ $out = $bom ? "\xFE\xFF" : '';
+ if(UTF8_MBSTRING) return $out.mb_convert_encoding($str,'UTF-16BE','UTF-8');
+
+ $uni = utf8_to_unicode($str);
+ foreach($uni as $cp){
+ $out .= pack('n',$cp);
+ }
+ return $out;
+ }
+}
+
+if(!function_exists('utf16be_to_utf8')){
+ /**
+ * UTF-8 to UTF-16BE conversion.
+ *
+ * Maybe really UCS-2 without mb_string due to utf8_to_unicode limits
+ */
+ function utf16be_to_utf8(&$str) {
+ $uni = unpack('n*',$str);
+ return unicode_to_utf8($uni);
+ }
+}
+
+if(!function_exists('utf8_bad_replace')){
+ /**
+ * 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 to search
+ * @param string to replace bad bytes with (defaults to '?') - use ASCII
+ * @return string
+ */
+ function utf8_bad_replace($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]));
+ }
+ $result = ob_get_contents();
+ ob_end_clean();
+ return $result;
+ }
+}
+
+if(!function_exists('utf8_correctIdx')){
+ /**
+ * adjust a byte index into a utf8 string to a utf8 character boundary
+ *
+ * @param $str string utf8 character string
+ * @param $i int byte index into $str
+ * @param $next bool 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
+ *
+ * @author chris smith <chris@jalakai.co.uk>
+ */
+ function utf8_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;
+ }
+}
+
+// only needed if no mb_string available
+if(!UTF8_MBSTRING){
+ /**
+ * UTF-8 Case lookup table
+ *
+ * This lookuptable defines the upper case letters to their correspponding
+ * lower case letter in UTF-8
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ global $UTF8_LOWER_TO_UPPER;
+ if(empty($UTF8_LOWER_TO_UPPER)) $UTF8_LOWER_TO_UPPER = array(
+ "z"=>"Z","y"=>"Y","x"=>"X","w"=>"W","v"=>"V","u"=>"U","t"=>"T","s"=>"S","r"=>"R","q"=>"Q",
+ "p"=>"P","o"=>"O","n"=>"N","m"=>"M","l"=>"L","k"=>"K","j"=>"J","i"=>"I","h"=>"H","g"=>"G",
+ "f"=>"F","e"=>"E","d"=>"D","c"=>"C","b"=>"B","a"=>"A","ῳ"=>"ῼ","ῥ"=>"Ῥ","ῡ"=>"Ῡ","ῑ"=>"Ῑ",
+ "ῐ"=>"Ῐ","ῃ"=>"ῌ","ι"=>"Ι","ᾳ"=>"ᾼ","ᾱ"=>"Ᾱ","ᾰ"=>"Ᾰ","ᾧ"=>"ᾯ","ᾦ"=>"ᾮ","ᾥ"=>"ᾭ","ᾤ"=>"ᾬ",
+ "ᾣ"=>"ᾫ","ᾢ"=>"ᾪ","ᾡ"=>"ᾩ","ᾗ"=>"ᾟ","ᾖ"=>"ᾞ","ᾕ"=>"ᾝ","ᾔ"=>"ᾜ","ᾓ"=>"ᾛ","ᾒ"=>"ᾚ","ᾑ"=>"ᾙ",
+ "ᾐ"=>"ᾘ","ᾇ"=>"ᾏ","ᾆ"=>"ᾎ","ᾅ"=>"ᾍ","ᾄ"=>"ᾌ","ᾃ"=>"ᾋ","ᾂ"=>"ᾊ","ᾁ"=>"ᾉ","ᾀ"=>"ᾈ","ώ"=>"Ώ",
+ "ὼ"=>"Ὼ","ύ"=>"Ύ","ὺ"=>"Ὺ","ό"=>"Ό","ὸ"=>"Ὸ","ί"=>"Ί","ὶ"=>"Ὶ","ή"=>"Ή","ὴ"=>"Ὴ","έ"=>"Έ",
+ "ὲ"=>"Ὲ","ά"=>"Ά","ὰ"=>"Ὰ","ὧ"=>"Ὧ","ὦ"=>"Ὦ","ὥ"=>"Ὥ","ὤ"=>"Ὤ","ὣ"=>"Ὣ","ὢ"=>"Ὢ","ὡ"=>"Ὡ",
+ "ὗ"=>"Ὗ","ὕ"=>"Ὕ","ὓ"=>"Ὓ","ὑ"=>"Ὑ","ὅ"=>"Ὅ","ὄ"=>"Ὄ","ὃ"=>"Ὃ","ὂ"=>"Ὂ","ὁ"=>"Ὁ","ὀ"=>"Ὀ",
+ "ἷ"=>"Ἷ","ἶ"=>"Ἶ","ἵ"=>"Ἵ","ἴ"=>"Ἴ","ἳ"=>"Ἳ","ἲ"=>"Ἲ","ἱ"=>"Ἱ","ἰ"=>"Ἰ","ἧ"=>"Ἧ","ἦ"=>"Ἦ",
+ "ἥ"=>"Ἥ","ἤ"=>"Ἤ","ἣ"=>"Ἣ","ἢ"=>"Ἢ","ἡ"=>"Ἡ","ἕ"=>"Ἕ","ἔ"=>"Ἔ","ἓ"=>"Ἓ","ἒ"=>"Ἒ","ἑ"=>"Ἑ",
+ "ἐ"=>"Ἐ","ἇ"=>"Ἇ","ἆ"=>"Ἆ","ἅ"=>"Ἅ","ἄ"=>"Ἄ","ἃ"=>"Ἃ","ἂ"=>"Ἂ","ἁ"=>"Ἁ","ἀ"=>"Ἀ","ỹ"=>"Ỹ",
+ "ỷ"=>"Ỷ","ỵ"=>"Ỵ","ỳ"=>"Ỳ","ự"=>"Ự","ữ"=>"Ữ","ử"=>"Ử","ừ"=>"Ừ","ứ"=>"Ứ","ủ"=>"Ủ","ụ"=>"Ụ",
+ "ợ"=>"Ợ","ỡ"=>"Ỡ","ở"=>"Ở","ờ"=>"Ờ","ớ"=>"Ớ","ộ"=>"Ộ","ỗ"=>"Ỗ","ổ"=>"Ổ","ồ"=>"Ồ","ố"=>"Ố",
+ "ỏ"=>"Ỏ","ọ"=>"Ọ","ị"=>"Ị","ỉ"=>"Ỉ","ệ"=>"Ệ","ễ"=>"Ễ","ể"=>"Ể","ề"=>"Ề","ế"=>"Ế","ẽ"=>"Ẽ",
+ "ẻ"=>"Ẻ","ẹ"=>"Ẹ","ặ"=>"Ặ","ẵ"=>"Ẵ","ẳ"=>"Ẳ","ằ"=>"Ằ","ắ"=>"Ắ","ậ"=>"Ậ","ẫ"=>"Ẫ","ẩ"=>"Ẩ",
+ "ầ"=>"Ầ","ấ"=>"Ấ","ả"=>"Ả","ạ"=>"Ạ","ẛ"=>"Ṡ","ẕ"=>"Ẕ","ẓ"=>"Ẓ","ẑ"=>"Ẑ","ẏ"=>"Ẏ","ẍ"=>"Ẍ",
+ "ẋ"=>"Ẋ","ẉ"=>"Ẉ","ẇ"=>"Ẇ","ẅ"=>"Ẅ","ẃ"=>"Ẃ","ẁ"=>"Ẁ","ṿ"=>"Ṿ","ṽ"=>"Ṽ","ṻ"=>"Ṻ","ṹ"=>"Ṹ",
+ "ṷ"=>"Ṷ","ṵ"=>"Ṵ","ṳ"=>"Ṳ","ṱ"=>"Ṱ","ṯ"=>"Ṯ","ṭ"=>"Ṭ","ṫ"=>"Ṫ","ṩ"=>"Ṩ","ṧ"=>"Ṧ","ṥ"=>"Ṥ",
+ "ṣ"=>"Ṣ","ṡ"=>"Ṡ","ṟ"=>"Ṟ","ṝ"=>"Ṝ","ṛ"=>"Ṛ","ṙ"=>"Ṙ","ṗ"=>"Ṗ","ṕ"=>"Ṕ","ṓ"=>"Ṓ","ṑ"=>"Ṑ",
+ "ṏ"=>"Ṏ","ṍ"=>"Ṍ","ṋ"=>"Ṋ","ṉ"=>"Ṉ","ṇ"=>"Ṇ","ṅ"=>"Ṅ","ṃ"=>"Ṃ","ṁ"=>"Ṁ","ḿ"=>"Ḿ","ḽ"=>"Ḽ",
+ "ḻ"=>"Ḻ","ḹ"=>"Ḹ","ḷ"=>"Ḷ","ḵ"=>"Ḵ","ḳ"=>"Ḳ","ḱ"=>"Ḱ","ḯ"=>"Ḯ","ḭ"=>"Ḭ","ḫ"=>"Ḫ","ḩ"=>"Ḩ",
+ "ḧ"=>"Ḧ","ḥ"=>"Ḥ","ḣ"=>"Ḣ","ḡ"=>"Ḡ","ḟ"=>"Ḟ","ḝ"=>"Ḝ","ḛ"=>"Ḛ","ḙ"=>"Ḙ","ḗ"=>"Ḗ","ḕ"=>"Ḕ",
+ "ḓ"=>"Ḓ","ḑ"=>"Ḑ","ḏ"=>"Ḏ","ḍ"=>"Ḍ","ḋ"=>"Ḋ","ḉ"=>"Ḉ","ḇ"=>"Ḇ","ḅ"=>"Ḅ","ḃ"=>"Ḃ","ḁ"=>"Ḁ",
+ "ֆ"=>"Ֆ","օ"=>"Օ","ք"=>"Ք","փ"=>"Փ","ւ"=>"Ւ","ց"=>"Ց","ր"=>"Ր","տ"=>"Տ","վ"=>"Վ","ս"=>"Ս",
+ "ռ"=>"Ռ","ջ"=>"Ջ","պ"=>"Պ","չ"=>"Չ","ո"=>"Ո","շ"=>"Շ","ն"=>"Ն","յ"=>"Յ","մ"=>"Մ","ճ"=>"Ճ",
+ "ղ"=>"Ղ","ձ"=>"Ձ","հ"=>"Հ","կ"=>"Կ","ծ"=>"Ծ","խ"=>"Խ","լ"=>"Լ","ի"=>"Ի","ժ"=>"Ժ","թ"=>"Թ",
+ "ը"=>"Ը","է"=>"Է","զ"=>"Զ","ե"=>"Ե","դ"=>"Դ","գ"=>"Գ","բ"=>"Բ","ա"=>"Ա","ԏ"=>"Ԏ","ԍ"=>"Ԍ",
+ "ԋ"=>"Ԋ","ԉ"=>"Ԉ","ԇ"=>"Ԇ","ԅ"=>"Ԅ","ԃ"=>"Ԃ","ԁ"=>"Ԁ","ӹ"=>"Ӹ","ӵ"=>"Ӵ","ӳ"=>"Ӳ","ӱ"=>"Ӱ",
+ "ӯ"=>"Ӯ","ӭ"=>"Ӭ","ӫ"=>"Ӫ","ө"=>"Ө","ӧ"=>"Ӧ","ӥ"=>"Ӥ","ӣ"=>"Ӣ","ӡ"=>"Ӡ","ӟ"=>"Ӟ","ӝ"=>"Ӝ",
+ "ӛ"=>"Ӛ","ә"=>"Ә","ӗ"=>"Ӗ","ӕ"=>"Ӕ","ӓ"=>"Ӓ","ӑ"=>"Ӑ","ӎ"=>"Ӎ","ӌ"=>"Ӌ","ӊ"=>"Ӊ","ӈ"=>"Ӈ",
+ "ӆ"=>"Ӆ","ӄ"=>"Ӄ","ӂ"=>"Ӂ","ҿ"=>"Ҿ","ҽ"=>"Ҽ","һ"=>"Һ","ҹ"=>"Ҹ","ҷ"=>"Ҷ","ҵ"=>"Ҵ","ҳ"=>"Ҳ",
+ "ұ"=>"Ұ","ү"=>"Ү","ҭ"=>"Ҭ","ҫ"=>"Ҫ","ҩ"=>"Ҩ","ҧ"=>"Ҧ","ҥ"=>"Ҥ","ң"=>"Ң","ҡ"=>"Ҡ","ҟ"=>"Ҟ",
+ "ҝ"=>"Ҝ","қ"=>"Қ","ҙ"=>"Ҙ","җ"=>"Җ","ҕ"=>"Ҕ","ғ"=>"Ғ","ґ"=>"Ґ","ҏ"=>"Ҏ","ҍ"=>"Ҍ","ҋ"=>"Ҋ",
+ "ҁ"=>"Ҁ","ѿ"=>"Ѿ","ѽ"=>"Ѽ","ѻ"=>"Ѻ","ѹ"=>"Ѹ","ѷ"=>"Ѷ","ѵ"=>"Ѵ","ѳ"=>"Ѳ","ѱ"=>"Ѱ","ѯ"=>"Ѯ",
+ "ѭ"=>"Ѭ","ѫ"=>"Ѫ","ѩ"=>"Ѩ","ѧ"=>"Ѧ","ѥ"=>"Ѥ","ѣ"=>"Ѣ","ѡ"=>"Ѡ","џ"=>"Џ","ў"=>"Ў","ѝ"=>"Ѝ",
+ "ќ"=>"Ќ","ћ"=>"Ћ","њ"=>"Њ","љ"=>"Љ","ј"=>"Ј","ї"=>"Ї","і"=>"І","ѕ"=>"Ѕ","є"=>"Є","ѓ"=>"Ѓ",
+ "ђ"=>"Ђ","ё"=>"Ё","ѐ"=>"Ѐ","я"=>"Я","ю"=>"Ю","э"=>"Э","ь"=>"Ь","ы"=>"Ы","ъ"=>"Ъ","щ"=>"Щ",
+ "ш"=>"Ш","ч"=>"Ч","ц"=>"Ц","х"=>"Х","ф"=>"Ф","у"=>"У","т"=>"Т","с"=>"С","р"=>"Р","п"=>"П",
+ "о"=>"О","н"=>"Н","м"=>"М","л"=>"Л","к"=>"К","й"=>"Й","и"=>"И","з"=>"З","ж"=>"Ж","е"=>"Е",
+ "д"=>"Д","г"=>"Г","в"=>"В","б"=>"Б","а"=>"А","ϵ"=>"Ε","ϲ"=>"Σ","ϱ"=>"Ρ","ϰ"=>"Κ","ϯ"=>"Ϯ",
+ "ϭ"=>"Ϭ","ϫ"=>"Ϫ","ϩ"=>"Ϩ","ϧ"=>"Ϧ","ϥ"=>"Ϥ","ϣ"=>"Ϣ","ϡ"=>"Ϡ","ϟ"=>"Ϟ","ϝ"=>"Ϝ","ϛ"=>"Ϛ",
+ "ϙ"=>"Ϙ","ϖ"=>"Π","ϕ"=>"Φ","ϑ"=>"Θ","ϐ"=>"Β","ώ"=>"Ώ","ύ"=>"Ύ","ό"=>"Ό","ϋ"=>"Ϋ","ϊ"=>"Ϊ",
+ "ω"=>"Ω","ψ"=>"Ψ","χ"=>"Χ","φ"=>"Φ","υ"=>"Υ","τ"=>"Τ","σ"=>"Σ","ς"=>"Σ","ρ"=>"Ρ","π"=>"Π",
+ "ο"=>"Ο","ξ"=>"Ξ","ν"=>"Ν","μ"=>"Μ","λ"=>"Λ","κ"=>"Κ","ι"=>"Ι","θ"=>"Θ","η"=>"Η","ζ"=>"Ζ",
+ "ε"=>"Ε","δ"=>"Δ","γ"=>"Γ","β"=>"Β","α"=>"Α","ί"=>"Ί","ή"=>"Ή","έ"=>"Έ","ά"=>"Ά","ʒ"=>"Ʒ",
+ "ʋ"=>"Ʋ","ʊ"=>"Ʊ","ʈ"=>"Ʈ","ʃ"=>"Ʃ","ʀ"=>"Ʀ","ɵ"=>"Ɵ","ɲ"=>"Ɲ","ɯ"=>"Ɯ","ɩ"=>"Ɩ","ɨ"=>"Ɨ",
+ "ɣ"=>"Ɣ","ɛ"=>"Ɛ","ə"=>"Ə","ɗ"=>"Ɗ","ɖ"=>"Ɖ","ɔ"=>"Ɔ","ɓ"=>"Ɓ","ȳ"=>"Ȳ","ȱ"=>"Ȱ","ȯ"=>"Ȯ",
+ "ȭ"=>"Ȭ","ȫ"=>"Ȫ","ȩ"=>"Ȩ","ȧ"=>"Ȧ","ȥ"=>"Ȥ","ȣ"=>"Ȣ","ȟ"=>"Ȟ","ȝ"=>"Ȝ","ț"=>"Ț","ș"=>"Ș",
+ "ȗ"=>"Ȗ","ȕ"=>"Ȕ","ȓ"=>"Ȓ","ȑ"=>"Ȑ","ȏ"=>"Ȏ","ȍ"=>"Ȍ","ȋ"=>"Ȋ","ȉ"=>"Ȉ","ȇ"=>"Ȇ","ȅ"=>"Ȅ",
+ "ȃ"=>"Ȃ","ȁ"=>"Ȁ","ǿ"=>"Ǿ","ǽ"=>"Ǽ","ǻ"=>"Ǻ","ǹ"=>"Ǹ","ǵ"=>"Ǵ","dz"=>"Dz","ǯ"=>"Ǯ","ǭ"=>"Ǭ",
+ "ǫ"=>"Ǫ","ǩ"=>"Ǩ","ǧ"=>"Ǧ","ǥ"=>"Ǥ","ǣ"=>"Ǣ","ǡ"=>"Ǡ","ǟ"=>"Ǟ","ǝ"=>"Ǝ","ǜ"=>"Ǜ","ǚ"=>"Ǚ",
+ "ǘ"=>"Ǘ","ǖ"=>"Ǖ","ǔ"=>"Ǔ","ǒ"=>"Ǒ","ǐ"=>"Ǐ","ǎ"=>"Ǎ","nj"=>"Nj","lj"=>"Lj","dž"=>"Dž","ƿ"=>"Ƿ",
+ "ƽ"=>"Ƽ","ƹ"=>"Ƹ","ƶ"=>"Ƶ","ƴ"=>"Ƴ","ư"=>"Ư","ƭ"=>"Ƭ","ƨ"=>"Ƨ","ƥ"=>"Ƥ","ƣ"=>"Ƣ","ơ"=>"Ơ",
+ "ƞ"=>"Ƞ","ƙ"=>"Ƙ","ƕ"=>"Ƕ","ƒ"=>"Ƒ","ƌ"=>"Ƌ","ƈ"=>"Ƈ","ƅ"=>"Ƅ","ƃ"=>"Ƃ","ſ"=>"S","ž"=>"Ž",
+ "ż"=>"Ż","ź"=>"Ź","ŷ"=>"Ŷ","ŵ"=>"Ŵ","ų"=>"Ų","ű"=>"Ű","ů"=>"Ů","ŭ"=>"Ŭ","ū"=>"Ū","ũ"=>"Ũ",
+ "ŧ"=>"Ŧ","ť"=>"Ť","ţ"=>"Ţ","š"=>"Š","ş"=>"Ş","ŝ"=>"Ŝ","ś"=>"Ś","ř"=>"Ř","ŗ"=>"Ŗ","ŕ"=>"Ŕ",
+ "œ"=>"Œ","ő"=>"Ő","ŏ"=>"Ŏ","ō"=>"Ō","ŋ"=>"Ŋ","ň"=>"Ň","ņ"=>"Ņ","ń"=>"Ń","ł"=>"Ł","ŀ"=>"Ŀ",
+ "ľ"=>"Ľ","ļ"=>"Ļ","ĺ"=>"Ĺ","ķ"=>"Ķ","ĵ"=>"Ĵ","ij"=>"IJ","ı"=>"I","į"=>"Į","ĭ"=>"Ĭ","ī"=>"Ī",
+ "ĩ"=>"Ĩ","ħ"=>"Ħ","ĥ"=>"Ĥ","ģ"=>"Ģ","ġ"=>"Ġ","ğ"=>"Ğ","ĝ"=>"Ĝ","ě"=>"Ě","ę"=>"Ę","ė"=>"Ė",
+ "ĕ"=>"Ĕ","ē"=>"Ē","đ"=>"Đ","ď"=>"Ď","č"=>"Č","ċ"=>"Ċ","ĉ"=>"Ĉ","ć"=>"Ć","ą"=>"Ą","ă"=>"Ă",
+ "ā"=>"Ā","ÿ"=>"Ÿ","þ"=>"Þ","ý"=>"Ý","ü"=>"Ü","û"=>"Û","ú"=>"Ú","ù"=>"Ù","ø"=>"Ø","ö"=>"Ö",
+ "õ"=>"Õ","ô"=>"Ô","ó"=>"Ó","ò"=>"Ò","ñ"=>"Ñ","ð"=>"Ð","ï"=>"Ï","î"=>"Î","í"=>"Í","ì"=>"Ì",
+ "ë"=>"Ë","ê"=>"Ê","é"=>"É","è"=>"È","ç"=>"Ç","æ"=>"Æ","å"=>"Å","ä"=>"Ä","ã"=>"Ã","â"=>"Â",
+ "á"=>"Á","à"=>"À","µ"=>"Μ","z"=>"Z","y"=>"Y","x"=>"X","w"=>"W","v"=>"V","u"=>"U","t"=>"T",
+ "s"=>"S","r"=>"R","q"=>"Q","p"=>"P","o"=>"O","n"=>"N","m"=>"M","l"=>"L","k"=>"K","j"=>"J",
+ "i"=>"I","h"=>"H","g"=>"G","f"=>"F","e"=>"E","d"=>"D","c"=>"C","b"=>"B","a"=>"A"
+ );
+
+ /**
+ * UTF-8 Case lookup table
+ *
+ * This lookuptable defines the lower case letters to their correspponding
+ * upper case letter in UTF-8
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ global $UTF8_UPPER_TO_LOWER;
+ if(empty($UTF8_UPPER_TO_LOWER)) $UTF8_UPPER_TO_LOWER = array (
+ "Z"=>"z","Y"=>"y","X"=>"x","W"=>"w","V"=>"v","U"=>"u","T"=>"t","S"=>"s","R"=>"r","Q"=>"q",
+ "P"=>"p","O"=>"o","N"=>"n","M"=>"m","L"=>"l","K"=>"k","J"=>"j","I"=>"i","H"=>"h","G"=>"g",
+ "F"=>"f","E"=>"e","D"=>"d","C"=>"c","B"=>"b","A"=>"a","ῼ"=>"ῳ","Ῥ"=>"ῥ","Ῡ"=>"ῡ","Ῑ"=>"ῑ",
+ "Ῐ"=>"ῐ","ῌ"=>"ῃ","Ι"=>"ι","ᾼ"=>"ᾳ","Ᾱ"=>"ᾱ","Ᾰ"=>"ᾰ","ᾯ"=>"ᾧ","ᾮ"=>"ᾦ","ᾭ"=>"ᾥ","ᾬ"=>"ᾤ",
+ "ᾫ"=>"ᾣ","ᾪ"=>"ᾢ","ᾩ"=>"ᾡ","ᾟ"=>"ᾗ","ᾞ"=>"ᾖ","ᾝ"=>"ᾕ","ᾜ"=>"ᾔ","ᾛ"=>"ᾓ","ᾚ"=>"ᾒ","ᾙ"=>"ᾑ",
+ "ᾘ"=>"ᾐ","ᾏ"=>"ᾇ","ᾎ"=>"ᾆ","ᾍ"=>"ᾅ","ᾌ"=>"ᾄ","ᾋ"=>"ᾃ","ᾊ"=>"ᾂ","ᾉ"=>"ᾁ","ᾈ"=>"ᾀ","Ώ"=>"ώ",
+ "Ὼ"=>"ὼ","Ύ"=>"ύ","Ὺ"=>"ὺ","Ό"=>"ό","Ὸ"=>"ὸ","Ί"=>"ί","Ὶ"=>"ὶ","Ή"=>"ή","Ὴ"=>"ὴ","Έ"=>"έ",
+ "Ὲ"=>"ὲ","Ά"=>"ά","Ὰ"=>"ὰ","Ὧ"=>"ὧ","Ὦ"=>"ὦ","Ὥ"=>"ὥ","Ὤ"=>"ὤ","Ὣ"=>"ὣ","Ὢ"=>"ὢ","Ὡ"=>"ὡ",
+ "Ὗ"=>"ὗ","Ὕ"=>"ὕ","Ὓ"=>"ὓ","Ὑ"=>"ὑ","Ὅ"=>"ὅ","Ὄ"=>"ὄ","Ὃ"=>"ὃ","Ὂ"=>"ὂ","Ὁ"=>"ὁ","Ὀ"=>"ὀ",
+ "Ἷ"=>"ἷ","Ἶ"=>"ἶ","Ἵ"=>"ἵ","Ἴ"=>"ἴ","Ἳ"=>"ἳ","Ἲ"=>"ἲ","Ἱ"=>"ἱ","Ἰ"=>"ἰ","Ἧ"=>"ἧ","Ἦ"=>"ἦ",
+ "Ἥ"=>"ἥ","Ἤ"=>"ἤ","Ἣ"=>"ἣ","Ἢ"=>"ἢ","Ἡ"=>"ἡ","Ἕ"=>"ἕ","Ἔ"=>"ἔ","Ἓ"=>"ἓ","Ἒ"=>"ἒ","Ἑ"=>"ἑ",
+ "Ἐ"=>"ἐ","Ἇ"=>"ἇ","Ἆ"=>"ἆ","Ἅ"=>"ἅ","Ἄ"=>"ἄ","Ἃ"=>"ἃ","Ἂ"=>"ἂ","Ἁ"=>"ἁ","Ἀ"=>"ἀ","Ỹ"=>"ỹ",
+ "Ỷ"=>"ỷ","Ỵ"=>"ỵ","Ỳ"=>"ỳ","Ự"=>"ự","Ữ"=>"ữ","Ử"=>"ử","Ừ"=>"ừ","Ứ"=>"ứ","Ủ"=>"ủ","Ụ"=>"ụ",
+ "Ợ"=>"ợ","Ỡ"=>"ỡ","Ở"=>"ở","Ờ"=>"ờ","Ớ"=>"ớ","Ộ"=>"ộ","Ỗ"=>"ỗ","Ổ"=>"ổ","Ồ"=>"ồ","Ố"=>"ố",
+ "Ỏ"=>"ỏ","Ọ"=>"ọ","Ị"=>"ị","Ỉ"=>"ỉ","Ệ"=>"ệ","Ễ"=>"ễ","Ể"=>"ể","Ề"=>"ề","Ế"=>"ế","Ẽ"=>"ẽ",
+ "Ẻ"=>"ẻ","Ẹ"=>"ẹ","Ặ"=>"ặ","Ẵ"=>"ẵ","Ẳ"=>"ẳ","Ằ"=>"ằ","Ắ"=>"ắ","Ậ"=>"ậ","Ẫ"=>"ẫ","Ẩ"=>"ẩ",
+ "Ầ"=>"ầ","Ấ"=>"ấ","Ả"=>"ả","Ạ"=>"ạ","Ṡ"=>"ẛ","Ẕ"=>"ẕ","Ẓ"=>"ẓ","Ẑ"=>"ẑ","Ẏ"=>"ẏ","Ẍ"=>"ẍ",
+ "Ẋ"=>"ẋ","Ẉ"=>"ẉ","Ẇ"=>"ẇ","Ẅ"=>"ẅ","Ẃ"=>"ẃ","Ẁ"=>"ẁ","Ṿ"=>"ṿ","Ṽ"=>"ṽ","Ṻ"=>"ṻ","Ṹ"=>"ṹ",
+ "Ṷ"=>"ṷ","Ṵ"=>"ṵ","Ṳ"=>"ṳ","Ṱ"=>"ṱ","Ṯ"=>"ṯ","Ṭ"=>"ṭ","Ṫ"=>"ṫ","Ṩ"=>"ṩ","Ṧ"=>"ṧ","Ṥ"=>"ṥ",
+ "Ṣ"=>"ṣ","Ṡ"=>"ṡ","Ṟ"=>"ṟ","Ṝ"=>"ṝ","Ṛ"=>"ṛ","Ṙ"=>"ṙ","Ṗ"=>"ṗ","Ṕ"=>"ṕ","Ṓ"=>"ṓ","Ṑ"=>"ṑ",
+ "Ṏ"=>"ṏ","Ṍ"=>"ṍ","Ṋ"=>"ṋ","Ṉ"=>"ṉ","Ṇ"=>"ṇ","Ṅ"=>"ṅ","Ṃ"=>"ṃ","Ṁ"=>"ṁ","Ḿ"=>"ḿ","Ḽ"=>"ḽ",
+ "Ḻ"=>"ḻ","Ḹ"=>"ḹ","Ḷ"=>"ḷ","Ḵ"=>"ḵ","Ḳ"=>"ḳ","Ḱ"=>"ḱ","Ḯ"=>"ḯ","Ḭ"=>"ḭ","Ḫ"=>"ḫ","Ḩ"=>"ḩ",
+ "Ḧ"=>"ḧ","Ḥ"=>"ḥ","Ḣ"=>"ḣ","Ḡ"=>"ḡ","Ḟ"=>"ḟ","Ḝ"=>"ḝ","Ḛ"=>"ḛ","Ḙ"=>"ḙ","Ḗ"=>"ḗ","Ḕ"=>"ḕ",
+ "Ḓ"=>"ḓ","Ḑ"=>"ḑ","Ḏ"=>"ḏ","Ḍ"=>"ḍ","Ḋ"=>"ḋ","Ḉ"=>"ḉ","Ḇ"=>"ḇ","Ḅ"=>"ḅ","Ḃ"=>"ḃ","Ḁ"=>"ḁ",
+ "Ֆ"=>"ֆ","Օ"=>"օ","Ք"=>"ք","Փ"=>"փ","Ւ"=>"ւ","Ց"=>"ց","Ր"=>"ր","Տ"=>"տ","Վ"=>"վ","Ս"=>"ս",
+ "Ռ"=>"ռ","Ջ"=>"ջ","Պ"=>"պ","Չ"=>"չ","Ո"=>"ո","Շ"=>"շ","Ն"=>"ն","Յ"=>"յ","Մ"=>"մ","Ճ"=>"ճ",
+ "Ղ"=>"ղ","Ձ"=>"ձ","Հ"=>"հ","Կ"=>"կ","Ծ"=>"ծ","Խ"=>"խ","Լ"=>"լ","Ի"=>"ի","Ժ"=>"ժ","Թ"=>"թ",
+ "Ը"=>"ը","Է"=>"է","Զ"=>"զ","Ե"=>"ե","Դ"=>"դ","Գ"=>"գ","Բ"=>"բ","Ա"=>"ա","Ԏ"=>"ԏ","Ԍ"=>"ԍ",
+ "Ԋ"=>"ԋ","Ԉ"=>"ԉ","Ԇ"=>"ԇ","Ԅ"=>"ԅ","Ԃ"=>"ԃ","Ԁ"=>"ԁ","Ӹ"=>"ӹ","Ӵ"=>"ӵ","Ӳ"=>"ӳ","Ӱ"=>"ӱ",
+ "Ӯ"=>"ӯ","Ӭ"=>"ӭ","Ӫ"=>"ӫ","Ө"=>"ө","Ӧ"=>"ӧ","Ӥ"=>"ӥ","Ӣ"=>"ӣ","Ӡ"=>"ӡ","Ӟ"=>"ӟ","Ӝ"=>"ӝ",
+ "Ӛ"=>"ӛ","Ә"=>"ә","Ӗ"=>"ӗ","Ӕ"=>"ӕ","Ӓ"=>"ӓ","Ӑ"=>"ӑ","Ӎ"=>"ӎ","Ӌ"=>"ӌ","Ӊ"=>"ӊ","Ӈ"=>"ӈ",
+ "Ӆ"=>"ӆ","Ӄ"=>"ӄ","Ӂ"=>"ӂ","Ҿ"=>"ҿ","Ҽ"=>"ҽ","Һ"=>"һ","Ҹ"=>"ҹ","Ҷ"=>"ҷ","Ҵ"=>"ҵ","Ҳ"=>"ҳ",
+ "Ұ"=>"ұ","Ү"=>"ү","Ҭ"=>"ҭ","Ҫ"=>"ҫ","Ҩ"=>"ҩ","Ҧ"=>"ҧ","Ҥ"=>"ҥ","Ң"=>"ң","Ҡ"=>"ҡ","Ҟ"=>"ҟ",
+ "Ҝ"=>"ҝ","Қ"=>"қ","Ҙ"=>"ҙ","Җ"=>"җ","Ҕ"=>"ҕ","Ғ"=>"ғ","Ґ"=>"ґ","Ҏ"=>"ҏ","Ҍ"=>"ҍ","Ҋ"=>"ҋ",
+ "Ҁ"=>"ҁ","Ѿ"=>"ѿ","Ѽ"=>"ѽ","Ѻ"=>"ѻ","Ѹ"=>"ѹ","Ѷ"=>"ѷ","Ѵ"=>"ѵ","Ѳ"=>"ѳ","Ѱ"=>"ѱ","Ѯ"=>"ѯ",
+ "Ѭ"=>"ѭ","Ѫ"=>"ѫ","Ѩ"=>"ѩ","Ѧ"=>"ѧ","Ѥ"=>"ѥ","Ѣ"=>"ѣ","Ѡ"=>"ѡ","Џ"=>"џ","Ў"=>"ў","Ѝ"=>"ѝ",
+ "Ќ"=>"ќ","Ћ"=>"ћ","Њ"=>"њ","Љ"=>"љ","Ј"=>"ј","Ї"=>"ї","І"=>"і","Ѕ"=>"ѕ","Є"=>"є","Ѓ"=>"ѓ",
+ "Ђ"=>"ђ","Ё"=>"ё","Ѐ"=>"ѐ","Я"=>"я","Ю"=>"ю","Э"=>"э","Ь"=>"ь","Ы"=>"ы","Ъ"=>"ъ","Щ"=>"щ",
+ "Ш"=>"ш","Ч"=>"ч","Ц"=>"ц","Х"=>"х","Ф"=>"ф","У"=>"у","Т"=>"т","С"=>"с","Р"=>"р","П"=>"п",
+ "О"=>"о","Н"=>"н","М"=>"м","Л"=>"л","К"=>"к","Й"=>"й","И"=>"и","З"=>"з","Ж"=>"ж","Е"=>"е",
+ "Д"=>"д","Г"=>"г","В"=>"в","Б"=>"б","А"=>"а","Ε"=>"ϵ","Σ"=>"ϲ","Ρ"=>"ϱ","Κ"=>"ϰ","Ϯ"=>"ϯ",
+ "Ϭ"=>"ϭ","Ϫ"=>"ϫ","Ϩ"=>"ϩ","Ϧ"=>"ϧ","Ϥ"=>"ϥ","Ϣ"=>"ϣ","Ϡ"=>"ϡ","Ϟ"=>"ϟ","Ϝ"=>"ϝ","Ϛ"=>"ϛ",
+ "Ϙ"=>"ϙ","Π"=>"ϖ","Φ"=>"ϕ","Θ"=>"ϑ","Β"=>"ϐ","Ώ"=>"ώ","Ύ"=>"ύ","Ό"=>"ό","Ϋ"=>"ϋ","Ϊ"=>"ϊ",
+ "Ω"=>"ω","Ψ"=>"ψ","Χ"=>"χ","Φ"=>"φ","Υ"=>"υ","Τ"=>"τ","Σ"=>"σ","Σ"=>"ς","Ρ"=>"ρ","Π"=>"π",
+ "Ο"=>"ο","Ξ"=>"ξ","Ν"=>"ν","Μ"=>"μ","Λ"=>"λ","Κ"=>"κ","Ι"=>"ι","Θ"=>"θ","Η"=>"η","Ζ"=>"ζ",
+ "Ε"=>"ε","Δ"=>"δ","Γ"=>"γ","Β"=>"β","Α"=>"α","Ί"=>"ί","Ή"=>"ή","Έ"=>"έ","Ά"=>"ά","Ʒ"=>"ʒ",
+ "Ʋ"=>"ʋ","Ʊ"=>"ʊ","Ʈ"=>"ʈ","Ʃ"=>"ʃ","Ʀ"=>"ʀ","Ɵ"=>"ɵ","Ɲ"=>"ɲ","Ɯ"=>"ɯ","Ɩ"=>"ɩ","Ɨ"=>"ɨ",
+ "Ɣ"=>"ɣ","Ɛ"=>"ɛ","Ə"=>"ə","Ɗ"=>"ɗ","Ɖ"=>"ɖ","Ɔ"=>"ɔ","Ɓ"=>"ɓ","Ȳ"=>"ȳ","Ȱ"=>"ȱ","Ȯ"=>"ȯ",
+ "Ȭ"=>"ȭ","Ȫ"=>"ȫ","Ȩ"=>"ȩ","Ȧ"=>"ȧ","Ȥ"=>"ȥ","Ȣ"=>"ȣ","Ȟ"=>"ȟ","Ȝ"=>"ȝ","Ț"=>"ț","Ș"=>"ș",
+ "Ȗ"=>"ȗ","Ȕ"=>"ȕ","Ȓ"=>"ȓ","Ȑ"=>"ȑ","Ȏ"=>"ȏ","Ȍ"=>"ȍ","Ȋ"=>"ȋ","Ȉ"=>"ȉ","Ȇ"=>"ȇ","Ȅ"=>"ȅ",
+ "Ȃ"=>"ȃ","Ȁ"=>"ȁ","Ǿ"=>"ǿ","Ǽ"=>"ǽ","Ǻ"=>"ǻ","Ǹ"=>"ǹ","Ǵ"=>"ǵ","Dz"=>"dz","Ǯ"=>"ǯ","Ǭ"=>"ǭ",
+ "Ǫ"=>"ǫ","Ǩ"=>"ǩ","Ǧ"=>"ǧ","Ǥ"=>"ǥ","Ǣ"=>"ǣ","Ǡ"=>"ǡ","Ǟ"=>"ǟ","Ǝ"=>"ǝ","Ǜ"=>"ǜ","Ǚ"=>"ǚ",
+ "Ǘ"=>"ǘ","Ǖ"=>"ǖ","Ǔ"=>"ǔ","Ǒ"=>"ǒ","Ǐ"=>"ǐ","Ǎ"=>"ǎ","Nj"=>"nj","Lj"=>"lj","Dž"=>"dž","Ƿ"=>"ƿ",
+ "Ƽ"=>"ƽ","Ƹ"=>"ƹ","Ƶ"=>"ƶ","Ƴ"=>"ƴ","Ư"=>"ư","Ƭ"=>"ƭ","Ƨ"=>"ƨ","Ƥ"=>"ƥ","Ƣ"=>"ƣ","Ơ"=>"ơ",
+ "Ƞ"=>"ƞ","Ƙ"=>"ƙ","Ƕ"=>"ƕ","Ƒ"=>"ƒ","Ƌ"=>"ƌ","Ƈ"=>"ƈ","Ƅ"=>"ƅ","Ƃ"=>"ƃ","S"=>"ſ","Ž"=>"ž",
+ "Ż"=>"ż","Ź"=>"ź","Ŷ"=>"ŷ","Ŵ"=>"ŵ","Ų"=>"ų","Ű"=>"ű","Ů"=>"ů","Ŭ"=>"ŭ","Ū"=>"ū","Ũ"=>"ũ",
+ "Ŧ"=>"ŧ","Ť"=>"ť","Ţ"=>"ţ","Š"=>"š","Ş"=>"ş","Ŝ"=>"ŝ","Ś"=>"ś","Ř"=>"ř","Ŗ"=>"ŗ","Ŕ"=>"ŕ",
+ "Œ"=>"œ","Ő"=>"ő","Ŏ"=>"ŏ","Ō"=>"ō","Ŋ"=>"ŋ","Ň"=>"ň","Ņ"=>"ņ","Ń"=>"ń","Ł"=>"ł","Ŀ"=>"ŀ",
+ "Ľ"=>"ľ","Ļ"=>"ļ","Ĺ"=>"ĺ","Ķ"=>"ķ","Ĵ"=>"ĵ","IJ"=>"ij","I"=>"ı","Į"=>"į","Ĭ"=>"ĭ","Ī"=>"ī",
+ "Ĩ"=>"ĩ","Ħ"=>"ħ","Ĥ"=>"ĥ","Ģ"=>"ģ","Ġ"=>"ġ","Ğ"=>"ğ","Ĝ"=>"ĝ","Ě"=>"ě","Ę"=>"ę","Ė"=>"ė",
+ "Ĕ"=>"ĕ","Ē"=>"ē","Đ"=>"đ","Ď"=>"ď","Č"=>"č","Ċ"=>"ċ","Ĉ"=>"ĉ","Ć"=>"ć","Ą"=>"ą","Ă"=>"ă",
+ "Ā"=>"ā","Ÿ"=>"ÿ","Þ"=>"þ","Ý"=>"ý","Ü"=>"ü","Û"=>"û","Ú"=>"ú","Ù"=>"ù","Ø"=>"ø","Ö"=>"ö",
+ "Õ"=>"õ","Ô"=>"ô","Ó"=>"ó","Ò"=>"ò","Ñ"=>"ñ","Ð"=>"ð","Ï"=>"ï","Î"=>"î","Í"=>"í","Ì"=>"ì",
+ "Ë"=>"ë","Ê"=>"ê","É"=>"é","È"=>"è","Ç"=>"ç","Æ"=>"æ","Å"=>"å","Ä"=>"ä","Ã"=>"ã","Â"=>"â",
+ "Á"=>"á","À"=>"à","Μ"=>"µ","Z"=>"z","Y"=>"y","X"=>"x","W"=>"w","V"=>"v","U"=>"u","T"=>"t",
+ "S"=>"s","R"=>"r","Q"=>"q","P"=>"p","O"=>"o","N"=>"n","M"=>"m","L"=>"l","K"=>"k","J"=>"j",
+ "I"=>"i","H"=>"h","G"=>"g","F"=>"f","E"=>"e","D"=>"d","C"=>"c","B"=>"b","A"=>"a"
+ );
+}; // end of case lookup tables
+
+/**
+ * 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 utf8_deaccent()
+ */
+global $UTF8_LOWER_ACCENTS;
+if(empty($UTF8_LOWER_ACCENTS)) $UTF8_LOWER_ACCENTS = array(
+ 'à' => 'a', 'ô' => 'o', 'ď' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'š' => 's', 'ơ' => 'o',
+ 'ß' => 'ss', 'ă' => 'a', 'ř' => 'r', 'ț' => 't', 'ň' => 'n', 'ā' => 'a', 'ķ' => 'k',
+ 'ŝ' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'ṗ' => 'p', 'ó' => 'o',
+ 'ú' => 'u', 'ě' => 'e', 'é' => 'e', 'ç' => 'c', 'ẁ' => 'w', 'ċ' => 'c', 'õ' => 'o',
+ 'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c',
+ 'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't',
+ 'ū' => 'u', 'č' => 'c', 'ö' => 'oe', 'è' => 'e', 'ŷ' => 'y', 'ą' => 'a', 'ł' => 'l',
+ 'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z',
+ 'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't',
+ 'ŗ' => 'r', 'ä' => 'ae', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'ue', 'ò' => 'o',
+ 'ē' => 'e', 'ñ' => 'n', 'ń' => 'n', 'ĥ' => 'h', 'ĝ' => 'g', 'đ' => 'd', 'ĵ' => 'j',
+ 'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o',
+ 'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g',
+ 'ṁ' => 'm', 'ō' => 'o', 'ĩ' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a',
+ 'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u', 'ĕ' => 'e',
+);
+
+/**
+ * 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 utf8_deaccent()
+ */
+global $UTF8_UPPER_ACCENTS;
+if(empty($UTF8_UPPER_ACCENTS)) $UTF8_UPPER_ACCENTS = array(
+ 'À' => 'A', 'Ô' => 'O', 'Ď' => 'D', 'Ḟ' => 'F', 'Ë' => 'E', 'Š' => 'S', 'Ơ' => 'O',
+ 'Ă' => 'A', 'Ř' => 'R', 'Ț' => 'T', 'Ň' => 'N', 'Ā' => 'A', 'Ķ' => 'K',
+ 'Ŝ' => 'S', 'Ỳ' => 'Y', 'Ņ' => 'N', 'Ĺ' => 'L', 'Ħ' => 'H', 'Ṗ' => 'P', 'Ó' => 'O',
+ 'Ú' => 'U', 'Ě' => 'E', 'É' => 'E', 'Ç' => 'C', 'Ẁ' => 'W', 'Ċ' => 'C', 'Õ' => 'O',
+ 'Ṡ' => 'S', 'Ø' => 'O', 'Ģ' => 'G', 'Ŧ' => 'T', 'Ș' => 'S', 'Ė' => 'E', 'Ĉ' => 'C',
+ 'Ś' => 'S', 'Î' => 'I', 'Ű' => 'U', 'Ć' => 'C', 'Ę' => 'E', 'Ŵ' => 'W', 'Ṫ' => 'T',
+ 'Ū' => 'U', 'Č' => 'C', 'Ö' => 'Oe', 'È' => 'E', 'Ŷ' => 'Y', 'Ą' => 'A', 'Ł' => 'L',
+ 'Ų' => 'U', 'Ů' => 'U', 'Ş' => 'S', 'Ğ' => 'G', 'Ļ' => 'L', 'Ƒ' => 'F', 'Ž' => 'Z',
+ 'Ẃ' => 'W', 'Ḃ' => 'B', 'Å' => 'A', 'Ì' => 'I', 'Ï' => 'I', 'Ḋ' => 'D', 'Ť' => 'T',
+ 'Ŗ' => 'R', 'Ä' => 'Ae', 'Í' => 'I', 'Ŕ' => 'R', 'Ê' => 'E', 'Ü' => 'Ue', 'Ò' => 'O',
+ 'Ē' => 'E', 'Ñ' => 'N', 'Ń' => 'N', 'Ĥ' => 'H', 'Ĝ' => 'G', 'Đ' => 'D', 'Ĵ' => 'J',
+ 'Ÿ' => 'Y', 'Ũ' => 'U', 'Ŭ' => 'U', 'Ư' => 'U', 'Ţ' => 'T', 'Ý' => 'Y', 'Ő' => 'O',
+ 'Â' => 'A', 'Ľ' => 'L', 'Ẅ' => 'W', 'Ż' => 'Z', 'Ī' => 'I', 'Ã' => 'A', 'Ġ' => 'G',
+ 'Ṁ' => 'M', 'Ō' => 'O', 'Ĩ' => 'I', 'Ù' => 'U', 'Į' => 'I', 'Ź' => 'Z', 'Á' => 'A',
+ 'Û' => 'U', 'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', 'Ĕ' => 'E',
+);
+
+/**
+ * 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 utf8_stripspecials()
+ */
+global $UTF8_SPECIAL_CHARS;
+if(empty($UTF8_SPECIAL_CHARS)) $UTF8_SPECIAL_CHARS = array(
+ 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
+ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002b, 0x002c,
+ 0x002f, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x005b,
+ 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e,
+ 0x007f, 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088,
+ 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091, 0x0092,
+ 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c,
+ 0x009d, 0x009e, 0x009f, 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6,
+ 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, 0x00b0,
+ 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba,
+ 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x00d7, 0x00f7, 0x02c7, 0x02d8, 0x02d9,
+ 0x02da, 0x02db, 0x02dc, 0x02dd, 0x0300, 0x0301, 0x0303, 0x0309, 0x0323, 0x0384,
+ 0x0385, 0x0387, 0x03c6, 0x03d1, 0x03d2, 0x03d5, 0x03d6, 0x05b0, 0x05b1,
+ 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, 0x05b8, 0x05b9, 0x05bb, 0x05bc,
+ 0x05bd, 0x05be, 0x05bf, 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05f3, 0x05f4, 0x060c,
+ 0x061b, 0x061f, 0x0640, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, 0x0650, 0x0651,
+ 0x0652, 0x066a, 0x0e3f, 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,
+ 0x01d6fc, 0x01d6fd, 0x01d6fe, 0x01d6ff, 0x01d700, 0x01d701, 0x01d702, 0x01d703,
+ 0x01d704, 0x01d705, 0x01d706, 0x01d707, 0x01d708, 0x01d709, 0x01d70a, 0x01d70b,
+ 0x01d70c, 0x01d70d, 0x01d70e, 0x01d70f, 0x01d710, 0x01d711, 0x01d712, 0x01d713,
+ 0x01d714, 0x01d715, 0x01d716, 0x01d717, 0x01d718, 0x01d719, 0x01d71a, 0x01d71b,
+ 0xc2a0, 0xe28087, 0xe280af, 0xe281a0, 0xefbbbf,
+);
+
+// utf8 version of above data
+global $UTF8_SPECIAL_CHARS2;
+if(empty($UTF8_SPECIAL_CHARS2)) $UTF8_SPECIAL_CHARS2 =
+ "\x1A".' !"#$%&\'()+,/;<=>?@[\]^`{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•�'.
+ '�—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½�'.
+ '�¿×÷ˇ˘˙˚˛˜˝̣̀́̃̉΄΅·ϖְֱֲֳִֵֶַָֹֻּֽ־ֿ�'.
+ '�ׁׂ׃׳״،؛؟ـًٌٍَُِّْ٪฿‌‍‎‏–—―‗‘’‚“”�'.
+ '��†‡•…‰′″‹›⁄₧₪₫€№℘™Ωℵ←↑→↓↔↕↵'.
+ '⇐⇑⇒⇓⇔∀∂∃∅∆∇∈∉∋∏∑−∕∗∙√∝∞∠∧∨�'.
+ '�∪∫∴∼≅≈≠≡≤≥⊂⊃⊄⊆⊇⊕⊗⊥⋅⌐⌠⌡〈〉⑩─�'.
+ '��┌┐└┘├┤┬┴┼═║╒╓╔╕╖╗╘╙╚╛╜╝╞╟╠'.
+ '╡╢╣╤╥╦╧╨╩╪╫╬▀▄█▌▐░▒▓■▲▼◆◊●�'.
+ '�★☎☛☞♠♣♥♦✁✂✃✄✆✇✈✉✌✍✎✏✐✑✒✓✔✕�'.
+ '��✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✩✪✫✬✭✮✯✰✱'.
+ '✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋�'.
+ '�❏❐❑❒❖❘❙❚❛❜❝❞❡❢❣❤❥❦❧❿➉➓➔➘➙➚�'.
+ '��➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➱➲➳➴➵➶'.
+ '➷➸➹➺➻➼➽➾'.
+ ' 、。〃〈〉《》「」『』【】〒〔〕〖〗〘〙〚〛〶'.
+ '�'.
+ '�ﹼﹽ'.
+ '!"#$%&'()*+,-./:;<=>?@[\]^`{|}~'.
+ '⦅⦆。「」、・¢£¬ ̄¦¥₩│←↑→↓■○'.
+ '𝛼𝛽𝛾𝛿𝜀𝜁𝜂𝜃𝜄𝜅𝜆𝜇𝜈𝜉𝜊𝜋𝜌𝜍𝜎𝜏𝜐𝜑𝜒𝜓𝜔𝜕𝜖𝜗𝜘𝜙𝜚𝜛'.
+ '   ⁠';
+
+/**
+ * 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.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Vitaly Blokhin <vitinfo@vitn.com>
+ * @link http://www.uconv.com/translit.htm
+ * @author Bisqwit <bisqwit@iki.fi>
+ * @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
+ * @author Arthit Suriyawongkul <arthit@gmail.com>
+ * @author Denis Scheither <amorphis@uni-bremen.de>
+ * @author Eivind Morland <eivind.morland@gmail.com>
+ */
+global $UTF8_ROMANIZATION;
+if(empty($UTF8_ROMANIZATION)) $UTF8_ROMANIZATION = array(
+ // 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/index.php b/index.php
new file mode 100644
index 000000000..ad0807727
--- /dev/null
+++ b/index.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Forwarder to doku.php
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+header("Location: doku.php");
diff --git a/install.php b/install.php
new file mode 100644
index 000000000..61db2be9f
--- /dev/null
+++ b/install.php
@@ -0,0 +1,548 @@
+<?php
+/**
+ * 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/');
+
+// 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); }
+
+// kill magic quotes
+if (get_magic_quotes_gpc() && !defined('MAGIC_QUOTES_STRIPPED')) {
+ if (!empty($_GET)) remove_magic_quotes($_GET);
+ if (!empty($_POST)) remove_magic_quotes($_POST);
+ if (!empty($_COOKIE)) remove_magic_quotes($_COOKIE);
+ if (!empty($_REQUEST)) remove_magic_quotes($_REQUEST);
+ @ini_set('magic_quotes_gpc', 0);
+ define('MAGIC_QUOTES_STRIPPED',1);
+}
+@set_magic_quotes_runtime(0);
+@ini_set('magic_quotes_sybase',0);
+
+// language strings
+require_once(DOKU_INC.'inc/lang/en/lang.php');
+$LC = preg_replace('/[^a-z\-]+/','',$_REQUEST['l']);
+if(!$LC) $LC = 'en';
+if($LC && $LC != 'en' ) {
+ require_once(DOKU_INC.'inc/lang/'.$LC.'/lang.php');
+}
+
+// initialise variables ...
+$error = array();
+
+$dokuwiki_hash = array(
+ '2005-09-22' => 'e33223e957b0b0a130d0520db08f8fb7',
+ '2006-03-05' => '51295727f79ab9af309a2fd9e0b61acc',
+ '2006-03-09' => '51295727f79ab9af309a2fd9e0b61acc',
+ '2006-11-06' => 'b3a8af76845977c2000d85d6990dd72b',
+ '2007-05-24' => 'd80f2740c84c4a6a791fd3c7a353536f',
+ '2007-06-26' => 'b3ca19c7a654823144119980be73cd77',
+ '2008-05-04' => '1e5c42eac3219d9e21927c39e3240aad',
+ '2009-02-14' => 'ec8c04210732a14fdfce0f7f6eead865',
+ '2009-12-25' => '993c4b2b385643efe5abf8e7010e11f4',
+ '2010-11-07' => '7921d48195f4db21b8ead6d9bea801b8',
+ '2011-05-25' => '4241865472edb6fa14a1227721008072',
+ '2011-11-10' => 'b46ff19a7587966ac4df61cbab1b8b31',
+ '2012-01-25' => '72c083c73608fc43c586901fd5dabb74',
+);
+
+
+
+// begin output
+header('Content-Type: text/html; charset=utf-8');
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $LC?>"
+ lang="<?php echo $LC?>" dir="<?php echo $lang['direction']?>">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title><?php echo $lang['i_installer']?></title>
+ <style type="text/css">
+ 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 type="text/javascript" language="javascript">
+ 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&w=64"
+ style="vertical-align: middle;" alt="" />
+ <?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/security.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
+ 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($_REQUEST['submit']){
+ if(!check_data($_REQUEST['d'])){
+ print_errors();
+ print_form($_REQUEST['d']);
+ }elseif(!store_data($_REQUEST['d'])){
+ echo '<p>'.$lang['i_failure'].'</p>';
+ print_errors();
+ }else{
+ echo '<p>'.$lang['i_success'].'</p>';
+ }
+ }else{
+ print_form($_REQUEST['d']);
+ }
+ ?>
+ </div>
+
+
+<div style="clear: both">
+ <a href="http://dokuwiki.org/"><img src="lib/tpl/default/images/button-dw.png" alt="driven by DokuWiki" /></a>
+ <a href="http://www.php.net"><img src="lib/tpl/default/images/button-php.gif" alt="powered by PHP" /></a>
+</div>
+</body>
+</html>
+<?php
+
+/**
+ * Print the input form
+ */
+function print_form($d){
+ global $lang;
+ global $LC;
+
+ include(DOKU_CONF.'license.php');
+
+ if(!is_array($d)) $d = array();
+ $d = array_map('htmlspecialchars',$d);
+
+ if(!isset($d['acl'])) $d['acl']=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>
+
+ </fieldset>
+ </fieldset>
+
+ <fieldset>
+ <p><?php echo $lang['i_license']?></p>
+ <?php
+ array_unshift($license,array('name' => 'None', 'url'=>''));
+ if(!isset($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="'.htmlspecialchars($key).'" id="lic_'.$key.'"'.
+ (($d['license'] == $key)?'checked="checked"':'').'>';
+ echo htmlspecialchars($lic['name']);
+ if($lic['url']) echo ' <a href="'.$lic['url'].'" target="_blank"><sup>[?]</sup></a>';
+ echo '</label>';
+ }
+ ?>
+ </fieldset>
+
+ </fieldset>
+ <fieldset id="process">
+ <input class="button" type="submit" name="submit" value="<?php echo $lang['btn_save']?>" />
+ </fieldset>
+ </form>
+ <?php
+}
+
+function print_retry() {
+ global $lang;
+ global $LC;
+ ?>
+ <form action="" method="get">
+ <fieldset>
+ <input type="hidden" name="l" value="<?php echo $LC ?>" />
+ <input class="button" type="submit" value="<?php echo $lang['i_retry'];?>" />
+ </fieldset>
+ </form>
+ <?php
+}
+
+/**
+ * Check validity of data
+ *
+ * @author Andreas Gohr
+ */
+function check_data(&$d){
+ global $lang;
+ global $error;
+
+ //autolowercase the username
+ $d['superuser'] = strtolower($d['superuser']);
+
+ $ok = true;
+
+ // check input
+ if(empty($d['title'])){
+ $error[] = sprintf($lang['i_badval'],$lang['i_wikiname']);
+ $ok = false;
+ }
+ if($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;
+ }
+ if($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;
+ }
+ }
+ return $ok;
+}
+
+/**
+ * Writes the data to the config files
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+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;
+ $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";
+ }
+ $ok = $ok && fileWrite(DOKU_LOCAL.'local.php',$output);
+
+ if ($d['acl']) {
+ // create users.auth.php
+ // --- user:MD5password:Real Name:email:groups,comma,seperated
+ $output = join(":",array($d['superuser'], md5($d['password']), $d['fullname'], $d['email'], 'admin,user'));
+ $output = @file_get_contents(DOKU_CONF.'users.auth.php.dist')."\n$output\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);
+ }
+ return $ok;
+}
+
+/**
+ * Write the given content to a file
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+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>
+ */
+function check_configs(){
+ global $error;
+ global $lang;
+ global $dokuwiki_hash;
+
+ $ok = true;
+
+ $config_files = array(
+ 'local' => DOKU_LOCAL.'local.php',
+ 'users' => DOKU_LOCAL.'users.auth.php',
+ 'auth' => DOKU_LOCAL.'acl.auth.php'
+ );
+
+ // main dokuwiki config file (conf/dokuwiki.php) must not have been modified
+ $installation_hash = md5(preg_replace("/(\015\012)|(\015)/","\012",
+ @file_get_contents(DOKU_CONF.'dokuwiki.php')));
+ if (!in_array($installation_hash, $dokuwiki_hash)) {
+ $error[] = sprintf($lang['i_badhash'],$installation_hash);
+ $ok = false;
+ }
+
+ // configs shouldn't exist
+ foreach ($config_files as $file) {
+ if (@file_exists($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>
+ */
+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>
+ */
+function check_functions(){
+ global $error;
+ global $lang;
+ $ok = true;
+
+ if(version_compare(phpversion(),'5.1.2','<')){
+ $error[] = sprintf($lang['i_phpver'],phpversion(),'5.1.2');
+ $ok = false;
+ }
+
+ $funcs = explode(' ','addslashes basename call_user_func chmod copy fgets '.
+ 'file file_exists fseek flush filesize ftell fopen '.
+ 'glob header ignore_user_abort ini_get mail 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');
+
+ if (!function_exists('mb_substr')) {
+ $funcs[] = 'utf8_encode';
+ $funcs[] = 'utf8_decode';
+ }
+
+ 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 '<input type="submit" value="'.$lang['btn_update'].'" />';
+ echo '</form>';
+}
+
+/**
+ * Print global error array
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function print_errors(){
+ global $error;
+ echo '<ul>';
+ foreach ($error as $err){
+ echo "<li>$err</li>";
+ }
+ echo '</ul>';
+}
+
+/**
+ * remove magic quotes recursivly
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function remove_magic_quotes(&$array) {
+ foreach (array_keys($array) as $key) {
+ if (is_array($array[$key])) {
+ remove_magic_quotes($array[$key]);
+ }else {
+ $array[$key] = stripslashes($array[$key]);
+ }
+ }
+}
+
diff --git a/lib/exe/ajax.php b/lib/exe/ajax.php
new file mode 100644
index 000000000..3d1584244
--- /dev/null
+++ b/lib/exe/ajax.php
@@ -0,0 +1,435 @@
+<?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();
+
+header('Content-Type: text/html; charset=utf-8');
+
+
+//call the requested function
+if(isset($_POST['call'])){
+ $call = $_POST['call'];
+}else if(isset($_GET['call'])){
+ $call = $_GET['call'];
+}else{
+ exit;
+}
+$callfn = 'ajax_'.$call;
+
+if(function_exists($callfn)){
+ $callfn();
+}else{
+ $evt = new Doku_Event('AJAX_CALL_UNKNOWN', $call);
+ if ($evt->advise_before()) {
+ print "AJAX call '".htmlspecialchars($call)."' unknown!\n";
+ exit;
+ }
+ $evt->advise_after();
+ unset($evt);
+}
+
+/**
+ * Searches for matching pagenames
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_qsearch(){
+ global $conf;
+ global $lang;
+
+ $query = $_POST['q'];
+ if(empty($query)) $query = $_GET['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>';
+ 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>';
+ }
+ print '</ul>';
+}
+
+/**
+ * Support OpenSearch suggestions
+ *
+ * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0
+ * @author Mike Frysinger <vapier@gentoo.org>
+ */
+function ajax_suggestions() {
+ global $conf;
+ global $lang;
+
+ $query = cleanID($_POST['q']);
+ if(empty($query)) $query = cleanID($_GET['q']);
+ if(empty($query)) return;
+
+ $data = array();
+ $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
+ );
+ $json = new JSON();
+
+ header('Content-Type: application/x-suggestions+json');
+ print $json->encode($suggestions);
+}
+
+/**
+ * Refresh a page lock and save draft
+ *
+ * Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_lock(){
+ global $conf;
+ global $lang;
+ global $ID;
+ global $INFO;
+
+ $ID = cleanID($_POST['id']);
+ if(empty($ID)) return;
+
+ $INFO = pageinfo();
+
+ if (!$INFO['writable']) {
+ echo 'Permission denied';
+ return;
+ }
+
+ if(!checklock($ID)){
+ lock($ID);
+ echo 1;
+ }
+
+ if($conf['usedraft'] && $_POST['wikitext']){
+ $client = $_SERVER['REMOTE_USER'];
+ if(!$client) $client = clientIP(true);
+
+ $draft = array('id' => $ID,
+ 'prefix' => substr($_POST['prefix'], 0, -1),
+ 'text' => $_POST['wikitext'],
+ 'suffix' => $_POST['suffix'],
+ 'date' => (int) $_POST['date'],
+ 'client' => $client,
+ );
+ $cname = getCacheName($draft['client'].$ID,'.draft');
+ if(io_saveFile($cname,serialize($draft))){
+ echo $lang['draftdate'].' '.dformat();
+ }
+ }
+
+}
+
+/**
+ * Delete a draft
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_draftdel(){
+ $id = cleanID($_REQUEST['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>
+ */
+function ajax_medians(){
+ global $conf;
+
+ // wanted namespace
+ $ns = cleanID($_POST['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>
+ */
+function ajax_medialist(){
+ global $conf;
+ global $NS;
+
+ $NS = $_POST['ns'];
+ if ($_POST['do'] == 'media') {
+ tpl_mediaFileList();
+ } else {
+ tpl_mediaContent(true);
+ }
+}
+
+/**
+ * Return the content of the right column
+ * (image details) for the Mediamanager
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function ajax_mediadetails(){
+ global $DEL, $NS, $IMG, $AUTH, $JUMPTO, $REV, $lang, $fullscreen, $conf;
+ $fullscreen = true;
+ require_once(DOKU_INC.'lib/exe/mediamanager.php');
+
+ if ($_REQUEST['image']) $image = cleanID($_REQUEST['image']);
+ if (isset($IMG)) $image = $IMG;
+ if (isset($JUMPTO)) $image = $JUMPTO;
+ if (isset($REV) && !$JUMPTO) $rev = $REV;
+
+ html_msgarea();
+ tpl_mediaFileDetails($image, $rev);
+}
+
+/**
+ * Returns image diff representation for mediamanager
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function ajax_mediadiff(){
+ global $NS;
+
+ if ($_REQUEST['image']) $image = cleanID($_REQUEST['image']);
+ $NS = $_POST['ns'];
+ $auth = auth_quickaclcheck("$ns:*");
+ media_diff($image, $NS, $auth, true);
+}
+
+function ajax_mediaupload(){
+ global $NS, $MSG;
+
+ if ($_FILES['qqfile']['tmp_name']) {
+ $id = ((empty($_POST['mediaid'])) ? $_FILES['qqfile']['name'] : $_POST['mediaid']);
+ } elseif (isset($_GET['qqfile'])) {
+ $id = $_GET['qqfile'];
+ }
+
+ $id = cleanID($id);
+
+ $NS = $_REQUEST['ns'];
+ $ns = $NS.':'.getNS($id);
+
+ $AUTH = auth_quickaclcheck("$ns:*");
+ if($AUTH >= AUTH_UPLOAD) { io_createNamespace("$ns:xxx", 'media'); }
+
+ if ($_FILES['qqfile']['error']) unset($_FILES['qqfile']);
+
+ if ($_FILES['qqfile']['tmp_name']) $res = media_upload($NS, $AUTH, $_FILES['qqfile']);
+ if (isset($_GET['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);
+
+ if (!$result) {
+ $error = '';
+ if (isset($MSG)) {
+ foreach($MSG as $msg) $error .= $msg['msg'];
+ }
+ $result = array('error' => $msg['msg'], 'ns' => $NS);
+ }
+ $json = new JSON;
+ echo htmlspecialchars($json->encode($result), ENT_NOQUOTES);
+}
+
+function dir_delete($path) {
+ if (!is_string($path) || $path == "") return false;
+
+ if (is_dir($path) && !is_link($path)) {
+ if (!$dh = @opendir($path)) return false;
+
+ while ($f = readdir($dh)) {
+ if ($f == '..' || $f == '.') continue;
+ dir_delete("$path/$f");
+ }
+
+ closedir($dh);
+ return @rmdir($path);
+ } else {
+ return @unlink($path);
+ }
+
+ return false;
+}
+
+/**
+ * Return sub index for index view
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function ajax_index(){
+ global $conf;
+
+ // wanted namespace
+ $ns = cleanID($_POST['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>
+ */
+function ajax_linkwiz(){
+ global $conf;
+ global $lang;
+
+ $q = ltrim(trim($_POST['q']),':');
+ $id = noNS($q);
+ $ns = getNS($q);
+
+ $ns = cleanID($ns);
+ $id = cleanID($id);
+
+ $nsd = utf8_encodeFN(str_replace(':','/',$ns));
+ $idd = utf8_encodeFN(str_replace(':','/',$id));
+
+ $data = array();
+ if($q && !$ns){
+
+ // use index to lookup matching pages
+ $pages = array();
+ $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 = htmlspecialchars($item['id']);
+ }
+
+ echo '<a href="'.$link.'" title="'.htmlspecialchars($item['id']).'" class="wikilink1">'.$name.'</a>';
+
+ if($item['title']){
+ echo '<span>'.htmlspecialchars($item['title']).'</span>';
+ }
+ echo '</div>';
+ }
+
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/lib/exe/css.php b/lib/exe/css.php
new file mode 100644
index 000000000..69b512205
--- /dev/null
+++ b/lib/exe/css.php
@@ -0,0 +1,343 @@
+<?php
+/**
+ * DokuWiki StyleSheet creator
+ *
+ * @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__).'/../../');
+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
+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;
+
+ $mediatype = 'screen';
+ if (isset($_REQUEST['s']) &&
+ in_array($_REQUEST['s'], array('all', 'print', 'feed'))) {
+ $mediatype = $_REQUEST['s'];
+ }
+
+ $tpl = trim(preg_replace('/[^\w-]+/','',$_REQUEST['t']));
+ if($tpl){
+ $tplinc = DOKU_INC.'lib/tpl/'.$tpl.'/';
+ $tpldir = DOKU_BASE.'lib/tpl/'.$tpl.'/';
+ }else{
+ $tplinc = tpl_incdir();
+ $tpldir = tpl_basedir();
+ }
+
+ // The generated script depends on some dynamic options
+ $cache = new cache('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tplinc.$mediatype,'.css');
+
+ // load template styles
+ $tplstyles = array();
+ if(@file_exists($tplinc.'style.ini')){
+ $ini = parse_ini_file($tplinc.'style.ini',true);
+ foreach($ini['stylesheets'] as $file => $mode){
+ $tplstyles[$mode][$tplinc.$file] = $tpldir;
+ }
+ }
+
+ // Array of needed files and their web locations, the latter ones
+ // are needed to fix relative paths in the stylesheets
+ $files = array();
+ // load core styles
+ $files[DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/';
+ // load jQuery-UI theme
+ $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($tplstyles[$mediatype])) {
+ $files = array_merge($files, $tplstyles[$mediatype]);
+ }
+ // if old 'default' userstyle setting exists, make it 'screen' userstyle for backwards compatibility
+ if (isset($config_cascade['userstyle']['default'])) {
+ $config_cascade['userstyle']['screen'] = $config_cascade['userstyle']['default'];
+ }
+ // load user styles
+ if(isset($config_cascade['userstyle'][$mediatype])){
+ $files[$config_cascade['userstyle'][$mediatype]] = DOKU_BASE;
+ }
+ // load rtl styles
+ // @todo: this currently adds the rtl styles only to the 'screen' media type
+ // but 'print' and 'all' should also be supported
+ if ($mediatype=='screen') {
+ if($lang['direction'] == 'rtl'){
+ if (isset($tplstyles['rtl'])) $files = array_merge($files, $tplstyles['rtl']);
+ }
+ }
+
+ $cache_files = array_merge(array_keys($files), getConfigFiles('main'));
+ $cache_files[] = $tplinc.'style.ini';
+ $cache_files[] = __FILE__;
+
+ // check cache age & handle conditional request
+ // This may exit if a cache can be used
+ http_cached($cache->cache,
+ $cache->useCache(array('files' => $cache_files)));
+
+ // start output buffering and build the stylesheet
+ ob_start();
+
+ // print the default classes for interwiki links and file downloads
+ css_interwiki();
+ css_filetypes();
+
+ // load files
+ foreach($files as $file => $location){
+ print css_loadfile($file, $location);
+ }
+
+ // end output buffering and get contents
+ $css = ob_get_contents();
+ ob_end_clean();
+
+ // apply style replacements
+ $css = css_applystyle($css,$tplinc);
+
+ // place all @import statements at the top of the file
+ $css = css_moveimports($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);
+}
+
+/**
+ * Does placeholder replacements in the style according to
+ * the ones defined in a templates style.ini file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_applystyle($css,$tplinc){
+ if(@file_exists($tplinc.'style.ini')){
+ $ini = parse_ini_file($tplinc.'style.ini',true);
+ $css = strtr($css,$ini['replacements']);
+ }
+ return $css;
+}
+
+/**
+ * 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
+ */
+function css_loadfile($file,$location=''){
+ if(!@file_exists($file)) return '';
+ $css = io_readFile($file);
+ if(!$location) return $css;
+
+ $css = preg_replace('#(url\([ \'"]*)(?!/|data:|http://|https://| |\'|")#','\\1'.$location,$css);
+ $css = preg_replace('#(@import\s+[\'"])(?!/|data:|http://|https://)#', '\\1'.$location, $css);
+
+ return $css;
+}
+
+/**
+ * Converte local image URLs to data URLs if the filesize is small
+ *
+ * Callback for preg_replace_callback
+ */
+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($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>
+ */
+function css_pluginstyles($mediatype='screen'){
+ global $lang;
+ $list = array();
+ $plugins = plugin_list();
+ foreach ($plugins as $p){
+ $list[DOKU_PLUGIN."$p/$mediatype.css"] = DOKU_BASE."lib/plugins/$p/";
+ // alternative for screen.css
+ if ($mediatype=='screen') {
+ $list[DOKU_PLUGIN."$p/style.css"] = DOKU_BASE."lib/plugins/$p/";
+ }
+ if($lang['direction'] == 'rtl'){
+ $list[DOKU_PLUGIN."$p/rtl.css"] = DOKU_BASE."lib/plugins/$p/";
+ }
+ }
+ return $list;
+}
+
+/**
+ * Move all @import statements in a combined stylesheet to the top so they
+ * aren't ignored by the browser.
+ *
+ * @author Gabriel Birke <birke@d-scribe.de>
+ */
+function css_moveimports($css)
+{
+ if(!preg_match_all('/@import\s+(?:url\([^)]+\)|"[^"]+")\s*[^;]*;\s*/', $css, $matches, PREG_OFFSET_CAPTURE)) {
+ return $css;
+ }
+ $newCss = "";
+ $imports = "";
+ $offset = 0;
+ foreach($matches[0] as $match) {
+ $newCss .= substr($css, $offset, $match[1] - $offset);
+ $imports .= $match[0];
+ $offset = $match[1] + strlen($match[0]);
+ }
+ $newCss .= substr($css, $offset);
+ return $imports.$newCss;
+}
+
+/**
+ * Very simple CSS optimizer
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_compress($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('/(?<!:)\/\/.*$/m','',$css);
+
+ // strip whitespaces
+ $css = preg_replace('![\r\n\t ]+!',' ',$css);
+ $css = preg_replace('/ ?([;,{}\/]) ?/','\\1',$css);
+ $css = preg_replace('/ ?: /',':',$css);
+
+ // 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);
+
+ return $css;
+}
+
+/**
+ * Callback for css_compress()
+ *
+ * Keeps short comments (< 5 chars) to maintain typical browser hacks
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_comment_cb($matches){
+ if(strlen($matches[2]) > 4) return '';
+ return $matches[0];
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/exe/detail.php b/lib/exe/detail.php
new file mode 100644
index 000000000..35186f5dd
--- /dev/null
+++ b/lib/exe/detail.php
@@ -0,0 +1,48 @@
+<?php
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+define('DOKU_MEDIADETAIL',1);
+require_once(DOKU_INC.'inc/init.php');
+//close session
+session_write_close();
+
+$IMG = getID('media');
+$ID = cleanID($_REQUEST['id']);
+
+if($conf['allowdebug'] && $_REQUEST['debug']){
+ print '<pre>';
+ foreach(explode(' ','basedir userewrite baseurl useslash') as $x){
+ print '$'."conf['$x'] = '".$conf[$x]."';\n";
+ }
+ foreach(explode(' ','DOCUMENT_ROOT HTTP_HOST SCRIPT_FILENAME PHP_SELF '.
+ 'REQUEST_URI SCRIPT_NAME PATH_INFO PATH_TRANSLATED') as $x){
+ print '$'."_SERVER['$x'] = '".$_SERVER[$x]."';\n";
+ }
+ print "getID('media'): ".getID('media')."\n";
+ print "getID('media',false): ".getID('media',false)."\n";
+ print '</pre>';
+}
+
+$ERROR = false;
+// check image permissions
+$AUTH = auth_quickaclcheck($IMG);
+if($AUTH >= AUTH_READ){
+ // check if image exists
+ $SRC = mediaFN($IMG);
+ if(!@file_exists($SRC)){
+ //doesn't exist!
+ header("HTTP/1.0 404 File not Found");
+ $ERROR = 'File not found';
+ }
+}else{
+ // no auth
+ $ERROR = p_locale_xhtml('denied');
+}
+
+// this makes some general infos available as well as the info about the
+// "parent" page
+$INFO = pageinfo();
+
+//start output and load template
+header('Content-Type: text/html; charset=utf-8');
+include(template('detail.php'));
+
diff --git a/lib/exe/fetch.php b/lib/exe/fetch.php
new file mode 100644
index 000000000..143d40f22
--- /dev/null
+++ b/lib/exe/fetch.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * DokuWiki media passthrough file
+ *
+ * @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__).'/../../');
+ define('DOKU_DISABLE_GZIP_OUTPUT', 1);
+ require_once(DOKU_INC.'inc/init.php');
+
+ //close session
+ session_write_close();
+
+ $mimetypes = getMimeTypes();
+
+ //get input
+ $MEDIA = stripctl(getID('media',false)); // no cleaning except control chars - maybe external
+ $CACHE = calc_cache($_REQUEST['cache']);
+ $WIDTH = (int) $_REQUEST['w'];
+ $HEIGHT = (int) $_REQUEST['h'];
+ $REV = (int) @$_REQUEST['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);
+
+ // 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,
+ );
+
+ // handle the file status
+ $evt = new Doku_Event('FETCH_MEDIA_STATUS', $data);
+ if ( $evt->advise_before() ) {
+ // redirects
+ if($data['status'] > 300 && $data['status'] <= 304){
+ send_redirect($data['statusmessage']);
+ }
+ // send any non 200 status
+ if($data['status'] != 200){
+ header('HTTP/1.0 ' . $data['status'] . ' ' . $data['statusmessage']);
+ }
+ // die on errors
+ if($data['status'] > 203){
+ print $data['statusmessage'];
+ exit;
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ //handle image resizing/cropping
+ if((substr($MIME,0,5) == 'image') && $WIDTH){
+ if($HEIGHT){
+ $data['file'] = $FILE = media_crop_image($data['file'],$EXT,$WIDTH,$HEIGHT);
+ }else{
+ $data['file'] = $FILE = media_resize_image($data['file'],$EXT,$WIDTH,$HEIGHT);
+ }
+ }
+
+ // finally send the file to the client
+ $evt = new Doku_Event('MEDIA_SENDFILE', $data);
+ if ($evt->advise_before()) {
+ sendFile($data['file'],$data['mime'],$data['download'],$data['cache']);
+ }
+ // Do something after the download finished.
+ $evt->advise_after();
+
+/* ------------------------------------------------------------------------ */
+
+/**
+ * Set headers and send the file to the client
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function sendFile($file,$mime,$dl,$cache){
+ global $conf;
+ $fmtime = @filemtime($file);
+ // send headers
+ header("Content-Type: $mime");
+ // smart http caching headers
+ if ($cache==-1) {
+ // cache
+ // cachetime or one hour
+ header('Expires: '.gmdate("D, d M Y H:i:s", time()+max($conf['cachetime'], 3600)).' GMT');
+ header('Cache-Control: public, proxy-revalidate, no-transform, max-age='.max($conf['cachetime'], 3600));
+ header('Pragma: public');
+ } else if ($cache>0) {
+ // recache
+ // remaining cachetime + 10 seconds so the newly recached media is used
+ header('Expires: '.gmdate("D, d M Y H:i:s", $fmtime+$conf['cachetime']+10).' GMT');
+ header('Cache-Control: public, proxy-revalidate, no-transform, max-age='.max($fmtime-time()+$conf['cachetime']+10, 0));
+ header('Pragma: public');
+ } else if ($cache==0) {
+ // nocache
+ header('Cache-Control: must-revalidate, no-transform, post-check=0, pre-check=0');
+ header('Pragma: public');
+ }
+ //send important headers first, script stops here if '304 Not Modified' response
+ http_conditionalRequest($fmtime);
+
+
+ //download or display?
+ if($dl){
+ header('Content-Disposition: attachment; filename="'.basename($file).'";');
+ }else{
+ header('Content-Disposition: inline; filename="'.basename($file).'";');
+ }
+
+ //use x-sendfile header to pass the delivery to compatible webservers
+ if (http_sendfile($file)) exit;
+
+ // send file contents
+ $fp = @fopen($file,"rb");
+ if($fp){
+ http_rangeRequest($fp,filesize($file),$mime);
+ }else{
+ header("HTTP/1.0 500 Internal Server Error");
+ print "Could not read $file - bad permissions?";
+ }
+}
+
+/**
+ * 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 $media reference to the media id
+ * @param $file reference to the file variable
+ * @returns array(STATUS, STATUSMESSAGE)
+ */
+function checkFileStatus(&$media, &$file, $rev='') {
+ global $MIME, $EXT, $CACHE;
+
+ //media to local file
+ if(preg_match('#^(https?)://#i',$media)){
+ //check hash
+ if(substr(md5(auth_cookiesalt().$media),0,6) != $_REQUEST['hash']){
+ 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 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>
+ */
+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
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/lib/exe/index.html b/lib/exe/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/exe/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<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/lib/exe/indexer.php b/lib/exe/indexer.php
new file mode 100644
index 000000000..95e2af05b
--- /dev/null
+++ b/lib/exe/indexer.php
@@ -0,0 +1,271 @@
+<?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',dirname(__FILE__).'/../../');
+define('DOKU_DISABLE_GZIP_OUTPUT',1);
+require_once(DOKU_INC.'inc/init.php');
+session_write_close(); //close session
+if(!defined('NL')) define('NL',"\n");
+
+// 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'];
+if(!$defer){
+ sendGIF(); // send gif
+}
+
+$ID = cleanID($_REQUEST['id']);
+
+// Catch any possible output (e.g. errors)
+$output = isset($_REQUEST['debug']) && $conf['allowdebug'];
+if(!$output) ob_start();
+
+// run one of the jobs
+$tmp = array(); // No event data
+$evt = new Doku_Event('INDEXER_TASKS_RUN', $tmp);
+if ($evt->advise_before()) {
+ runIndexer() or
+ runSitemapper() or
+ sendDigest() or
+ runTrimRecentChanges() or
+ runTrimRecentChanges(true) or
+ $evt->advise_after();
+}
+if($defer) sendGIF();
+
+if(!$output) ob_end_clean();
+exit;
+
+// --------------------------------------------------------------------
+
+/**
+ * Trims the recent changes cache (or imports the old changelog) as needed.
+ *
+ * @param media_changes If the media changelog shall be trimmed instead of
+ * the page changelog
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function runTrimRecentChanges($media_changes = false) {
+ global $conf;
+
+ $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);
+ return false;
+ }
+
+ io_saveFile($fn.'_tmp', ''); // presave tmp as 2nd lock
+ $trim_time = time() - $conf['recent_days']*86400;
+ $out_lines = array();
+
+ for ($i=0; $i<count($lines); $i++) {
+ $log = parseChangelogLine($lines[$i]);
+ if ($log === false) continue; // discard junk
+ if ($log['date'] < $trim_time) {
+ $old_lines[$log['date'].".$i"] = $lines[$i]; // keep old lines for now (append .$i to prevent key collisions)
+ } else {
+ $out_lines[$log['date'].".$i"] = $lines[$i]; // definitely keep these lines
+ }
+ }
+
+ if (count($lines)==count($out_lines)) {
+ // nothing to trim
+ @unlink($fn.'_tmp');
+ io_unlock($fn);
+ 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);
+ }
+
+ // 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);
+ }
+ return true;
+ }
+
+ // nothing done
+ return false;
+}
+
+/**
+ * Runs the indexer for the current page
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function runIndexer(){
+ global $ID;
+ global $conf;
+ print "runIndexer(): started".NL;
+
+ if(!$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
+ */
+function runSitemapper(){
+ print "runSitemapper(): started".NL;
+ $result = Sitemapper::generate() && Sitemapper::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>
+ */
+function sendDigest() {
+ echo 'sendDigest(): start'.NL;
+ global $ID;
+ global $conf;
+ if (!$conf['subscribers']) {
+ return;
+ }
+ $subscriptions = subscription_find($ID, array('style' => '(digest|list)',
+ 'escaped' => true));
+ global $auth;
+ global $lang;
+ global $conf;
+ global $USERINFO;
+
+ // remember current user info
+ $olduinfo = $USERINFO;
+ $olduser = $_SERVER['REMOTE_USER'];
+
+ foreach($subscriptions as $id => $users) {
+ if (!subscription_lock($id)) {
+ continue;
+ }
+ foreach($users as $data) {
+ list($user, $style, $lastupdate) = $data;
+ $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);
+ $_SERVER['REMOTE_USER'] = $user;
+ if ($USERINFO === false) {
+ continue;
+ }
+
+ if (substr($id, -1, 1) === ':') {
+ // The subscription target is a namespace
+ $changes = getRecentsSince($lastupdate, null, getNS($id));
+ } else {
+ if(auth_quickaclcheck($id) < AUTH_READ) continue;
+
+ $meta = p_get_metadata($id);
+ $changes = array($meta['last_change']);
+ }
+
+ // Filter out pages only changed in small and own edits
+ $change_ids = array();
+ foreach($changes as $rev) {
+ $n = 0;
+ while (!is_null($rev) && $rev['date'] >= $lastupdate &&
+ ($_SERVER['REMOTE_USER'] === $rev['user'] ||
+ $rev['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT)) {
+ $rev = getRevisions($rev['id'], $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'];
+ }
+ }
+
+ if ($style === 'digest') {
+ foreach($change_ids as $change_id) {
+ subscription_send_digest($USERINFO['mail'], $change_id,
+ $lastupdate);
+ }
+ } elseif ($style === 'list') {
+ subscription_send_list($USERINFO['mail'], $change_ids, $id);
+ }
+ // TODO: Handle duplicate subscriptions.
+
+ // Update notification time.
+ subscription_set($user, $id, $style, time(), true);
+ }
+ subscription_unlock($id);
+ }
+
+ // restore current user info
+ $USERINFO = $olduinfo;
+ $_SERVER['REMOTE_USER'] = $olduser;
+}
+
+/**
+ * Just send a 1x1 pixel blank gif to the browser
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Harry Fuecks <fuecks@gmail.com>
+ */
+function sendGIF(){
+ if(isset($_REQUEST['debug'])){
+ header('Content-Type: text/plain');
+ return;
+ }
+ $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
+ header('Content-Type: image/gif');
+ header('Content-Length: '.strlen($img));
+ header('Connection: Close');
+ print $img;
+ flush();
+ // Browser should drop connection after this
+ // Thinks it's got the whole image
+}
+
+//Setup VIM: ex: et ts=4 :
+// No trailing PHP closing tag - no output please!
+// See Note at http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php
diff --git a/lib/exe/js.php b/lib/exe/js.php
new file mode 100644
index 000000000..963eebd5f
--- /dev/null
+++ b/lib/exe/js.php
@@ -0,0 +1,358 @@
+<?php
+/**
+ * DokuWiki JavaScript creator
+ *
+ * @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__).'/../../');
+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: text/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;
+
+ // The generated script depends on some dynamic options
+ $cache = new cache('scripts'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'],
+ '.js');
+
+ // load minified version for some files
+ $min = $conf['compress'] ? '.min' : '';
+
+ // array of core files
+ $files = array(
+ DOKU_INC."lib/scripts/jquery/jquery$min.js",
+ DOKU_INC.'lib/scripts/jquery/jquery.cookie.js',
+ DOKU_INC."lib/scripts/jquery/jquery-ui$min.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/tw-sack.js',
+ DOKU_INC.'lib/scripts/qsearch.js',
+ DOKU_INC.'lib/scripts/tree.js',
+ DOKU_INC.'lib/scripts/index.js',
+ DOKU_INC.'lib/scripts/drag.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().'script.js',
+ );
+
+ // add possible plugin scripts and userscript
+ $files = array_merge($files,js_pluginscripts());
+ if(isset($config_cascade['userscript']['default'])){
+ $files[] = $config_cascade['userscript']['default'];
+ }
+
+ $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
+ http_cached($cache->cache,
+ $cache->useCache(array('files' => $cache_files)));
+
+ // 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()."';";
+ // FIXME: Move those to JSINFO
+ print "var DOKU_UHN = ".((int) useHeading('navigation')).";";
+ print "var DOKU_UHC = ".((int) useHeading('content')).";";
+
+ // load JS specific translations
+ $json = new JSON();
+ $lang['js']['plugins'] = js_pluginstrings();
+ echo 'LANG = '.$json->encode($lang['js']).";\n";
+
+ // load toolbar
+ toolbar_JSdefines('toolbar');
+
+ // load files
+ foreach($files as $file){
+ echo "\n\n/* XXXXXXXXXX begin of ".str_replace(DOKU_INC, '', $file) ." XXXXXXXXXX */\n\n";
+ js_load($file);
+ 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();
+
+ // 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>
+ */
+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 = basename($ifile);
+ if($loaded[$base]) 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>
+ */
+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>
+ */
+function js_pluginstrings()
+{
+ global $conf;
+ $pluginstrings = array();
+ $plugins = plugin_list();
+ foreach ($plugins as $p){
+ if (isset($lang)) unset($lang);
+ if (@file_exists(DOKU_PLUGIN."$p/lang/en/lang.php")) {
+ include DOKU_PLUGIN."$p/lang/en/lang.php";
+ }
+ if (isset($conf['lang']) && $conf['lang']!='en' && @file_exists(DOKU_PLUGIN."$p/lang/".$conf['lang']."/lang.php")) {
+ include DOKU_PLUGIN."$p/lang/".$conf['lang']."/lang.php";
+ }
+ if (isset($lang['js'])) {
+ $pluginstrings[$p] = $lang['js'];
+ }
+ }
+ return $pluginstrings;
+}
+
+/**
+ * Escapes a String to be embedded in a JavaScript call, keeps \n
+ * as newline
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+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>
+ */
+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/
+ */
+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'\"[]";
+
+ $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);
+ $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} != '/'){
+ while( ($s{$i+$j} != '\\') && ($s{$i+$j} != '/')){
+ $j = $j + 1;
+ }
+ if($s{$i+$j} == '\\') $j = $j + 2;
+ }
+ $result .= substr($s,$i,$j+1);
+ $i = $i + $j + 1;
+ continue;
+ }
+ }
+
+ // double quote strings
+ if($ch == '"'){
+ $j = 1;
+ while( $s{$i+$j} != '"' && ($i+$j < $slen)){
+ if( $s{$i+$j} == '\\' && ($s{$i+$j+1} == '"' || $s{$i+$j+1} == '\\') ){
+ $j += 2;
+ }else{
+ $j += 1;
+ }
+ }
+ $result .= substr($s,$i,$j+1);
+ $i = $i + $j + 1;
+ continue;
+ }
+
+ // single quote strings
+ if($ch == "'"){
+ $j = 1;
+ while( $s{$i+$j} != "'" && ($i+$j < $slen)){
+ if( $s{$i+$j} == '\\' && ($s{$i+$j+1} == "'" || $s{$i+$j+1} == '\\') ){
+ $j += 2;
+ }else{
+ $j += 1;
+ }
+ }
+ $result .= substr($s,$i,$j+1);
+ $i = $i + $j + 1;
+ continue;
+ }
+
+ // whitespaces
+ if( $ch == ' ' || $ch == "\r" || $ch == "\n" || $ch == "\t" ){
+ // 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
+ $lch = substr($result,-1);
+ 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/lib/exe/mediamanager.php b/lib/exe/mediamanager.php
new file mode 100644
index 000000000..5f09fe1f8
--- /dev/null
+++ b/lib/exe/mediamanager.php
@@ -0,0 +1,122 @@
+<?php
+ 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');
+
+ trigger_event('MEDIAMANAGER_STARTED',$tmp=array());
+ session_write_close(); //close session
+
+ // handle passed message
+ if($_REQUEST['msg1']) msg(hsc($_REQUEST['msg1']),1);
+ if($_REQUEST['err']) msg(hsc($_REQUEST['err']),-1);
+
+
+ // get namespace to display (either direct or from deletion order)
+ if($_REQUEST['delete']){
+ $DEL = cleanID($_REQUEST['delete']);
+ $IMG = $DEL;
+ $NS = getNS($DEL);
+ }elseif($_REQUEST['edit']){
+ $IMG = cleanID($_REQUEST['edit']);
+ $NS = getNS($IMG);
+ }elseif($_REQUEST['img']){
+ $IMG = cleanID($_REQUEST['img']);
+ $NS = getNS($IMG);
+ }else{
+ $NS = $_REQUEST['ns'];
+ $NS = cleanID($NS);
+ }
+
+ // check auth
+ $AUTH = auth_quickaclcheck("$NS:*");
+
+ // do not display the manager if user does not have read access
+ if($AUTH < AUTH_READ && !$fullscreen) {
+ header('HTTP/1.0 403 Forbidden');
+ die($lang['accessdenied']);
+ }
+
+ // create the given namespace (just for beautification)
+ if($AUTH >= AUTH_UPLOAD) { io_createNamespace("$NS:xxx", 'media'); }
+
+ // handle flash upload
+ if(isset($_FILES['Filedata'])){
+ $_FILES['upload'] =& $_FILES['Filedata'];
+ $JUMPTO = media_upload($NS,$AUTH);
+ if($JUMPTO == false){
+ header("HTTP/1.0 400 Bad Request");
+ echo 'Upload failed';
+ }
+ echo 'ok';
+ exit;
+ }
+
+ // give info on PHP catched upload errors
+ if($_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($_FILES['upload']['tmp_name']){
+ $JUMPTO = media_upload($NS,$AUTH);
+ if($JUMPTO) $NS = getNS($JUMPTO);
+ }
+
+ // handle meta saving
+ if($IMG && @array_key_exists('save', $_REQUEST['do'])){
+ $JUMPTO = media_metasave($IMG,$AUTH,$_REQUEST['meta']);
+ }
+
+ if($IMG && ($_REQUEST['mediado'] == 'save' || @array_key_exists('save', $_REQUEST['mediado']))) {
+ $JUMPTO = media_metasave($IMG,$AUTH,$_REQUEST['meta']);
+ }
+
+ if ($_REQUEST['rev'] && $conf['mediarevisions']) $REV = (int) $_REQUEST['rev'];
+
+ if($_REQUEST['mediado'] == 'restore' && $conf['mediarevisions']){
+ $JUMPTO = media_restore($_REQUEST['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='.$_REQUEST['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/lib/exe/opensearch.php b/lib/exe/opensearch.php
new file mode 100644
index 000000000..73939c347
--- /dev/null
+++ b/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/default/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>'.htmlspecialchars($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/lib/exe/xmlrpc.php b/lib/exe/xmlrpc.php
new file mode 100644
index 000000000..1264ff333
--- /dev/null
+++ b/lib/exe/xmlrpc.php
@@ -0,0 +1,888 @@
+<?php
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+
+// fix when '< ?xml' isn't on the very first line
+if(isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
+
+/**
+ * Increased whenever the API is changed
+ */
+define('DOKU_XMLRPC_API_VERSION', 7);
+
+require_once(DOKU_INC.'inc/init.php');
+session_write_close(); //close session
+
+if(!$conf['xmlrpc']) die('XML-RPC server not enabled.');
+
+/**
+ * Contains needed wrapper functions and registers all available
+ * XMLRPC functions.
+ */
+class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer {
+ var $methods = array();
+ var $public_methods = array();
+
+ /**
+ * Checks if the current user is allowed to execute non anonymous methods
+ */
+ function checkAuth(){
+ global $conf;
+ global $USERINFO;
+
+ if(!$conf['useacl']) return true; //no ACL - then no checks
+ if(trim($conf['xmlrpcuser']) == '') return true; //no restrictions
+
+ return auth_isMember($conf['xmlrpcuser'],$_SERVER['REMOTE_USER'],(array) $USERINFO['grps']);
+ }
+
+ /**
+ * Adds a callback, extends parent method
+ *
+ * add another parameter to define if anonymous access to
+ * this method should be granted.
+ */
+ function addCallback($method, $callback, $args, $help, $public=false){
+ if($public) $this->public_methods[] = $method;
+ return parent::addCallback($method, $callback, $args, $help);
+ }
+
+ /**
+ * Execute a call, extends parent method
+ *
+ * Checks for authentication first
+ */
+ function call($methodname, $args){
+ if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){
+ if (!isset($_SERVER['REMOTE_USER'])) {
+ header('HTTP/1.1 401 Unauthorized');
+ } else {
+ header('HTTP/1.1 403 Forbidden');
+ }
+ return new IXR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".');
+ }
+ return parent::call($methodname, $args);
+ }
+
+ /**
+ * Constructor. Register methods and run Server
+ */
+ function dokuwiki_xmlrpc_server(){
+ $this->IXR_IntrospectionServer();
+
+ /* DokuWiki's own methods */
+ $this->addCallback(
+ 'dokuwiki.getXMLRPCAPIVersion',
+ 'this:getAPIVersion',
+ array('integer'),
+ 'Returns the XMLRPC API version.',
+ true
+ );
+
+ $this->addCallback(
+ 'dokuwiki.getVersion',
+ 'getVersion',
+ array('string'),
+ 'Returns the running DokuWiki version.',
+ true
+ );
+
+ $this->addCallback(
+ 'dokuwiki.login',
+ 'this:login',
+ array('integer','string','string'),
+ 'Tries to login with the given credentials and sets auth cookies.',
+ true
+ );
+
+ $this->addCallback(
+ 'dokuwiki.getPagelist',
+ 'this:readNamespace',
+ array('struct','string','struct'),
+ 'List all pages within the given namespace.'
+ );
+
+ $this->addCallback(
+ 'dokuwiki.search',
+ 'this:search',
+ array('struct','string'),
+ 'Perform a fulltext search and return a list of matching pages'
+ );
+
+ $this->addCallback(
+ 'dokuwiki.getTime',
+ 'time',
+ array('int'),
+ 'Return the current time at the wiki server.'
+ );
+
+ $this->addCallback(
+ 'dokuwiki.setLocks',
+ 'this:setLocks',
+ array('struct','struct'),
+ 'Lock or unlock pages.'
+ );
+
+
+ $this->addCallback(
+ 'dokuwiki.getTitle',
+ 'this:getTitle',
+ array('string'),
+ 'Returns the wiki title.',
+ true
+ );
+
+ $this->addCallback(
+ 'dokuwiki.appendPage',
+ 'this:appendPage',
+ array('int', 'string', 'string', 'struct'),
+ 'Append text to a wiki page.'
+ );
+
+ /* Wiki API v2 http://www.jspwiki.org/wiki/WikiRPCInterface2 */
+ $this->addCallback(
+ 'wiki.getRPCVersionSupported',
+ 'this:wiki_RPCVersion',
+ array('int'),
+ 'Returns 2 with the supported RPC API version.',
+ true
+ );
+ $this->addCallback(
+ 'wiki.getPage',
+ 'this:rawPage',
+ array('string','string'),
+ 'Get the raw Wiki text of page, latest version.'
+ );
+ $this->addCallback(
+ 'wiki.getPageVersion',
+ 'this:rawPage',
+ array('string','string','int'),
+ 'Get the raw Wiki text of page.'
+ );
+ $this->addCallback(
+ 'wiki.getPageHTML',
+ 'this:htmlPage',
+ array('string','string'),
+ 'Return page in rendered HTML, latest version.'
+ );
+ $this->addCallback(
+ 'wiki.getPageHTMLVersion',
+ 'this:htmlPage',
+ array('string','string','int'),
+ 'Return page in rendered HTML.'
+ );
+ $this->addCallback(
+ 'wiki.getAllPages',
+ 'this:listPages',
+ array('struct'),
+ 'Returns a list of all pages. The result is an array of utf8 pagenames.'
+ );
+ $this->addCallback(
+ 'wiki.getAttachments',
+ 'this:listAttachments',
+ array('struct', 'string', 'struct'),
+ 'Returns a list of all media files.'
+ );
+ $this->addCallback(
+ 'wiki.getBackLinks',
+ 'this:listBackLinks',
+ array('struct','string'),
+ 'Returns the pages that link to this page.'
+ );
+ $this->addCallback(
+ 'wiki.getPageInfo',
+ 'this:pageInfo',
+ array('struct','string'),
+ 'Returns a struct with infos about the page.'
+ );
+ $this->addCallback(
+ 'wiki.getPageInfoVersion',
+ 'this:pageInfo',
+ array('struct','string','int'),
+ 'Returns a struct with infos about the page.'
+ );
+ $this->addCallback(
+ 'wiki.getPageVersions',
+ 'this:pageVersions',
+ array('struct','string','int'),
+ 'Returns the available revisions of the page.'
+ );
+ $this->addCallback(
+ 'wiki.putPage',
+ 'this:putPage',
+ array('int', 'string', 'string', 'struct'),
+ 'Saves a wiki page.'
+ );
+ $this->addCallback(
+ 'wiki.listLinks',
+ 'this:listLinks',
+ array('struct','string'),
+ 'Lists all links contained in a wiki page.'
+ );
+ $this->addCallback(
+ 'wiki.getRecentChanges',
+ 'this:getRecentChanges',
+ array('struct','int'),
+ 'Returns a struct about all recent changes since given timestamp.'
+ );
+ $this->addCallback(
+ 'wiki.getRecentMediaChanges',
+ 'this:getRecentMediaChanges',
+ array('struct','int'),
+ 'Returns a struct about all recent media changes since given timestamp.'
+ );
+ $this->addCallback(
+ 'wiki.aclCheck',
+ 'this:aclCheck',
+ array('int', 'string'),
+ 'Returns the permissions of a given wiki page.'
+ );
+ $this->addCallback(
+ 'wiki.putAttachment',
+ 'this:putAttachment',
+ array('struct', 'string', 'base64', 'struct'),
+ 'Upload a file to the wiki.'
+ );
+ $this->addCallback(
+ 'wiki.deleteAttachment',
+ 'this:deleteAttachment',
+ array('int', 'string'),
+ 'Delete a file from the wiki.'
+ );
+ $this->addCallback(
+ 'wiki.getAttachment',
+ 'this:getAttachment',
+ array('base64', 'string'),
+ 'Download a file from the wiki.'
+ );
+ $this->addCallback(
+ 'wiki.getAttachmentInfo',
+ 'this:getAttachmentInfo',
+ array('struct', 'string'),
+ 'Returns a struct with infos about the attachment.'
+ );
+
+ /**
+ * Trigger XMLRPC_CALLBACK_REGISTER, action plugins can use this event
+ * to extend the XMLRPC interface and register their own callbacks.
+ *
+ * Event data:
+ * The XMLRPC server object:
+ *
+ * $event->data->addCallback() - register a callback, the second
+ * paramter has to be of the form "plugin:<pluginname>:<plugin
+ * method>"
+ *
+ * $event->data->callbacks - an array which holds all awaylable
+ * callbacks
+ */
+ trigger_event('XMLRPC_CALLBACK_REGISTER', $this);
+
+ $this->serve();
+ }
+
+ /**
+ * Return a raw wiki page
+ */
+ function rawPage($id,$rev=''){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ $text = rawWiki($id,$rev);
+ if(!$text) {
+ return pageTemplate($id);
+ } else {
+ return $text;
+ }
+ }
+
+ /**
+ * Return a media file encoded in base64
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ */
+ function getAttachment($id){
+ $id = cleanID($id);
+ if (auth_quickaclcheck(getNS($id).':*') < AUTH_READ)
+ return new IXR_Error(211, 'You are not allowed to read this file');
+
+ $file = mediaFN($id);
+ if (!@ file_exists($file))
+ return new IXR_Error(221, 'The requested file does not exist');
+
+ $data = io_readFile($file, false);
+ $base64 = new IXR_Base64($data);
+ return $base64;
+ }
+
+ /**
+ * Return info about a media file
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ */
+ function getAttachmentInfo($id){
+ $id = cleanID($id);
+ $info = array(
+ 'lastModified' => 0,
+ 'size' => 0,
+ );
+
+ $file = mediaFN($id);
+ if ((auth_quickaclcheck(getNS($id).':*') >= AUTH_READ) && file_exists($file)){
+ $info['lastModified'] = new IXR_Date(filemtime($file));
+ $info['size'] = filesize($file);
+ }
+
+ return $info;
+ }
+
+ /**
+ * Return a wiki page rendered to html
+ */
+ function htmlPage($id,$rev=''){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ return p_wiki_xhtml($id,$rev,false);
+ }
+
+ /**
+ * List all pages - we use the indexer list here
+ */
+ 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'] = new IXR_Date(@filemtime(wikiFN($pages[$idx])));
+ $list[] = $page;
+ }
+
+ return $list;
+ }
+
+ /**
+ * List all pages in the given namespace (and below)
+ */
+ function readNamespace($ns,$opts){
+ 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)
+ */
+ function search($query){
+ require_once(DOKU_INC.'inc/fulltext.php');
+
+ $regex = '';
+ $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,
+ );
+ }
+ return $pages;
+ }
+
+ /**
+ * Returns the wiki title.
+ */
+ 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>
+ */
+ function listAttachments($ns, $options = array()) {
+ global $conf;
+ global $lang;
+
+ $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]['lastModified'] = new IXR_Date($data[$i]['mtime']);
+ }
+ return $data;
+ } else {
+ return new IXR_Error(215, 'You are not allowed to list media files.');
+ }
+ }
+
+ /**
+ * Return a list of backlinks
+ */
+ function listBackLinks($id){
+ return ft_backlinks(cleanID($id));
+ }
+
+ /**
+ * Return some basic data about a page
+ */
+ function pageInfo($id,$rev=''){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ $file = wikiFN($id,$rev);
+ $time = @filemtime($file);
+ if(!$time){
+ return new IXR_Error(121, 'The requested page does not exist');
+ }
+
+ $info = getRevisionInfo($id, $time, 1024);
+
+ $data = array(
+ 'name' => $id,
+ 'lastModified' => new IXR_Date($time),
+ 'author' => (($info['user']) ? $info['user'] : $info['ip']),
+ 'version' => $time
+ );
+
+ return ($data);
+ }
+
+ /**
+ * Save a wiki page
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function putPage($id, $text, $params) {
+ global $TEXT;
+ global $lang;
+ global $conf;
+
+ $id = cleanID($id);
+ $TEXT = cleanText($text);
+ $sum = $params['sum'];
+ $minor = $params['minor'];
+
+ if(empty($id))
+ return new IXR_Error(131, 'Empty page ID');
+
+ if(!page_exists($id) && trim($TEXT) == '' ) {
+ return new IXR_ERROR(132, 'Refusing to write an empty new wiki page');
+ }
+
+ if(auth_quickaclcheck($id) < AUTH_EDIT)
+ return new IXR_Error(112, 'You are not allowed to edit this page');
+
+ // Check, if page is locked
+ if(checklock($id))
+ return new IXR_Error(133, 'The page is currently locked');
+
+ // SPAM check
+ if(checkwordblock())
+ return new IXR_Error(134, 'Positive wordblock check');
+
+ // 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 0;
+ }
+
+ /**
+ * Appends text to a wiki page.
+ */
+ function appendPage($id, $text, $params) {
+ $currentpage = $this->rawPage($id);
+ if (!is_string($currentpage)) {
+ return $currentpage;
+ }
+ return $this->putPage($id, $currentpage.$text, $params);
+ }
+
+ /**
+ * Uploads a file to the wiki.
+ *
+ * Michael Klier <chi@chimeric.de>
+ */
+ function putAttachment($id, $file, $params) {
+ $id = cleanID($id);
+ $auth = auth_quickaclcheck(getNS($id).':*');
+
+ if(!isset($id)) {
+ return new IXR_ERROR(231, 'Filename not given.');
+ }
+
+ global $conf;
+
+ $ftmp = $conf['tmpdir'] . '/' . md5($id.clientIP());
+
+ // save temporary file
+ @unlink($ftmp);
+ if (preg_match('/^[A-Za-z0-9\+\/]*={0,2}$/', $file) === 1) {
+ // DEPRECATED: Double-decode file if it still looks like base64
+ // after first decoding (which is done by the library)
+ $file = base64_decode($file);
+ }
+ io_saveFile($ftmp, $file);
+
+ $res = media_save(array('name' => $ftmp), $id, $params['ow'], $auth, 'rename');
+ if (is_array($res)) {
+ return new IXR_ERROR(-$res[1], $res[0]);
+ } else {
+ return $res;
+ }
+ }
+
+ /**
+ * Deletes a file from the wiki.
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ */
+ 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) {
+ return new IXR_ERROR(212, "You don't have permissions to delete files.");
+ } elseif ($res & DOKU_MEDIA_INUSE) {
+ return new IXR_ERROR(232, 'File is still referenced');
+ } else {
+ return new IXR_ERROR(233, 'Could not delete file');
+ }
+ }
+
+ /**
+ * Returns the permissions of a given wiki page
+ */
+ function aclCheck($id) {
+ $id = cleanID($id);
+ return auth_quickaclcheck($id);
+ }
+
+ /**
+ * Lists all links contained in a wiki page
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function listLinks($id) {
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ $links = array();
+
+ // resolve page instructions
+ $ins = p_cached_instructions(wikiFN($id));
+
+ // instantiate new Renderer - needed for interwiki links
+ include(DOKU_INC.'inc/parser/xhtml.php');
+ $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>
+ */
+ function getRecentChanges($timestamp) {
+ if(strlen($timestamp) != 10)
+ return new IXR_Error(311, 'The provided value is not a valid timestamp');
+
+ $recents = getRecentsSince($timestamp);
+
+ $changes = array();
+
+ foreach ($recents as $recent) {
+ $change = array();
+ $change['name'] = $recent['id'];
+ $change['lastModified'] = new IXR_Date($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
+ return new IXR_Error(321, 'There are no changes in the specified timeframe');
+ }
+ }
+
+ /**
+ * Returns a list of recent media changes since give timestamp
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function getRecentMediaChanges($timestamp) {
+ if(strlen($timestamp) != 10)
+ return new IXR_Error(311, 'The provided value is not a valid timestamp');
+
+ $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES);
+
+ $changes = array();
+
+ foreach ($recents as $recent) {
+ $change = array();
+ $change['name'] = $recent['id'];
+ $change['lastModified'] = new IXR_Date($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
+ return new IXR_Error(321, 'There are no changes in the specified timeframe');
+ }
+ }
+
+ /**
+ * Returns a list of available revisions of a given wiki page
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ function pageVersions($id, $first) {
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return new IXR_Error(111, 'You are not allowed to read this page');
+ }
+ global $conf;
+
+ $versions = array();
+
+ if(empty($id))
+ return new IXR_Error(131, 'Empty page ID');
+
+ $revisions = getRevisions($id, $first, $conf['recent']+1);
+
+ if(count($revisions)==0 && $first!=0) {
+ $first=0;
+ $revisions = getRevisions($id, $first, $conf['recent']+1);
+ }
+
+ if(count($revisions)>0 && $first==0) {
+ array_unshift($revisions, ''); // include current revision
+ array_pop($revisions); // remove extra log entry
+ }
+
+ $hasNext = false;
+ if(count($revisions)>$conf['recent']) {
+ $hasNext = true;
+ 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){
+ $info = getRevisionInfo($id, $time, 1024);
+ if(!empty($info)) {
+ $data['user'] = $info['user'];
+ $data['ip'] = $info['ip'];
+ $data['type'] = $info['type'];
+ $data['sum'] = $info['sum'];
+ $data['modified'] = new IXR_Date($info['date']);
+ $data['version'] = $info['date'];
+ array_push($versions, $data);
+ }
+ }
+ }
+ return $versions;
+ } else {
+ return array();
+ }
+ }
+
+ /**
+ * The version of Wiki RPC API supported
+ */
+ function wiki_RPCVersion(){
+ 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.
+ */
+ function setLocks($set){
+ $locked = array();
+ $lockfail = array();
+ $unlocked = array();
+ $unlockfail = array();
+
+ foreach((array) $set['lock'] as $id){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)){
+ $lockfail[] = $id;
+ }else{
+ lock($id);
+ $locked[] = $id;
+ }
+ }
+
+ foreach((array) $set['unlock'] as $id){
+ $id = cleanID($id);
+ if(auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)){
+ $unlockfail[] = $id;
+ }else{
+ $unlocked[] = $id;
+ }
+ }
+
+ return array(
+ 'locked' => $locked,
+ 'lockfail' => $lockfail,
+ 'unlocked' => $unlocked,
+ 'unlockfail' => $unlockfail,
+ );
+ }
+
+ function getAPIVersion(){
+ return DOKU_XMLRPC_API_VERSION;
+ }
+
+ function login($user,$pass){
+ global $conf;
+ global $auth;
+ if(!$conf['useacl']) return 0;
+ if(!$auth) return 0;
+
+ @session_start(); // reopen session for login
+ if($auth->canDo('external')){
+ $ok = $auth->trustExternal($user,$pass,false);
+ }else{
+ $evdata = array(
+ 'user' => $user,
+ 'password' => $pass,
+ 'sticky' => false,
+ 'silent' => true,
+ );
+ $ok = trigger_event('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper');
+ }
+ session_write_close(); // we're done with the session
+
+ return $ok;
+ }
+
+
+}
+
+$server = new dokuwiki_xmlrpc_server();
+
+// vim:ts=4:sw=4:et:
diff --git a/lib/images/admin/README b/lib/images/admin/README
new file mode 100644
index 000000000..90bab9578
--- /dev/null
+++ b/lib/images/admin/README
@@ -0,0 +1,2 @@
+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
diff --git a/lib/images/admin/acl.png b/lib/images/admin/acl.png
new file mode 100644
index 000000000..c8f610c12
--- /dev/null
+++ b/lib/images/admin/acl.png
Binary files differ
diff --git a/lib/images/admin/config.png b/lib/images/admin/config.png
new file mode 100644
index 000000000..3ec3923d1
--- /dev/null
+++ b/lib/images/admin/config.png
Binary files differ
diff --git a/lib/images/admin/plugin.png b/lib/images/admin/plugin.png
new file mode 100644
index 000000000..f71124e5c
--- /dev/null
+++ b/lib/images/admin/plugin.png
Binary files differ
diff --git a/lib/images/admin/popularity.png b/lib/images/admin/popularity.png
new file mode 100644
index 000000000..19392367a
--- /dev/null
+++ b/lib/images/admin/popularity.png
Binary files differ
diff --git a/lib/images/admin/revert.png b/lib/images/admin/revert.png
new file mode 100644
index 000000000..5304f1b76
--- /dev/null
+++ b/lib/images/admin/revert.png
Binary files differ
diff --git a/lib/images/admin/usermanager.png b/lib/images/admin/usermanager.png
new file mode 100644
index 000000000..898544ce9
--- /dev/null
+++ b/lib/images/admin/usermanager.png
Binary files differ
diff --git a/lib/images/arrow_down.gif b/lib/images/arrow_down.gif
new file mode 100644
index 000000000..ff13b9585
--- /dev/null
+++ b/lib/images/arrow_down.gif
Binary files differ
diff --git a/lib/images/arrow_up.gif b/lib/images/arrow_up.gif
new file mode 100644
index 000000000..d491c18db
--- /dev/null
+++ b/lib/images/arrow_up.gif
Binary files differ
diff --git a/lib/images/at.gif b/lib/images/at.gif
new file mode 100644
index 000000000..8bdf40d54
--- /dev/null
+++ b/lib/images/at.gif
Binary files differ
diff --git a/lib/images/blank.gif b/lib/images/blank.gif
new file mode 100644
index 000000000..9935f8210
--- /dev/null
+++ b/lib/images/blank.gif
Binary files differ
diff --git a/lib/images/close.png b/lib/images/close.png
new file mode 100644
index 000000000..4ccef0603
--- /dev/null
+++ b/lib/images/close.png
Binary files differ
diff --git a/lib/images/del.png b/lib/images/del.png
new file mode 100644
index 000000000..e59ded55f
--- /dev/null
+++ b/lib/images/del.png
Binary files differ
diff --git a/lib/images/diff.png b/lib/images/diff.png
new file mode 100644
index 000000000..657b10999
--- /dev/null
+++ b/lib/images/diff.png
Binary files differ
diff --git a/lib/images/edit.gif b/lib/images/edit.gif
new file mode 100644
index 000000000..a2a23de7b
--- /dev/null
+++ b/lib/images/edit.gif
Binary files differ
diff --git a/lib/images/error.png b/lib/images/error.png
new file mode 100644
index 000000000..7bd84f7a3
--- /dev/null
+++ b/lib/images/error.png
Binary files differ
diff --git a/lib/images/fileicons/7z.png b/lib/images/fileicons/7z.png
new file mode 100644
index 000000000..52f7d5d72
--- /dev/null
+++ b/lib/images/fileicons/7z.png
Binary files differ
diff --git a/lib/images/fileicons/audio.png b/lib/images/fileicons/audio.png
new file mode 100644
index 000000000..98883256d
--- /dev/null
+++ b/lib/images/fileicons/audio.png
Binary files differ
diff --git a/lib/images/fileicons/bz2.png b/lib/images/fileicons/bz2.png
new file mode 100644
index 000000000..6ec2f98ef
--- /dev/null
+++ b/lib/images/fileicons/bz2.png
Binary files differ
diff --git a/lib/images/fileicons/c.png b/lib/images/fileicons/c.png
new file mode 100644
index 000000000..6f57337c7
--- /dev/null
+++ b/lib/images/fileicons/c.png
Binary files differ
diff --git a/lib/images/fileicons/conf.png b/lib/images/fileicons/conf.png
new file mode 100644
index 000000000..20c20fa3d
--- /dev/null
+++ b/lib/images/fileicons/conf.png
Binary files differ
diff --git a/lib/images/fileicons/cpp.png b/lib/images/fileicons/cpp.png
new file mode 100644
index 000000000..6f2797da5
--- /dev/null
+++ b/lib/images/fileicons/cpp.png
Binary files differ
diff --git a/lib/images/fileicons/cs.png b/lib/images/fileicons/cs.png
new file mode 100644
index 000000000..d3afa112c
--- /dev/null
+++ b/lib/images/fileicons/cs.png
Binary files differ
diff --git a/lib/images/fileicons/css.png b/lib/images/fileicons/css.png
new file mode 100644
index 000000000..89c1537fd
--- /dev/null
+++ b/lib/images/fileicons/css.png
Binary files differ
diff --git a/lib/images/fileicons/csv.png b/lib/images/fileicons/csv.png
new file mode 100644
index 000000000..b604453c4
--- /dev/null
+++ b/lib/images/fileicons/csv.png
Binary files differ
diff --git a/lib/images/fileicons/deb.png b/lib/images/fileicons/deb.png
new file mode 100644
index 000000000..8fe57327a
--- /dev/null
+++ b/lib/images/fileicons/deb.png
Binary files differ
diff --git a/lib/images/fileicons/doc.png b/lib/images/fileicons/doc.png
new file mode 100644
index 000000000..79d8ff1cd
--- /dev/null
+++ b/lib/images/fileicons/doc.png
Binary files differ
diff --git a/lib/images/fileicons/docx.png b/lib/images/fileicons/docx.png
new file mode 100644
index 000000000..79d8ff1cd
--- /dev/null
+++ b/lib/images/fileicons/docx.png
Binary files differ
diff --git a/lib/images/fileicons/file.png b/lib/images/fileicons/file.png
new file mode 100644
index 000000000..8158a8a21
--- /dev/null
+++ b/lib/images/fileicons/file.png
Binary files differ
diff --git a/lib/images/fileicons/gif.png b/lib/images/fileicons/gif.png
new file mode 100644
index 000000000..1d9dd562a
--- /dev/null
+++ b/lib/images/fileicons/gif.png
Binary files differ
diff --git a/lib/images/fileicons/gz.png b/lib/images/fileicons/gz.png
new file mode 100644
index 000000000..48f19596c
--- /dev/null
+++ b/lib/images/fileicons/gz.png
Binary files differ
diff --git a/lib/images/fileicons/htm.png b/lib/images/fileicons/htm.png
new file mode 100644
index 000000000..d45e4c19a
--- /dev/null
+++ b/lib/images/fileicons/htm.png
Binary files differ
diff --git a/lib/images/fileicons/html.png b/lib/images/fileicons/html.png
new file mode 100644
index 000000000..d45e4c19a
--- /dev/null
+++ b/lib/images/fileicons/html.png
Binary files differ
diff --git a/lib/images/fileicons/index.php b/lib/images/fileicons/index.php
new file mode 100644
index 000000000..c1e64fe2a
--- /dev/null
+++ b/lib/images/fileicons/index.php
@@ -0,0 +1,50 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
+ lang="en" dir="ltr">
+<head>
+ <title>filetype icons</title>
+
+ <style type="text/css">
+ 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>
+
+<div class="white box">
+<?php
+foreach (glob('*.png') as $img) {
+ echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
+}
+?>
+</div>
+
+<div class="black box">
+<?php
+foreach (glob('*.png') as $img) {
+ echo '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
+}
+?>
+</div>
+
+</body>
+</html>
diff --git a/lib/images/fileicons/java.png b/lib/images/fileicons/java.png
new file mode 100644
index 000000000..c5f2fd09f
--- /dev/null
+++ b/lib/images/fileicons/java.png
Binary files differ
diff --git a/lib/images/fileicons/jpeg.png b/lib/images/fileicons/jpeg.png
new file mode 100644
index 000000000..1d9dd562a
--- /dev/null
+++ b/lib/images/fileicons/jpeg.png
Binary files differ
diff --git a/lib/images/fileicons/jpg.png b/lib/images/fileicons/jpg.png
new file mode 100644
index 000000000..1d9dd562a
--- /dev/null
+++ b/lib/images/fileicons/jpg.png
Binary files differ
diff --git a/lib/images/fileicons/js.png b/lib/images/fileicons/js.png
new file mode 100644
index 000000000..0c314eb56
--- /dev/null
+++ b/lib/images/fileicons/js.png
Binary files differ
diff --git a/lib/images/fileicons/lua.png b/lib/images/fileicons/lua.png
new file mode 100644
index 000000000..994c6e8f0
--- /dev/null
+++ b/lib/images/fileicons/lua.png
Binary files differ
diff --git a/lib/images/fileicons/mp3.png b/lib/images/fileicons/mp3.png
new file mode 100644
index 000000000..411dad080
--- /dev/null
+++ b/lib/images/fileicons/mp3.png
Binary files differ
diff --git a/lib/images/fileicons/odc.png b/lib/images/fileicons/odc.png
new file mode 100644
index 000000000..4d6676c3a
--- /dev/null
+++ b/lib/images/fileicons/odc.png
Binary files differ
diff --git a/lib/images/fileicons/odf.png b/lib/images/fileicons/odf.png
new file mode 100644
index 000000000..cb88d68e6
--- /dev/null
+++ b/lib/images/fileicons/odf.png
Binary files differ
diff --git a/lib/images/fileicons/odg.png b/lib/images/fileicons/odg.png
new file mode 100644
index 000000000..a07216f4a
--- /dev/null
+++ b/lib/images/fileicons/odg.png
Binary files differ
diff --git a/lib/images/fileicons/odi.png b/lib/images/fileicons/odi.png
new file mode 100644
index 000000000..a07216f4a
--- /dev/null
+++ b/lib/images/fileicons/odi.png
Binary files differ
diff --git a/lib/images/fileicons/odp.png b/lib/images/fileicons/odp.png
new file mode 100644
index 000000000..2f2574af6
--- /dev/null
+++ b/lib/images/fileicons/odp.png
Binary files differ
diff --git a/lib/images/fileicons/ods.png b/lib/images/fileicons/ods.png
new file mode 100644
index 000000000..4d6676c3a
--- /dev/null
+++ b/lib/images/fileicons/ods.png
Binary files differ
diff --git a/lib/images/fileicons/odt.png b/lib/images/fileicons/odt.png
new file mode 100644
index 000000000..f9c126efd
--- /dev/null
+++ b/lib/images/fileicons/odt.png
Binary files differ
diff --git a/lib/images/fileicons/ogg.png b/lib/images/fileicons/ogg.png
new file mode 100644
index 000000000..0a21eae65
--- /dev/null
+++ b/lib/images/fileicons/ogg.png
Binary files differ
diff --git a/lib/images/fileicons/pdf.png b/lib/images/fileicons/pdf.png
new file mode 100644
index 000000000..029dcffec
--- /dev/null
+++ b/lib/images/fileicons/pdf.png
Binary files differ
diff --git a/lib/images/fileicons/php.png b/lib/images/fileicons/php.png
new file mode 100644
index 000000000..f81e405de
--- /dev/null
+++ b/lib/images/fileicons/php.png
Binary files differ
diff --git a/lib/images/fileicons/pl.png b/lib/images/fileicons/pl.png
new file mode 100644
index 000000000..92f3f9754
--- /dev/null
+++ b/lib/images/fileicons/pl.png
Binary files differ
diff --git a/lib/images/fileicons/png.png b/lib/images/fileicons/png.png
new file mode 100644
index 000000000..1d9dd562a
--- /dev/null
+++ b/lib/images/fileicons/png.png
Binary files differ
diff --git a/lib/images/fileicons/ppt.png b/lib/images/fileicons/ppt.png
new file mode 100644
index 000000000..b7afb2266
--- /dev/null
+++ b/lib/images/fileicons/ppt.png
Binary files differ
diff --git a/lib/images/fileicons/pptx.png b/lib/images/fileicons/pptx.png
new file mode 100644
index 000000000..b7afb2266
--- /dev/null
+++ b/lib/images/fileicons/pptx.png
Binary files differ
diff --git a/lib/images/fileicons/ps.png b/lib/images/fileicons/ps.png
new file mode 100644
index 000000000..40a80baad
--- /dev/null
+++ b/lib/images/fileicons/ps.png
Binary files differ
diff --git a/lib/images/fileicons/py.png b/lib/images/fileicons/py.png
new file mode 100644
index 000000000..15a727c54
--- /dev/null
+++ b/lib/images/fileicons/py.png
Binary files differ
diff --git a/lib/images/fileicons/rar.png b/lib/images/fileicons/rar.png
new file mode 100644
index 000000000..c761a4f7f
--- /dev/null
+++ b/lib/images/fileicons/rar.png
Binary files differ
diff --git a/lib/images/fileicons/rb.png b/lib/images/fileicons/rb.png
new file mode 100644
index 000000000..408f708a1
--- /dev/null
+++ b/lib/images/fileicons/rb.png
Binary files differ
diff --git a/lib/images/fileicons/rpm.png b/lib/images/fileicons/rpm.png
new file mode 100644
index 000000000..5cf727de0
--- /dev/null
+++ b/lib/images/fileicons/rpm.png
Binary files differ
diff --git a/lib/images/fileicons/rtf.png b/lib/images/fileicons/rtf.png
new file mode 100644
index 000000000..99fe3d8fd
--- /dev/null
+++ b/lib/images/fileicons/rtf.png
Binary files differ
diff --git a/lib/images/fileicons/sql.png b/lib/images/fileicons/sql.png
new file mode 100644
index 000000000..a7b0684c7
--- /dev/null
+++ b/lib/images/fileicons/sql.png
Binary files differ
diff --git a/lib/images/fileicons/swf.png b/lib/images/fileicons/swf.png
new file mode 100644
index 000000000..ecc7309ad
--- /dev/null
+++ b/lib/images/fileicons/swf.png
Binary files differ
diff --git a/lib/images/fileicons/sxc.png b/lib/images/fileicons/sxc.png
new file mode 100644
index 000000000..4d6676c3a
--- /dev/null
+++ b/lib/images/fileicons/sxc.png
Binary files differ
diff --git a/lib/images/fileicons/sxd.png b/lib/images/fileicons/sxd.png
new file mode 100644
index 000000000..a07216f4a
--- /dev/null
+++ b/lib/images/fileicons/sxd.png
Binary files differ
diff --git a/lib/images/fileicons/sxi.png b/lib/images/fileicons/sxi.png
new file mode 100644
index 000000000..2f2574af6
--- /dev/null
+++ b/lib/images/fileicons/sxi.png
Binary files differ
diff --git a/lib/images/fileicons/sxw.png b/lib/images/fileicons/sxw.png
new file mode 100644
index 000000000..f9c126efd
--- /dev/null
+++ b/lib/images/fileicons/sxw.png
Binary files differ
diff --git a/lib/images/fileicons/tar.png b/lib/images/fileicons/tar.png
new file mode 100644
index 000000000..a28c86f2d
--- /dev/null
+++ b/lib/images/fileicons/tar.png
Binary files differ
diff --git a/lib/images/fileicons/tgz.png b/lib/images/fileicons/tgz.png
new file mode 100644
index 000000000..48f19596c
--- /dev/null
+++ b/lib/images/fileicons/tgz.png
Binary files differ
diff --git a/lib/images/fileicons/txt.png b/lib/images/fileicons/txt.png
new file mode 100644
index 000000000..bb94949f6
--- /dev/null
+++ b/lib/images/fileicons/txt.png
Binary files differ
diff --git a/lib/images/fileicons/wav.png b/lib/images/fileicons/wav.png
new file mode 100644
index 000000000..c167f4fdb
--- /dev/null
+++ b/lib/images/fileicons/wav.png
Binary files differ
diff --git a/lib/images/fileicons/xls.png b/lib/images/fileicons/xls.png
new file mode 100644
index 000000000..24911b802
--- /dev/null
+++ b/lib/images/fileicons/xls.png
Binary files differ
diff --git a/lib/images/fileicons/xlsx.png b/lib/images/fileicons/xlsx.png
new file mode 100644
index 000000000..24911b802
--- /dev/null
+++ b/lib/images/fileicons/xlsx.png
Binary files differ
diff --git a/lib/images/fileicons/xml.png b/lib/images/fileicons/xml.png
new file mode 100644
index 000000000..ae9831b34
--- /dev/null
+++ b/lib/images/fileicons/xml.png
Binary files differ
diff --git a/lib/images/fileicons/zip.png b/lib/images/fileicons/zip.png
new file mode 100644
index 000000000..fb8850c9a
--- /dev/null
+++ b/lib/images/fileicons/zip.png
Binary files differ
diff --git a/lib/images/history.png b/lib/images/history.png
new file mode 100644
index 000000000..82a418d44
--- /dev/null
+++ b/lib/images/history.png
Binary files differ
diff --git a/lib/images/icon-file.png b/lib/images/icon-file.png
new file mode 100644
index 000000000..d350c8c31
--- /dev/null
+++ b/lib/images/icon-file.png
Binary files differ
diff --git a/lib/images/icon-list.png b/lib/images/icon-list.png
new file mode 100644
index 000000000..ecfeed92d
--- /dev/null
+++ b/lib/images/icon-list.png
Binary files differ
diff --git a/lib/images/icon-sort.png b/lib/images/icon-sort.png
new file mode 100644
index 000000000..c6403dd3c
--- /dev/null
+++ b/lib/images/icon-sort.png
Binary files differ
diff --git a/lib/images/icon-thumb.png b/lib/images/icon-thumb.png
new file mode 100644
index 000000000..ccc7a101d
--- /dev/null
+++ b/lib/images/icon-thumb.png
Binary files differ
diff --git a/lib/images/index.html b/lib/images/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/images/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<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/lib/images/info.png b/lib/images/info.png
new file mode 100644
index 000000000..121c7336d
--- /dev/null
+++ b/lib/images/info.png
Binary files differ
diff --git a/lib/images/interwiki.png b/lib/images/interwiki.png
new file mode 100644
index 000000000..f957e71e5
--- /dev/null
+++ b/lib/images/interwiki.png
Binary files differ
diff --git a/lib/images/interwiki/amazon.de.gif b/lib/images/interwiki/amazon.de.gif
new file mode 100644
index 000000000..6e36a051a
--- /dev/null
+++ b/lib/images/interwiki/amazon.de.gif
Binary files differ
diff --git a/lib/images/interwiki/amazon.gif b/lib/images/interwiki/amazon.gif
new file mode 100644
index 000000000..6e36a051a
--- /dev/null
+++ b/lib/images/interwiki/amazon.gif
Binary files differ
diff --git a/lib/images/interwiki/amazon.uk.gif b/lib/images/interwiki/amazon.uk.gif
new file mode 100644
index 000000000..6e36a051a
--- /dev/null
+++ b/lib/images/interwiki/amazon.uk.gif
Binary files differ
diff --git a/lib/images/interwiki/callto.gif b/lib/images/interwiki/callto.gif
new file mode 100644
index 000000000..f6d424554
--- /dev/null
+++ b/lib/images/interwiki/callto.gif
Binary files differ
diff --git a/lib/images/interwiki/coral.gif b/lib/images/interwiki/coral.gif
new file mode 100644
index 000000000..0f9f67587
--- /dev/null
+++ b/lib/images/interwiki/coral.gif
Binary files differ
diff --git a/lib/images/interwiki/doku.gif b/lib/images/interwiki/doku.gif
new file mode 100644
index 000000000..3ccf01227
--- /dev/null
+++ b/lib/images/interwiki/doku.gif
Binary files differ
diff --git a/lib/images/interwiki/dokubug.gif b/lib/images/interwiki/dokubug.gif
new file mode 100644
index 000000000..3432b8d57
--- /dev/null
+++ b/lib/images/interwiki/dokubug.gif
Binary files differ
diff --git a/lib/images/interwiki/google.gif b/lib/images/interwiki/google.gif
new file mode 100644
index 000000000..3a28437f3
--- /dev/null
+++ b/lib/images/interwiki/google.gif
Binary files differ
diff --git a/lib/images/interwiki/meatball.gif b/lib/images/interwiki/meatball.gif
new file mode 100644
index 000000000..8a4cbdbfc
--- /dev/null
+++ b/lib/images/interwiki/meatball.gif
Binary files differ
diff --git a/lib/images/interwiki/paypal.gif b/lib/images/interwiki/paypal.gif
new file mode 100644
index 000000000..1d2834062
--- /dev/null
+++ b/lib/images/interwiki/paypal.gif
Binary files differ
diff --git a/lib/images/interwiki/phpfn.gif b/lib/images/interwiki/phpfn.gif
new file mode 100644
index 000000000..89ac1db94
--- /dev/null
+++ b/lib/images/interwiki/phpfn.gif
Binary files differ
diff --git a/lib/images/interwiki/sb.gif b/lib/images/interwiki/sb.gif
new file mode 100644
index 000000000..710e4945b
--- /dev/null
+++ b/lib/images/interwiki/sb.gif
Binary files differ
diff --git a/lib/images/interwiki/skype.png b/lib/images/interwiki/skype.png
new file mode 100644
index 000000000..c70216702
--- /dev/null
+++ b/lib/images/interwiki/skype.png
Binary files differ
diff --git a/lib/images/interwiki/wiki.gif b/lib/images/interwiki/wiki.gif
new file mode 100644
index 000000000..df241d6bb
--- /dev/null
+++ b/lib/images/interwiki/wiki.gif
Binary files differ
diff --git a/lib/images/interwiki/wp.gif b/lib/images/interwiki/wp.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wp.gif
Binary files differ
diff --git a/lib/images/interwiki/wpde.gif b/lib/images/interwiki/wpde.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpde.gif
Binary files differ
diff --git a/lib/images/interwiki/wpes.gif b/lib/images/interwiki/wpes.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpes.gif
Binary files differ
diff --git a/lib/images/interwiki/wpfr.gif b/lib/images/interwiki/wpfr.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpfr.gif
Binary files differ
diff --git a/lib/images/interwiki/wpjp.gif b/lib/images/interwiki/wpjp.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpjp.gif
Binary files differ
diff --git a/lib/images/interwiki/wpmeta.gif b/lib/images/interwiki/wpmeta.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wpmeta.gif
Binary files differ
diff --git a/lib/images/interwiki/wppl.gif b/lib/images/interwiki/wppl.gif
new file mode 100644
index 000000000..b07fd893d
--- /dev/null
+++ b/lib/images/interwiki/wppl.gif
Binary files differ
diff --git a/lib/images/larger.gif b/lib/images/larger.gif
new file mode 100644
index 000000000..e137c92fa
--- /dev/null
+++ b/lib/images/larger.gif
Binary files differ
diff --git a/lib/images/license/badge/cc-by-nc-nd.png b/lib/images/license/badge/cc-by-nc-nd.png
new file mode 100644
index 000000000..94aae9e09
--- /dev/null
+++ b/lib/images/license/badge/cc-by-nc-nd.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by-nc-sa.png b/lib/images/license/badge/cc-by-nc-sa.png
new file mode 100644
index 000000000..51141f5ec
--- /dev/null
+++ b/lib/images/license/badge/cc-by-nc-sa.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by-nc.png b/lib/images/license/badge/cc-by-nc.png
new file mode 100644
index 000000000..aeb8cdc8c
--- /dev/null
+++ b/lib/images/license/badge/cc-by-nc.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by-nd.png b/lib/images/license/badge/cc-by-nd.png
new file mode 100644
index 000000000..6a2e59a68
--- /dev/null
+++ b/lib/images/license/badge/cc-by-nd.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by-sa.png b/lib/images/license/badge/cc-by-sa.png
new file mode 100644
index 000000000..f0aa4aaf0
--- /dev/null
+++ b/lib/images/license/badge/cc-by-sa.png
Binary files differ
diff --git a/lib/images/license/badge/cc-by.png b/lib/images/license/badge/cc-by.png
new file mode 100644
index 000000000..c7389b2f6
--- /dev/null
+++ b/lib/images/license/badge/cc-by.png
Binary files differ
diff --git a/lib/images/license/badge/cc-zero.png b/lib/images/license/badge/cc-zero.png
new file mode 100644
index 000000000..fd3dff422
--- /dev/null
+++ b/lib/images/license/badge/cc-zero.png
Binary files differ
diff --git a/lib/images/license/badge/cc.png b/lib/images/license/badge/cc.png
new file mode 100644
index 000000000..8ac73aa4e
--- /dev/null
+++ b/lib/images/license/badge/cc.png
Binary files differ
diff --git a/lib/images/license/badge/gnufdl.png b/lib/images/license/badge/gnufdl.png
new file mode 100644
index 000000000..e92910128
--- /dev/null
+++ b/lib/images/license/badge/gnufdl.png
Binary files differ
diff --git a/lib/images/license/badge/publicdomain.png b/lib/images/license/badge/publicdomain.png
new file mode 100644
index 000000000..8148d037a
--- /dev/null
+++ b/lib/images/license/badge/publicdomain.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-nc-nd.png b/lib/images/license/button/cc-by-nc-nd.png
new file mode 100644
index 000000000..ac58d8627
--- /dev/null
+++ b/lib/images/license/button/cc-by-nc-nd.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-nc-sa.png b/lib/images/license/button/cc-by-nc-sa.png
new file mode 100644
index 000000000..a9d23c0b6
--- /dev/null
+++ b/lib/images/license/button/cc-by-nc-sa.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-nc.png b/lib/images/license/button/cc-by-nc.png
new file mode 100644
index 000000000..d936464ad
--- /dev/null
+++ b/lib/images/license/button/cc-by-nc.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-nd.png b/lib/images/license/button/cc-by-nd.png
new file mode 100644
index 000000000..3fc490870
--- /dev/null
+++ b/lib/images/license/button/cc-by-nd.png
Binary files differ
diff --git a/lib/images/license/button/cc-by-sa.png b/lib/images/license/button/cc-by-sa.png
new file mode 100644
index 000000000..3c6270a0d
--- /dev/null
+++ b/lib/images/license/button/cc-by-sa.png
Binary files differ
diff --git a/lib/images/license/button/cc-by.png b/lib/images/license/button/cc-by.png
new file mode 100644
index 000000000..867daaee4
--- /dev/null
+++ b/lib/images/license/button/cc-by.png
Binary files differ
diff --git a/lib/images/license/button/cc-zero.png b/lib/images/license/button/cc-zero.png
new file mode 100644
index 000000000..251efcd1c
--- /dev/null
+++ b/lib/images/license/button/cc-zero.png
Binary files differ
diff --git a/lib/images/license/button/cc.png b/lib/images/license/button/cc.png
new file mode 100644
index 000000000..9c492950f
--- /dev/null
+++ b/lib/images/license/button/cc.png
Binary files differ
diff --git a/lib/images/license/button/gnufdl.png b/lib/images/license/button/gnufdl.png
new file mode 100644
index 000000000..0b52ea12e
--- /dev/null
+++ b/lib/images/license/button/gnufdl.png
Binary files differ
diff --git a/lib/images/license/button/publicdomain.png b/lib/images/license/button/publicdomain.png
new file mode 100644
index 000000000..54ea38b64
--- /dev/null
+++ b/lib/images/license/button/publicdomain.png
Binary files differ
diff --git a/lib/images/list-minus.gif b/lib/images/list-minus.gif
new file mode 100644
index 000000000..36902f159
--- /dev/null
+++ b/lib/images/list-minus.gif
Binary files differ
diff --git a/lib/images/list-plus.gif b/lib/images/list-plus.gif
new file mode 100644
index 000000000..adc3fac8a
--- /dev/null
+++ b/lib/images/list-plus.gif
Binary files differ
diff --git a/lib/images/loading.gif b/lib/images/loading.gif
new file mode 100644
index 000000000..35058e20f
--- /dev/null
+++ b/lib/images/loading.gif
Binary files differ
diff --git a/lib/images/magnifier.png b/lib/images/magnifier.png
new file mode 100644
index 000000000..89febff10
--- /dev/null
+++ b/lib/images/magnifier.png
Binary files differ
diff --git a/lib/images/media_align_center.png b/lib/images/media_align_center.png
new file mode 100644
index 000000000..807f9d9a8
--- /dev/null
+++ b/lib/images/media_align_center.png
Binary files differ
diff --git a/lib/images/media_align_left.png b/lib/images/media_align_left.png
new file mode 100644
index 000000000..fa6cf33ca
--- /dev/null
+++ b/lib/images/media_align_left.png
Binary files differ
diff --git a/lib/images/media_align_noalign.png b/lib/images/media_align_noalign.png
new file mode 100644
index 000000000..263e090fe
--- /dev/null
+++ b/lib/images/media_align_noalign.png
Binary files differ
diff --git a/lib/images/media_align_right.png b/lib/images/media_align_right.png
new file mode 100644
index 000000000..33539dbdb
--- /dev/null
+++ b/lib/images/media_align_right.png
Binary files differ
diff --git a/lib/images/media_link_direct.png b/lib/images/media_link_direct.png
new file mode 100644
index 000000000..4350b803d
--- /dev/null
+++ b/lib/images/media_link_direct.png
Binary files differ
diff --git a/lib/images/media_link_displaylnk.png b/lib/images/media_link_displaylnk.png
new file mode 100644
index 000000000..53927566a
--- /dev/null
+++ b/lib/images/media_link_displaylnk.png
Binary files differ
diff --git a/lib/images/media_link_lnk.png b/lib/images/media_link_lnk.png
new file mode 100644
index 000000000..5ff4ee182
--- /dev/null
+++ b/lib/images/media_link_lnk.png
Binary files differ
diff --git a/lib/images/media_link_nolnk.png b/lib/images/media_link_nolnk.png
new file mode 100644
index 000000000..c9378c7fd
--- /dev/null
+++ b/lib/images/media_link_nolnk.png
Binary files differ
diff --git a/lib/images/media_size_large.png b/lib/images/media_size_large.png
new file mode 100644
index 000000000..012a418c3
--- /dev/null
+++ b/lib/images/media_size_large.png
Binary files differ
diff --git a/lib/images/media_size_medium.png b/lib/images/media_size_medium.png
new file mode 100644
index 000000000..1469f519f
--- /dev/null
+++ b/lib/images/media_size_medium.png
Binary files differ
diff --git a/lib/images/media_size_original.png b/lib/images/media_size_original.png
new file mode 100644
index 000000000..f58d056aa
--- /dev/null
+++ b/lib/images/media_size_original.png
Binary files differ
diff --git a/lib/images/media_size_small.png b/lib/images/media_size_small.png
new file mode 100644
index 000000000..a0aafa4a7
--- /dev/null
+++ b/lib/images/media_size_small.png
Binary files differ
diff --git a/lib/images/mediamanager.png b/lib/images/mediamanager.png
new file mode 100644
index 000000000..822b8458a
--- /dev/null
+++ b/lib/images/mediamanager.png
Binary files differ
diff --git a/lib/images/minus.gif b/lib/images/minus.gif
new file mode 100644
index 000000000..7e8cbd754
--- /dev/null
+++ b/lib/images/minus.gif
Binary files differ
diff --git a/lib/images/notify.png b/lib/images/notify.png
new file mode 100644
index 000000000..c18ef1001
--- /dev/null
+++ b/lib/images/notify.png
Binary files differ
diff --git a/lib/images/ns.png b/lib/images/ns.png
new file mode 100644
index 000000000..c35e832da
--- /dev/null
+++ b/lib/images/ns.png
Binary files differ
diff --git a/lib/images/page.png b/lib/images/page.png
new file mode 100644
index 000000000..b1b7ebe94
--- /dev/null
+++ b/lib/images/page.png
Binary files differ
diff --git a/lib/images/pencil.png b/lib/images/pencil.png
new file mode 100644
index 000000000..78142b61e
--- /dev/null
+++ b/lib/images/pencil.png
Binary files differ
diff --git a/lib/images/plus.gif b/lib/images/plus.gif
new file mode 100644
index 000000000..3da3b9458
--- /dev/null
+++ b/lib/images/plus.gif
Binary files differ
diff --git a/lib/images/smaller.gif b/lib/images/smaller.gif
new file mode 100644
index 000000000..66d3a51e7
--- /dev/null
+++ b/lib/images/smaller.gif
Binary files differ
diff --git a/lib/images/smileys/delete.gif b/lib/images/smileys/delete.gif
new file mode 100644
index 000000000..e94c68c56
--- /dev/null
+++ b/lib/images/smileys/delete.gif
Binary files differ
diff --git a/lib/images/smileys/facepalm.gif b/lib/images/smileys/facepalm.gif
new file mode 100644
index 000000000..5bebb2097
--- /dev/null
+++ b/lib/images/smileys/facepalm.gif
Binary files differ
diff --git a/lib/images/smileys/fixme.gif b/lib/images/smileys/fixme.gif
new file mode 100644
index 000000000..e19141370
--- /dev/null
+++ b/lib/images/smileys/fixme.gif
Binary files differ
diff --git a/lib/images/smileys/icon_arrow.gif b/lib/images/smileys/icon_arrow.gif
new file mode 100644
index 000000000..6771defd3
--- /dev/null
+++ b/lib/images/smileys/icon_arrow.gif
Binary files differ
diff --git a/lib/images/smileys/icon_biggrin.gif b/lib/images/smileys/icon_biggrin.gif
new file mode 100644
index 000000000..aa29c14f6
--- /dev/null
+++ b/lib/images/smileys/icon_biggrin.gif
Binary files differ
diff --git a/lib/images/smileys/icon_confused.gif b/lib/images/smileys/icon_confused.gif
new file mode 100644
index 000000000..0ea9ed241
--- /dev/null
+++ b/lib/images/smileys/icon_confused.gif
Binary files differ
diff --git a/lib/images/smileys/icon_cool.gif b/lib/images/smileys/icon_cool.gif
new file mode 100644
index 000000000..3469ad482
--- /dev/null
+++ b/lib/images/smileys/icon_cool.gif
Binary files differ
diff --git a/lib/images/smileys/icon_cry.gif b/lib/images/smileys/icon_cry.gif
new file mode 100644
index 000000000..25aea5753
--- /dev/null
+++ b/lib/images/smileys/icon_cry.gif
Binary files differ
diff --git a/lib/images/smileys/icon_doubt.gif b/lib/images/smileys/icon_doubt.gif
new file mode 100644
index 000000000..b4afc6da7
--- /dev/null
+++ b/lib/images/smileys/icon_doubt.gif
Binary files differ
diff --git a/lib/images/smileys/icon_doubt2.gif b/lib/images/smileys/icon_doubt2.gif
new file mode 100644
index 000000000..1f57eb963
--- /dev/null
+++ b/lib/images/smileys/icon_doubt2.gif
Binary files differ
diff --git a/lib/images/smileys/icon_eek.gif b/lib/images/smileys/icon_eek.gif
new file mode 100644
index 000000000..276b01d55
--- /dev/null
+++ b/lib/images/smileys/icon_eek.gif
Binary files differ
diff --git a/lib/images/smileys/icon_evil.gif b/lib/images/smileys/icon_evil.gif
new file mode 100644
index 000000000..d756916c9
--- /dev/null
+++ b/lib/images/smileys/icon_evil.gif
Binary files differ
diff --git a/lib/images/smileys/icon_exclaim.gif b/lib/images/smileys/icon_exclaim.gif
new file mode 100644
index 000000000..215b32e76
--- /dev/null
+++ b/lib/images/smileys/icon_exclaim.gif
Binary files differ
diff --git a/lib/images/smileys/icon_frown.gif b/lib/images/smileys/icon_frown.gif
new file mode 100644
index 000000000..d46caf78f
--- /dev/null
+++ b/lib/images/smileys/icon_frown.gif
Binary files differ
diff --git a/lib/images/smileys/icon_fun.gif b/lib/images/smileys/icon_fun.gif
new file mode 100644
index 000000000..6d3c44276
--- /dev/null
+++ b/lib/images/smileys/icon_fun.gif
Binary files differ
diff --git a/lib/images/smileys/icon_idea.gif b/lib/images/smileys/icon_idea.gif
new file mode 100644
index 000000000..41eaa0624
--- /dev/null
+++ b/lib/images/smileys/icon_idea.gif
Binary files differ
diff --git a/lib/images/smileys/icon_kaddi.gif b/lib/images/smileys/icon_kaddi.gif
new file mode 100644
index 000000000..56344bbb0
--- /dev/null
+++ b/lib/images/smileys/icon_kaddi.gif
Binary files differ
diff --git a/lib/images/smileys/icon_lol.gif b/lib/images/smileys/icon_lol.gif
new file mode 100644
index 000000000..d1c20c07a
--- /dev/null
+++ b/lib/images/smileys/icon_lol.gif
Binary files differ
diff --git a/lib/images/smileys/icon_mrgreen.gif b/lib/images/smileys/icon_mrgreen.gif
new file mode 100644
index 000000000..fc5d91683
--- /dev/null
+++ b/lib/images/smileys/icon_mrgreen.gif
Binary files differ
diff --git a/lib/images/smileys/icon_neutral.gif b/lib/images/smileys/icon_neutral.gif
new file mode 100644
index 000000000..c82a974c7
--- /dev/null
+++ b/lib/images/smileys/icon_neutral.gif
Binary files differ
diff --git a/lib/images/smileys/icon_question.gif b/lib/images/smileys/icon_question.gif
new file mode 100644
index 000000000..4e3092498
--- /dev/null
+++ b/lib/images/smileys/icon_question.gif
Binary files differ
diff --git a/lib/images/smileys/icon_razz.gif b/lib/images/smileys/icon_razz.gif
new file mode 100644
index 000000000..310655eec
--- /dev/null
+++ b/lib/images/smileys/icon_razz.gif
Binary files differ
diff --git a/lib/images/smileys/icon_redface.gif b/lib/images/smileys/icon_redface.gif
new file mode 100644
index 000000000..160c20f33
--- /dev/null
+++ b/lib/images/smileys/icon_redface.gif
Binary files differ
diff --git a/lib/images/smileys/icon_rolleyes.gif b/lib/images/smileys/icon_rolleyes.gif
new file mode 100644
index 000000000..502c5c174
--- /dev/null
+++ b/lib/images/smileys/icon_rolleyes.gif
Binary files differ
diff --git a/lib/images/smileys/icon_sad.gif b/lib/images/smileys/icon_sad.gif
new file mode 100644
index 000000000..d46caf78f
--- /dev/null
+++ b/lib/images/smileys/icon_sad.gif
Binary files differ
diff --git a/lib/images/smileys/icon_silenced.gif b/lib/images/smileys/icon_silenced.gif
new file mode 100644
index 000000000..5f722e04e
--- /dev/null
+++ b/lib/images/smileys/icon_silenced.gif
Binary files differ
diff --git a/lib/images/smileys/icon_smile.gif b/lib/images/smileys/icon_smile.gif
new file mode 100644
index 000000000..df125e2b5
--- /dev/null
+++ b/lib/images/smileys/icon_smile.gif
Binary files differ
diff --git a/lib/images/smileys/icon_smile2.gif b/lib/images/smileys/icon_smile2.gif
new file mode 100644
index 000000000..6b4909c81
--- /dev/null
+++ b/lib/images/smileys/icon_smile2.gif
Binary files differ
diff --git a/lib/images/smileys/icon_surprised.gif b/lib/images/smileys/icon_surprised.gif
new file mode 100644
index 000000000..aaa94f1da
--- /dev/null
+++ b/lib/images/smileys/icon_surprised.gif
Binary files differ
diff --git a/lib/images/smileys/icon_twisted.gif b/lib/images/smileys/icon_twisted.gif
new file mode 100644
index 000000000..eaec19338
--- /dev/null
+++ b/lib/images/smileys/icon_twisted.gif
Binary files differ
diff --git a/lib/images/smileys/icon_wink.gif b/lib/images/smileys/icon_wink.gif
new file mode 100644
index 000000000..78b6ad3db
--- /dev/null
+++ b/lib/images/smileys/icon_wink.gif
Binary files differ
diff --git a/lib/images/success.png b/lib/images/success.png
new file mode 100644
index 000000000..9241adbb2
--- /dev/null
+++ b/lib/images/success.png
Binary files differ
diff --git a/lib/images/throbber.gif b/lib/images/throbber.gif
new file mode 100644
index 000000000..27178a8cf
--- /dev/null
+++ b/lib/images/throbber.gif
Binary files differ
diff --git a/lib/images/toolbar/bold.png b/lib/images/toolbar/bold.png
new file mode 100644
index 000000000..51ddb8880
--- /dev/null
+++ b/lib/images/toolbar/bold.png
Binary files differ
diff --git a/lib/images/toolbar/chars.png b/lib/images/toolbar/chars.png
new file mode 100644
index 000000000..bad37e503
--- /dev/null
+++ b/lib/images/toolbar/chars.png
Binary files differ
diff --git a/lib/images/toolbar/h.png b/lib/images/toolbar/h.png
new file mode 100644
index 000000000..6a48cbbc0
--- /dev/null
+++ b/lib/images/toolbar/h.png
Binary files differ
diff --git a/lib/images/toolbar/h1.png b/lib/images/toolbar/h1.png
new file mode 100644
index 000000000..85bd06e6c
--- /dev/null
+++ b/lib/images/toolbar/h1.png
Binary files differ
diff --git a/lib/images/toolbar/h2.png b/lib/images/toolbar/h2.png
new file mode 100644
index 000000000..be2c60031
--- /dev/null
+++ b/lib/images/toolbar/h2.png
Binary files differ
diff --git a/lib/images/toolbar/h3.png b/lib/images/toolbar/h3.png
new file mode 100644
index 000000000..350da88b6
--- /dev/null
+++ b/lib/images/toolbar/h3.png
Binary files differ
diff --git a/lib/images/toolbar/h4.png b/lib/images/toolbar/h4.png
new file mode 100644
index 000000000..bc1b7038f
--- /dev/null
+++ b/lib/images/toolbar/h4.png
Binary files differ
diff --git a/lib/images/toolbar/h5.png b/lib/images/toolbar/h5.png
new file mode 100644
index 000000000..b6c263dfb
--- /dev/null
+++ b/lib/images/toolbar/h5.png
Binary files differ
diff --git a/lib/images/toolbar/hequal.png b/lib/images/toolbar/hequal.png
new file mode 100644
index 000000000..da4e921ff
--- /dev/null
+++ b/lib/images/toolbar/hequal.png
Binary files differ
diff --git a/lib/images/toolbar/hminus.png b/lib/images/toolbar/hminus.png
new file mode 100644
index 000000000..c00f70223
--- /dev/null
+++ b/lib/images/toolbar/hminus.png
Binary files differ
diff --git a/lib/images/toolbar/hplus.png b/lib/images/toolbar/hplus.png
new file mode 100644
index 000000000..6124b5c33
--- /dev/null
+++ b/lib/images/toolbar/hplus.png
Binary files differ
diff --git a/lib/images/toolbar/hr.png b/lib/images/toolbar/hr.png
new file mode 100644
index 000000000..de3a8a55b
--- /dev/null
+++ b/lib/images/toolbar/hr.png
Binary files differ
diff --git a/lib/images/toolbar/image.png b/lib/images/toolbar/image.png
new file mode 100644
index 000000000..70b12fcc2
--- /dev/null
+++ b/lib/images/toolbar/image.png
Binary files differ
diff --git a/lib/images/toolbar/italic.png b/lib/images/toolbar/italic.png
new file mode 100644
index 000000000..d69e66070
--- /dev/null
+++ b/lib/images/toolbar/italic.png
Binary files differ
diff --git a/lib/images/toolbar/link.png b/lib/images/toolbar/link.png
new file mode 100644
index 000000000..01105b0d3
--- /dev/null
+++ b/lib/images/toolbar/link.png
Binary files differ
diff --git a/lib/images/toolbar/linkextern.png b/lib/images/toolbar/linkextern.png
new file mode 100644
index 000000000..acc0c6fc5
--- /dev/null
+++ b/lib/images/toolbar/linkextern.png
Binary files differ
diff --git a/lib/images/toolbar/mono.png b/lib/images/toolbar/mono.png
new file mode 100644
index 000000000..b91ad2e0d
--- /dev/null
+++ b/lib/images/toolbar/mono.png
Binary files differ
diff --git a/lib/images/toolbar/ol.png b/lib/images/toolbar/ol.png
new file mode 100644
index 000000000..186f1fad4
--- /dev/null
+++ b/lib/images/toolbar/ol.png
Binary files differ
diff --git a/lib/images/toolbar/sig.png b/lib/images/toolbar/sig.png
new file mode 100644
index 000000000..72fdad0a0
--- /dev/null
+++ b/lib/images/toolbar/sig.png
Binary files differ
diff --git a/lib/images/toolbar/smiley.png b/lib/images/toolbar/smiley.png
new file mode 100644
index 000000000..85036c1a8
--- /dev/null
+++ b/lib/images/toolbar/smiley.png
Binary files differ
diff --git a/lib/images/toolbar/strike.png b/lib/images/toolbar/strike.png
new file mode 100644
index 000000000..e532d1f07
--- /dev/null
+++ b/lib/images/toolbar/strike.png
Binary files differ
diff --git a/lib/images/toolbar/ul.png b/lib/images/toolbar/ul.png
new file mode 100644
index 000000000..008820722
--- /dev/null
+++ b/lib/images/toolbar/ul.png
Binary files differ
diff --git a/lib/images/toolbar/underline.png b/lib/images/toolbar/underline.png
new file mode 100644
index 000000000..fa271517c
--- /dev/null
+++ b/lib/images/toolbar/underline.png
Binary files differ
diff --git a/lib/images/trash.png b/lib/images/trash.png
new file mode 100644
index 000000000..350c5e1cf
--- /dev/null
+++ b/lib/images/trash.png
Binary files differ
diff --git a/lib/images/up.png b/lib/images/up.png
new file mode 100644
index 000000000..b1eac912d
--- /dev/null
+++ b/lib/images/up.png
Binary files differ
diff --git a/lib/images/wrap.gif b/lib/images/wrap.gif
new file mode 100644
index 000000000..f2253e4a2
--- /dev/null
+++ b/lib/images/wrap.gif
Binary files differ
diff --git a/lib/index.html b/lib/index.html
new file mode 100644
index 000000000..8cb33512e
--- /dev/null
+++ b/lib/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<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/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php
new file mode 100644
index 000000000..c3461b78b
--- /dev/null
+++ b/lib/plugins/acl/admin.php
@@ -0,0 +1,824 @@
+<?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)
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_acl extends DokuWiki_Admin_Plugin {
+ var $acl = null;
+ var $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
+ */
+ var $current_item = null;
+ var $who = '';
+ var $usersgroups = array();
+ var $specials = array();
+
+ /**
+ * return prompt for admin menu
+ */
+ function getMenuText($language) {
+ return $this->getLang('admin_acl');
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ function getMenuSort() {
+ return 1;
+ }
+
+ /**
+ * handle user request
+ *
+ * Initializes internal vars and handles modifications
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function handle() {
+ global $AUTH_ACL;
+ global $ID;
+ global $auth;
+ global $config_cascade;
+
+ // fresh 1:1 copy without replacements
+ $AUTH_ACL = file($config_cascade['acl']['default']);
+
+
+ // namespace given?
+ if($_REQUEST['ns'] == '*'){
+ $this->ns = '*';
+ }else{
+ $this->ns = cleanID($_REQUEST['ns']);
+ }
+
+ if ($_REQUEST['current_ns']) {
+ $this->current_item = array('id' => cleanID($_REQUEST['current_ns']), 'type' => 'd');
+ } elseif ($_REQUEST['current_id']) {
+ $this->current_item = array('id' => cleanID($_REQUEST['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($_REQUEST['acl_w']);
+ if($_REQUEST['acl_t'] == '__g__' && $who){
+ $this->who = '@'.ltrim($auth->cleanGroup($who),'@');
+ }elseif($_REQUEST['acl_t'] == '__u__' && $who){
+ $this->who = ltrim($who,'@');
+ if($this->who != '%USER%'){ #keep wildcard as is
+ $this->who = $auth->cleanUser($this->who);
+ }
+ }elseif($_REQUEST['acl_t'] &&
+ $_REQUEST['acl_t'] != '__u__' &&
+ $_REQUEST['acl_t'] != '__g__'){
+ $this->who = $_REQUEST['acl_t'];
+ }elseif($who){
+ $this->who = $who;
+ }
+
+ // handle modifications
+ if(isset($_REQUEST['cmd']) && checkSecurityToken()){
+
+ // scope for modifications
+ if($this->ns){
+ if($this->ns == '*'){
+ $scope = '*';
+ }else{
+ $scope = $this->ns.':*';
+ }
+ }else{
+ $scope = $ID;
+ }
+
+ if(isset($_REQUEST['cmd']['save']) && $scope && $this->who && isset($_REQUEST['acl'])){
+ // handle additions or single modifications
+ $this->_acl_del($scope, $this->who);
+ $this->_acl_add($scope, $this->who, (int) $_REQUEST['acl']);
+ }elseif(isset($_REQUEST['cmd']['del']) && $scope && $this->who){
+ // handle single deletions
+ $this->_acl_del($scope, $this->who);
+ }elseif(isset($_REQUEST['cmd']['update'])){
+ // handle update of the whole file
+ foreach((array) $_REQUEST['del'] as $where => $names){
+ // remove all rules marked for deletion
+ foreach($names as $who)
+ unset($_REQUEST['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((array) $_REQUEST['acl'] as $where => $opt){
+ foreach($opt as $who => $perm){
+ if ($who[0]=='@') {
+ if ($who!='@ALL') {
+ $who = '@'.ltrim($auth->cleanGroup($who),'@');
+ }
+ } elseif ($who != '%USER%'){ #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->_init_acl_config();
+ }
+
+ /**
+ * 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>
+ */
+ function html() {
+ global $ID;
+
+ 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->_html_explorer();
+ echo '</div>'.NL;
+
+ echo '<div id="acl__detail">'.NL;
+ $this->_html_detail();
+ echo '</div>'.NL;
+ echo '</div>'.NL;
+
+ echo '<div class="clearer"></div>';
+ echo '<h2>'.$this->getLang('current').'</h2>'.NL;
+ echo '<div class="level2">'.NL;
+ $this->_html_table();
+ echo '</div>'.NL;
+
+ echo '<div class="footnotes"><div class="fn">'.NL;
+ echo '<sup><a id="fn__1" class="fn_bot" name="fn__1" href="#fnt__1">1)</a></sup>'.NL;
+ echo $this->getLang('p_include');
+ echo '</div></div>';
+
+ echo '</div>'.NL;
+ }
+
+ /**
+ * returns array with set options for building links
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _get_opts($addopts=null){
+ global $ID;
+ $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>
+ */
+ function _html_explorer(){
+ global $conf;
+ global $ID;
+ global $lang;
+
+ $dir = $conf['datadir'];
+ $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->_get_tree($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,'_html_list_acl'),
+ array($this,'_html_li_acl'));
+
+ }
+
+ /**
+ * get a combined list of media and page files
+ *
+ * @param string $folder an already converted filesystem folder of the current namespace
+ * @param string $limit limit the search to this folder
+ */
+ function _get_tree($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,'_tree_sort'));
+ $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]);
+ }
+ return $data;
+ }
+
+ /**
+ * usort callback
+ *
+ * Sorts the combined trees of media and page files
+ */
+ function _tree_sort($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;
+ }
+
+ /**
+ * Display the current ACL for selected where/who combination with
+ * selectors and modification form
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_detail(){
+ global $conf;
+ 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->_html_select();
+ echo '<input type="text" name="acl_w" class="edit" value="'.(($inl)?'':hsc(ltrim($this->who,'@'))).'" />'.NL;
+ echo '<input type="submit" value="'.$this->getLang('btn_select').'" class="button" />'.NL;
+ echo '</div>'.NL;
+
+ echo '<div id="acl__info">';
+ $this->_html_info();
+ 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 infos and editor
+ */
+ function _html_info(){
+ global $ID;
+
+ if($this->who){
+ $current = $this->_get_exact_perm();
+
+ // explain current permissions
+ $this->_html_explain($current);
+ // load editor
+ $this->_html_acleditor($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>
+ */
+ function _html_acleditor($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->_html_checkboxes($current,empty($this->ns),'acl');
+
+ if(is_null($current)){
+ echo '<input type="submit" name="cmd[save]" class="button" value="'.$lang['btn_save'].'" />'.NL;
+ }else{
+ echo '<input type="submit" name="cmd[save]" class="button" value="'.$lang['btn_update'].'" />'.NL;
+ echo '<input type="submit" name="cmd[del]" class="button" value="'.$lang['btn_delete'].'" />'.NL;
+ }
+
+ echo '</fieldset>';
+ }
+
+ /**
+ * Explain the currently set permissions in plain english/$lang
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_explain($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>
+ */
+ function _html_list_acl($item){
+ global $ID;
+ $ret = '';
+ // what to display
+ if($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';
+
+ // namespace or page?
+ if($item['type']=='d'){
+ if($item['open']){
+ $img = DOKU_BASE.'lib/images/minus.gif';
+ $alt = '&minus;';
+ }else{
+ $img = DOKU_BASE.'lib/images/plus.gif';
+ $alt = '+';
+ }
+ $ret .= '<img src="'.$img.'" alt="'.$alt.'" />';
+ $ret .= '<a href="'.wl('',$this->_get_opts(array('ns'=>$item['id'],'sectok'=>getSecurityToken()))).'" class="idx_dir'.$cl.'">';
+ $ret .= $base;
+ $ret .= '</a>';
+ }else{
+ $ret .= '<a href="'.wl('',$this->_get_opts(array('id'=>$item['id'],'ns'=>'','sectok'=>getSecurityToken()))).'" class="wikilink1'.$cl.'">';
+ $ret .= noNS($item['id']);
+ $ret .= '</a>';
+ }
+ return $ret;
+ }
+
+
+ function _html_li_acl($item){
+ return '<li class="level' . $item['level'] . ' ' .
+ ($item['open'] ? 'open' : 'closed') . '">';
+ }
+
+
+ /**
+ * Get current ACL settings as multidim array
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _init_acl_config(){
+ 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('/\s+/',$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>
+ */
+ function _html_table(){
+ 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" name="fnt__1" 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->_html_checkboxes($perm,$ispage,'acl['.$where.']['.$who.']');
+ echo '</td>';
+
+ echo '<td align="center">';
+ echo '<input type="checkbox" name="del['.hsc($where).'][]" value="'.hsc($who).'" />';
+ echo '</td>';
+ echo '</tr>';
+ }
+ }
+
+ echo '<tr>';
+ echo '<th align="right" colspan="4">';
+ echo '<input type="submit" value="'.$lang['btn_update'].'" name="cmd[update]" class="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>
+ */
+ function _get_exact_perm(){
+ 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>
+ */
+ function _acl_add($acl_scope, $acl_user, $acl_level){
+ global $config_cascade;
+ $acl_config = file_get_contents($config_cascade['acl']['default']);
+ $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";
+
+ $new_config = $acl_config.$new_acl;
+
+ return io_saveFile($config_cascade['acl']['default'], $new_config);
+ }
+
+ /**
+ * remove acl-entry from conf/acl.auth.php
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ */
+ function _acl_del($acl_scope, $acl_user){
+ global $config_cascade;
+ $acl_config = file($config_cascade['acl']['default']);
+ $acl_user = auth_nameencode($acl_user,true);
+
+ $acl_pattern = '^'.preg_quote($acl_scope,'/').'\s+'.$acl_user.'\s+[0-8].*$';
+
+ // save all non!-matching
+ $new_config = preg_grep("/$acl_pattern/", $acl_config, PREG_GREP_INVERT);
+
+ return io_saveFile($config_cascade['acl']['default'], join('',$new_config));
+ }
+
+ /**
+ * print the permission radio boxes
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _html_checkboxes($setperm,$ispage,$name){
+ global $lang;
+
+ static $label = 0; //number labels
+ $ret = '';
+
+ if($ispage && $setperm > AUTH_EDIT) $perm = 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.'" title="'.$this->getLang('acl_perm'.$perm).'"'.$class.'>';
+ $ret .= '<input '.buildAttributes($atts).' />&nbsp;';
+ $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>
+ */
+ function _html_select(){
+ global $conf;
+ $inlist = false;
+
+ 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{
+ $usel = '';
+ $gsel = '';
+ $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="&nbsp;">'.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="&nbsp;">'.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/lib/plugins/acl/ajax.php b/lib/plugins/acl/ajax.php
new file mode 100644
index 000000000..71a2eb03a
--- /dev/null
+++ b/lib/plugins/acl/ajax.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * AJAX call handler for ACL plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+//fix for Opera XMLHttpRequests
+if(!count($_POST) && !empty($HTTP_RAW_POST_DATA)){
+ parse_str($HTTP_RAW_POST_DATA, $_POST);
+}
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../../');
+require_once(DOKU_INC.'inc/init.php');
+//close session
+session_write_close();
+
+if(!auth_isadmin()) die('for admins only');
+if(!checkSecurityToken()) die('CRSF Attack');
+
+$ID = getID();
+
+$acl = plugin_load('admin','acl');
+$acl->handle();
+
+$ajax = $_REQUEST['ajax'];
+header('Content-Type: text/html; charset=utf-8');
+
+if($ajax == 'info'){
+ $acl->_html_info();
+}elseif($ajax == 'tree'){
+ global $conf;
+ global $ID;
+
+ $dir = $conf['datadir'];
+ $ns = $_REQUEST['ns'];
+ if($ns == '*'){
+ $ns ='';
+ }
+ $ns = cleanID($ns);
+ $lvl = count(explode(':',$ns));
+ $ns = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $data = $acl->_get_tree($ns,$ns);
+
+ foreach(array_keys($data) as $item){
+ $data[$item]['level'] = $lvl+1;
+ }
+ echo html_buildlist($data, 'acl', array($acl, '_html_list_acl'),
+ array($acl, '_html_li_acl'));
+}
+
diff --git a/lib/plugins/acl/lang/af/lang.php b/lib/plugins/acl/lang/af/lang.php
new file mode 100644
index 000000000..04d9b0acf
--- /dev/null
+++ b/lib/plugins/acl/lang/af/lang.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['page'] = 'Bladsy';
+$lang['acl_perm0'] = 'Niks';
+$lang['acl_perm1'] = 'Lees';
+$lang['acl_perm2'] = 'Verander';
+$lang['acl_perm4'] = 'Maak';
diff --git a/lib/plugins/acl/lang/ar/help.txt b/lib/plugins/acl/lang/ar/help.txt
new file mode 100644
index 000000000..70f5cf645
--- /dev/null
+++ b/lib/plugins/acl/lang/ar/help.txt
@@ -0,0 +1,11 @@
+=== مساعدة سريعة: ===
+
+على هذه الصفحة يمكنك إضافة أو إزالة الصلاحيات الخاصة بالنطاقات و الصفحات في ويكيتك.
+
+الشريط الأيسر يظهر كل النطاقات و الصفحات المتاحة.
+
+النموذج في الأسفل يمكنك من رؤية و تعديل الصلاحيات لمستخدم محدد أو مجموعة .
+
+في الجدول في الأسفل تجد قواعد التحكم بالوصول معروضة. يمكنك استخدامها لحذف أو تغيير عدة قواعد بسرعة.
+
+قراءة [[doku>acl|المستندات الرسمية عن ACL]] قد يساعدك على الفهم الكامل لطريقة عمل التحكم بالوصول في دوكو ويكي.
diff --git a/lib/plugins/acl/lang/ar/lang.php b/lib/plugins/acl/lang/ar/lang.php
new file mode 100644
index 000000000..7c05b721c
--- /dev/null
+++ b/lib/plugins/acl/lang/ar/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Mostafa Hussein <mostafa@gmail.com>
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['admin_acl'] = 'إدارة قوائم التحكم بالدخول';
+$lang['acl_group'] = 'مجموعة';
+$lang['acl_user'] = 'مستخدم';
+$lang['acl_perms'] = 'ترخيص لـ';
+$lang['page'] = 'صفحة';
+$lang['namespace'] = 'فضاء التسمية';
+$lang['btn_select'] = 'اختيار';
+$lang['p_user_id'] = 'المستخدم<b class="acluser">%s</b> عنده حاليا الصلاحيات التالية على الصفحة<b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'المستخدم <b class="acluser">%s</b> عنده حاليا الصلاحيات التالية في النطاق<b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'أعضاء مجموعة<b class="aclgroup">%s</b> عندهم حاليا الصلاحيات التالية على الصفحة page <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'أعضاء مجموعة <b class="aclgroup">%s</b> عندهم حاليا الصلاحيات التالية في النطاق <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'رجاء <b>مستخدما أو مجموعة</b> في النموذج أعلاه لعرض أو تحرير اعداد الصلاحيات للصفحة<b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'رجاء Please <b>أدخل مستخدما أو مجموعة</b> في النموذج أعلاه لعرض أو تحرير اعداد الصلاحيات للنطاق<b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'لاحظ: هذه الصلاحيات لم تنشأ إراديا بل وُرثت من مجموعات أخرى أو نطاقات أعلى.';
+$lang['p_isadmin'] = 'لاحظ: المجموعة أو المستخدم المحدد عندهم دائما صلاحيات كاملة بسبب ضبطهم كمستخدمين متفوقين.';
+$lang['p_include'] = 'الصلاحيات الاعلى تتضمن الأخفض. صلاحيات الإنشاء ، والرفع، والحذف تطبق فقط على النطاقات، وليس على الصفحات.';
+$lang['current'] = 'قواعد ACL الحالية';
+$lang['where'] = 'الصفحة/النطاق';
+$lang['who'] = 'اسم المستخدم / المجموعة';
+$lang['perm'] = 'التصاريح';
+$lang['acl_perm0'] = 'لا يوجد';
+$lang['acl_perm1'] = 'قراءة';
+$lang['acl_perm2'] = 'تحرير';
+$lang['acl_perm4'] = 'إنشاء';
+$lang['acl_perm8'] = 'تحميل';
+$lang['acl_perm16'] = 'مسح';
+$lang['acl_new'] = 'أضف أضافة جديدة';
+$lang['acl_mod'] = 'عدل المدخلة';
diff --git a/lib/plugins/acl/lang/bg/help.txt b/lib/plugins/acl/lang/bg/help.txt
new file mode 100644
index 000000000..2de453420
--- /dev/null
+++ b/lib/plugins/acl/lang/bg/help.txt
@@ -0,0 +1,11 @@
+=== Помощ ===
+
+От тук можете да добавяте и премахвате права за именни пространства и страници във вашето Wiki.
+
+Левият панел показва всички налични именни пространства и страници.
+
+Формата отгоре ви позволява да преглеждате и променяте правата на избран потребител или група.
+
+В таблицата отдолу са показани всички актуални правила за контрол на достъпа. Можете да я ползвате за бързо изтриване или промяна на множество правила.
+
+За да разберете как работи контрола на достъпа в DokuWiki трябва да прочетете [[doku>acl|документацията относно ACL]]. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/bg/lang.php b/lib/plugins/acl/lang/bg/lang.php
new file mode 100644
index 000000000..e260be918
--- /dev/null
+++ b/lib/plugins/acl/lang/bg/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * bulgarian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['admin_acl'] = 'Управление на списъците за достъп';
+$lang['acl_group'] = 'Група';
+$lang['acl_user'] = 'Потребител';
+$lang['acl_perms'] = 'Права за';
+$lang['page'] = 'Страница';
+$lang['namespace'] = 'Именно пространство';
+$lang['btn_select'] = 'Избери';
+$lang['p_user_id'] = 'Потребителят <b class="acluser">%s</b> в момента има следните права за страницата <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Потребителят <b class="acluser">%s</b> в момента има следните права за именното пространство <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Членовете на групата <b class="aclgroup">%s</b> в момента имат следните права за страницата <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Членовете на групата <b class="aclgroup">%s</b> в момента имат следните права за именното пространство <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Моля, <b>въведете потребител или група</b> в полето отгоре, за да видите или промените правата за страницата <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Моля, <b>въведете потребител или група</b> в полето отгоре, за да видите или промените правата за именното пространство <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Бележка: Тези разрешения не са зададени директно, а са наследени от други групи или именни пространства.';
+$lang['p_isadmin'] = 'Бележка: Избраната група или потребител има всички права, защото е определен за супер потребител.';
+$lang['p_include'] = 'Висши права включват по-нисшите такива. Правата за създаване, качване и изтриване са приложими само за именни пространства, но не за страници.';
+$lang['current'] = 'Текущи ACL права';
+$lang['where'] = 'Страница/Именно пространство';
+$lang['who'] = 'Потребител/Група';
+$lang['perm'] = 'Права';
+$lang['acl_perm0'] = 'Никакви';
+$lang['acl_perm1'] = 'Четене';
+$lang['acl_perm2'] = 'Редактиране';
+$lang['acl_perm4'] = 'Създаване';
+$lang['acl_perm8'] = 'Качване';
+$lang['acl_perm16'] = 'Изтриване';
+$lang['acl_new'] = 'Добавяне на право';
+$lang['acl_mod'] = 'Промяна на записа';
diff --git a/lib/plugins/acl/lang/ca-valencia/help.txt b/lib/plugins/acl/lang/ca-valencia/help.txt
new file mode 100644
index 000000000..87450d2fa
--- /dev/null
+++ b/lib/plugins/acl/lang/ca-valencia/help.txt
@@ -0,0 +1,15 @@
+=== Ajuda ràpida: ===
+
+En esta pàgina pot afegir i llevar permissos per a espais de noms i
+pàgines del wiki.
+
+El panel esquerre mostra tots els espais de noms i pàgines disponibles.
+
+El formulari de dalt permet vore i modificar els permissos de l'usuari
+o grup seleccionat.
+
+En la taula de baix es mostren totes les regles d'accés actuals. Pot
+usar-la per a canviar o borrar ràpidament vàries regles.
+
+Llegint la [[doku>acl|documentació oficial sobre ACL]] podrà
+comprendre millor com funciona el control d'accés en DokuWiki.
diff --git a/lib/plugins/acl/lang/ca-valencia/lang.php b/lib/plugins/acl/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..ef0ae92eb
--- /dev/null
+++ b/lib/plugins/acl/lang/ca-valencia/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * valencian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bernat Arlandis i Mañó <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['admin_acl'] = 'Gestor de les llistes de control d\'accés';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Usuari';
+$lang['acl_perms'] = 'Permissos per a';
+$lang['page'] = 'Pàgina';
+$lang['namespace'] = 'Espai de noms';
+$lang['btn_select'] = 'Seleccionar';
+$lang['p_user_id'] = 'L\'usuari <b class="acluser">%s</b> té actualment els següents permissos en la pàgina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'L\'usuari <b class="acluser">%s</b> té actualment els següents permissos en l\'espai de noms <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Els membres del grup <b class="aclgroup">%s</b> tenen actualment els següents permissos en la pàgina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Els membres del grup <b class="aclgroup">%s</b> tenen actualment els següents permissos en l\'espai de noms <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Per favor, <b>introduïxca un usuari o grup</b> en el formulari de dalt per a vore o editar els per a la pàgina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Per favor, <b>introduïxca un usuari o grup</b> en el formulari de dalt per a vore o editar els permissos per a l\'espai de noms <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: estos permissos no s\'han indicat explícitament sino que s\'hereten d\'atres grups o d\'espais de noms antecessors.';
+$lang['p_isadmin'] = 'Nota: el grup o usuari seleccionat té sempre tots els permissos perque està configurat com a super-usuari.';
+$lang['p_include'] = 'Els permissos més alts inclouen als més baixos. Els permissos per a crear, enviar i borrar només valen per a espais de noms, pàgines no.';
+$lang['current'] = 'Regles ACL actuals';
+$lang['where'] = 'Pàgina/espai de noms';
+$lang['who'] = 'Usuari/grup';
+$lang['perm'] = 'Permissos';
+$lang['acl_perm0'] = 'Cap';
+$lang['acl_perm1'] = 'Llegir';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Crear';
+$lang['acl_perm8'] = 'Pujar';
+$lang['acl_perm16'] = 'Borrar';
+$lang['acl_new'] = 'Afegir entrada nova';
+$lang['acl_mod'] = 'Modificar entrada';
diff --git a/lib/plugins/acl/lang/ca/help.txt b/lib/plugins/acl/lang/ca/help.txt
new file mode 100644
index 000000000..d9bcc126d
--- /dev/null
+++ b/lib/plugins/acl/lang/ca/help.txt
@@ -0,0 +1,11 @@
+=== Ajuda ràpida ===
+
+En aquesta pàgina podeu afegir i treure permisos per a espais i pàgines del vostre wiki.
+
+La subfinestra de l'esquerra mostra tots els espais i pàgines disponibles.
+
+El formulari de dalt us permet veure i modificar els permisos de l'usuari o grup que seleccioneu.
+
+En la taula de baix es mostren totes les regles de control d'accés que hagin estat definides. Podeu utilitzar aquesta taula per suprimir o modificar ràpidament totes les regles que vulgueu.
+
+Llegir la [[doku>acl|documentació oficial sobre ACL]] us pot ajudar a entendre del tot com funciona el control d'accés en DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/ca/lang.php b/lib/plugins/acl/lang/ca/lang.php
new file mode 100644
index 000000000..10f656062
--- /dev/null
+++ b/lib/plugins/acl/lang/ca/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * catalan language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ */
+$lang['admin_acl'] = 'Gestió de la Llista de Control d\'Accés';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Usuari';
+$lang['acl_perms'] = 'Permisos per a';
+$lang['page'] = 'Pàgina';
+$lang['namespace'] = 'Espai';
+$lang['btn_select'] = 'Selecciona';
+$lang['p_user_id'] = 'L\'usuari <b class="acluser">%s</b> té a hores d\'ara els permisos següents en la pàgina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'L\'usuari <b class="acluser">%s</b> té a hores d\'ara els permisos següents en l\'espai <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Els membres del grup <b class="aclgroup">%s</b> tenen a hores d\'ara els permisos següents en la pàgina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Els membres del grup <b class="aclgroup">%s</b> tenen a hores d\'ara els permisos següents en l\'espai <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Introduïu un usuari o grup</b> en el formulari de dalt per veure o editar els seus permisos en la pàgina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = '<b>Introduïu un usuari o grup</b> en el formulari de dalt per veure o editar els seus permisos en l\'espai <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: aquests permisos no s\'han definit explícitament, sinó que són heretats d\'altres grups o d\'espais d\'ordre superior.';
+$lang['p_isadmin'] = 'Nota: l\'usuari o grup seleccionat té sempre tots els permisos perquè ha estat configurat com a superusuari.';
+$lang['p_include'] = 'Els permisos més alts inclouen tots els permisos inferiors. Els permisos per a crear, penjar i suprimir només s\'apliquen als espais, no a pàgines.';
+$lang['current'] = 'Regles ACL actuals';
+$lang['where'] = 'Pàgina/espai';
+$lang['who'] = 'Usuari/grup';
+$lang['perm'] = 'Permisos';
+$lang['acl_perm0'] = 'Cap';
+$lang['acl_perm1'] = 'Lectura';
+$lang['acl_perm2'] = 'Edició';
+$lang['acl_perm4'] = 'Creació';
+$lang['acl_perm8'] = 'Penjar fitxers';
+$lang['acl_perm16'] = 'Suprimir';
+$lang['acl_new'] = 'Afegeix nova entrada';
+$lang['acl_mod'] = 'Modifica entrada';
diff --git a/lib/plugins/acl/lang/cs/help.txt b/lib/plugins/acl/lang/cs/help.txt
new file mode 100644
index 000000000..1dbc88ad0
--- /dev/null
+++ b/lib/plugins/acl/lang/cs/help.txt
@@ -0,0 +1,11 @@
+=== Nápověda: ===
+
+Na této stránce můžete přidávat a odebírat oprávnění na jmenné prostory a stránky Vaší wiki.
+
+Levý panel zobrazuje všechny dostupné jmenné prostory a stránky.
+
+Formulář výše umožňuje vidět a modifikovat oprávnění vybraného uživatele nebo skupiny.
+
+V tabulce uvedené níže jsou zobrazeny všechny aktuální pravidla pro řízení přístupu (oprávnění). Zde můžete rychle odebírat a měnit více položek (oprávnění) najednou.
+
+Pro detailnější nápovědu si přečtěte stránku [[doku>acl|oficiální dokumentaci ACL]], která Vám může pomoci plně pochopit princip, jak řízení přístupu na DokuWiki funguje.
diff --git a/lib/plugins/acl/lang/cs/lang.php b/lib/plugins/acl/lang/cs/lang.php
new file mode 100644
index 000000000..cc1d97023
--- /dev/null
+++ b/lib/plugins/acl/lang/cs/lang.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['admin_acl'] = 'Správa přístupových práv';
+$lang['acl_group'] = 'Skupina';
+$lang['acl_user'] = 'Uživatel';
+$lang['acl_perms'] = 'Práva pro';
+$lang['page'] = 'Stránka';
+$lang['namespace'] = 'Jmenný prostor';
+$lang['btn_select'] = 'Vybrat';
+$lang['p_user_id'] = 'Uživatel <b class="acluser">%s</b> má nyní na stránku <b class="aclpage">%s</b> následující oprávnění: <i>%s</i>.';
+$lang['p_user_ns'] = 'Uživatel <b class="acluser">%s</b> má nyní na jmenný prostor <b class="aclns">%s</b> následující oprávnění: <i>%s</i>.';
+$lang['p_group_id'] = 'Členové skupiny <b class="aclgroup">%s</b> mají nyní na stránku <b class="aclpage">%s</b> následující oprávnění: <i>%s</i>.';
+$lang['p_group_ns'] = 'Členové skupiny <b class="aclgroup">%s</b> mají nyní na jmenný prostor <b class="aclns">%s</b> následující oprávnění: <i>%s</i>.';
+$lang['p_choose_id'] = 'Prosím, <b>vložte uživatele nebo skupinu</b> ve formě uvedené výše, abyste mohli prohlížet a editovat množinu oprávnění pro stránku <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Prosím, <b>vložte uživatele nebo skupinu</b> ve formě uvedené výše, abyste mohli prohlížet a editovat množinu oprávnění pro jmenný prostor <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Poznámka: Tato oprávnění nebyla nastavena explicitně, ale jsou zděděna z jiné skupiny nebo z nadřazeného jmenného prostoru.';
+$lang['p_isadmin'] = 'Poznámka: Vybraná skupina nebo uživatel má vždy plná oprávnění, protože je nastaven jako správce (superuser).';
+$lang['p_include'] = 'Vyšší oprávnění zahrnují nižší oprávnění. Vytvořit, Nahrát a Smazat se vztahují jen k jmenným prostorů, nikoliv ke stránkám.';
+$lang['current'] = 'Aktuální ACL pravidla';
+$lang['where'] = 'Stránka/Jmenný prostor';
+$lang['who'] = 'Uživatel/Skupina';
+$lang['perm'] = 'Oprávnění';
+$lang['acl_perm0'] = 'Žádné';
+$lang['acl_perm1'] = 'Čtení';
+$lang['acl_perm2'] = 'Úpravy';
+$lang['acl_perm4'] = 'Vytvoření';
+$lang['acl_perm8'] = 'Upload';
+$lang['acl_perm16'] = 'Mazání';
+$lang['acl_new'] = 'Přidat novou položku';
+$lang['acl_mod'] = 'Editovat položku';
diff --git a/lib/plugins/acl/lang/da/help.txt b/lib/plugins/acl/lang/da/help.txt
new file mode 100644
index 000000000..c8eedfc48
--- /dev/null
+++ b/lib/plugins/acl/lang/da/help.txt
@@ -0,0 +1,11 @@
+=== Vejledning ===
+
+På denne side kan du tilføje og fjerne tilladelser for navnerum og sider i din wiki.
+
+Panelet i venstre side viser alle tilgængelige navnerum og sider.
+
+I kassen for oven giver dig mulighed for at se og ændre tilladelser for en bestemt bruger eller gruppe.
+
+Nedenstående skema viser dig alle de satte regler for adgangskontrol. Du kan bruge den til hurtigt at slette eller ændre nogle af dem.
+
+Ved at læse [[doku>acl|den officielle vejledning til ACL]] kan du opnå yderligere hjælp til at blive sat helt ind i, hvordan adgangskontrol virker i DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/da/lang.php b/lib/plugins/acl/lang/da/lang.php
new file mode 100644
index 000000000..f82098dee
--- /dev/null
+++ b/lib/plugins/acl/lang/da/lang.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author koeppe <koeppe@kazur.dk>
+ * @author Jon Bendtsen <bendtsen@diku.dk>
+ * @author Lars Næsbye Christensen <larsnaesbye@stud.ku.dk>
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['admin_acl'] = 'Rettighedsadministration';
+$lang['acl_group'] = 'Gruppe';
+$lang['acl_user'] = 'Bruger';
+$lang['acl_perms'] = 'Rettigheder for';
+$lang['page'] = 'Dokument';
+$lang['namespace'] = 'Navnerum';
+$lang['btn_select'] = 'Vælg';
+$lang['p_user_id'] = 'Bruger <b class="acluser">%s</b> har følgende adgang på siden <b class="aclpage">%s</b>: <i>%s</i>';
+$lang['p_user_ns'] = 'Bruger <b class="acluser">%s</b> har foreløbig følgende tilladelse i navnerummet <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Medlemmerne af gruppen <b class="aclgroup">%s</b> har foreløbigt de følgende tilladelser på siden <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Medlemmerne af gruppen <b class="aclgroup">%s</b> har foreløbigt de følgende tilladelser i navnerummet <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Venligst <b>udfyld en bruger eller gruppe</b> i ovennævnte formular for at se eller redigere tilladelserne for denne side<b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Venligst <b>udfyld en bruger eller gruppe</b> i ovennævnte formular for at se eller redigere tilladelserne for navnerummet <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Bemærk: Disse tilladelser var ikke lagt entydigt ind, men var arvet fra andre grupper eller højere navnerum.';
+$lang['p_isadmin'] = 'Bemærk: Den valgte gruppe eller bruger har altid fuld adgang, fordi den er sat til at være en supergruppe eller -bruger';
+$lang['p_include'] = 'Højere tilladelse inkluderer også lavere. Tilladelser til at oprette, lægge filer op og slette gælder kun for navnerum, ikke sider.';
+$lang['current'] = 'Aktuelle ACL-regler';
+$lang['where'] = 'Side/navnerum';
+$lang['who'] = 'Bruger/gruppe';
+$lang['perm'] = 'Rettigheder';
+$lang['acl_perm0'] = 'Ingen';
+$lang['acl_perm1'] = 'Læs';
+$lang['acl_perm2'] = 'Skriv';
+$lang['acl_perm4'] = 'Opret';
+$lang['acl_perm8'] = 'Overføre';
+$lang['acl_perm16'] = 'Slet';
+$lang['acl_new'] = 'Tilføj ny post';
+$lang['acl_mod'] = 'Ændre post';
diff --git a/lib/plugins/acl/lang/de-informal/help.txt b/lib/plugins/acl/lang/de-informal/help.txt
new file mode 100644
index 000000000..d7930f8df
--- /dev/null
+++ b/lib/plugins/acl/lang/de-informal/help.txt
@@ -0,0 +1,11 @@
+=== Schnellhilfe ===
+
+Auf dieser Seite kannst Du Rechte für Namensräume und Seiten in deinem Wiki hinzufügen oder entfernen.
+
+Der linke Bereich zeigt alle Namensräume und Seiten.
+
+Das obere Formular zeigt die die Rechte der ausgewählten Gruppe bzw. Benutzers.
+
+In der Tabelle unten werden alle momentan gesetzten Zugriffsregeln gezeigt. Hier kannst Du schnell mehrere Regeln löschen oder ändern.
+
+Das Lesen von [[doku>acl|official documentation on ACL]] kann Dir helfen zu verstehen, wie die Zugriffskontrole in DokuWiki funktioniert.
diff --git a/lib/plugins/acl/lang/de-informal/lang.php b/lib/plugins/acl/lang/de-informal/lang.php
new file mode 100644
index 000000000..3f4b08c2a
--- /dev/null
+++ b/lib/plugins/acl/lang/de-informal/lang.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['admin_acl'] = 'Zugriffskontrollsystem Management';
+$lang['acl_group'] = 'Gruppe';
+$lang['acl_user'] = 'Benutzer';
+$lang['acl_perms'] = 'Rechte für';
+$lang['page'] = 'Seite';
+$lang['namespace'] = 'Namensraum';
+$lang['btn_select'] = 'Auswählen';
+$lang['p_user_id'] = 'Benutzer <b class="acluser">%s</b> hat im Moment folgende Rechte auf der Seite <b class="aclpage">%s</b>: <i>%s</i>';
+$lang['p_user_ns'] = 'Benutzer <b class="acluser">%s</b> hat momentan die folgenden Rechte im Namensraum <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Die Gruppenmitglieder <b class="aclgroup">%s</b> haben momentan die folgenden Rechte auf der Seite <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Die Mitglieder der Gruppe <b class="aclgroup">%s</b> haben gerade Zugriff in folgenden Namensräumen <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Bitte <b>gib einen Nutzer oder eine Gruppe</b> in das Formular ein, um die Berechtigungen der Seite <b class="aclpage">%s</b> anzusehen oder zu bearbeiten.';
+$lang['p_choose_ns'] = 'Bitte <b>gib einen Nutzer oder eine Gruppe</b> in das Formular ein, um die Berechtigungen des Namenraumes <b class="aclpage">%s</b> anzusehen oder zu bearbeiten.';
+$lang['p_inherited'] = 'Hinweis: Diese Rechte wurden nicht explizit gesetzt, sondern von anderen Gruppen oder übergeordneten Namensräumen geerbt.';
+$lang['p_isadmin'] = 'Hinweis: Die gewählte Gruppe oder der Benutzer haben immer die vollen Rechte, weil sie als Superuser konfiguriert sind.';
+$lang['p_include'] = 'Höhere Rechte schließen kleinere mit ein. Hochlade- und Löschrechte sind nur für Namensräume, nicht für Seiten.';
+$lang['current'] = 'Momentane Zugriffsregeln';
+$lang['where'] = 'Seite/Namensraum';
+$lang['who'] = 'Benutzer/Gruppe';
+$lang['perm'] = 'Rechte';
+$lang['acl_perm0'] = 'Keine';
+$lang['acl_perm1'] = 'Lesen';
+$lang['acl_perm2'] = 'Bearbeiten';
+$lang['acl_perm4'] = 'Erstellen';
+$lang['acl_perm8'] = 'Hochladen';
+$lang['acl_perm16'] = 'Löschen';
+$lang['acl_new'] = 'Neuen Eintrag zufügen';
+$lang['acl_mod'] = 'Eintrag modifizieren';
diff --git a/lib/plugins/acl/lang/de/help.txt b/lib/plugins/acl/lang/de/help.txt
new file mode 100644
index 000000000..783ae22e7
--- /dev/null
+++ b/lib/plugins/acl/lang/de/help.txt
@@ -0,0 +1,11 @@
+=== Kurzhilfe ===
+
+Auf dieser Seite können sie Zugriffsberechtigungen für Seiten und Namensräume festlegen und ändern.
+
+Die Liste links zeigt alle verfügbaren Namensräume und Seiten.
+
+Das Formular oben erlaubt Anzeige, Ändern und Hinzufügen von Zugriffsregeln für einen ausgewählten Nutzer oder eine Gruppe.
+
+In der Tabelle unten werden alle bestehenden Regeln aufgeführt und können dort modifiziert oder gelöscht werden.
+
+Für ein tiefergehendes Verständnis wie Zugriffsbeschränkungen in DokuWiki funktionieren, sollten Sie die [[doku>acl|offizielle Dokumentation]] lesen. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/de/lang.php b/lib/plugins/acl/lang/de/lang.php
new file mode 100644
index 000000000..eb23636c4
--- /dev/null
+++ b/lib/plugins/acl/lang/de/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * german language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Christof <gagi@fin.de>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['admin_acl'] = 'Zugangsverwaltung';
+$lang['acl_group'] = 'Gruppe';
+$lang['acl_user'] = 'Benutzer';
+$lang['acl_perms'] = 'Berechtigungen für';
+$lang['page'] = 'Seite';
+$lang['namespace'] = 'Namensraum';
+$lang['btn_select'] = 'Auswählen';
+$lang['p_user_id'] = 'Nutzer <b class="acluser">%s</b> hat momentan folgende Berechtigungen für die Seite <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Nutzer <b class="acluser">%s</b> hat momentan folgende Berechtigungen im Namensraum <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Mitglieder der Gruppe <b class="aclgroup">%s</b> haben momentan folgende Berechtigungen für die Seite <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Mitglieder der Gruppe <b class="aclgroup">%s</b> haben momentan folgende Berechtigungen für den Namensraum <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Bitte geben Sie in obigem Formular eine <b>einen Nutzer oder eine Gruppe</b> an, um die Berechtigungen für die Seite <b class="aclpage">%s</b> zu sehen oder zu ändern.';
+$lang['p_choose_ns'] = 'Bitte geben Sie in obigem Formular eine <b>einen Nutzer oder eine Gruppe</b> an, um die Berechtigungen für den Namensraum <b class="aclns">%s</b> zu sehen oder zu ändern.';
+$lang['p_inherited'] = 'Hinweis: Diese Berechtigungen wurden nicht explizit gesetzt, sondern von anderen Gruppen oder höher liegenden Namensräumen geerbt.';
+$lang['p_isadmin'] = 'Hinweis: Die ausgewählte Gruppe oder Nutzer haben immer alle Berechtigungen das sie als Superuser konfiguriert wurden.';
+$lang['p_include'] = 'Höhere Berechtigungen schließen niedrigere mit ein. Anlegen, Hochladen und Entfernen gilt nur für Namensräume, nicht für einzelne Seiten';
+$lang['current'] = 'Momentane Zugriffsregeln';
+$lang['where'] = 'Seite/Namensraum';
+$lang['who'] = 'Nutzer/Gruppe';
+$lang['perm'] = 'Berechtigungen';
+$lang['acl_perm0'] = 'Keine';
+$lang['acl_perm1'] = 'Lesen';
+$lang['acl_perm2'] = 'Bearbeiten';
+$lang['acl_perm4'] = 'Anlegen';
+$lang['acl_perm8'] = 'Hochladen';
+$lang['acl_perm16'] = 'Entfernen';
+$lang['acl_new'] = 'Eintrag hinzufügen';
+$lang['acl_mod'] = 'Eintrag bearbeiten';
diff --git a/lib/plugins/acl/lang/el/help.txt b/lib/plugins/acl/lang/el/help.txt
new file mode 100644
index 000000000..ea2f816c0
--- /dev/null
+++ b/lib/plugins/acl/lang/el/help.txt
@@ -0,0 +1,10 @@
+=== Γρήγορη Βοήθεια: ===
+
+Στη σελίδα αυτή μπορείτε να προσθέσετε και αφαιρέσετε δικαιώματα πρόσβασης για φακέλους και σελίδες στο wiki σας.
+
+Το αριστερό πλαίσιο δείχνει όλους τους διαθέσιμους φακέλους και αρχεία.
+
+Η παραπάνω φόρμα επιτρέπει να δείτε και να τροποποιήσετε τα διακαιώματα μίας επιλεγμένης ομάδας χρηστών ή ενός χρήστη.
+
+Στον παρακάτω πίνακα εμφανίζονται όλοι οι τρέχοντες κανόνες παραχώρησης δικαιωμάτων πρόσβασης. Μπορείτε να τον χρησιμοποιήσετε ώστε να σβήσετε ή να τροποποιήσετε γρήγορα πολλαπλούς κανόνες.
+Διαβάζοντας την [[doku>acl|επίσημη τεκμηρίωση για τις Λίστες Δικαιωμάτων Πρόσβασης - ACL]] ίσως σας βοηθήσει να καταλάβετε πλήρως το πως αυτές εφαρμόζονται στην DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/el/lang.php b/lib/plugins/acl/lang/el/lang.php
new file mode 100644
index 000000000..e1cd26755
--- /dev/null
+++ b/lib/plugins/acl/lang/el/lang.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @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 Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['admin_acl'] = 'Διαχείριση Δικαιωμάτων Πρόσβασης';
+$lang['acl_group'] = 'Ομάδα';
+$lang['acl_user'] = 'Χρήστης';
+$lang['acl_perms'] = 'Δικαιώματα για';
+$lang['page'] = 'Σελίδα';
+$lang['namespace'] = 'Φάκελος';
+$lang['btn_select'] = 'Επιλογή';
+$lang['p_user_id'] = 'Ο χρήστης <b class="acluser">%s</b> έχει τα ακόλουθα δικαιώματα πρόσβασης στην σελίδα <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Ο χρήστης <b class="acluser">%s</b> έχει τα ακόλουθα δικαιώματα πρόσβασης στον φάκελο <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Τα μέλη της ομάδας <b class="aclgroup">%s</b> έχουν τα ακόλουθα δικαιώματα πρόσβασης στην σελίδα <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Τα μέλη της ομάδας <b class="aclgroup">%s</b> έχουν τα ακόλουθα δικαιώματα πρόσβασης στον φάκελο <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Παρακαλώ <b>δώστε ένα όνομα χρήστη ή ομάδας χρηστών</b> στην παραπάνω μορφή για να δείτε τα αντίστοιχα δικαιώματα πρόσβασης για την σελίδα <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Παρακαλώ <b>δώστε ένα όνομα χρήστη ή ομάδας χρηστών</b> στην παραπάνω μορφή για να δείτε τα αντίστοιχα δικαιώματα πρόσβασης για τον φάκελο <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Σημείωση: Αυτά τα διακαιώματα χρήσης δεν ορίστηκαν άμεσα αλλά κληρονομήθηκαν από άλλες ομάδες χρηστών ή φακέλους σε υψηλότερο επίπεδο.';
+$lang['p_isadmin'] = 'Σημείωση: Η επιλεγμένη ομάδα χρηστών ή χρήστης έχει πάντα πλήρη διακαιώματα πρόσβασης διότι είναι δηλωμένος σαν υπερχρήστης (superuser).';
+$lang['p_include'] = 'Τα υψηλότερα δικαιώματα πρόσβασης περιλαμβάνουν τα χαμηλότερα. Τα δικαιώματα για Δημιουργία, Φόρτωση και Διαγραφή αφορούν μόνο φακέλους και όχι σελίδες. ';
+$lang['current'] = 'Τρέχοντες κανόνες Λίστας Δικαιωμάτων Πρόσβασης - ACL';
+$lang['where'] = 'Σελίδα/Φάκελος';
+$lang['who'] = 'Χρήστης/Ομάδα χρηστών';
+$lang['perm'] = 'Δικαιώματα πρόσβασης';
+$lang['acl_perm0'] = 'Κανένα';
+$lang['acl_perm1'] = 'Ανάγνωση';
+$lang['acl_perm2'] = 'Τροποποίηση';
+$lang['acl_perm4'] = 'Δημιουργία';
+$lang['acl_perm8'] = 'Φόρτωση';
+$lang['acl_perm16'] = 'Διαγραφή';
+$lang['acl_new'] = 'Προσθήκη νέας εγγραφής';
+$lang['acl_mod'] = 'Τροποποίηση εγγραφής';
diff --git a/lib/plugins/acl/lang/en/help.txt b/lib/plugins/acl/lang/en/help.txt
new file mode 100644
index 000000000..2b80cc4c7
--- /dev/null
+++ b/lib/plugins/acl/lang/en/help.txt
@@ -0,0 +1,12 @@
+=== 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/lib/plugins/acl/lang/en/lang.php b/lib/plugins/acl/lang/en/lang.php
new file mode 100644
index 000000000..779614d32
--- /dev/null
+++ b/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/lib/plugins/acl/lang/eo/help.txt b/lib/plugins/acl/lang/eo/help.txt
new file mode 100644
index 000000000..cc3f63e5a
--- /dev/null
+++ b/lib/plugins/acl/lang/eo/help.txt
@@ -0,0 +1,11 @@
+=== Helpeto: ===
+
+En tiu ĉi paĝo vi povas aldoni kaj forigi rajtojn por nomspacoj kaj paĝoj en via vikio.
+
+La maldekstra panelo montras ĉiujn disponeblajn nomspacojn kaj paĝojn.
+
+La suba agordilo permesas al vi rigardi kaj modifi la rajtojn de elektita uzanto aŭ grupo.
+
+En la suba tabelo ĉiuj aktuale difinitaj alirkontrolaj reguloj estas montritaj. Vi povas uzi ĝin por rapide forigi aŭ ŝanĝi multoblajn regulojn.
+
+Legado de la [[doku&gt;acl|oficiala dokumentaro pri ACL]] povus helpi vin bone kompreni kiel alirkontrolo funkcias en DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/eo/lang.php b/lib/plugins/acl/lang/eo/lang.php
new file mode 100644
index 000000000..72ce576ee
--- /dev/null
+++ b/lib/plugins/acl/lang/eo/lang.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['admin_acl'] = 'Administrado de Alirkontrola Listo (ACL)';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Uzanto';
+$lang['acl_perms'] = 'Rajtoj por';
+$lang['page'] = 'Paĝo';
+$lang['namespace'] = 'Nomspaco';
+$lang['btn_select'] = 'Elekti';
+$lang['p_user_id'] = 'Uzanto &lt;b class=&quot;acluser&quot;&gt;%s&lt;/b&gt; aktuale havas la jenajn rajtojn en la paĝo &lt;b class=&quot;aclpage&quot;&gt;%s&lt;/b&gt;: &lt;i&gt;%s&lt;/i&gt;.';
+$lang['p_user_ns'] = 'Uzanto &lt;b class=&quot;acluser&quot;&gt;%s&lt;/b&gt; aktuale havas la jenajn rajtojn en la nomspaco &lt;b class=&quot;aclns&quot;&gt;%s&lt;/b&gt;: &lt;i&gt;%s&lt;/i&gt;.';
+$lang['p_group_id'] = 'Anoj de la grupo &lt;b class=&quot;aclgroup&quot;&gt;%s&lt;/b&gt; aktuale havas la jenajn rajtojn en la paĝo &lt;b class=&quot;aclpage&quot;&gt;%s&lt;/b&gt;: &lt;i&gt;%s&lt;/i&gt;.';
+$lang['p_group_ns'] = 'Anoj de la grupo &lt;b class=&quot;aclgroup&quot;&gt;%s&lt;/b&gt; aktuale havas la jenajn rajtojn en la nomspaco &lt;b class=&quot;aclns&quot;&gt;%s&lt;/b&gt;: &lt;i&gt;%s&lt;/i&gt;.';
+$lang['p_choose_id'] = 'Bonvolu &lt;b&gt;enmeti uzanton aŭ grupon&lt;/b&gt; en la suba agordilo por rigardi aŭ redakti la aron da rajtoj por la paĝo &lt;b class=&quot;aclpage&quot;&gt;%s&lt;/b&gt;.';
+$lang['p_choose_ns'] = 'Bonvolu &lt;b&gt;enmeti uzanton aŭ grupon&lt;/b&gt; en la suba agordilo por rigardi aŭ redakti la aron da rajtoj por la nomspaco &lt;b class=&quot;aclns&quot;&gt;%s&lt;/b&gt;.';
+$lang['p_inherited'] = 'Rimarko: tiuj rajtoj ne estis rekte difinitaj, sed ili estis hereditaj el aliaj pli superaj grupoj aŭ nomspacoj.';
+$lang['p_isadmin'] = 'Rimarko: la elektita grupo aŭ uzanto ĉiam havas plenan rajtaron ĉar ĝi estas difinita kiel superuzanto.';
+$lang['p_include'] = 'Plialtaj permesoj inkluzivas malpli altajn. La permesoj por Krei, Alŝuti kaj Forigi nur aplikeblas al nomspacoj, ne al paĝoj.';
+$lang['current'] = 'Aktuala regularo ACL';
+$lang['where'] = 'Paĝo/Nomspaco';
+$lang['who'] = 'Uzanto/Grupo';
+$lang['perm'] = 'Rajtoj';
+$lang['acl_perm0'] = 'Nenio';
+$lang['acl_perm1'] = 'Legi';
+$lang['acl_perm2'] = 'Redakti';
+$lang['acl_perm4'] = 'Krei';
+$lang['acl_perm8'] = 'Alŝuti';
+$lang['acl_perm16'] = 'Forigi';
+$lang['acl_new'] = 'Aldoni novan Enmetaĵon';
+$lang['acl_mod'] = 'Modifi Enmetaĵon';
diff --git a/lib/plugins/acl/lang/es/help.txt b/lib/plugins/acl/lang/es/help.txt
new file mode 100644
index 000000000..c683477a8
--- /dev/null
+++ b/lib/plugins/acl/lang/es/help.txt
@@ -0,0 +1,11 @@
+=== Ayuda rápida: ===
+
+En esta página puede agregar o retirar permisos para los espacios de nombres y páginas en su wiki.
+
+El panel de la izquierda muiestra todos los espacios de nombres y páginas
+
+El formulario inferior permite ver y modificar los permisos del usuario o grupo elegido.
+
+En la tabla anterior se muestran todas las reglas de control de acceso vigentes Puede usarla para borrar o cambiar varias reglas rápidamente.
+
+Consultar el [[doku>acl|official documentation on ACL]] puede ayudarle a entender completamente como el control de acceso trabaja en DokuWiki.
diff --git a/lib/plugins/acl/lang/es/lang.php b/lib/plugins/acl/lang/es/lang.php
new file mode 100644
index 000000000..ee50a7530
--- /dev/null
+++ b/lib/plugins/acl/lang/es/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Spanish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Miguel Pagano <miguel.pagano@gmail.com>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['admin_acl'] = 'Administración de lista de control de acceso';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Usuario';
+$lang['acl_perms'] = 'Permiso para';
+$lang['page'] = 'Página';
+$lang['namespace'] = 'Espacio de nombres';
+$lang['btn_select'] = 'Seleccionar';
+$lang['p_user_id'] = 'El usuario <b class="acluser">%s</b> tiene los siguientes permisos sobre la página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'El usuario <b class="acluser">%s</b> tiene los siguientes permisos sobre el espacio de nombres <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Los miembros del grupo <b class="aclgroup">%s</b> tienen actualmente los siguientes permisos sobre la página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Los miembros del grupo <b class="aclgroup">%s</b> tienen actualmente los siguientes permisos sobre el espacio de nombres <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Por favor <b>proporcione un usuario o grupo</b>en el formulario arriba mostrado para ver o editar los permisos asignados sobre la página<b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Por favor <b>proporcione un usuario o grupo</b>en el formulario arriba mostrado para ver o editar los permisos asignados sobre el espacio de nombres <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: Esos permisos no fueron establecidos explícitamente sino que fueron heredados desde otros grupos o espacios de nombres superiores';
+$lang['p_isadmin'] = 'Nota: El grupo o usuario seleccionado simepre tiene permisos totales debido a que se encuentra configurado como superusuario.';
+$lang['p_include'] = 'Los permisos superiores incluyen a los inferiores. Los permisos Crear, Cargar y Eliminar sólo se aplican a los espacios de nombres, no a las páginas.';
+$lang['current'] = 'Reglas ACL vigentes';
+$lang['where'] = 'Página/Espacio de nombres';
+$lang['who'] = 'Usuario/Grupo';
+$lang['perm'] = 'Permisos';
+$lang['acl_perm0'] = 'ninguno';
+$lang['acl_perm1'] = 'Leer';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Crear';
+$lang['acl_perm8'] = 'Subir un fichero';
+$lang['acl_perm16'] = 'Borrar';
+$lang['acl_new'] = 'Agregar una nueva entrada';
+$lang['acl_mod'] = 'Modificar una entrada';
diff --git a/lib/plugins/acl/lang/et/lang.php b/lib/plugins/acl/lang/et/lang.php
new file mode 100644
index 000000000..bc4c73a16
--- /dev/null
+++ b/lib/plugins/acl/lang/et/lang.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oliver S6ro <seem.iges@mail.ee>
+ * @author Aari Juhanson <aari@vmg.vil.ee>
+ * @author Kaiko Kaur <kaiko@kultuur.edu.ee>
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
+$lang['admin_acl'] = 'Ligipääsukontrolli nimekirja haldamine';
+$lang['acl_group'] = 'Grupp';
+$lang['acl_user'] = 'Kasutaja';
+$lang['acl_perms'] = 'Lubatud';
+$lang['page'] = 'leht';
+$lang['namespace'] = 'alajaotus';
+$lang['btn_select'] = 'Vali';
+$lang['who'] = 'Kasutaja/Grupp';
+$lang['perm'] = 'Õigused';
+$lang['acl_perm0'] = 'Pole';
+$lang['acl_perm1'] = 'Lugemine';
+$lang['acl_perm2'] = 'Toimetamine';
+$lang['acl_perm4'] = 'Tekitamine';
+$lang['acl_perm8'] = 'Üles laadimine';
+$lang['acl_perm16'] = 'Kustuta';
+$lang['acl_new'] = 'Uue kirje lisamine';
+$lang['acl_mod'] = 'Muuda sissekannet';
diff --git a/lib/plugins/acl/lang/eu/help.txt b/lib/plugins/acl/lang/eu/help.txt
new file mode 100644
index 000000000..9e6070a10
--- /dev/null
+++ b/lib/plugins/acl/lang/eu/help.txt
@@ -0,0 +1,11 @@
+=== Laguntza Bizkorra: ===
+
+Orri honetan wiki-ko orri eta izen-espazioen baimenak gehitu eta kendu ahal ditzakezu.
+
+Ezkerreko panelak eskuragarri dauden orri eta izen-espazioak erakusten ditu.
+
+Goiko formularioak aukeratutako erabiltzaile edo taldearen baimenak ikusi eta aldatzea ahalbidetzen dizu.
+
+Beheko taulan une honetan ezarritako atzipen kontrol arauak daude. Hainbat arau bizkor ezabatu edo aldatzeko erabili dezakezu.
+
+[[doku>acl|Atzipen Kontrol Listen inguruko dokumentazio ofiziala]] irakurtzeak atzipen kontrolak DokuWiki-n nola funtzionatzen duen ulertzen lagundu zaitzaike.
diff --git a/lib/plugins/acl/lang/eu/lang.php b/lib/plugins/acl/lang/eu/lang.php
new file mode 100644
index 000000000..99e70ad00
--- /dev/null
+++ b/lib/plugins/acl/lang/eu/lang.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['admin_acl'] = 'Atzipen Kontrol Listaren Kudeaketa';
+$lang['acl_group'] = 'Taldea';
+$lang['acl_user'] = 'Erabiltzailea';
+$lang['acl_perms'] = 'Baimenak honetarako:';
+$lang['page'] = 'Orria';
+$lang['namespace'] = 'Izen-espazioa';
+$lang['btn_select'] = 'Aukeratu';
+$lang['p_user_id'] = '<b class="acluser">%s</b> erabiltzaileak une honetan honako baimenak ditu <b class="aclpage">%s</b> orrian: <i>%s</i>.';
+$lang['p_user_ns'] = '<b class="acluser">%s</b> erabiltzaileak une honetan honako baimenak ditu <b class="aclns">%s</b> izen-espazioan: <i>%s</i>.';
+$lang['p_group_id'] = '<b class="aclgroup">%s</b> taldeko kideek une honetan honako baimenak dituzte <b class="aclpage">%s</b> orrian: <i>%s</i>.';
+$lang['p_group_ns'] = '<b class="aclgroup">%s</b> taldeko kideek une honetan honako baimenak dituzte <b class="aclns">%s</b> izen-espazioan: <i>%s</i>.';
+$lang['p_choose_id'] = 'Mesedez <b>sartu erabiltzaile edo taldea</b> goiko formularioan <b class="aclpage">%s</b> orrian ezarritako baimenak ikusi edo aldatzeko.';
+$lang['p_choose_ns'] = 'Mesedez <b>sartu erabiltzaile edo taldea</b> goiko formularioan <b class="aclns">%s</b> izen-espazioan ezarritako baimenak ikusi edo aldatzeko.';
+$lang['p_inherited'] = 'Oharra: Baimen horiek ez dira esplizituki jarriak, beste talde batzuetatik edo goragoko izen-espazioetatik heredatuak baizik.';
+$lang['p_isadmin'] = 'Oharra: Aukeratutako talde edo erabiltzaileak beti daika baimen osoa, supererabiltzaile gisa konfiguratuta baitago.';
+$lang['p_include'] = 'Baimen handiagoek baimen txikiagoak barneratzen dituzte. Sortu, Igo eta Ezabatu baimenak izen-espazioei soilik aplikatzen zaizkie, ez orriei.';
+$lang['current'] = 'Uneko AKL Arauak';
+$lang['where'] = 'Orria/Izen-espazioa';
+$lang['who'] = 'Erabiltzailea/Taldea';
+$lang['perm'] = 'Baimenak';
+$lang['acl_perm0'] = 'Inork';
+$lang['acl_perm1'] = 'Irakurri';
+$lang['acl_perm2'] = 'Editatu';
+$lang['acl_perm4'] = 'Sortu';
+$lang['acl_perm8'] = 'Igo';
+$lang['acl_perm16'] = 'Ezabatu';
+$lang['acl_new'] = 'Sarrera berri bat gehitu';
+$lang['acl_mod'] = 'Aldatu Sarrera';
diff --git a/lib/plugins/acl/lang/fa/help.txt b/lib/plugins/acl/lang/fa/help.txt
new file mode 100644
index 000000000..1ec797faf
--- /dev/null
+++ b/lib/plugins/acl/lang/fa/help.txt
@@ -0,0 +1,11 @@
+=== راهنما: ===
+
+در این صفحه شما می‌توانید دسترسی صفحات و فضای‌نام‌ها را مدیریت کنید.
+
+در قسمت سمت راست، لیست تمام صفحات و فضای‌نام‌ها را مشاهده می‌کنید.
+
+در فرم بالا می‌توانید دسترسی‌های کاربران و گروه‌های مختلف را مشاهده و ویرایش کنید.
+
+در جدول زیر، تمامی قوانین مدیریتی را مشاهده می‌کنید. شما می‌توانید آن‌ها را حذف یا تعدادی از آن‌ها رو تغییر دهید.
+
+ممکن است خواندن [[doku>acl|مطلب رسمی در مورد مدیریت دسترسی‌ها]] شما را در درک بهتر این قسمت DokuWiki یاری کند. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/fa/lang.php b/lib/plugins/acl/lang/fa/lang.php
new file mode 100644
index 000000000..ed576c271
--- /dev/null
+++ b/lib/plugins/acl/lang/fa/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['admin_acl'] = 'مدیریت کنترل دسترسی‌ها';
+$lang['acl_group'] = 'گروه';
+$lang['acl_user'] = 'کاربر';
+$lang['acl_perms'] = 'مجوز برای';
+$lang['page'] = 'صفحه';
+$lang['namespace'] = 'فضای‌نام';
+$lang['btn_select'] = 'انتخاب';
+$lang['p_user_id'] = 'کاربر <b class="acluser">%s</b> دسترسی‌های زیر را برای صفحه‌ی <b class="aclpage">%s</b> دارد: <i>%s</i>.';
+$lang['p_user_ns'] = 'کاربر <b class="acluser">%s</b> دسترسی‌های زیر را برای فضای‌نام <b class="aclpage">%s</b> دارد: <i>%s</i>.';
+$lang['p_group_id'] = 'اعضای گروه <b class="aclgroup">%s</b> دسترسی‌های زیر را برای صفحه‌ی <b class="aclpage">%s</b> دارند: <i>%s</i>.';
+$lang['p_group_ns'] = 'اعضای گروه <b class="aclgroup">%s</b> دسترسی‌های زیر را برای فضای‌نام <b class="aclpage">%s</b> دارند: <i>%s</i>.';
+$lang['p_choose_id'] = 'خواهشمندیم <b>نام یک کاربر یا گروه</b> را در فرم بالا وارد کنید تا دسترسی‌های آن را برای صفحه‌ی <b class="aclpage">%s</b> ببینید و ویرایش کنید.';
+$lang['p_choose_ns'] = 'خواهشمندیم <b>نام یک کاربر یا گروه</b> را در فرم بالا وارد کنید تا دسترسی‌های آن را برای فضای‌نام <b class="aclpage">%s</b> ببینید و ویرایش کنید.';
+$lang['p_inherited'] = 'توجه: دسترسی‌ها مستقیمن مقداردهی نشده است، بلکه از گروه‌های بالا یا فضای‌نام گرفته شده است.';
+$lang['p_isadmin'] = 'توجه: کاربر یا گروه انتخاب شده همیشه با تمام دسترسی می‌باشد، زیرا به عنوان «superuser» انتخاب شده است.';
+$lang['p_include'] = 'دسترسی‌های بالا، دسترسی‌های پایین را شامل می‌شود. ایجاد، ارسال و حذف فقط به فضای‌نام الحاق می‌شود.';
+$lang['current'] = 'قوانین دسترسی فعلی';
+$lang['where'] = 'صفحه/فضای‌نام';
+$lang['who'] = 'کاربر/گروه';
+$lang['perm'] = 'دسترسی‌ها';
+$lang['acl_perm0'] = 'هیچ‌کدام';
+$lang['acl_perm1'] = 'خواندن';
+$lang['acl_perm2'] = 'ویزایش';
+$lang['acl_perm4'] = 'ایجاد';
+$lang['acl_perm8'] = 'ارسال';
+$lang['acl_perm16'] = 'حذف';
+$lang['acl_new'] = 'اضافه کردن ورودی جدید';
+$lang['acl_mod'] = 'ویرایش ورودی';
diff --git a/lib/plugins/acl/lang/fi/help.txt b/lib/plugins/acl/lang/fi/help.txt
new file mode 100644
index 000000000..d821f2d89
--- /dev/null
+++ b/lib/plugins/acl/lang/fi/help.txt
@@ -0,0 +1,11 @@
+=== Pika-apu: ===
+
+Tällä sivulla voit lisätä tai poistaa oikeuksia wikisi nimiavaruuksiin tai sivuihin.
+
+Vasen osa näyttää kaikki tarjolla olevat nimiavaruudet ja sivut.
+
+Yllä olevan kaavakkeen avulla voit katsoa ja muokata oikeuksia valitulle käyttäjälle ja ryhmälle.
+
+Alla olevassa taulukossa on näkyvissä päällä olevat pääsyoikeudet. Voit käyttää sitä muokataksesi tai poistaaksesi useita oikeuksia.
+
+[[doku>acl|Virallisen käyttöoikeus (ACL) dokumentaation]] lukeminen voi helpottaa sinua täysin ymmärtämään mitän käyttöoikeudet toimivat DokuWikissä.
diff --git a/lib/plugins/acl/lang/fi/lang.php b/lib/plugins/acl/lang/fi/lang.php
new file mode 100644
index 000000000..4f145e0f6
--- /dev/null
+++ b/lib/plugins/acl/lang/fi/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['admin_acl'] = 'Käyttöoikeudet (ACL)';
+$lang['acl_group'] = 'Ryhmä';
+$lang['acl_user'] = 'Käyttäjä';
+$lang['acl_perms'] = 'Oikeudet';
+$lang['page'] = 'Sivu';
+$lang['namespace'] = 'Nimiavaruus';
+$lang['btn_select'] = 'Valitse';
+$lang['p_user_id'] = 'Käyttäjällä <b class="acluser">%s</b> on tällä hetkellä seuraavat oikeudet sivulla <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Käyttäjällä <b class="acluser">%s</b> on tällä hetkellä seuraavat oikeudet nimiavaruudessa <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Ryhmän <b class="aclgroup">%s</b> jäsenillä on tällä hetkellä seuraavat oikeudet sivulla <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Ryhmän <b class="aclgroup">%s</b> jäsenillä on tällä hetkellä seuraavat oikeudet nimiavaruudessa <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Ole hyvä ja <b>syötä ryhmän nimi</b> yllä olevaan kaavakkeeseen katsoaksesi tai muokataksesi oikeuksia sivulle <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Ole hyvä ja <b>syötä ryhmän nimi</b> yllä olevaan kaavakkeeseen katsoaksesi tai muokataksesi oikeuksia nimiavaruuteen <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Huomaa: Oikeuksia ei ole erikseen asetettu, vaan ne on peritty toiselta ryhmältä tai ylemmältä nimiavaruudelta.';
+$lang['p_isadmin'] = 'Huomaa: Valitulla ryhmällä tai käyttäjällä on aina täydet oikeudet, koska se on määritelty pääkäyttäjäksi (Superuser)';
+$lang['p_include'] = 'Korkeammat oikeudet sisältävät matalammat. Luonti-, Lähetys- ja Poisto-oikeudet vaikuttavat vain nimiavaruuksiin, ei sivuihin.';
+$lang['current'] = 'Tämänhetkiset käyttöoikeudet (ACL)';
+$lang['where'] = 'Sivu/Nimiavaruus';
+$lang['who'] = 'Käyttäjä/Ryhmä';
+$lang['perm'] = 'Oikeudet';
+$lang['acl_perm0'] = 'Ei mitään';
+$lang['acl_perm1'] = 'Luku';
+$lang['acl_perm2'] = 'Muokkaus';
+$lang['acl_perm4'] = 'Luonti';
+$lang['acl_perm8'] = 'Lähetys';
+$lang['acl_perm16'] = 'Poisto';
+$lang['acl_new'] = 'Lisää uusi';
+$lang['acl_mod'] = 'Muokkaa';
diff --git a/lib/plugins/acl/lang/fr/help.txt b/lib/plugins/acl/lang/fr/help.txt
new file mode 100644
index 000000000..158ec92ed
--- /dev/null
+++ b/lib/plugins/acl/lang/fr/help.txt
@@ -0,0 +1,9 @@
+=== Aide rapide ===
+
+Cette page vous permet d'ajouter ou de supprimer des permissions pour les catégories et les pages de votre wiki. Le panneau de gauche liste toutes les catégories et les pages disponibles.
+
+Le formulaire ci-dessus permet d'afficher et de modifier les permissions d'un utilisateur ou d'un groupe sélectionné.
+
+Dans le tableau ci-dessous, toutes les listes de contrôle d'accès actuelles sont affichées. Vous pouvez l'utiliser pour supprimer ou modifier rapidement plusieurs ACL.
+
+La lecture de [[doku>fr:acl|la documentation officielle des ACL]] pourra vous permettre de bien comprendre le fonctionnement du contrôle d'accès dans DokuWiki.
diff --git a/lib/plugins/acl/lang/fr/lang.php b/lib/plugins/acl/lang/fr/lang.php
new file mode 100644
index 000000000..a33a52bf0
--- /dev/null
+++ b/lib/plugins/acl/lang/fr/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * french language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Sébastien Bauer <sebastien.bauer@advalvas.be>
+ * @author Antoine Fixary <antoine.fixary@freesbee.fr>
+ * @author cumulus <pta-n56@myamail.com>
+ * @author Gwenn Gueguen <contact@demisel.net>
+ * @author Guy Brand <gb@unistra.fr>
+ * @author Fabien Chabreuil <fabien@integralpersonality.com>
+ * @author Stéphane Chamberland <stephane.chamberland@ec.gc.ca>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['admin_acl'] = 'Gestion de la liste des contrôles d\'accès (ACL)';
+$lang['acl_group'] = 'Groupe';
+$lang['acl_user'] = 'Utilisateur';
+$lang['acl_perms'] = 'Permission pour';
+$lang['page'] = 'Page';
+$lang['namespace'] = 'Catégorie';
+$lang['btn_select'] = 'Sélectionner';
+$lang['p_user_id'] = 'Permissions actuelles de l\'utilisateur <strong class="acluser">%s</strong> sur la page <strong class="aclpage">%s</strong>: <em>%s</em>.';
+$lang['p_user_ns'] = 'Permissions actuelles de l\'utilisateur <strong class="acluser">%s</strong> sur la catégorie <strong class="aclns">%s</strong>: <em>%s</em>.';
+$lang['p_group_id'] = 'Permissions actuelles des membres du groupe <strong class="aclgroup">%s</strong> sur la page <strong class="aclpage">%s</strong>: <em>%s</em>.';
+$lang['p_group_ns'] = 'Permissions actuelles des membres du groupe <strong class="aclgroup">%s</strong> sur la catégorie <strong class="aclns">%s</strong>: <em>%s</em>.';
+$lang['p_choose_id'] = 'Saisissez un nom <strong>d\'utilisateur ou de groupe</strong> dans le formulaire ci-dessus pour afficher ou éditer les permissions relatives à la page <strong class="aclpage">%s</strong>.';
+$lang['p_choose_ns'] = 'Saisissez un nom <strong>d\'utilisateur ou de groupe</strong> dans le formulaire ci-dessous pour afficher ou éditer les permissions relatives à la catégorie <strong class="aclns">%s</strong>.';
+$lang['p_inherited'] = 'Note : Ces permissions n\'ont pas été explicitement fixées mais sont héritées d\'autres groupes ou catégories supérieures.';
+$lang['p_isadmin'] = 'Note : Le groupe ou l\'utilisateur sélectionné dispose de toutes les permissions car il est paramétré en tant que superutilisateur.';
+$lang['p_include'] = 'Les permissions les plus élevées induisent les plus faibles. Création, Télécharger et Effacer ne s\'appliquent qu\'aux catégories, pas aux pages.';
+$lang['current'] = 'ACL actuelles';
+$lang['where'] = 'Page/Catégorie';
+$lang['who'] = 'Utilisateur/Groupe';
+$lang['perm'] = 'Permissions';
+$lang['acl_perm0'] = 'Aucune';
+$lang['acl_perm1'] = 'Lecture';
+$lang['acl_perm2'] = 'Écriture';
+$lang['acl_perm4'] = 'Création';
+$lang['acl_perm8'] = 'Téléverser';
+$lang['acl_perm16'] = 'Effacer';
+$lang['acl_new'] = 'Ajouter une nouvelle entrée';
+$lang['acl_mod'] = 'Modifier l\'entrée';
diff --git a/lib/plugins/acl/lang/gl/help.txt b/lib/plugins/acl/lang/gl/help.txt
new file mode 100644
index 000000000..593dcef07
--- /dev/null
+++ b/lib/plugins/acl/lang/gl/help.txt
@@ -0,0 +1,11 @@
+=== Axuda Rápida: ===
+
+Nesta páxina podes engadir e eliminar permisos para os nomes de espazo e as páxinas do teu wiki.
+
+O panel da esquerda amosa todos os nomes de espazo e páxinas dispoñíbeis.
+
+O formulario de enriba permíteche ver e modificares os permisos do usuario ou grupo seleccionado.
+
+Na táboa de embaixo amósanse todas as regras de control de accesos estabelecidas. Podes empregala para mudares ou eliminares varias regras dun xeito rápido.
+
+A lectura da [[doku>acl|documentación oficial da ACL]] pode servirche de axuda para comprenderes como funciona o control de accesos no Dokuwiki.
diff --git a/lib/plugins/acl/lang/gl/lang.php b/lib/plugins/acl/lang/gl/lang.php
new file mode 100644
index 000000000..db57598e6
--- /dev/null
+++ b/lib/plugins/acl/lang/gl/lang.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['admin_acl'] = 'Xestión da Lista de Control de Acceso (ACL)';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Usuario';
+$lang['acl_perms'] = 'Permisos para';
+$lang['page'] = 'Páxina';
+$lang['namespace'] = 'Nome de espazo';
+$lang['btn_select'] = 'Escolle';
+$lang['p_user_id'] = 'O usuario <b class="acluser">%s</b> dispón actualmente dos seguintes permisos na páxina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'O usuario <b class="acluser">%s</b> dispón actualmente dos seguintes permisos no nome de espazo <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Os membros do grupo <b class="aclgroup">%s</b> dispoñen actualmente dos seguintes permisos na páxina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Os membros do grupo <b class="aclgroup">%s</b> cdispoñen actualmente dos seguintes permisos no nome de espazo <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Por favor, <b>insire un usuario ou grupo</b> no formulario de enriba para ver ou editar os permisos establecidos para a páxina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Por favor <b>insire un usuario ou grupo</b> no formulario de enriba para ver ou editar os permisos establecidos no nome de espazo <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: Estes permisos non foron establecidos explicitamente senón que foron herdadas de outros grupos ou nomes de espazo meirandes.';
+$lang['p_isadmin'] = 'Nota: O grupo ou usuario seleccionado terá sempre permisos completos por estar configurado como super-usuario.';
+$lang['p_include'] = 'Os permisos meirandes inclúen os menores. Os permisos de Creación, Subida e Eliminado só se aplican aos nomes de espazo, non ás páxinas.';
+$lang['current'] = 'Regras ACL Actuais';
+$lang['where'] = 'Páxina/Nome de Espazo';
+$lang['who'] = 'Usuario/Grupo';
+$lang['perm'] = 'Permisos';
+$lang['acl_perm0'] = 'Ningún';
+$lang['acl_perm1'] = 'Ler';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Crear';
+$lang['acl_perm8'] = 'Subir arquivos';
+$lang['acl_perm16'] = 'Eliminar';
+$lang['acl_new'] = 'Engadir nova Entrada';
+$lang['acl_mod'] = 'Modificar Entrada';
diff --git a/lib/plugins/acl/lang/he/help.txt b/lib/plugins/acl/lang/he/help.txt
new file mode 100644
index 000000000..33f2933b9
--- /dev/null
+++ b/lib/plugins/acl/lang/he/help.txt
@@ -0,0 +1,11 @@
+=== עזרה חפוזה: ===
+
+בדף זה ניתן להוסיף ולהסיר הרשאות למרחבי שמות ולדפים בויקי שלך.
+
+הצד השמאלי מציג את כל מרבי השמות והדפים הזמינים.
+
+הטופס מעלה מאפשר לך לראות ולשנות את ההרשאות של משתמש או קבוצה נבחרים.
+
+בטבלה מטה מוצגים כל כללי בקרת הגישה הנוכחיים. ניתן להשתמש בה כדי למחוק או לשנות מספר כללים במהירות.
+
+קריאת [[doku>acl|התיעוד הרשמי ל-ACL ACL]] יכולה לעזור לך להבין באופן מלא כיצד בקרת הגישה עובדת בדוקוויקי.
diff --git a/lib/plugins/acl/lang/he/lang.php b/lib/plugins/acl/lang/he/lang.php
new file mode 100644
index 000000000..91025f4b8
--- /dev/null
+++ b/lib/plugins/acl/lang/he/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * hebrew language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author DoK <kamberd@yahoo.com>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['admin_acl'] = 'ניהול רשימת בקרת גישות';
+$lang['acl_group'] = 'קבוצה';
+$lang['acl_user'] = 'משתמש';
+$lang['acl_perms'] = 'הרשאות עבור';
+$lang['page'] = 'דף';
+$lang['namespace'] = 'מרחב שמות';
+$lang['p_user_id'] = 'למשתמש <b class="acluser">%s</b> יש כרגע את ההרשאות הבאות בדף <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'למשתמש <b class="acluser">%s</b> יש כרגע את ההרשאות הבאות במרחב השם <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'לחברי קבוצת <b class="aclgroup">%s</b> יש כרגע את ההרשאות הבאות בדף <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'לחברי קבוצת <b class="aclgroup">%s</b> יש כרגע את ההרשאות הבאות במרחב השם <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'נא <b>להזין משתמש או קבוצה</b> בטופס מעלה כדי לצפות או לערוך את ההרשאות המוגדרות עבור הדף <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'נא <b>להזין משתמש או קבוצה</b> בטופס מעלה כדי לצפות או לערוך את ההרשאות המוגדרות עבור מרחב השם <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'לתשומת לבך: הרשאות אלו לא הוגדרו באופן מפורש אלא נורשו מקבוצות אחרות או ממרחב שמות גבוה יותר.';
+$lang['p_isadmin'] = 'לתשומת לבך: לקבוצה או המשתמש שנבחרו יש תמיד הרשאות מלאות בגלל הגדרתם כמשתמש-על.';
+$lang['current'] = 'חוקי ה-ACL הנוכחיים';
+$lang['where'] = 'דף/מרחב שם';
+$lang['who'] = 'משתמש/קבוצה';
+$lang['perm'] = 'הרשאות';
+$lang['acl_perm0'] = 'ללא';
+$lang['acl_perm1'] = 'קריאה';
+$lang['acl_perm2'] = 'עריכה';
+$lang['acl_perm4'] = 'יצירה';
+$lang['acl_perm8'] = 'העלאה';
+$lang['acl_perm16'] = 'מחיקה';
+$lang['acl_new'] = 'הוספת רשומה חדשה';
+$lang['acl_mod'] = 'שינויי מובאה';
diff --git a/lib/plugins/acl/lang/hi/lang.php b/lib/plugins/acl/lang/hi/lang.php
new file mode 100644
index 000000000..d6f78ffd6
--- /dev/null
+++ b/lib/plugins/acl/lang/hi/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
diff --git a/lib/plugins/acl/lang/hr/help.txt b/lib/plugins/acl/lang/hr/help.txt
new file mode 100644
index 000000000..4e7cfc3c2
--- /dev/null
+++ b/lib/plugins/acl/lang/hr/help.txt
@@ -0,0 +1,11 @@
+=== Brza Pomoć: ===
+
+Na ovoj stranici možeš dodavati i brisati dozvole za imenske prostore i stranice u svom wiki-u.
+
+Lijevi prozor prikazuje sve dostupne imenske prostore i stranice.
+
+Forma iznad ti omogućuje pregled i mijenjanje dozvola odabranom korisniku ili grupi.
+
+U tablici ispod prikazana su sva trenutno postavljena pravila kontrole pristupa. Koristite je za višestruko brisanje ili mijenjanje pravila.
+
+Čitanje [[doku>acl|službena dokumentacija o ACL]] može vam pomoći potpuno razumijeti kako kontrola pristupa radi u DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/hr/lang.php b/lib/plugins/acl/lang/hr/lang.php
new file mode 100644
index 000000000..8c21f1b0b
--- /dev/null
+++ b/lib/plugins/acl/lang/hr/lang.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
+$lang['admin_acl'] = 'Upravljanje listom kontrole pristupa';
+$lang['acl_group'] = 'Grupa';
+$lang['acl_user'] = 'Korisnik';
+$lang['acl_perms'] = 'Dozvole za';
+$lang['page'] = 'Stranica';
+$lang['namespace'] = 'Imenski prostor';
+$lang['btn_select'] = 'Odaberi';
+$lang['p_user_id'] = 'Korisnik <b class="acluser">%s</b> trenutno ima sljedeće dozvole na stranici <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Korisnik <b class="acluser">%s</b> trenutno ima sljedeće dozvole u imenskom prostoru <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Članovi grupe <b class="aclgroup">%s</b> trenutno imaju sljedeće dozvole na stranici <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Članovi grupe <b class="aclgroup">%s</b> trenutno imaju sljedeće dozvole u imenskom prostoru <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Molim <b>unesti korisnika ili grupu</b> u gornju formu za pregled ili uređivanje dozvola postavljenih za stranicu <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Molim <b>unesti korisnika ili grupu</b> u gornju formu za pregled ili uređivanje dozvola postavljenih za imenski prostor <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Napomena: Ove dozvole nisu postavljene eksplicitno već su naslijeđene od drugih grupa ili nadređenih imenskih prostora.';
+$lang['p_isadmin'] = 'Napomena: Odabrana grupa ili korisnik uvijek ima sve dozvole jer je postavljen kao superuser.';
+$lang['p_include'] = 'Više dozvole uključuju sve niže. Dozvole Kreiraj, Učitaj i Briši se primjenjuju samo na imenske prostore, ne stranice.';
+$lang['current'] = 'Trenutna ACL Pravila';
+$lang['where'] = 'Stranica/Imenski prostor';
+$lang['who'] = 'Korisnik/Grupa';
+$lang['perm'] = 'Dozvole';
+$lang['acl_perm0'] = 'Ništa';
+$lang['acl_perm1'] = 'Čitaj';
+$lang['acl_perm2'] = 'Uredi';
+$lang['acl_perm4'] = 'Kreiraj';
+$lang['acl_perm8'] = 'Učitaj';
+$lang['acl_perm16'] = 'Briši';
+$lang['acl_new'] = 'Dodaj novi Zapis';
+$lang['acl_mod'] = 'Promijeni Zapis';
diff --git a/lib/plugins/acl/lang/hu/help.txt b/lib/plugins/acl/lang/hu/help.txt
new file mode 100644
index 000000000..57f16a39c
--- /dev/null
+++ b/lib/plugins/acl/lang/hu/help.txt
@@ -0,0 +1,12 @@
+=== Hozzáférési lista (ACL) kezelő ===
+
+Ezen az oldalon jogokat oszthat és vehet el a wiki oldalakhoz és névterekhez.
+
+A bal oldalon látható az összes névtér és oldal.
+
+A felső form segít a kiválasztott felhasználó vagy csoport jogosultságainak megtekintésében vagy változtatásában.
+
+Az alsó táblázat mutatja az összes jelenleg érvényes hozzáférési szabályt. Ennek segítségével gyorsan törölhetők vagy megváltoztathatók a szabályok.
+
+A [[doku>acl|hivatalos ACL dokumentáció]] segíthet a DokuWiki hozzáférés-kezelés működésének megértésében.
+
diff --git a/lib/plugins/acl/lang/hu/lang.php b/lib/plugins/acl/lang/hu/lang.php
new file mode 100644
index 000000000..255d838b6
--- /dev/null
+++ b/lib/plugins/acl/lang/hu/lang.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['admin_acl'] = 'Hozzáférési lista (ACL) kezelő';
+$lang['acl_group'] = 'Csoport:';
+$lang['acl_user'] = 'Felhasználó:';
+$lang['acl_perms'] = 'Jogosultság ehhez:';
+$lang['page'] = 'oldal';
+$lang['namespace'] = 'névtér';
+$lang['btn_select'] = 'Kiválaszt';
+$lang['p_user_id'] = 'A(z) <b class="acluser">%s</b> felhasználónak jelenleg a következő jogosultsága van ezen az oldalon: <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'A(z) <b class="acluser">%s</b> felhasználónak jelenleg a következő jogosultsága van ebben a névtérben: <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'A(z) <b class="aclgroup">%s</b> csoport tagjainak jelenleg a következő jogosultsága van ezen az oldalon: <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'A(z) <b class="aclgroup">%s</b> csoport tagjainak jelenleg a következő jogosultsága van ebben a névtérben: <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'A felső formon <b>adjon meg egy felhasználót vagy csoportot</b>, akinek a(z) <b class="aclpage">%s</b> oldalhoz beállított jogosultságait megtekinteni vagy változtatni szeretné.';
+$lang['p_choose_ns'] = 'A felső formon <b>adjon meg egy felhasználót vagy csoportot</b>, akinek a(z) <b class="aclns">%s</b> névtérhez beállított jogosultságait megtekinteni vagy változtatni szeretné.';
+$lang['p_inherited'] = 'Megjegyzés: ezek a jogok nem itt lettek explicit beállítva, hanem öröklődtek egyéb csoportokból vagy felsőbb névterekből.';
+$lang['p_isadmin'] = 'Megjegyzés: a kiválasztott csoportnak vagy felhasználónak mindig teljes jogosultsága lesz, mert Wiki-gazdának van beállítva.';
+$lang['p_include'] = 'A magasabb jogok tartalmazzák az alacsonyabbakat. A Létrehozás, Feltöltés és Törlés jogosultságok csak névterekre alkalmazhatók, az egyes oldalakra nem.';
+$lang['current'] = 'Jelenlegi hozzáférési szabályok';
+$lang['where'] = 'Oldal/névtér';
+$lang['who'] = 'Felhasználó/Csoport';
+$lang['perm'] = 'Jogosultságok';
+$lang['acl_perm0'] = 'Semmi';
+$lang['acl_perm1'] = 'Olvasás';
+$lang['acl_perm2'] = 'Szerkesztés';
+$lang['acl_perm4'] = 'Létrehozás';
+$lang['acl_perm8'] = 'Feltöltés';
+$lang['acl_perm16'] = 'Törlés';
+$lang['acl_new'] = 'Új bejegyzés hozzáadása';
+$lang['acl_mod'] = 'Bejegyzés módosítása';
diff --git a/lib/plugins/acl/lang/ia/help.txt b/lib/plugins/acl/lang/ia/help.txt
new file mode 100644
index 000000000..59f5764eb
--- /dev/null
+++ b/lib/plugins/acl/lang/ia/help.txt
@@ -0,0 +1,11 @@
+=== Adjuta rapide: ===
+
+In iste pagina tu pote adder e remover permissiones pro spatios de nomines e paginas in tu wiki.
+
+Le columna sinistre presenta tote le spatios de nomines e paginas disponibile.
+
+Le formulario hic supra permitte vider e modificar le permissiones de un usator o gruppo seligite.
+
+In le tabella hic infra se monstra tote le regulas de controlo de accesso actualmente configurate. Tu pote usar lo pro rapidemente deler o modificar plure regulas.
+
+Es recommendate leger le [[doku>acl|documentation official super ACL]] pro comprender completemente como le controlo de accesso functiona in DokuWiki.
diff --git a/lib/plugins/acl/lang/ia/lang.php b/lib/plugins/acl/lang/ia/lang.php
new file mode 100644
index 000000000..f7d076539
--- /dev/null
+++ b/lib/plugins/acl/lang/ia/lang.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['admin_acl'] = 'Gestion de listas de controlo de accesso';
+$lang['acl_group'] = 'Gruppo';
+$lang['acl_user'] = 'Usator';
+$lang['acl_perms'] = 'Permissiones pro';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Spatio de nomines';
+$lang['btn_select'] = 'Seliger';
+$lang['p_user_id'] = 'Le usator <b class="acluser">%s</b> ha actualmente le sequente permissiones in le pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Le usator <b class="acluser">%s</b> ha actualmente le sequente permissiones in le spatio de nomines <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Le membros del gruppo <b class="aclgroup">%s</b> a actualmente le sequente permissiones in le pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Le membros del gruppo <b class="aclgroup">%s</b> ha actualmente le sequente permissiones in le spatio de nomines <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Per favor <b>entra un usator o gruppo</b> in le formulario hic supra pro vider o modificar le permissiones configurate pro le pagina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Per favor <b>entra un usator o gruppo</b> in le formulario hic supra pro vider o modificar le permissiones configurate pro le spatio de nomines <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota ben: Iste permissiones non ha essite configurate explicitemente ma ha essite hereditate de altere gruppos o de spatios de nomines superior.';
+$lang['p_isadmin'] = 'Nota ben: Le gruppo o usator seligite ha sempre permissiones integral proque es configurate como superusator.';
+$lang['p_include'] = 'Le permissiones superior include les inferior. Le permissiones de Crear, Incargar e Deler es solmente applicabile a spatios de nomines, non a paginas.';
+$lang['current'] = 'Regulas ACL actual';
+$lang['where'] = 'Pagina/Spatio de nomines';
+$lang['who'] = 'Usator/Gruppo';
+$lang['perm'] = 'Permissiones';
+$lang['acl_perm0'] = 'Nulle';
+$lang['acl_perm1'] = 'Leger';
+$lang['acl_perm2'] = 'Modificar';
+$lang['acl_perm4'] = 'Crear';
+$lang['acl_perm8'] = 'Incargar';
+$lang['acl_perm16'] = 'Deler';
+$lang['acl_new'] = 'Adder nove entrata';
+$lang['acl_mod'] = 'Modificar entrata';
diff --git a/lib/plugins/acl/lang/id-ni/lang.php b/lib/plugins/acl/lang/id-ni/lang.php
new file mode 100644
index 000000000..d367340b7
--- /dev/null
+++ b/lib/plugins/acl/lang/id-ni/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/acl/lang/id/lang.php b/lib/plugins/acl/lang/id/lang.php
new file mode 100644
index 000000000..650637635
--- /dev/null
+++ b/lib/plugins/acl/lang/id/lang.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author mubaidillah <mubaidillah@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['admin_acl'] = 'Manajemen Daftar Pengendali Akses';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'User';
+$lang['acl_perms'] = 'Ijin untuk';
+$lang['page'] = 'Halaman';
+$lang['namespace'] = 'Namespace';
+$lang['btn_select'] = 'Pilih';
+$lang['acl_perm1'] = 'Baca';
+$lang['acl_perm2'] = 'Ubah';
+$lang['acl_perm4'] = 'Buat';
+$lang['acl_perm8'] = 'Upload';
+$lang['acl_perm16'] = 'Hapus';
+$lang['acl_new'] = 'Tambah Entry baru';
diff --git a/lib/plugins/acl/lang/is/lang.php b/lib/plugins/acl/lang/is/lang.php
new file mode 100644
index 000000000..b45faa80a
--- /dev/null
+++ b/lib/plugins/acl/lang/is/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['acl_group'] = 'Hópur';
+$lang['acl_user'] = 'Notandi';
+$lang['page'] = 'Síða';
+$lang['namespace'] = 'Nafnrými';
+$lang['btn_select'] = 'Veldu';
+$lang['where'] = 'Síða/Nafnrými';
+$lang['acl_perm16'] = 'Eyða';
diff --git a/lib/plugins/acl/lang/it/help.txt b/lib/plugins/acl/lang/it/help.txt
new file mode 100644
index 000000000..8bf68e8e7
--- /dev/null
+++ b/lib/plugins/acl/lang/it/help.txt
@@ -0,0 +1,11 @@
+=== Breve Aiuto: ===
+
+In questa pagina puoi aggiungere e rimuovere permessi per categorie e pagine del tuo wiki.
+
+Il pannello di sinistra mostra tutte le categorie e le pagine disponibili.
+
+Il campo sopra ti permette di vedere e modificare i permessi di un utente o gruppo selezionato.
+
+Nella tabella sotto, sono riportate tutte le regole di controllo degli accessi attualmente impostate. Puoi utilizzarla per eliminare o cambiare al volo varie regole.
+
+Leggere la [[doku>acl|documentazione ufficale delle ACL]] può aiutarti a capire pienamente come funziona il controllo degli accessi in DokuWiki.
diff --git a/lib/plugins/acl/lang/it/lang.php b/lib/plugins/acl/lang/it/lang.php
new file mode 100644
index 000000000..f789b979f
--- /dev/null
+++ b/lib/plugins/acl/lang/it/lang.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Giorgio Vecchiocattivi <giorgio@vecchio.it>
+ * @author Roberto Bolli <http://www.rbnet.it/>
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['admin_acl'] = 'Gestione Lista Controllo Accessi (ACL)';
+$lang['acl_group'] = 'Gruppo';
+$lang['acl_user'] = 'Utente';
+$lang['acl_perms'] = 'Permessi per';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Categoria';
+$lang['btn_select'] = 'Seleziona';
+$lang['p_user_id'] = 'L\'utente <b class="acluser">%s</b> attualmente ha i seguenti permessi sulla pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'L\'utente <b class="acluser">%s</b> attualmente ha i seguenti permessi per la categoria <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'I membri del gruppo<b class="aclgroup">%s</b> attualmente hanno i seguenti permessi sulla pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'I membri del gruppo<b class="aclgroup">%s</b> attualmente hanno i seguenti permessi per la categoria <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Inserisci un utente o gruppo</b> nel campo sopra per modificare i permessi impostati per la pagina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = '<b>Inserisci un utente o un gruppo</b> nel campo sopra per modificare i permessi impostati per la categoria <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Nota: questi permessi non sono stati esplicitamente impostati, ma sono stati ereditati da altri gruppi o da categorie superiori.';
+$lang['p_isadmin'] = 'Nota: il gruppo o utente selezionato ha sempre tutti i permessi perché è configurato come amministratore.';
+$lang['p_include'] = 'I permessi più elevati includono i permessi inferiori. I permessi Crea, Carica ed Elimina si applicano soltanto alle categorie e non alle pagine.';
+$lang['current'] = 'Regole ACL attuali';
+$lang['where'] = 'Pagina/Categoria';
+$lang['who'] = 'Utente/Gruppo';
+$lang['perm'] = 'Permessi';
+$lang['acl_perm0'] = 'Nessuno';
+$lang['acl_perm1'] = 'Lettura';
+$lang['acl_perm2'] = 'Modifica';
+$lang['acl_perm4'] = 'Crea';
+$lang['acl_perm8'] = 'Carica';
+$lang['acl_perm16'] = 'Elimina';
+$lang['acl_new'] = 'Aggiungi nuovo valore';
+$lang['acl_mod'] = 'Modifica valore';
diff --git a/lib/plugins/acl/lang/ja/help.txt b/lib/plugins/acl/lang/ja/help.txt
new file mode 100644
index 000000000..f7867f8e2
--- /dev/null
+++ b/lib/plugins/acl/lang/ja/help.txt
@@ -0,0 +1,11 @@
+=== クイックヘルプ: ===
+
+このページでは、Wiki内の名前空間とページに対する権限を追加・削除することができます。
+
+左側のボックスには存在する名前空間とページが表示されています。
+
+上記のフォームを使って、選択したユーザーもしくはグループの権限を閲覧・変更することができます。
+
+以下のテープルには、現在設定されているアクセスコントロールのルールが表示されています。このテーブルを使って、複数のルールを素早く変更・削除することが可能です。
+
+DokuWikiのアクセスコントロールについては、[[doku>acl|official documentation on ACL]] をお読み下さい。 \ No newline at end of file
diff --git a/lib/plugins/acl/lang/ja/lang.php b/lib/plugins/acl/lang/ja/lang.php
new file mode 100644
index 000000000..831fd2d5c
--- /dev/null
+++ b/lib/plugins/acl/lang/ja/lang.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * japanese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Davilin(Yuji Takenaka) <webmaster@davilin.com>
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['admin_acl'] = 'アクセスコントロール管理';
+$lang['acl_group'] = 'グループ';
+$lang['acl_user'] = 'ユーザー';
+$lang['acl_perms'] = '権限を追加';
+$lang['page'] = '文書';
+$lang['namespace'] = '名前空間';
+$lang['btn_select'] = '選択';
+$lang['p_user_id'] = 'ユーザー <b class="acluser">%s</b> は、ページ <b class="aclpage">%s</b> に対して次の権限を持っています: <i>%s</i>';
+$lang['p_user_ns'] = 'ユーザー <b class="acluser">%s</b> は、名前空間 <b class="aclns">%s</b> に対して次の権限を持っています: <i>%s</i>';
+$lang['p_group_id'] = 'グループ <b class="aclgroup">%s</b> のメンバーは、ページ <b class="aclpage">%s</b> に対して次の権限を持っています: <i>%s</i>';
+$lang['p_group_ns'] = 'グループ <b class="aclgroup">%s</b> のメンバーは、名前空間 <b class="aclns">%s</b> に対して次の権限を持っています: <i>%s</i>';
+$lang['p_choose_id'] = 'ページ <b class="aclpage">%s</b> にセットされた権限を閲覧・編集するためには、上記のフォームに<b>ユーザー名もしくはグループ名を入力して下さい</b>。';
+$lang['p_choose_ns'] = '名前空間 <b class="aclns">%s</b> にセットされた権限を閲覧・編集するためには、上記のフォームに<b>ユーザー名もしくはグループ名を入力して下さい</b>。';
+$lang['p_inherited'] = '注意:これらの権限は明示されていませんが、他のグループもしくは上位の名前空間の権限を継承します。';
+$lang['p_isadmin'] = '注意:選択したグループもしくはユーザーはスーパーユーザーであるため、全ての権限があります。';
+$lang['p_include'] = '高次の権限は、それより低次の権限を含みます。作成・アップロード・削除の権限は、ページではなく名前空間のみに適用されます。';
+$lang['current'] = '現在のACLルール';
+$lang['where'] = 'ページ/名前空間';
+$lang['who'] = 'ユーザー/グループ';
+$lang['perm'] = '権限';
+$lang['acl_perm0'] = '無し';
+$lang['acl_perm1'] = '読取';
+$lang['acl_perm2'] = '編集';
+$lang['acl_perm4'] = '作成';
+$lang['acl_perm8'] = 'アップロード';
+$lang['acl_perm16'] = '削除';
+$lang['acl_new'] = '新規エントリ';
+$lang['acl_mod'] = 'エントリの編集';
diff --git a/lib/plugins/acl/lang/kk/lang.php b/lib/plugins/acl/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/acl/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/acl/lang/ko/help.txt b/lib/plugins/acl/lang/ko/help.txt
new file mode 100644
index 000000000..516198ee5
--- /dev/null
+++ b/lib/plugins/acl/lang/ko/help.txt
@@ -0,0 +1,11 @@
+=== 도움말: ===
+
+현재 페이지에서 위키 네임스페이스와 페이지에 대한 접근 권한을 추가하거나 삭제할 수 있습니다.
+
+왼쪽 영역을 선택가능한 네임스페이스들과 페이지 목록을 보여줍니다.
+
+위쪽 입력 양식에서 선택된 사용자와 그룹의 접근 권한을 보거나 변경할 수 있습니다.
+
+아래 테이블에서 현재 설정된 모든 접근 제어 규칙들을 볼 수 있으며, 즉시 여러 규칙들을 삭제하거나 변경할 수 있습니다.
+
+DokuWiki에서 접근 제어가 어떻게 동작되는지 알려면 [[doku>acl|official documentation on ACL]] 읽기 바랍니다. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/ko/lang.php b/lib/plugins/acl/lang/ko/lang.php
new file mode 100644
index 000000000..6f4e991cb
--- /dev/null
+++ b/lib/plugins/acl/lang/ko/lang.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * korean 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 jk Lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['admin_acl'] = '접근 제어 목록 관리';
+$lang['acl_group'] = '그룹';
+$lang['acl_user'] = '사용자';
+$lang['acl_perms'] = '권한';
+$lang['page'] = '페이지';
+$lang['namespace'] = '네임스페이스';
+$lang['btn_select'] = '선택';
+$lang['p_user_id'] = '사용자 <b class="acluser">%s</b>는 현재 <b class="aclpage">%s</b>: <i>%s</i> 페이지 접근이 가능합니다.';
+$lang['p_user_ns'] = '사용자 <b class="acluser">%s</b>는 현재 <b class="aclns">%s</b>: <i>%s</i> 네임스페이스 접근이 가능합니다.';
+$lang['p_group_id'] = '그룹 <b class="aclgroup">%s</b> 사용자는 현재 <b class="aclpage">%s</b>: <i>%s</i> 페이지 접근이 가능합니다.';
+$lang['p_group_ns'] = '그룹 <b class="aclgroup">%s</b> 사용자는 현재 <b class="aclns">%s</b>: <i>%s</i> 네임스페이스 접근이 가능합니다.';
+$lang['p_choose_id'] = '<b class="aclpage">%s</b> 페이지 접근 권한을 보거나 변경하려면 <b>사용자</b>나 <b>그룹</b>을 위 양식에 입력하기 바랍니다.';
+$lang['p_choose_ns'] = '<b class="aclns">%s</b> 네임스페이스 접근 권한을 보거나 변경하려면 <b>사용자</b>나 <b>그룹</b>을 위 양식에 입력하기 바랍니다.';
+$lang['p_inherited'] = '주의: 권한이 명시적으로 설정되지 않았으므로 다른 그룹들이나 상위 네임스페이스로 부터 가져왔습니다.';
+$lang['p_isadmin'] = '주의: 슈퍼유저로 설정되어 있으므로 선택된 그룹이나 사용자는 언제나 모든 접근 권한을 가집니다.';
+$lang['p_include'] = '더 높은 접근권한은 하위를 포함합니다. 페이지가 아닌 네임스페이스에는 생성, 업로드, 삭제 권한만 적용됩니다.';
+$lang['current'] = '현 ACL 규칙';
+$lang['where'] = '페이지/네임스페이스';
+$lang['who'] = '사용자/그룹';
+$lang['perm'] = '접근 권한';
+$lang['acl_perm0'] = '없음';
+$lang['acl_perm1'] = '읽기';
+$lang['acl_perm2'] = '수정';
+$lang['acl_perm4'] = '생성';
+$lang['acl_perm8'] = '업로드';
+$lang['acl_perm16'] = '삭제';
+$lang['acl_new'] = '새 항목 추가';
+$lang['acl_mod'] = '선택 항목 변경';
diff --git a/lib/plugins/acl/lang/la/help.txt b/lib/plugins/acl/lang/la/help.txt
new file mode 100644
index 000000000..553884c30
--- /dev/null
+++ b/lib/plugins/acl/lang/la/help.txt
@@ -0,0 +1,11 @@
+=== Auxilium: ===
+
+Hic facultates generum paginarumque addere delereue potes.
+
+Tabella sinistra omnes paginas generaque ostendit.
+
+His campis mutare facultates electorum Sodalium Gregumque potes.
+
+In tabula omnes administrationis leges ostensae sunt. Delere quoque uel mutare plures leges potes.
+
+Si [[doku>acl|official documentation on ACL]] legas, maius auxilium in Vicem mutando habes. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/la/lang.php b/lib/plugins/acl/lang/la/lang.php
new file mode 100644
index 000000000..941de1f79
--- /dev/null
+++ b/lib/plugins/acl/lang/la/lang.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['admin_acl'] = 'Administratio Indicis Custodiae Aditus';
+$lang['acl_group'] = 'Grex';
+$lang['acl_user'] = 'Sodalis';
+$lang['acl_perms'] = 'Facultas:';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Genus';
+$lang['btn_select'] = 'eligere';
+$lang['p_user_id'] = 'Sodalis <b class="acluser">%s</b> nunc has facultates paginae "<b class="aclpage">%s</b> habes: <i>%s</i>.';
+$lang['p_user_ns'] = 'Sodalis <b class="acluser">%s</b> nunc has facultates generis "<b class="aclns">%s</b> habes: <i>%s</i>.';
+$lang['p_group_id'] = 'Socius\a gregis <b class="aclgroup">%s</b> nunc has facultates paginae "<b class="aclpage">%s</b> habes: <i>%s</i>.';
+$lang['p_group_ns'] = 'Socius\a gregis <b class="aclgroup">%s</b> nunc has facultates generis "<b class="aclns">%s</b> habes: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Sodalis grexue</b> in campo insere ut facultates paginae <b class="aclpage">%s</b> uideas.';
+$lang['p_choose_ns'] = '<b>Sodalis grexue</b> in campo insere ut facultates generis <b class="aclns">%s</b> uideas.';
+$lang['p_inherited'] = 'Caue: hae facultates et huic rei et aliis gregibus uel generibus legitimae sunt.';
+$lang['p_isadmin'] = 'Caue: electi greges semper plenum ius habent, eo quod ut magister\stra elegitur.';
+$lang['p_include'] = 'Maiores facultates minores includunt. Creandi, onerandi uel delendi facultates solum generibus, non paginis sunt.';
+$lang['current'] = 'Communes ICA leges';
+$lang['where'] = 'Pagina/Genus';
+$lang['who'] = 'Sodalis/Grex';
+$lang['perm'] = 'Facultates';
+$lang['acl_perm0'] = 'Nihil';
+$lang['acl_perm1'] = 'Legere';
+$lang['acl_perm2'] = 'Recensere';
+$lang['acl_perm4'] = 'Creare';
+$lang['acl_perm8'] = 'Onerare';
+$lang['acl_perm16'] = 'Delere';
+$lang['acl_new'] = 'Nouom addere';
+$lang['acl_mod'] = 'Nouom recensere';
diff --git a/lib/plugins/acl/lang/lb/help.txt b/lib/plugins/acl/lang/lb/help.txt
new file mode 100644
index 000000000..e36ed373f
--- /dev/null
+++ b/lib/plugins/acl/lang/lb/help.txt
@@ -0,0 +1,11 @@
+=== Séier Hëllef: ===
+
+Op dëser Säit kanns de Rechter fir Namespacen a Säiten an dengem Wiki setzen.
+
+Op der lénkser Säit hues de all d'Namespacen a Säiten.
+
+Am Formulär hei uewendriwwer kanns de d'Rechter vun dem ausgewielte Benotzer oder Grupp änneren
+
+An der Tabell hei ënnendrënner kanns de all d'Reegele gesinn déi de Moment gesat sinn. Du kanns se huelen fir Reegelen ze änneren oder ze läschen.
+
+Déi [[doku>acl|offiziell Dokumentatioun iwwert ACL]] hëlleft der besser ze verstoen wéi déi Reegelen am Dokuwiki funktionéieren.
diff --git a/lib/plugins/acl/lang/lb/lang.php b/lib/plugins/acl/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/acl/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/acl/lang/lt/lang.php b/lib/plugins/acl/lang/lt/lang.php
new file mode 100644
index 000000000..f11944746
--- /dev/null
+++ b/lib/plugins/acl/lang/lt/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * lithuanian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Linas Valiukas <shirshegsm@gmail.com>
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['admin_acl'] = 'Priėjimo Kontrolės Sąrašų valdymas';
+$lang['acl_group'] = 'Grupė';
+$lang['acl_user'] = 'Vartotojas';
+$lang['acl_perms'] = 'Leidimai';
+$lang['page'] = 'Puslapis';
+$lang['namespace'] = 'Pavadinimas';
+$lang['btn_select'] = 'Rinktis';
+$lang['acl_perm1'] = 'Skaityti';
+$lang['acl_perm2'] = 'Redaguoti';
+$lang['acl_perm4'] = 'Sukurti';
+$lang['acl_perm8'] = 'Atsiųsti';
+$lang['acl_perm16'] = 'Ištrinti';
+$lang['acl_new'] = 'Pridėti naują įrašą';
diff --git a/lib/plugins/acl/lang/lv/help.txt b/lib/plugins/acl/lang/lv/help.txt
new file mode 100644
index 000000000..f570d798c
--- /dev/null
+++ b/lib/plugins/acl/lang/lv/help.txt
@@ -0,0 +1,11 @@
+=== Īsa palīdzība ===
+
+Šajā lapā var uzdot un noņemt tiesības uz lapām un nodaļām.
+
+Kreisajā pusē parādītas visas pieejamās nodaļas un lapas.
+
+Formā augšpusē var redzēt un grozīt norādītā lietotāja vai grupas tiesības .
+
+Apakšā tabulā parādīts visu tiesību saraksts. To var lietot, lai ātri mainītu vairākus pieejas tiesību noteikumus.
+
+[[doku>acl|Officiālajos piekļuves tiesību noteikumu dokumentos]] var atrast izvērstu informāciju, kā darbojas DokuWiki sistēmas piekļuves tiesību kontrole.
diff --git a/lib/plugins/acl/lang/lv/lang.php b/lib/plugins/acl/lang/lv/lang.php
new file mode 100644
index 000000000..f478b32c6
--- /dev/null
+++ b/lib/plugins/acl/lang/lv/lang.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * latvian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['admin_acl'] = 'Piekļuves tiesību vadība';
+$lang['acl_group'] = 'Grupa';
+$lang['acl_user'] = 'Lietotājs';
+$lang['acl_perms'] = 'Tiesības';
+$lang['page'] = 'Lapa';
+$lang['namespace'] = 'Nodaļa';
+$lang['btn_select'] = 'Izvēlēties';
+$lang['p_user_id'] = 'Lietotājam <b class="acluser">%s</b> ir tiesības <i>%s</i> lapu <b class="aclpage">%s</b> .';
+$lang['p_user_ns'] = 'Lietotājam <b class="acluser">%s</b> nodaļā <b class="aclns">%s</b> ir tiesības <i>%s</i>.';
+$lang['p_group_id'] = 'Grupas <b class="aclgroup">%s</b> biedriem ir tiesības <i>%s</i> lapu <b class="aclpage">%s</b>.';
+$lang['p_group_ns'] = 'Grupas <b class="aclgroup">%s</b> biedriem ir tiesības <i>%s</i> nodaļu <b class="aclns">%s</b>: .';
+$lang['p_choose_id'] = 'Lūdzu <b>ieraksti lietotāju vai grupu</b> augstāk norādītajā laukā, lai skatītu vai labotu tiesības lapai <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Lūdzu <b>ieraksti lietotāju vai grupu</b> augstāk norādītajā laukā, lai skatītu vai labotu tiesības nodaļai <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Ievēro: Šīs tiesības nav tieši uzdotas, bet mantotas no citām grupām vai augstākām nodaļām. ';
+$lang['p_isadmin'] = 'Ievēro: Norādītajai grupai vai lietotājam vienmēr ir visas tiesības, jo tas konfigurēts kā <i>superuser</i>.';
+$lang['p_include'] = 'Augstāka atļauja iekļauj arī zemākās tiesības. Izveidošanas, augšupielādēšanas un dzēšanas tiesības attiecas tikai uz nodaļām, nevis lapām.';
+$lang['current'] = 'Patreizējo tiesību saraksts (ACL)';
+$lang['where'] = 'Lapa/nodaļa';
+$lang['who'] = 'Lietotājs/grupa';
+$lang['perm'] = 'Tiesības';
+$lang['acl_perm0'] = 'nekādas';
+$lang['acl_perm1'] = 'lasīt';
+$lang['acl_perm2'] = 'labot';
+$lang['acl_perm4'] = 'izveidot';
+$lang['acl_perm8'] = 'augšupielādēt';
+$lang['acl_perm16'] = 'dzēst';
+$lang['acl_new'] = 'pievienot jaunu šķirkli';
+$lang['acl_mod'] = 'labot šķirkli';
diff --git a/lib/plugins/acl/lang/mk/lang.php b/lib/plugins/acl/lang/mk/lang.php
new file mode 100644
index 000000000..d576c3d1d
--- /dev/null
+++ b/lib/plugins/acl/lang/mk/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
+$lang['acl_group'] = 'Група';
+$lang['acl_user'] = 'Корисник';
+$lang['acl_perms'] = 'Пермисии за';
+$lang['page'] = 'Страница';
+$lang['btn_select'] = 'Избери';
+$lang['current'] = 'Моментални ACL правила';
+$lang['who'] = 'Корисник/група';
+$lang['perm'] = 'Пермисии';
+$lang['acl_perm0'] = 'Ништо';
+$lang['acl_perm1'] = 'Читај';
+$lang['acl_perm2'] = 'Уреди';
+$lang['acl_perm4'] = 'Креирај';
+$lang['acl_perm8'] = 'Качи';
+$lang['acl_perm16'] = 'Избриши';
+$lang['acl_new'] = 'Додај нов запис';
+$lang['acl_mod'] = 'Измени запис';
diff --git a/lib/plugins/acl/lang/mr/help.txt b/lib/plugins/acl/lang/mr/help.txt
new file mode 100644
index 000000000..e8aa13b52
--- /dev/null
+++ b/lib/plugins/acl/lang/mr/help.txt
@@ -0,0 +1,12 @@
+=== त्वरित मदत ===
+
+या पानावर तुमची तुमच्या विकी मधील पाने किंवा नेमस्पेस वरील परवानग्या बदलू शकता.
+
+डाविकडील मार्जिन मधे सर्व उपलब्ध पाने आणि नेमस्पेस दाखवले आहेत.
+
+वरील फॉर्म वापरून तुमची निवडलेल्या सदस्य किंवा गटाच्या परवानग्या बदलू शकता.
+
+खालील टेबल मधे सध्या सेट असलेले नियम दिलेले आहेत.
+हे टेबल वापरून तुम्ही चटकन हे नियम बदलू शकता.
+
+[[doku>acl| ACL वरील अधिकृत माहितीसंग्रह ]] वाचून तुम्हाला डॉक्युविकिमधे परवानगीची व्यवस्था कशी काम करते ते नीट समजेल. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/mr/lang.php b/lib/plugins/acl/lang/mr/lang.php
new file mode 100644
index 000000000..978df758a
--- /dev/null
+++ b/lib/plugins/acl/lang/mr/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['admin_acl'] = 'Access Control List व्यवस्थापन';
+$lang['acl_group'] = 'गट';
+$lang['acl_user'] = 'सदस्य';
+$lang['acl_perms'] = 'परवानगी \'च्या साठी';
+$lang['page'] = 'पान';
+$lang['namespace'] = 'नेमस्पेस';
+$lang['btn_select'] = 'निवडा';
+$lang['p_user_id'] = '<b class="acluser">%s</b> ह्या सदस्याला सध्या <b class="aclpage">%s</b> या पानावर पुढील परवानग्या आहेत : <i>%s</i>.';
+$lang['p_user_ns'] = '<b class="acluser">%s</b> या सदस्याला सध्या <b class="aclns">%s</b> या नेमस्पेसवर पुढील परवानग्या आहेत : <i>%s</i>.';
+$lang['p_group_id'] = '<b class="aclgroup">%s</b> या गटाच्या सदस्याना सध्या <b class="aclpage">%s</b> या पानावर पुढील परवानग्या आहेत : <i>%s</i>.';
+$lang['p_group_ns'] = '<b class="aclgroup">%s</b> या गटाच्या सदस्याना सध्या <b class="aclns">%s</b> या नेमस्पेसवर पुढील परवानग्या आहेत : <i>%s</i>.';
+$lang['p_choose_id'] = 'वरील फॉर्म मधे एखाद्या <b>सदस्य किंवा गटाचे </b> नाव टाकुन <b class="aclpage">%s</b> या पानासाठी त्यांच्या परवानग्या पाहू/बदलू शकता.';
+$lang['p_choose_ns'] = 'वरील फॉर्म मधे एखाद्या <b>सदस्य किंवा गटाचे </b> नाव टाकुन <b class="aclns">%s</b> या नेमस्पेससाठी त्यांच्या परवानग्या पाहू/बदलू शकता.';
+$lang['p_inherited'] = 'टीप : ह्या परवानग्या प्रत्यक्ष सेट केल्या नसून त्या इतर गट किंवा अधिक उच्च नेमस्पेस कडून वारसाहक्काने :) आल्या आहेत.';
+$lang['p_isadmin'] = 'टीप : निवडलेल्या सदस्य किंवा गटाला कायम सर्व परवानग्या असतात कारण तो सुपर सदस्य म्हणुन सेट केला आहे.';
+$lang['p_include'] = 'उच्च परवानग्यांमधे त्याखालिल परवानग्या अध्याहृत असतात. क्रिएट, अपलोड आणि डिलीट परवानग्या फ़क्त नामसमुहावर (नेमस्पेस) लागू असतात, पानांवर नाही.';
+$lang['current'] = 'सद्य ACL नियम';
+$lang['where'] = 'पान/नेमस्पेस';
+$lang['who'] = 'सदस्य/गट';
+$lang['perm'] = 'परवानग्या';
+$lang['acl_perm0'] = 'काही नाही.';
+$lang['acl_perm1'] = 'वाचन';
+$lang['acl_perm2'] = 'संपादन';
+$lang['acl_perm4'] = 'निर्माण';
+$lang['acl_perm8'] = 'अपलोड';
+$lang['acl_perm16'] = 'डिलीट';
+$lang['acl_new'] = 'नवीन एंट्री करा';
+$lang['acl_mod'] = 'एंट्री बदला';
diff --git a/lib/plugins/acl/lang/ms/lang.php b/lib/plugins/acl/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/acl/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/acl/lang/ne/lang.php b/lib/plugins/acl/lang/ne/lang.php
new file mode 100644
index 000000000..6a29a9fa8
--- /dev/null
+++ b/lib/plugins/acl/lang/ne/lang.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['admin_acl'] = 'एक्सेस कन्ट्रोल लिस्ट व्यवस्थापन';
+$lang['acl_group'] = 'समूह';
+$lang['acl_user'] = 'प्रोगकर्ता';
+$lang['acl_perms'] = 'को लागि अनुमति';
+$lang['page'] = 'पृष्ठ';
+$lang['namespace'] = 'नेमस्पेस';
+$lang['btn_select'] = 'छान्नुहोस्';
+$lang['current'] = 'हालैको ACL नियमहरु ';
+$lang['where'] = 'पृष्ठ / नेमस्पेस';
+$lang['who'] = 'प्रयोगकर्ता / समूह ';
+$lang['perm'] = 'अनुमति';
+$lang['acl_perm0'] = 'कुनै पनि होइन';
+$lang['acl_perm1'] = 'पठन गर्नुहोस्';
+$lang['acl_perm2'] = 'सम्पादन गर्नुहोस्';
+$lang['acl_perm4'] = 'निर्माण गर्नुहोस्';
+$lang['acl_perm8'] = 'अपलोड गर्नुहोस्';
+$lang['acl_perm16'] = 'मेटाउनुहोस्';
+$lang['acl_new'] = 'नयाँ प्रविष्ठि गर्नुहोस्';
+$lang['acl_mod'] = 'प्रविष्ठि सच्याउनुहोस्';
diff --git a/lib/plugins/acl/lang/nl/help.txt b/lib/plugins/acl/lang/nl/help.txt
new file mode 100644
index 000000000..255f21ba0
--- /dev/null
+++ b/lib/plugins/acl/lang/nl/help.txt
@@ -0,0 +1,11 @@
+=== Snelle hulp: ===
+
+Op deze pagina kun je bevoegdheden toevoegen en verwijderen voor namespaces en pagina's in je wiki.
+
+Het linkerpaneel geeft alle beschikbare namespaces en pagina's weer.
+
+In het formulier hierboven kun je bevoegdheden zien en aanpassen voor een selecteerde gebruiker of groep.
+
+In de tabel hieronder worden alle momenteel ingestelde toegangsregels weergegeven. Je kunt hier snel regels wijzigen of verwijderen.
+
+Lees de [[doku>acl|documentatie over ACLs]] om de mogelijkheden volledig te begrijpen.
diff --git a/lib/plugins/acl/lang/nl/lang.php b/lib/plugins/acl/lang/nl/lang.php
new file mode 100644
index 000000000..cb0765505
--- /dev/null
+++ b/lib/plugins/acl/lang/nl/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * dutch language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author François Kooman <fkooman.tuxed.net>
+ * @author Jack van Klaren <dokuwiki@afentoe.xs4all.nl>
+ * @author Riny Heijdendael <riny@heijdendael.nl>
+ * @author Koen Huybrechts <huybkoen@gmail.com>
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['admin_acl'] = 'Toegangsrechten';
+$lang['acl_group'] = 'Groep';
+$lang['acl_user'] = 'Gebruiker';
+$lang['acl_perms'] = 'Permissies voor';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Namespace';
+$lang['btn_select'] = 'Selecteer';
+$lang['p_user_id'] = 'Gebruiker <b class="acluser">%s</b> heeft momenteel de volgende bevoegdheden op pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Gebruiker <b class="acluser">%s</b> heeft momenteel de volgende bevoegdheden op namespace <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Leden van groep <b class="aclgroup">%s</b> hebben momenteel de volgende bevoegdheden op pagina <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Leden van groep <b class="aclgroup">%s</b>hebben momenteel de volgende bevoegdheden op namespace <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Vul een <b>gebruiker of groep</b> in in het bovenstaande formulier om de bevoegdheden te bekijken of te bewerken voor de pagina <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Vul een <b>gebruiker of groep</b> in in het bovenstaande formulier om de bevoegdheden te bekijken of te bewerken voor de namespace <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Let op: Deze permissies zijn niet expliciet ingesteld maar overerfd van andere groepen of hogere namespaces.';
+$lang['p_isadmin'] = 'Let op: De geselecteerde groep of gebruiker heeft altijd volledige toegangsrechten omdat hij als superuser geconfigureerd is.';
+$lang['p_include'] = 'Hogere permissies bevatten ook de lagere. Aanmaken, uploaden en verwijderen gelden alleen voor namespaces, niet voor pagina\'s.';
+$lang['current'] = 'Huidige ACL regels';
+$lang['where'] = 'Pagina/namespace';
+$lang['who'] = 'Gebruiker/Groep';
+$lang['perm'] = 'Bevoegdheden';
+$lang['acl_perm0'] = 'Geen';
+$lang['acl_perm1'] = 'Lezen';
+$lang['acl_perm2'] = 'Bewerken';
+$lang['acl_perm4'] = 'Aanmaken';
+$lang['acl_perm8'] = 'Uploaden';
+$lang['acl_perm16'] = 'Verwijderen';
+$lang['acl_new'] = 'Nieuwe regel toevoegen';
+$lang['acl_mod'] = 'Regel aanpassen';
diff --git a/lib/plugins/acl/lang/no/help.txt b/lib/plugins/acl/lang/no/help.txt
new file mode 100644
index 000000000..c3d3688a9
--- /dev/null
+++ b/lib/plugins/acl/lang/no/help.txt
@@ -0,0 +1,11 @@
+=== Hurtighjelp: ===
+
+På denne siden kan du legge til og fjerne tillatelser for navnerom og sider i din wiki.
+
+Venstre panel viser alle tilgjengelige navnerom og sider.
+
+Skjemaet over tillater deg å se og modifisere tillatelser for en valgt bruker eller gruppe.
+
+I tabellen nedenfor vises alle nærværende satte adgangskontroll-regler. Du kan bruke den til raskt å slette eller endre mange regler i slengen.
+
+Å lese [[doku>acl|den offisielle dokumentasjonen for ACL]] kan hjelpe deg å fullt ut forstå hvordan adgangskontroll fungerer i DokuWiki.
diff --git a/lib/plugins/acl/lang/no/lang.php b/lib/plugins/acl/lang/no/lang.php
new file mode 100644
index 000000000..09d71937a
--- /dev/null
+++ b/lib/plugins/acl/lang/no/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Norwegian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Reidar Mosvold <Reidar.Mosvold@hit.no>
+ * @author Jorge Barrera Grandon <jorge@digitalwolves.org>
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['admin_acl'] = 'Administrasjon av lister for adgangskontroll (ACL)';
+$lang['acl_group'] = 'Gruppe';
+$lang['acl_user'] = 'Bruker';
+$lang['acl_perms'] = 'Rettigheter for';
+$lang['page'] = 'Side';
+$lang['namespace'] = 'Navnerom';
+$lang['btn_select'] = 'Velg';
+$lang['p_user_id'] = 'Bruker <b class="acluser">%s</b> har for tiden følgende tillatelser i for siden <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Bruker <b class="acluser">%s</b> har for tiden følgende tillatelser i navnerom <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Medlemmer av gruppe <b class="aclgroup">%s</b> har for tiden følgende tillatelser i for siden <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Medlemmer av gruppe <b class="aclgroup">%s</b> har for tiden følgende tillatelser i navnerom <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Før inn en bruker eller gruppe</b> i skjemaet over for å vise eller redigere tillatelser satt for siden <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = '<b>Før inn en bruker eller gruppe</b> i skjemaet over for å vise eller redigere tillatelser satt for navnerommet <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Merk: Disse tillatelser ble ikke eksplisitt satt, men ble arvet fra andre grupper eller høyere navnerom.';
+$lang['p_isadmin'] = 'Merk: Den valgte gruppen eller bruker har altid fulle tillatelser fordi vedkommende er konfigurert som superbruker.';
+$lang['p_include'] = 'Høyere tillgangsrettigheter inkluderer lavere. Rettigheter for å opprette, laste opp og slette gjelder bare for navnerom, ikke enkeltsider.';
+$lang['current'] = 'Gjeldende ACL-regler';
+$lang['where'] = 'Side/Navnerom';
+$lang['who'] = 'Bruker/Gruppe';
+$lang['perm'] = 'Rettigheter';
+$lang['acl_perm0'] = 'Ingen';
+$lang['acl_perm1'] = 'Lese';
+$lang['acl_perm2'] = 'Redigere';
+$lang['acl_perm4'] = 'Opprette';
+$lang['acl_perm8'] = 'Laste opp';
+$lang['acl_perm16'] = 'Slette';
+$lang['acl_new'] = 'Legg til ny oppføring';
+$lang['acl_mod'] = 'Endre oppføring';
diff --git a/lib/plugins/acl/lang/pl/help.txt b/lib/plugins/acl/lang/pl/help.txt
new file mode 100644
index 000000000..331fd2a7a
--- /dev/null
+++ b/lib/plugins/acl/lang/pl/help.txt
@@ -0,0 +1,11 @@
+=== Pomoc ===
+
+Na tej stronie możesz zmienić uprawnienia do stron i katalogów w wiki.
+
+Lewy panel pokazuje wszystkie dostępne katalogi i strony.
+
+Formularz powyżej pozwala wyświetlać uprawnienia wybranego użytkownika oraz grupy.
+
+W tabeli poniżej znajdują się wszystkie aktywne reguły dotyczące uprawnień.
+
+Więcej informacji na temat uprawnień w DokuWiki możesz znaleźć w [[doku>acl|oficjalnej dokumentacji uprawnień]].
diff --git a/lib/plugins/acl/lang/pl/lang.php b/lib/plugins/acl/lang/pl/lang.php
new file mode 100644
index 000000000..1b10b5232
--- /dev/null
+++ b/lib/plugins/acl/lang/pl/lang.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * polish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['admin_acl'] = 'Zarządzanie uprawnieniami';
+$lang['acl_group'] = 'Grupa';
+$lang['acl_user'] = 'Użytkownik';
+$lang['acl_perms'] = 'Uprawnienia użytkownika';
+$lang['page'] = 'Strona';
+$lang['namespace'] = 'Katalog';
+$lang['btn_select'] = 'Wybierz';
+$lang['p_user_id'] = 'Użytkownik <b class="acluser">%s</b> posiada następujące uprawnienia do strony <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Użytkownik <b class="acluser">%s</b> posiada następujące uprawnienia do katalogów <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Członkowie grupy <b class="aclgroup">%s</b> posiadają następujące uprawnienia do strony <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Członkowie grupy <b class="aclgroup">%s</b> posiadają następujące uprawnienia do katalogu <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Podaj <b>nazwę użytkownika lub grupy</b> w powyższym formularzu, by wyświetlić lub zmienić uprawnienia do strony <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Podaj <b>nazwę użytkownika lub grupy</b> w powyższym formularzu, by wyświetlić lub zmienić uprawnienia do katalogu <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Uwaga: Uprawnienia nie zostały nadane wprost ale są dziedziczone z grupy lub katalogu.';
+$lang['p_isadmin'] = 'Uwaga: Wybrana grupa lub użytkownika zawsze dysponuje pełnymi uprawnieniami ponieważ posiada uprawnienia administratora.';
+$lang['p_include'] = 'Szersze uprawnienia zawierają węższe. Tworzenie, przesyłanie plików oraz usuwanie mają znaczenie tylko dla katalogów, nie dla stron.';
+$lang['current'] = 'Aktywne reguły zarządzania uprawnieniami';
+$lang['where'] = 'Strona/Katalog';
+$lang['who'] = 'Użytkownik/Grupa';
+$lang['perm'] = 'Uprawnienie';
+$lang['acl_perm0'] = 'Żadne';
+$lang['acl_perm1'] = 'Czytanie';
+$lang['acl_perm2'] = 'Zmiana';
+$lang['acl_perm4'] = 'Tworzenie';
+$lang['acl_perm8'] = 'Przesyłanie plików';
+$lang['acl_perm16'] = 'Usuwanie';
+$lang['acl_new'] = 'Dodaj nowy wpis';
+$lang['acl_mod'] = 'Zmień wpis';
diff --git a/lib/plugins/acl/lang/pt-br/help.txt b/lib/plugins/acl/lang/pt-br/help.txt
new file mode 100644
index 000000000..b2a49a90d
--- /dev/null
+++ b/lib/plugins/acl/lang/pt-br/help.txt
@@ -0,0 +1,11 @@
+=== Ajuda rápida: ===
+
+Nessa página você pode adicionar e remover permissões para espaços de nomes e páginas do seu wiki.
+
+O painel à esquerda mostra todos os espaços de nomes e páginas disponíveis.
+
+O formulário acima permite a visualização e modificação das permissões de um determinado usuário ou grupo.
+
+Na tabela abaixo são exibidas todas as regras de controle de acesso definidas. Você pode usá-la para excluir ou mudar rapidamente várias regras.
+
+A leitura da [[doku>acl|documentação oficial sobre ACL]] pode ajudar a compreender melhor como o controle de acessos funciona no DokuWiki.
diff --git a/lib/plugins/acl/lang/pt-br/lang.php b/lib/plugins/acl/lang/pt-br/lang.php
new file mode 100644
index 000000000..a0c997600
--- /dev/null
+++ b/lib/plugins/acl/lang/pt-br/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Brazilian Portuguese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Luis Fernando Enciso <lfenciso@certto.com.br>
+ * @author Alauton/Loug
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['admin_acl'] = 'Administração da Lista de Controles de Acesso';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Usuário';
+$lang['acl_perms'] = 'Permissões para';
+$lang['page'] = 'Página';
+$lang['namespace'] = 'Espaço de nomes';
+$lang['btn_select'] = 'Selecionar';
+$lang['p_user_id'] = 'O usuário <b class="acluser">%s</b> possui as seguintes permissões na página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'O usuário <b class="acluser">%s</b> possui as seguintes permissões no espaço de nomes <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Os membros do grupo <b class="aclgroup">%s</b> possuem as seguintes permissões na página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Os membros do grupo <b class="aclgroup">%s</b> possuem as seguintes permissões no espaço de nomes <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Por favor <b>digite um usuário ou grupo</b> no formulário acima para ver ou editar as permissões para a página <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Por favor <b>digite um usuário ou grupo</b> no formulário acima para ver ou editar as permissões para o espaço de nomes <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Nota: Essas permissões não foram definidas explicitamente, mas sim herdadas de outros grupos ou espaço de nomes superiores.';
+$lang['p_isadmin'] = 'Nota: O grupo ou usuário selecionado sempre tem permissões completas, porque ele está configurado como superusuário.';
+$lang['p_include'] = 'As permissões superiores incluem as inferiores. Permissões para Criar, Enviar e Apagar aplicam-se apenas aos espaços de nomes e não às páginas.';
+$lang['current'] = 'Regras atuais da ACL';
+$lang['where'] = 'Página/Espaço de nomes';
+$lang['who'] = 'Usuário/Grupo';
+$lang['perm'] = 'Permissões';
+$lang['acl_perm0'] = 'Nenhuma';
+$lang['acl_perm1'] = 'Ler';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Criar';
+$lang['acl_perm8'] = 'Enviar';
+$lang['acl_perm16'] = 'Excluir';
+$lang['acl_new'] = 'Adicionar nova entrada';
+$lang['acl_mod'] = 'Modificar a entrada';
diff --git a/lib/plugins/acl/lang/pt/help.txt b/lib/plugins/acl/lang/pt/help.txt
new file mode 100644
index 000000000..cf4619deb
--- /dev/null
+++ b/lib/plugins/acl/lang/pt/help.txt
@@ -0,0 +1,9 @@
+=== Auxílio Rápido ===
+
+Nesta página podes adicionar e remover permissões para espaço de nomes e páginas no seu wiki.
+
+O painel esquerdo exibe todos os espaço de nomes e páginas. O formulario acima permite a visualização e modificar as permissões de um selecionado utilizador ou grupo.
+
+Na tabela inferior são exibidas todas as actuais regras de controle de acesso. Podes utilisá-la para excluir ou mudar rapidamente várias regras ao mesmo tempo.
+
+A leitura da [[doku>acl|documentação oficial acerca ACL]] pode ajudar a compreender melhor como o controle de acessos funciona no DokuWiki.
diff --git a/lib/plugins/acl/lang/pt/lang.php b/lib/plugins/acl/lang/pt/lang.php
new file mode 100644
index 000000000..d90bab624
--- /dev/null
+++ b/lib/plugins/acl/lang/pt/lang.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author José Carlos Monteiro <jose.c.monteiro@netcabo.pt>
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['admin_acl'] = 'Gestão de ACLs';
+$lang['acl_group'] = 'Grupo';
+$lang['acl_user'] = 'Utilizador';
+$lang['acl_perms'] = 'Permissão para';
+$lang['page'] = 'Documento';
+$lang['namespace'] = 'Namespace';
+$lang['btn_select'] = 'Selecionar';
+$lang['p_user_id'] = 'O utilizador <b class="acluser">%s</b> tem as seguintes permissões na página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'O utilizador <b class="acluser">%s</b> tem as seguintes permissões no espaço de nomes <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Os membros do grupo <b class="aclgroup">%s</b> têm as seguintes permissões na página <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Os membros do grupo <b class="aclgroup">%s</b> têm as seguintes permissões no espaço de nomes <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Por favor <b>digite um utilizador ou grupo</b> no formulário acima para ver ou editar as permissões para a página <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Por favor <b>digite um utilizador ou grupo</b> no formulário acima para ver ou editar as permissões para o espaço de nomes <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Nota: Essas permissões não foram definidas explicitamente, mas sim herdadas de outros grupos ou espaço de nomes superiores.';
+$lang['p_isadmin'] = 'Nota: O grupo ou utilizador seleccionado tem sempre permissões completas, porque ele está configurado como superutilizador.';
+$lang['p_include'] = 'As permissões superiores incluem as inferiores. Permissões para Criar, Enviar e Apagar aplicam-se apenas aos espaços de nomes e não às páginas.';
+$lang['current'] = 'Regras Actuais ACL';
+$lang['where'] = 'Página/Espaço de Nomes';
+$lang['who'] = 'Utilizador/Grupo';
+$lang['perm'] = 'Permissões';
+$lang['acl_perm0'] = 'Nenhum';
+$lang['acl_perm1'] = 'Ler';
+$lang['acl_perm2'] = 'Editar';
+$lang['acl_perm4'] = 'Criar';
+$lang['acl_perm8'] = 'Carregar';
+$lang['acl_perm16'] = 'Remover';
+$lang['acl_new'] = 'Adicionar nova entrada';
+$lang['acl_mod'] = 'Modificar Entrada';
diff --git a/lib/plugins/acl/lang/ro/help.txt b/lib/plugins/acl/lang/ro/help.txt
new file mode 100644
index 000000000..3f762613c
--- /dev/null
+++ b/lib/plugins/acl/lang/ro/help.txt
@@ -0,0 +1,11 @@
+=== Quick Help: ===
+
+Pe această pagină puteţi adăuga şi elimina autorizaţiile pentru spaţiile de nume şi paginile din wiki.
+
+Panoul din stânga afişează toate spaţiile de nume şi paginile disponibile.
+
+Formularul de sus vă permite să vedeţi şi să modificaţi autorizaţiile unui anume utilizator sau grup.
+
+In tabelul de jos sunt arătate toate regulile de control a accesului setate. Îl puteţi folosi pentru a şterge sau modifica rapid mai multe reguli.
+
+Consultarea [[doku>acl|official documentation on ACL]] vă poate ajuta să înţelegeţi deplin cum funcţionează controlul accesului în DocuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/ro/lang.php b/lib/plugins/acl/lang/ro/lang.php
new file mode 100644
index 000000000..6d63ad024
--- /dev/null
+++ b/lib/plugins/acl/lang/ro/lang.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['admin_acl'] = 'Managementul Listei de Control a Accesului';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Utilizator';
+$lang['acl_perms'] = 'Autorizare pentru';
+$lang['page'] = 'Pagina';
+$lang['namespace'] = 'Spaţiu de nume';
+$lang['btn_select'] = 'Selectează';
+$lang['p_user_id'] = 'Utilizatorul <b class="acluser">%s</b> are următoarele autorizaţii pe pagină <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Utilizatorul <b class="acluser">%s</b> are următoarele autorizaţii pe spaţiul de nume <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Membrii grupului <b class="aclgroup">%s</b> au următoarele autorizaţii pe pagină <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Membrii grupului <b class="aclgroup">%s</b> au următoarele autorizaţii pe spaţiul de nume <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = '<b>Introduceţi un utilizator sau un grup</b> în formularul de mai sus pentru a vizualiza sau edita autorizaţiile paginii <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = '<b>Introduceţi un utilizator sau un grup</b> în formularul de mai sus pentru a vizualiza sau edita autorizaţiile spaţiului de nume <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Notă: Aceste autorizaţii nu au fost setate explicit ci au fost moştenite de la alte grupuri sau spaţii de nume superioare ierarhic.';
+$lang['p_isadmin'] = 'Notă: Grupul sau utilizatorul selectat are intotdeauna toate autorizatiile întrucât este configurat ca superutilizator.';
+$lang['p_include'] = 'Permisiunile superioare le includ pe cele inferioare. Permisiunile de Creare, Upload şi Ştergere se aplică doar numelor de spaţiu, nu paginilor.';
+$lang['current'] = 'Reguli ACL actuale';
+$lang['where'] = 'Pagină/Spaţiu de nume';
+$lang['who'] = 'Utilizator/Grup';
+$lang['perm'] = 'Autorizaţii';
+$lang['acl_perm0'] = 'Nici una';
+$lang['acl_perm1'] = 'Citire';
+$lang['acl_perm2'] = 'Editare';
+$lang['acl_perm4'] = 'Creare';
+$lang['acl_perm8'] = 'Încărcare';
+$lang['acl_perm16'] = 'Ştergere';
+$lang['acl_new'] = 'Adaugă intrare nouă';
+$lang['acl_mod'] = 'Modifică intrare';
diff --git a/lib/plugins/acl/lang/ru/help.txt b/lib/plugins/acl/lang/ru/help.txt
new file mode 100644
index 000000000..7807105a8
--- /dev/null
+++ b/lib/plugins/acl/lang/ru/help.txt
@@ -0,0 +1,7 @@
+=== Краткая справка ===
+
+На этой странице вы можете добавить или удалить права доступа к пространствам имён и страницам своей вики.\\
+На панели слева отображены доступные пространства имён и страницы.\\
+Форма выше позволяет вам просмотреть и изменить права доступа для выбранного пользователя или группы.\\
+Текущие права доступа отображены в таблице ниже. Вы можете использовать её для быстрого удаления или изменения правил.\\
+Прочтение [[doku>acl|официальной документации по ACL]] может помочь вам в полном понимании работы управления правами доступа в «ДокуВики».
diff --git a/lib/plugins/acl/lang/ru/lang.php b/lib/plugins/acl/lang/ru/lang.php
new file mode 100644
index 000000000..6d04dde21
--- /dev/null
+++ b/lib/plugins/acl/lang/ru/lang.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Russian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['admin_acl'] = 'Управление списками контроля доступа';
+$lang['acl_group'] = 'Группа';
+$lang['acl_user'] = 'Пользователь';
+$lang['acl_perms'] = 'Права доступа для';
+$lang['page'] = 'Страница';
+$lang['namespace'] = 'Пространство имён';
+$lang['btn_select'] = 'Выбрать';
+$lang['p_user_id'] = 'Сейчас пользователь <b class="acluser">%s</b> имеет следующие права на доступ к странице <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Сейчас пользователь <b class="acluser">%s</b> имеет следующие права на доступ к пространству имён <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Сейчас члены группы <b class="aclgroup">%s</b> имеют следующие права на доступ к странице <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Сейчас члены группы <b class="aclgroup">%s</b> cимеют следующие права на доступ к пространству имён <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Пожалуйста, <b>введите пользователя или группу</b> в форме выше, чтобы просмотреть или отредактировать права на доступ к странице <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Пожалуйста, <b>введите пользователя или группу</b> в форме выше, чтобы просмотреть или отредактировать права на доступ к пространству имён <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Замечание: эти права доступа не были заданы явно, а были унаследованы от других групп или пространств имён более высокого порядка.';
+$lang['p_isadmin'] = 'Замечание: выбранный пользователь всегда имеет полные права, так как он является суперпользователем.';
+$lang['p_include'] = 'Более высокие права доступа включают в себя более низкие. Права доступа «Создание», «Загрузка» и «Удаление» относятся только к пространствам имён, а не к страницам.';
+$lang['current'] = 'Текущие права ACL';
+$lang['where'] = 'Страница/Пространство имён';
+$lang['who'] = 'Пользователь/Группа';
+$lang['perm'] = 'Права доступа';
+$lang['acl_perm0'] = 'Нет доступа';
+$lang['acl_perm1'] = 'Чтение';
+$lang['acl_perm2'] = 'Правка';
+$lang['acl_perm4'] = 'Создание';
+$lang['acl_perm8'] = 'Загрузка файлов';
+$lang['acl_perm16'] = 'Удаление';
+$lang['acl_new'] = 'Добавить новую запись';
+$lang['acl_mod'] = 'Отредактировать запись';
diff --git a/lib/plugins/acl/lang/sk/help.txt b/lib/plugins/acl/lang/sk/help.txt
new file mode 100644
index 000000000..103a0341a
--- /dev/null
+++ b/lib/plugins/acl/lang/sk/help.txt
@@ -0,0 +1,11 @@
+=== Krátka nápoveda: ===
+
+Na tejto stránke môžete pridávať alebo rušiť oprávnenia pre menné priestory a stránky vo Vašej wiki.
+
+Ľavý panel zobrazuje všetky dostupné menné priestory a stránky.
+
+Formulár zobrazený vyššie Vám dovoľuje prehliadať a meniť oprávnenia pre vybraného používateľa alebo skupinu.
+
+V tabuľke nižšie sú zobrazené všetky aktuálne prístupové pravidlá. Môžete v nej rýchlo rušiť alebo meniť viacero pravidiel súčasne.
+
+Prečítanie [[doku>acl|oficiálnej dokumentácie ACL]] Vám môže pomôcť plne pochopiť spôsob ako fungujú prístupové pravidlá (oprávnenia) v DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/sk/lang.php b/lib/plugins/acl/lang/sk/lang.php
new file mode 100644
index 000000000..398f8c63d
--- /dev/null
+++ b/lib/plugins/acl/lang/sk/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Slovak language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Ondrej Vegh <ov@vsieti.sk>
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['admin_acl'] = 'Správa zoznamu prístupových práv';
+$lang['acl_group'] = 'Skupina';
+$lang['acl_user'] = 'Užívateľ';
+$lang['acl_perms'] = 'Práva pre';
+$lang['page'] = 'Stránka';
+$lang['namespace'] = 'Menný priestor';
+$lang['btn_select'] = 'Vybrať';
+$lang['p_user_id'] = 'Používateľ <b class="acluser">%s</b> má aktuálne nasledujúce oprávnenia k stránke <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Používateľ <b class="acluser">%s</b> má aktuálne nasledujúce oprávnenia v mennom priestore <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Členovia skupiny <b class="aclgroup">%s</b> majú aktuálne nasledujúce oprávnenia k stránke <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Členovia skupiny <b class="aclgroup">%s</b> majú aktuálne nasledujúce oprávnenia v mennom priestore <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Prosím <b>zadajte používateľa alebo skupinu</b> do formulára zobrazeného vyššie, aby ste mohli prezerať alebo meniť oprávnenia k stránke <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Prosím <b>zadajte používateľa alebo skupinu</b> do formulára zobrazeného vyššie, aby ste mohli prezerať alebo meniť oprávnenia v mennom priestore <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Poznámka: Tieto oprávnenia neboli nastavené explicitne, ale boli odvodené z inej skupiny alebo nadradeného menného priestoru.';
+$lang['p_isadmin'] = 'Poznámka: Vybraná skupina alebo používateľ má vždy najvyššie oprávnenia, pretože je vedená/vedený ako správca.';
+$lang['p_include'] = 'Vyššie oprávnenia zahŕňajú nižšie. Oprávnenie Vytvoriť, Nahrať a Zmazať sa vzťahujú iba k menným priestorom, nie ku stránkam.';
+$lang['current'] = 'Aktuálne pravidlá prístupu (ACL)';
+$lang['where'] = 'Stránka/Menný priestor';
+$lang['who'] = 'Používateľ/Skupina';
+$lang['perm'] = 'Povolenia';
+$lang['acl_perm0'] = 'Žiadne';
+$lang['acl_perm1'] = 'Čítať';
+$lang['acl_perm2'] = 'Zmeniť';
+$lang['acl_perm4'] = 'Vytvoriť';
+$lang['acl_perm8'] = 'Nahrať súbor';
+$lang['acl_perm16'] = 'Zmazať';
+$lang['acl_new'] = 'Pridať nový záznam';
+$lang['acl_mod'] = 'Upraviť záznam';
diff --git a/lib/plugins/acl/lang/sl/help.txt b/lib/plugins/acl/lang/sl/help.txt
new file mode 100644
index 000000000..ff096ae0e
--- /dev/null
+++ b/lib/plugins/acl/lang/sl/help.txt
@@ -0,0 +1,11 @@
+=== Hitra pomoč ===
+
+Na tej strani je mogoče dodajati, odstranjevati in spreminjati dovoljenja za delo z wiki stranmi in imenskimi prostori.
+
+Na veli strani so izpisani vsi imenski prostori in strani.
+
+Na obrazcu zgoraj je mogoče pregledovati in spreminjati dovoljenja za izbranega uporabnika ali skupino.
+
+V preglednici spodaj so prikazana vsa pravila nadzora. Ta je mogoče hitro spreminjati ali brisati.
+
+Več podrobnosti o delovanju nadzora dostopa sistema DokuWiki je mogoče najti v [[doku>acl|uradni dokumentaciji ACL]].
diff --git a/lib/plugins/acl/lang/sl/lang.php b/lib/plugins/acl/lang/sl/lang.php
new file mode 100644
index 000000000..44e45e491
--- /dev/null
+++ b/lib/plugins/acl/lang/sl/lang.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Dejan Levec <webphp@gmail.com>
+ * @author Boštjan Seničar <senicar@gmail.com>
+ * @author Gregor Skumavc (grega.skumavc@gmail.com)
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['admin_acl'] = 'Upravljanje dostopa';
+$lang['acl_group'] = 'Skupina';
+$lang['acl_user'] = 'Uporabnik';
+$lang['acl_perms'] = 'Dovoljenja za';
+$lang['page'] = 'Stran';
+$lang['namespace'] = 'Imenski prostor';
+$lang['btn_select'] = 'Izberi';
+$lang['p_user_id'] = 'Uporabnik %s ima naslednja dovoljenja za stran %s: %s.';
+$lang['p_user_ns'] = 'Uporabnik %s ima naslednja dovoljenja za imenski prostor %s: %s.';
+$lang['p_group_id'] = 'Uporabniška skupina %s ima naslednja dovoljenja za stran %s: %s.';
+$lang['p_group_ns'] = 'Uporabniška skupina %s ima naslednja dovoljenja za imenski prostor %s: %s.';
+$lang['p_choose_id'] = 'Vnesite ime <b>uporabnika ali skupine</b> v zgornji obrazec za ogled ali urejanje dovoljenj za stran %s.';
+$lang['p_choose_ns'] = 'Vnesite ime <b>uporabnika ali skupine</b> v zgornji obrazec za ogled ali urejanje dovoljenj za imenski prostor %s.';
+$lang['p_inherited'] = 'Opomba: trenutna dovoljenja niso bila posebej določena, temveč so bila prevzeta iz drugih skupin ali višjih imenskih prostorov.';
+$lang['p_isadmin'] = 'Opomba: izbrana skupina ali uporabnik imajo vsa dovoljenja za spreminjanje, saj so določeni kot skrbniki sistema.';
+$lang['p_include'] = 'Višja dovoljenja vključujejo tudi nižja. ';
+$lang['current'] = 'Trenutna pravila dostopa';
+$lang['where'] = 'Stran / Imenski prostor';
+$lang['who'] = 'Uporabnik/Skupina';
+$lang['perm'] = 'Dovoljenja';
+$lang['acl_perm0'] = 'Nič';
+$lang['acl_perm1'] = 'Preberi';
+$lang['acl_perm2'] = 'Uredi';
+$lang['acl_perm4'] = 'Ustvari';
+$lang['acl_perm8'] = 'Naloži';
+$lang['acl_perm16'] = 'Zbriši';
+$lang['acl_new'] = 'Dodaj nov zapis';
+$lang['acl_mod'] = 'Spremeni zapis';
diff --git a/lib/plugins/acl/lang/sq/help.txt b/lib/plugins/acl/lang/sq/help.txt
new file mode 100644
index 000000000..84a567f8b
--- /dev/null
+++ b/lib/plugins/acl/lang/sq/help.txt
@@ -0,0 +1,11 @@
+=== Ndihmë e Shpejtë: ===
+
+Në këtë faqe mund të shtoni ose hiqni të drejta për hapësira emri dhe faqe në wiki-n tuaj.
+
+Paneli i majtë tregon të gjitha faqet dhe hapësirat e emrit të disponueshme.
+
+Forma më sipër ju lejon të shihni dhe ndryshoni lejet për një grup ose përdorues të përzgjedhur.
+
+Në tabelën më poshtë tregohen të gjitha rregullat e vendosjes së aksesit. Mund ta përdorni për të fshirë shpejt ose ndryshuar shumë rregulla njëkohësisht.
+
+Leximi i [[doku>acl|dokumentimit zyrtar mbi ACL]] mund t'ju ndihmojë për të kuptuar plotësisht sesi funksionin Kontrolli i Aksesit në DokuWiki.
diff --git a/lib/plugins/acl/lang/sq/lang.php b/lib/plugins/acl/lang/sq/lang.php
new file mode 100644
index 000000000..30fc99bb0
--- /dev/null
+++ b/lib/plugins/acl/lang/sq/lang.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['admin_acl'] = 'Menaxhimi i Listës së Kontrollit të Aksesit';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Përdorues';
+$lang['acl_perms'] = 'Të drejta për';
+$lang['page'] = 'Faqe';
+$lang['namespace'] = 'Hapësira e Emrit';
+$lang['btn_select'] = 'Zgjidh';
+$lang['p_user_id'] = 'Përdoruesi <b class="acluser">%s</b> momentalisht ka të drejtat e mëposhtme mbi faqen <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Përdoruesi <b class="acluser">%s</b> momentalisht ka të drejtat e mëposhtme mbi hapësirën e emrit <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Anëtarët e grupit <b class="aclgroup">%s</b> momentalisht kanë të drejtat e mëposhtme mbi faqen <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Anëtarët e grupit <b class="aclgroup">%s</b> momentalisht kanë të drejtat e mëposhtme mbi hapësirën e emrit <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Ju lutemi <b>futni një përdorues ose grup</b> në formën e mësipërme për të parë ose ndryshuar bashkësinë e të drejtave për faqen <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Ju lutemi <b>futni një përdorues ose grup</b> në formën e mësipërme për të parë ose ndryshuar bashkësinë e të drejtave për hapësirën e emrit <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Shënim: Ato të drejta nuk janë vendosur specifikisht por janë të trashëguara nga grupe të tjera ose hapësira emri më të larta.';
+$lang['p_isadmin'] = 'Shënim: Grupi ose përdoruesi i përzgjedhur ka gjithmonë të drejta të plota sepse është konfiguruar si superpërdorues.';
+$lang['p_include'] = 'Të drejtat më të larta i përfshijnë edhe ato më të ultat. Të drejtat Krijo, Ngarko dhe Fshi u aplikohen vetëm hapësirave të emrit, jo faqeve.';
+$lang['current'] = 'Rregullat aktuale ACL';
+$lang['where'] = 'Faqe/Hapësirë Emri';
+$lang['who'] = 'Përdorues/Grup';
+$lang['perm'] = 'Të Drejta';
+$lang['acl_perm0'] = 'Asgjë';
+$lang['acl_perm1'] = 'Lexim';
+$lang['acl_perm2'] = 'Redaktim';
+$lang['acl_perm4'] = 'Krijim';
+$lang['acl_perm8'] = 'Ngarkim';
+$lang['acl_perm16'] = 'Fshi';
+$lang['acl_new'] = 'Shto Hyrje të re';
+$lang['acl_mod'] = 'Ndrysho Hyrje';
diff --git a/lib/plugins/acl/lang/sr/help.txt b/lib/plugins/acl/lang/sr/help.txt
new file mode 100644
index 000000000..0ec8921d4
--- /dev/null
+++ b/lib/plugins/acl/lang/sr/help.txt
@@ -0,0 +1,11 @@
+=== Приручна помоћ: ===
+
+На овој страни можете додати или уклонити дозволе за странице и именске просторе на Вашем викију.
+
+Леви панел приказује све доступне именске просторе и странице.
+
+Формулар изнад омогућава приказ и измену дозвола за одабране кориснике или групе.
+
+У табели испод су приказане све тренутно постављене дозволе. Можете је користити за брзо брисање или измену више правила.
+
+Читање [[doku>acl|званичне документације о ACL]] Вам може помоћи у потпуном разумевању рада дозвола приступа у DokuWiki-ју.
diff --git a/lib/plugins/acl/lang/sr/lang.php b/lib/plugins/acl/lang/sr/lang.php
new file mode 100644
index 000000000..20fbb0382
--- /dev/null
+++ b/lib/plugins/acl/lang/sr/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * serbian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Filip Brcic <brcha@users.sourceforge.net>
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['admin_acl'] = 'Управљање листом контроле приступа';
+$lang['acl_group'] = 'Група';
+$lang['acl_user'] = 'Корисник';
+$lang['acl_perms'] = 'Дозволе за';
+$lang['page'] = 'Страница';
+$lang['namespace'] = 'Именски простор';
+$lang['btn_select'] = 'Одабери';
+$lang['p_user_id'] = 'Корисник <b class="acluser">%s</b> тренутно има следеће дозволе за ову страницу <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Корисник <b class="acluser">%s</b> тренутно има следеће дозволе за овај именски простор <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Чланови групе <b class="acluser">%s</b> тренутно имају следеће дозволе за ову страницу <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Чланови групе <b class="acluser">%s</b> тренутно имају следеће дозволе за овај именски простор <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Молим Вас <b>унесите корисника или групу</b> у формулар изнад да бисте приказали или изменили дозволе за страницу <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Молим Вас <b>унесите корисника или групу</b> у формулар изнад да бисте приказали или изменили дозволе за именски простор <b class="aclpage">%s</b>.';
+$lang['p_inherited'] = 'Напомена: Ове дозволе се не постављају експлицитно већ само тамо где се не сударају са осталим групама или вишем иманском простору.';
+$lang['p_isadmin'] = 'Напомена: Одабран корисник или група има увек пуне дозволе јер је постављен за суперкорисника.';
+$lang['p_include'] = 'Више дозволе укључују ниже. Дозволе одавања, слања и брисања ће бити примењене само на именске просторе, не и на стране.';
+$lang['current'] = 'Тренутна правила проступа';
+$lang['where'] = 'Страница/Именски простор';
+$lang['who'] = 'Корисник/Група';
+$lang['perm'] = 'Дозволе';
+$lang['acl_perm0'] = 'Ништа';
+$lang['acl_perm1'] = 'Читање';
+$lang['acl_perm2'] = 'Измена';
+$lang['acl_perm4'] = 'Прављење';
+$lang['acl_perm8'] = 'Слање';
+$lang['acl_perm16'] = 'Брисање';
+$lang['acl_new'] = 'Додај нови унос';
+$lang['acl_mod'] = 'Измени унос';
diff --git a/lib/plugins/acl/lang/sv/help.txt b/lib/plugins/acl/lang/sv/help.txt
new file mode 100644
index 000000000..5ba770fa0
--- /dev/null
+++ b/lib/plugins/acl/lang/sv/help.txt
@@ -0,0 +1,8 @@
+=== Hjälp ===
+På den här sidan kan du lägga till och ta bort åtkomsträttigheter för namnrymder och enstaka sidor i din wiki.
+
+Till vänster visas alla tillgängliga namnrymder och sidor du kan välja. I formuläret ovanför kan du sedan välja användare eller grupp för vilken åtkomsträttigheterna ska visas eller ändras.
+
+Tabellen nedanför visar samtliga uppsatta regler för åtkomsträttigheter. Den kan du använda för att snabbt ta bort eller ändra flera regler på en gång.
+
+Läs gärna [[doku>acl|den officiella dokumentationen för ACL]] som kan hjälpa dig till fullo förstå hur åtkomsträttigheter fungerar i DokuWiki. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/sv/lang.php b/lib/plugins/acl/lang/sv/lang.php
new file mode 100644
index 000000000..7f963d5e1
--- /dev/null
+++ b/lib/plugins/acl/lang/sv/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * swedish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['admin_acl'] = 'Hantera behörighetslistan (ACL)';
+$lang['acl_group'] = 'Grupp';
+$lang['acl_user'] = 'Användare';
+$lang['acl_perms'] = 'Behörighet för';
+$lang['page'] = 'Sida';
+$lang['namespace'] = 'Namnrymd';
+$lang['btn_select'] = 'Välj';
+$lang['p_user_id'] = 'Användaren <b class="acluser">%s</b> har förnärvarande följande rättigheter på sidan <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Användaren <b class="acluser">%s</b> har för närvarande följande rättigheter i namnrymden <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Medlemmar av gruppen <b class="aclgroup">%s</b> har för närvarande följande rättigheter på sidan <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Medlemmar av gruppen <b class="aclgroup">%s</b> har för närvarande följande rättigheter i namnrymden <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Vänligen <b>ange en användare eller grupp</b> i formuläret ovan för att visa eller ändra rättigheterna för sidan <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Vänligen <b>ange en användare eller grupp</b> i formuläret ovan för att visa eller ändra rättigheterna för namnrymden <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Notering: De här rättigheterna är inte explicit satta utan var ärvda från andra grupper eller högre namnrymder.';
+$lang['p_isadmin'] = 'Notering: Den valda gruppen eller användaren har alltid fulla rättigheter på grund av att den är konfigurerad som superanvändare.';
+$lang['p_include'] = 'Högre rättigheter inkluderar lägre. Rättigheter för Skapa, Ladda upp och Radera är endast applicerbara namnrymder, inte sidor.';
+$lang['current'] = 'Nuvarande ACL regler';
+$lang['where'] = 'Sida/Namnrymd';
+$lang['who'] = 'Användare/Grupp';
+$lang['perm'] = 'Rättigheter';
+$lang['acl_perm0'] = 'Inga';
+$lang['acl_perm1'] = 'Läsa';
+$lang['acl_perm2'] = 'Redigera';
+$lang['acl_perm4'] = 'Skapa';
+$lang['acl_perm8'] = 'Ladda upp';
+$lang['acl_perm16'] = 'Radera';
+$lang['acl_new'] = 'Lägg till ny behörighet';
+$lang['acl_mod'] = 'Ändra behörighet';
diff --git a/lib/plugins/acl/lang/th/help.txt b/lib/plugins/acl/lang/th/help.txt
new file mode 100644
index 000000000..52edca93f
--- /dev/null
+++ b/lib/plugins/acl/lang/th/help.txt
@@ -0,0 +1,11 @@
+=== ตัวช่วยอย่างเร็ว ===
+
+ในหน้านี้คุณสามารถเพิ่มและถอดสิทธิ์สำหรับเนมสเปซ และเพจในวิกิของคุณ
+
+แถบด้านซ้ายจะแสดงรายชื่อเนมสเปซ และเพจที่มีอยู่ทั้งหมด
+
+แบบฟอร์มข้างบนอนุญาติให้คุณมองเห็น และแก้ไขสิทธิ์ของผู้ใช้หรือกลุ่มที่เลือกไว้ได้
+
+ในตารางด้านล่างได้แสดงกฏควบคุมการเข้าถึงทั้งหมดไว้ คุณสามารถใช้มันลบ หรือเปลี่ยนกฏครั้งละหลายๆตัวพร้อมกันได้อย่างรวดเร็ว
+
+การอ่าน [[doku>acl|official documentation on ACL]] น่าจะช่วยให้คุณเข้าใจวิธีควบคุมการเข้าถึงของโดกุวิกิได้อย่างถ่องแท้ \ No newline at end of file
diff --git a/lib/plugins/acl/lang/th/lang.php b/lib/plugins/acl/lang/th/lang.php
new file mode 100644
index 000000000..472c33cdc
--- /dev/null
+++ b/lib/plugins/acl/lang/th/lang.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['admin_acl'] = 'จัดการรายชื่อเพื่อควบคุมการเข้าถึง (Access Control List:ACL)';
+$lang['acl_group'] = 'กลุ่ม';
+$lang['acl_user'] = 'ผู้ใช้';
+$lang['acl_perms'] = 'สิทธิสำหรับ';
+$lang['page'] = 'เพจ';
+$lang['namespace'] = 'เนมสเปซ';
+$lang['btn_select'] = 'เลือก';
+$lang['where'] = 'เพจ/เนมสเปซ';
+$lang['who'] = 'ผู้ใช้/กลุ่ม';
+$lang['perm'] = 'สิทธิ์';
+$lang['acl_perm0'] = 'ไร้สิทธิ์';
+$lang['acl_perm1'] = 'อ่าน';
+$lang['acl_perm2'] = 'แก้ไข';
+$lang['acl_perm4'] = 'สร้าง';
+$lang['acl_perm8'] = 'อัพโหลด';
+$lang['acl_perm16'] = 'ลบ';
+$lang['acl_new'] = 'เพิ่มเนื้อหาใหม่';
+$lang['acl_mod'] = 'ปรับแก้เนื้อหา';
diff --git a/lib/plugins/acl/lang/tr/help.txt b/lib/plugins/acl/lang/tr/help.txt
new file mode 100644
index 000000000..b467c5019
--- /dev/null
+++ b/lib/plugins/acl/lang/tr/help.txt
@@ -0,0 +1,11 @@
+=== Hızlı yardım: ===
+
+Bu sayfada Wiki'nizin namespace ve sayfaları için izinleri belirleyebilirsiniz.
+
+Soldaki kısım varolan namespace ve sayfaları listeler.
+
+Yukarıdaki kısım seçilen bir kullanıcı veya grup için izinleri görüp değiştirmenizi sağlar.
+
+Aşağıdaki tablo ise varolan erişim kontrol kurallarını gösterir. Bu tabloyu birden fazla kuralı hızlıca silip değiştirmek için kullanabilirsiniz.
+
+Resmi ACL dökümanını ([[doku>acl|official documentation on ACL]]) okuyarak erişim kontrolünün nasıl çalıştığını öğrenebilirsiniz.
diff --git a/lib/plugins/acl/lang/tr/lang.php b/lib/plugins/acl/lang/tr/lang.php
new file mode 100644
index 000000000..de96d2906
--- /dev/null
+++ b/lib/plugins/acl/lang/tr/lang.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * turkish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Selim Farsakoğlu <farsakogluselim@yahoo.de>
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['admin_acl'] = 'Erişim Kontrol Listesi (ACL) Yönetimi';
+$lang['acl_group'] = 'Grup';
+$lang['acl_user'] = 'Kullanıcı';
+$lang['acl_perms'] = 'Şunun için yetkiler:';
+$lang['page'] = 'Sayfa';
+$lang['namespace'] = 'Namespace';
+$lang['btn_select'] = 'Seç';
+$lang['p_user_id'] = '<b class="acluser">%s</b> kullanıcısının şu anda <b class="aclpage">%s</b> sayfası için yetkisi: <i>%s</i>.';
+$lang['p_user_ns'] = '<b class="acluser">%s</b> kullanıcısının şu anda <b class="aclns">%s</b> namesapace\'i için yetkisi: <i>%s</i>.';
+$lang['p_group_id'] = '<b class="aclgroup">%s</b> grubunun şu anda <b class="aclpage">%s</b> sayfası için yetkisi: <i>%s</i>.';
+$lang['p_group_ns'] = '<b class="aclgroup">%s</b> grubunun şu anda <b class="aclns">%s</b> namesapace\'i için yetkisi: <i>%s</i>.';
+$lang['p_choose_id'] = 'Lütfen <b class="aclpage">%s</b> sayfasına izin verilen yetkilerini görmek veya değiştirmek için yukarıdaki forma <b>bir kullanıcı veya grup adı</b> girin.';
+$lang['p_choose_ns'] = 'Lütfen <b class="aclpage">%s</b> namespace\'ie izin verilen yetkileri görmek veya değiştirmek için yukarıdaki forma <b>bir kullanıcı veya grup adı</b> girin.';
+$lang['p_inherited'] = 'Not: Bu izinler doğrudan ayarlanmadan başka grup veya üst namespace\'lerden gelmektedir.';
+$lang['p_isadmin'] = 'Not: Seçili grup veya kullanıcı, "Ana kullanıcı" olarak atandığından tüm izinlere sahiptir.';
+$lang['p_include'] = 'Üst seviye izinler alt izinleri içermektedir. Oluşturma, Yükleme ve Silme yetkisi sadece namespace\'e uygulanmaktadır. Bu yetki sayfalara uygulanmaz.';
+$lang['current'] = 'Şimdiki ACL(İzin Kontrol listesi) kuralları';
+$lang['where'] = 'Sayfa/Namespace';
+$lang['who'] = 'Kullanıcı/Grup';
+$lang['perm'] = 'İzinler';
+$lang['acl_perm0'] = 'Yok';
+$lang['acl_perm1'] = 'Okuma';
+$lang['acl_perm2'] = 'Değiştirme';
+$lang['acl_perm4'] = 'Oluşturma';
+$lang['acl_perm8'] = 'Yükleme';
+$lang['acl_perm16'] = 'Silme';
+$lang['acl_new'] = 'Yeni giriş ekle';
+$lang['acl_mod'] = 'Eski girişi değiştirme';
diff --git a/lib/plugins/acl/lang/uk/help.txt b/lib/plugins/acl/lang/uk/help.txt
new file mode 100644
index 000000000..d16af0aa9
--- /dev/null
+++ b/lib/plugins/acl/lang/uk/help.txt
@@ -0,0 +1,11 @@
+=== Швидка довідка: ===
+
+На цій сторінці ви можете додавати чи знищувати права доступу для просторів імен чи сторінок вашої вікі.
+
+Ліва панель показує всі доступні простори імен і сторінки.
+
+Верхня форма дозволяє переглянути і редагувати права доступу для обраного користувача чи групи
+
+В таблиці знизу показані всі оголошені правила доступу. Можете її використовувати для швидкого знищення чи модифікації кількох правил.
+
+Додаткова допомога в [[doku>acl|офіційній документації по ACL]] допоможе вам більше зрозуміти як працює контроль доступу у ДокуВікі. \ No newline at end of file
diff --git a/lib/plugins/acl/lang/uk/lang.php b/lib/plugins/acl/lang/uk/lang.php
new file mode 100644
index 000000000..99b4b2623
--- /dev/null
+++ b/lib/plugins/acl/lang/uk/lang.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * ukrainian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oleksiy Voronin <ovoronin@gmail.com>
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ */
+$lang['admin_acl'] = 'Керування списками контролю доступу';
+$lang['acl_group'] = 'Група';
+$lang['acl_user'] = 'Користувач';
+$lang['acl_perms'] = 'Права доступу для';
+$lang['page'] = 'Сторінка';
+$lang['namespace'] = 'Простір імен';
+$lang['btn_select'] = 'Вибрати';
+$lang['p_user_id'] = 'Користувач <b class="acluser">%s</b> зараз має такі права доступу до сторінки <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'Користувач <b class="acluser">%s</b> зараз має такі права доступу до простору імен <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Члени групи <b class="aclgroup">%s</b> зараз мають такі права для сторінки <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Члени групи <b class="aclgroup">%s</b> зараз мають такі права доступу до простору імен <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_choose_id'] = 'Будь-ласка <b>введіть користувача або групу<b> в поле зверху, щоб подивитися чи змінити права доступу до сторінки <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Будь-ласка <b>введіть користувача або групу<b> у вікно зверху, щоб подивитися чи змінити права доступу до сторінки <b class="aclns">%s</b>.';
+$lang['p_inherited'] = 'Зверніть увагу! Права доступу, не встановлені явно, наслідуються від інших груп чи вищих просторів імен.';
+$lang['p_isadmin'] = 'Зверніть увагу! Обрані група чи користувач завжди мають повні права доступу, оскільки вони є суперкористувачами.';
+$lang['p_include'] = 'Старші права доступу включають молодші. Створення, Завантаження і Вилучення застосовні лише до просторів імен.';
+$lang['current'] = 'Поточні правила ACL';
+$lang['where'] = 'Сторінка/Простір імен';
+$lang['who'] = 'Користувач/Група';
+$lang['perm'] = 'Права доступу';
+$lang['acl_perm0'] = 'Жодних';
+$lang['acl_perm1'] = 'Читання';
+$lang['acl_perm2'] = 'Редагування';
+$lang['acl_perm4'] = 'Створення';
+$lang['acl_perm8'] = 'Завантаження';
+$lang['acl_perm16'] = 'Вилучення';
+$lang['acl_new'] = 'Додати новий запис';
+$lang['acl_mod'] = 'Змінити запис';
diff --git a/lib/plugins/acl/lang/vi/lang.php b/lib/plugins/acl/lang/vi/lang.php
new file mode 100644
index 000000000..6237f79ba
--- /dev/null
+++ b/lib/plugins/acl/lang/vi/lang.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * vietnamese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author James Do <jdo@myrealbox.com>
+ */
+
+$lang['admin_acl'] = 'Quản lý phép truy nhật {Access Control List}';
+$lang['acl_group'] = 'Nhóm';
+$lang['acl_user'] = 'Người';
+$lang['acl_perms'] = 'Phép truy nhập cho';
+$lang['page'] = 'Trang';
+$lang['namespace'] = 'Không gian tên';
+
+$lang['acl_perm1'] = 'Đọc';
+$lang['acl_perm2'] = 'Biên soạn';
+$lang['acl_perm4'] = 'Tạo';
+$lang['acl_perm8'] = 'Tải lên';
+$lang['acl_new'] = 'Thêm mục mới';
+//Setup VIM: ex: et ts=2 :
diff --git a/lib/plugins/acl/lang/zh-tw/help.txt b/lib/plugins/acl/lang/zh-tw/help.txt
new file mode 100644
index 000000000..bc1bddb00
--- /dev/null
+++ b/lib/plugins/acl/lang/zh-tw/help.txt
@@ -0,0 +1,12 @@
+=== 快速指南: ===
+
+你可以用這個頁面為維基中的命名空間或頁面增加或移除權限。
+
+左方面板顯示了所有命名空間和頁面。
+
+上方表格允許你觀看及修改選取的使用者或群組的權限。
+
+下方表格顯示了目前所有的存取控制表 (ACL),你可以用它快速刪除或更改多項規則。
+
+閱讀 [[doku>acl|official documentation on ACL]] 可以幫助你完整地了解 DokuWiki 存取控制的運作。
+
diff --git a/lib/plugins/acl/lang/zh-tw/lang.php b/lib/plugins/acl/lang/zh-tw/lang.php
new file mode 100644
index 000000000..085537864
--- /dev/null
+++ b/lib/plugins/acl/lang/zh-tw/lang.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Chinese(Traditional) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author chinsan <chinsan@mail2000.com.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin <danny0838@pchome.com.tw>
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['admin_acl'] = '管理存取控制表 (ACL)';
+$lang['acl_group'] = '群組';
+$lang['acl_user'] = '使用者';
+$lang['acl_perms'] = '設定權限於';
+$lang['page'] = '頁面';
+$lang['namespace'] = '命名空間';
+$lang['btn_select'] = '選擇';
+$lang['p_user_id'] = '使用者 <b class="acluser">%s</b> 目前在頁面 <b class="aclpage">%s</b> 擁有以下權限:<i>%s</i>。';
+$lang['p_user_ns'] = '使用者 <b class=\"acluser\">%s</b> 目前在命名空間 <b class=\"aclns\">%s</b> 擁有以下權限:<i>%s</i>。';
+$lang['p_group_id'] = '群組 <b class="aclgroup">%s</b> 的成員目前在頁面 <b class="aclpage">%s</b> 擁有以下權限:<i>%s</i>。';
+$lang['p_group_ns'] = '群組 <b class=\"aclgroup\">%s</b> 的成員目前在命名空間 <b class=\"aclns\">%s</b> 擁有以下權限:<i>%s</i>。';
+$lang['p_choose_id'] = '請在上方表格<b>輸入使用者或群組</b>以檢視或編輯頁面 <b class="aclpage">%s</b> 的權限設定。';
+$lang['p_choose_ns'] = '請在上方表格<b>輸入使用者或群組</b>以檢視或編輯命名空間 <b class=\"aclns\">%s</b> 的權限設定。';
+$lang['p_inherited'] = '注意:這些權限並未明確指定,而是從群組或上層的命名空間繼承而來。';
+$lang['p_isadmin'] = '注意:選取的群組或使用者擁有完整權限,因為它被設定為超級使用者。';
+$lang['p_include'] = '較高的權限亦包含了較低的權限。新增、上傳與刪除權限只能設定在命名空間,不能設定在頁面。';
+$lang['current'] = '目前的存取控制規則';
+$lang['where'] = '頁面/命名空間';
+$lang['who'] = '使用者/群組';
+$lang['perm'] = '權限';
+$lang['acl_perm0'] = '無';
+$lang['acl_perm1'] = '讀取頁面';
+$lang['acl_perm2'] = '編輯頁面';
+$lang['acl_perm4'] = '新增頁面';
+$lang['acl_perm8'] = '上傳圖檔';
+$lang['acl_perm16'] = '刪除檔案';
+$lang['acl_new'] = '增加規則';
+$lang['acl_mod'] = '修改規則';
diff --git a/lib/plugins/acl/lang/zh/help.txt b/lib/plugins/acl/lang/zh/help.txt
new file mode 100644
index 000000000..526dcee9b
--- /dev/null
+++ b/lib/plugins/acl/lang/zh/help.txt
@@ -0,0 +1,11 @@
+=== 快速帮助 ===
+
+本页中您可以添加或移除命名空间或页面的权限。
+
+左边的窗格显示的是全部可用的命名空间和页面。
+
+您可以在上方的表格中查看并修改选定用户或组的权限。
+
+下方的表格中显示的是当前设置的全部访问控制规则。 您可以通过它快速删除或更改多条规则。
+
+参阅 [[doku>acl|official documentation on ACL]] 能帮助您完整地理解 DokuWiki 中的访问控制是如何工作的。
diff --git a/lib/plugins/acl/lang/zh/lang.php b/lib/plugins/acl/lang/zh/lang.php
new file mode 100644
index 000000000..983882eaf
--- /dev/null
+++ b/lib/plugins/acl/lang/zh/lang.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Chinese(Simplified) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['admin_acl'] = '访问控制列表(ACL)管理器';
+$lang['acl_group'] = '组';
+$lang['acl_user'] = '用户';
+$lang['acl_perms'] = '许可给';
+$lang['page'] = '页面';
+$lang['namespace'] = '命名空间';
+$lang['btn_select'] = '選擇';
+$lang['p_user_id'] = '用户 <b class="acluser">%s</b> 当前在页面 <b class="aclpage">%s</b> 拥有以下权限:<i>%s</i>。';
+$lang['p_user_ns'] = '用户 <b class="acluser">%s</b> 当前在命名空间 <b class="aclns">%s</b> 拥有以下权限:<i>%s</i>。';
+$lang['p_group_id'] = '<b class="aclgroup">%s</b> 组成员当前在页面 <b class="aclpage">%s</b> 拥有以下权限:<i>%s</i>。';
+$lang['p_group_ns'] = '<b class="aclgroup">%s</b> 组成员当前在命名空间 <b class="aclns">%s</b> 拥有以下权限:<i>%s</i>。';
+$lang['p_choose_id'] = '请在上表中<b>输入用户名或组名称</b>,来查看或编辑页面 <b class="aclpage">%s</b> 的权限设置。';
+$lang['p_choose_ns'] = '请在上表中<b>输入用户名或组名称</b>,来查看或编辑命名空间 <b class="aclns">%s</b> 的权限设置。';
+$lang['p_inherited'] = '请注意:这些权限并没有明确设定,而是从其他组或更高级的名称空间继承而来。';
+$lang['p_isadmin'] = '请注意:选定的组或用户拥有完全权限,因为它被设定为超级用户。';
+$lang['p_include'] = '高权限包含低权限。创建、上传和删除权限只能应用于名称空间,而不是单个页面。';
+$lang['current'] = '当前 ACL 规则';
+$lang['where'] = '页面/命名空间';
+$lang['who'] = '用户/组';
+$lang['perm'] = '权限';
+$lang['acl_perm0'] = '无';
+$lang['acl_perm1'] = '读取';
+$lang['acl_perm2'] = '编辑';
+$lang['acl_perm4'] = '创建';
+$lang['acl_perm8'] = '上传';
+$lang['acl_perm16'] = '删除';
+$lang['acl_new'] = '添加新条目';
+$lang['acl_mod'] = '编辑条目';
diff --git a/lib/plugins/acl/pix/group.png b/lib/plugins/acl/pix/group.png
new file mode 100644
index 000000000..d80eb2606
--- /dev/null
+++ b/lib/plugins/acl/pix/group.png
Binary files differ
diff --git a/lib/plugins/acl/pix/ns.png b/lib/plugins/acl/pix/ns.png
new file mode 100644
index 000000000..c35e832da
--- /dev/null
+++ b/lib/plugins/acl/pix/ns.png
Binary files differ
diff --git a/lib/plugins/acl/pix/page.png b/lib/plugins/acl/pix/page.png
new file mode 100644
index 000000000..b1b7ebe94
--- /dev/null
+++ b/lib/plugins/acl/pix/page.png
Binary files differ
diff --git a/lib/plugins/acl/pix/user.png b/lib/plugins/acl/pix/user.png
new file mode 100644
index 000000000..7b4a507a0
--- /dev/null
+++ b/lib/plugins/acl/pix/user.png
Binary files differ
diff --git a/lib/plugins/acl/plugin.info.txt b/lib/plugins/acl/plugin.info.txt
new file mode 100644
index 000000000..f108a2390
--- /dev/null
+++ b/lib/plugins/acl/plugin.info.txt
@@ -0,0 +1,6 @@
+author Andreas Gohr
+email andi@splitbrain.org
+date 2011-04-16
+name ACL Manager
+desc Manage Page Access Control Lists
+url http://dokuwiki.org/plugin:acl
diff --git a/lib/plugins/acl/rtl.css b/lib/plugins/acl/rtl.css
new file mode 100644
index 000000000..e79abe596
--- /dev/null
+++ b/lib/plugins/acl/rtl.css
@@ -0,0 +1,40 @@
+div#acl_manager div#acl__tree {
+ float: right;
+ text-align: right;
+}
+
+div#acl_manager div#acl__tree li {
+ padding-left: 0em;
+ padding-right: 1em;
+}
+
+div#acl_manager div#acl__tree ul img {
+ margin-left: 0.25em;
+ margin-right: 0em;
+}
+
+
+div#acl_manager div#acl__detail {
+ float: left;
+}
+
+div#acl_manager .aclgroup {
+ background: transparent url(pix/group.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+div#acl_manager .acluser {
+ background: transparent url(pix/user.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+div#acl_manager .aclpage {
+ background: transparent url(pix/page.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+div#acl_manager .aclns {
+ background: transparent url(pix/ns.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
diff --git a/lib/plugins/acl/script.js b/lib/plugins/acl/script.js
new file mode 100644
index 000000000..0ba91cdc9
--- /dev/null
+++ b/lib/plugins/acl/script.js
@@ -0,0 +1,127 @@
+/**
+ * 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').change(dw_acl.userselhandler);
+ jQuery('#acl__user input[type=submit]').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/plugins/acl/ajax.php',
+ jQuery.extend(dw_acl.parseatt($clicky.parent().find('a')[0].search),
+ {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')
+ .html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="..." />')
+ .load(
+ DOKU_BASE + 'lib/plugins/acl/ajax.php',
+ jQuery('#acl__detail form').serialize() + '&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);
+
+var acl = {
+ init: DEPRECATED_WRAP(dw_acl.init, dw_acl),
+ userselhandler: DEPRECATED_WRAP(dw_acl.userselhandler, dw_acl),
+ loadinfo: DEPRECATED_WRAP(dw_acl.loadinfo, dw_acl),
+ parseatt: DEPRECATED_WRAP(dw_acl.parseatt, dw_acl),
+ treehandler: DEPRECATED_WRAP(dw_acl.treehandler, dw_acl)
+};
diff --git a/lib/plugins/acl/style.css b/lib/plugins/acl/style.css
new file mode 100644
index 000000000..b7154aa78
--- /dev/null
+++ b/lib/plugins/acl/style.css
@@ -0,0 +1,97 @@
+
+div#acl_manager div#acl__tree {
+ font-size: 90%;
+ width: 25%;
+ height: 300px;
+ float: left;
+ overflow: auto;
+ border: 1px solid __border__;
+ text-align: left;
+}
+
+div#acl_manager div#acl__tree a.cur {
+ background-color: __highlight__;
+ font-weight: bold;
+}
+
+div#acl_manager div#acl__tree ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+div#acl_manager div#acl__tree li {
+ padding-left: 1em;
+ list-style-image: none;
+}
+
+div#acl_manager div#acl__tree ul img {
+ margin-right: 0.25em;
+ cursor: pointer;
+}
+
+div#acl_manager div#acl__detail {
+ width: 73%;
+ height: 300px;
+ float: right;
+ overflow: auto;
+}
+
+div#acl_manager div#acl__detail fieldset {
+ width: 90%;
+}
+
+div#acl_manager div#acl__detail div#acl__user {
+ border: 1px solid __border__;
+ padding: 0.5em;
+ margin-bottom: 0.6em;
+}
+
+div#acl_manager table.inline {
+ width: 100%;
+ margin: 0;
+}
+
+div#acl_manager .aclgroup {
+ background: transparent url(pix/group.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+
+div#acl_manager .acluser {
+ background: transparent url(pix/user.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+
+div#acl_manager .aclpage {
+ background: transparent url(pix/page.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+
+div#acl_manager .aclns {
+ background: transparent url(pix/ns.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+
+div#acl_manager label.disabled {
+ color: __text_neu__!important;
+}
+
+#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/lib/plugins/action.php b/lib/plugins/action.php
new file mode 100644
index 000000000..885bd7c96
--- /dev/null
+++ b/lib/plugins/action.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Action Plugin Prototype
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to interfere with the event system
+ * need to inherit from this class
+ */
+class DokuWiki_Action_Plugin extends DokuWiki_Plugin {
+
+ /**
+ * Registers a callback function for a given event
+ */
+ function register($controller) {
+ trigger_error('register() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+}
diff --git a/lib/plugins/admin.php b/lib/plugins/admin.php
new file mode 100644
index 000000000..9a1fb9fdc
--- /dev/null
+++ b/lib/plugins/admin.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Admin Plugin Prototype
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class DokuWiki_Admin_Plugin extends DokuWiki_Plugin {
+
+ function getMenuText($language) {
+ $menutext = $this->getLang('menu');
+ if (!$menutext) {
+ $info = $this->getInfo();
+ $menutext = $info['name'].' ...';
+ }
+ return $menutext;
+ }
+
+ function getMenuSort() {
+ return 1000;
+ }
+
+ function handle() {
+ trigger_error('handle() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ function html() {
+ trigger_error('html() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ function forAdminOnly() {
+ return true;
+ }
+
+ function getTOC(){
+ return array();
+ }
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/config/admin.php b/lib/plugins/config/admin.php
new file mode 100644
index 000000000..9a9bb5329
--- /dev/null
+++ b/lib/plugins/config/admin.php
@@ -0,0 +1,357 @@
+<?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>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+define('CM_KEYMARKER','____'); // used for settings with multiple dimensions of array indices
+
+define('PLUGIN_SELF',dirname(__FILE__).'/');
+define('PLUGIN_METADATA',PLUGIN_SELF.'settings/config.metadata.php');
+if(!defined('DOKU_PLUGIN_IMAGES')) define('DOKU_PLUGIN_IMAGES',DOKU_BASE.'lib/plugins/config/images/');
+
+require_once(PLUGIN_SELF.'settings/config.class.php'); // main configuration class and generic settings classes
+require_once(PLUGIN_SELF.'settings/extra.class.php'); // settings classes specific to these settings
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_config extends DokuWiki_Admin_Plugin {
+
+ var $_file = PLUGIN_METADATA;
+ var $_config = null;
+ var $_input = null;
+ var $_changed = false; // set to true if configuration has altered
+ var $_error = false;
+ var $_session_started = false;
+ var $_localised_prompts = false;
+
+ function getMenuSort() { return 100; }
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ global $ID;
+
+ if (!$this->_restore_session()) return $this->_close_session();
+ if (!isset($_REQUEST['save']) || ($_REQUEST['save'] != 1)) return $this->_close_session();
+ if (!checkSecurityToken()) return $this->_close_session();
+
+ if (is_null($this->_config)) { $this->_config = new configuration($this->_file); }
+
+ // don't go any further if the configuration is locked
+ if ($this->_config->_locked) return $this->_close_session();
+
+ $this->_input = $_REQUEST['config'];
+
+ while (list($key) = each($this->_config->setting)) {
+ $input = isset($this->_input[$key]) ? $this->_input[$key] : NULL;
+ if ($this->_config->setting[$key]->update($input)) {
+ $this->_changed = true;
+ }
+ if ($this->_config->setting[$key]->error()) $this->_error = true;
+ }
+
+ if ($this->_changed && !$this->_error) {
+ $this->_config->save_settings($this->getPluginName());
+
+ // save state & force a page reload to get the new settings to take effect
+ $_SESSION['PLUGIN_CONFIG'] = array('state' => 'updated', 'time' => time());
+ $this->_close_session();
+ header("Location: ".wl($ID,array('do'=>'admin','page'=>'config'),true,'&'));
+ exit();
+ }
+
+ $this->_close_session();
+ }
+
+ /**
+ * output appropriate html
+ */
+ function html() {
+ $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
+ global $lang;
+ global $ID;
+
+ if (is_null($this->_config)) { $this->_config = new configuration($this->_file); }
+ $this->setupLocale(true);
+
+ print $this->locale_xhtml('intro');
+
+ ptln('<div id="config__manager">');
+
+ if ($this->_config->locked)
+ ptln('<div class="info">'.$this->getLang('locked').'</div>');
+ elseif ($this->_error)
+ ptln('<div class="error">'.$this->getLang('error').'</div>');
+ elseif ($this->_changed)
+ ptln('<div class="success">'.$this->getLang('updated').'</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.
+ ptln('<form action="'.script().'" method="post">');
+ ptln('<div class="no"><input type="hidden" name="id" value="'.$ID.'" /></div>');
+ formSecurityToken();
+ $this->_print_h1('dokuwiki_settings', $this->getLang('_header_dokuwiki'));
+
+ $undefined_settings = array();
+ $in_fieldset = false;
+ $first_plugin_fieldset = true;
+ $first_template_fieldset = true;
+ foreach($this->_config->setting as $setting) {
+ if (is_a($setting, 'setting_hidden')) {
+ // skip hidden (and undefined) settings
+ if ($allow_debug && is_a($setting, 'setting_undefined')) {
+ $undefined_settings[] = $setting;
+ } else {
+ continue;
+ }
+ } else if (is_a($setting, 'setting_fieldset')) {
+ // config setting group
+ if ($in_fieldset) {
+ ptln(' </table>');
+ ptln(' </fieldset>');
+ } else {
+ $in_fieldset = true;
+ }
+ if ($first_plugin_fieldset && substr($setting->_key, 0, 10)=='plugin'.CM_KEYMARKER) {
+ $this->_print_h1('plugin_settings', $this->getLang('_header_plugin'));
+ $first_plugin_fieldset = false;
+ } else if ($first_template_fieldset && substr($setting->_key, 0, 7)=='tpl'.CM_KEYMARKER) {
+ $this->_print_h1('template_settings', $this->getLang('_header_template'));
+ $first_template_fieldset = false;
+ }
+ ptln(' <fieldset id="'.$setting->_key.'">');
+ ptln(' <legend>'.$setting->prompt($this).'</legend>');
+ ptln(' <div class="table">');
+ ptln(' <table class="inline">');
+ } else {
+ // config settings
+ list($label,$input) = $setting->html($this, $this->_error);
+
+ $class = $setting->is_default() ? ' class="default"' : ($setting->is_protected() ? ' class="protected"' : '');
+ $error = $setting->error() ? ' class="value error"' : ' class="value"';
+ $icon = $setting->caution() ? '<img src="'.DOKU_PLUGIN_IMAGES.$setting->caution().'.png" alt="'.$setting->caution().'" title="'.$this->getLang($setting->caution()).'" />' : '';
+
+ ptln(' <tr'.$class.'>');
+ ptln(' <td class="label">');
+ ptln(' <span class="outkey">'.$setting->_out_key(true, true).'</span>');
+ ptln(' '.$icon.$label);
+ ptln(' </td>');
+ ptln(' <td'.$error.'>'.$input.'</td>');
+ ptln(' </tr>');
+ }
+ }
+
+ ptln(' </table>');
+ ptln(' </div>');
+ if ($in_fieldset) {
+ ptln(' </fieldset>');
+ }
+
+ // show undefined settings list
+ if ($allow_debug && !empty($undefined_settings)) {
+ function _setting_natural_comparison($a, $b) { return strnatcmp($a->_key, $b->_key); }
+ usort($undefined_settings, '_setting_natural_comparison');
+ $this->_print_h1('undefined_settings', $this->getLang('_header_undefined'));
+ ptln('<fieldset>');
+ ptln('<div class="table">');
+ ptln('<table class="inline">');
+ $undefined_setting_match = array();
+ foreach($undefined_settings as $setting) {
+ if (preg_match('/^(?:plugin|tpl)'.CM_KEYMARKER.'.*?'.CM_KEYMARKER.'(.*)$/', $setting->_key, $undefined_setting_match)) {
+ $undefined_setting_key = $undefined_setting_match[1];
+ } else {
+ $undefined_setting_key = $setting->_key;
+ }
+ ptln(' <tr>');
+ ptln(' <td class="label"><span title="$meta[\''.$undefined_setting_key.'\']">$'.$this->_config->_name.'[\''.$setting->_out_key().'\']</span></td>');
+ ptln(' <td>'.$this->getLang('_msg_'.get_class($setting)).'</td>');
+ ptln(' </tr>');
+ }
+ ptln('</table>');
+ ptln('</div>');
+ ptln('</fieldset>');
+ }
+
+ // finish up form
+ ptln('<p>');
+ ptln(' <input type="hidden" name="do" value="admin" />');
+ ptln(' <input type="hidden" name="page" value="config" />');
+
+ if (!$this->_config->locked) {
+ ptln(' <input type="hidden" name="save" value="1" />');
+ ptln(' <input type="submit" name="submit" class="button" value="'.$lang['btn_save'].'" accesskey="s" />');
+ ptln(' <input type="reset" class="button" value="'.$lang['btn_reset'].'" />');
+ }
+
+ ptln('</p>');
+
+ ptln('</form>');
+ ptln('</div>');
+ }
+
+ /**
+ * @return boolean true - proceed with handle, false - don't proceed
+ */
+ function _restore_session() {
+
+ // dokuwiki closes the session before act_dispatch. $_SESSION variables are all set,
+ // however they can't be changed without starting the session again
+ if (!headers_sent()) {
+ session_start();
+ $this->_session_started = true;
+ }
+
+ if (!isset($_SESSION['PLUGIN_CONFIG'])) return true;
+
+ $session = $_SESSION['PLUGIN_CONFIG'];
+ unset($_SESSION['PLUGIN_CONFIG']);
+
+ // still valid?
+ if (time() - $session['time'] > 120) return true;
+
+ switch ($session['state']) {
+ case 'updated' :
+ $this->_changed = true;
+ return false;
+ }
+
+ return true;
+ }
+
+ function _close_session() {
+ if ($this->_session_started) session_write_close();
+ }
+
+ function setupLocale($prompts=false) {
+
+ parent::setupLocale();
+ if (!$prompts || $this->_localised_prompts) return;
+
+ $this->_setup_localised_plugin_prompts();
+ $this->_localised_prompts = true;
+
+ }
+
+ function _setup_localised_plugin_prompts() {
+ global $conf;
+
+ $langfile = '/lang/'.$conf['lang'].'/settings.php';
+ $enlangfile = '/lang/en/settings.php';
+
+ if ($dh = opendir(DOKU_PLUGIN)) {
+ while (false !== ($plugin = readdir($dh))) {
+ if ($plugin == '.' || $plugin == '..' || $plugin == 'tmp' || $plugin == 'config') continue;
+ if (is_file(DOKU_PLUGIN.$plugin)) continue;
+
+ if (@file_exists(DOKU_PLUGIN.$plugin.$enlangfile)){
+ $lang = array();
+ @include(DOKU_PLUGIN.$plugin.$enlangfile);
+ if ($conf['lang'] != 'en') @include(DOKU_PLUGIN.$plugin.$langfile);
+ foreach ($lang as $key => $value){
+ $this->lang['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
+ }
+ }
+
+ // fill in the plugin name if missing (should exist for plugins with settings)
+ if (!isset($this->lang['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.'plugin_settings_name'])) {
+ $this->lang['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.'plugin_settings_name'] =
+ ucwords(str_replace('_', ' ', $plugin)).' '.$this->getLang('_plugin_sufix');
+ }
+ }
+ closedir($dh);
+ }
+
+ // the same for the active template
+ $tpl = $conf['template'];
+
+ if (@file_exists(tpl_incdir().$enlangfile)){
+ $lang = array();
+ @include(tpl_incdir().$enlangfile);
+ if ($conf['lang'] != 'en') @include(tpl_incdir().$langfile);
+ foreach ($lang as $key => $value){
+ $this->lang['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
+ }
+ }
+
+ // fill in the template name if missing (should exist for templates with settings)
+ if (!isset($this->lang['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.'template_settings_name'])) {
+ $this->lang['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.'template_settings_name'] =
+ ucwords(str_replace('_', ' ', $tpl)).' '.$this->getLang('_template_sufix');
+ }
+
+ return true;
+ }
+
+ /**
+ * Generates a two-level table of contents for the config plugin.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+ function getTOC() {
+ if (is_null($this->_config)) { $this->_config = new configuration($this->_file); }
+ $this->setupLocale(true);
+
+ $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
+
+ // gather toc data
+ $has_undefined = false;
+ $toc = array('conf'=>array(), 'plugin'=>array(), 'template'=>null);
+ foreach($this->_config->setting as $setting) {
+ if (is_a($setting, 'setting_fieldset')) {
+ if (substr($setting->_key, 0, 10)=='plugin'.CM_KEYMARKER) {
+ $toc['plugin'][] = $setting;
+ } else if (substr($setting->_key, 0, 7)=='tpl'.CM_KEYMARKER) {
+ $toc['template'] = $setting;
+ } else {
+ $toc['conf'][] = $setting;
+ }
+ } else if (!$has_undefined && is_a($setting, 'setting_undefined')) {
+ $has_undefined = true;
+ }
+ }
+
+ // build toc
+ $t = array();
+
+ $t[] = html_mktocitem('configuration_manager', $this->getLang('_configuration_manager'), 1);
+ $t[] = html_mktocitem('dokuwiki_settings', $this->getLang('_header_dokuwiki'), 1);
+ foreach($toc['conf'] as $setting) {
+ $name = $setting->prompt($this);
+ $t[] = html_mktocitem($setting->_key, $name, 2);
+ }
+ if (!empty($toc['plugin'])) {
+ $t[] = html_mktocitem('plugin_settings', $this->getLang('_header_plugin'), 1);
+ }
+ foreach($toc['plugin'] as $setting) {
+ $name = $setting->prompt($this);
+ $t[] = html_mktocitem($setting->_key, $name, 2);
+ }
+ if (isset($toc['template'])) {
+ $t[] = html_mktocitem('template_settings', $this->getLang('_header_template'), 1);
+ $setting = $toc['template'];
+ $name = $setting->prompt($this);
+ $t[] = html_mktocitem($setting->_key, $name, 2);
+ }
+ if ($has_undefined && $allow_debug) {
+ $t[] = html_mktocitem('undefined_settings', $this->getLang('_header_undefined'), 1);
+ }
+
+ return $t;
+ }
+
+ function _print_h1($id, $text) {
+ ptln('<h1><a name="'.$id.'" id="'.$id.'">'.$text.'</a></h1>');
+ }
+
+
+}
diff --git a/lib/plugins/config/images/danger.png b/lib/plugins/config/images/danger.png
new file mode 100644
index 000000000..7bd84f7a3
--- /dev/null
+++ b/lib/plugins/config/images/danger.png
Binary files differ
diff --git a/lib/plugins/config/images/security.png b/lib/plugins/config/images/security.png
new file mode 100644
index 000000000..1800f8e56
--- /dev/null
+++ b/lib/plugins/config/images/security.png
Binary files differ
diff --git a/lib/plugins/config/images/warning.png b/lib/plugins/config/images/warning.png
new file mode 100644
index 000000000..c5e482f84
--- /dev/null
+++ b/lib/plugins/config/images/warning.png
Binary files differ
diff --git a/lib/plugins/config/lang/af/lang.php b/lib/plugins/config/lang/af/lang.php
new file mode 100644
index 000000000..cf71576d8
--- /dev/null
+++ b/lib/plugins/config/lang/af/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['userewrite'] = 'Gebraik moie URLs';
+$lang['sepchar'] = 'Blydsy naam woord spassie';
+$lang['typography_o_0'] = 'Niks';
+$lang['userewrite_o_0'] = 'niks';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['deaccent_o_0'] = 'aff';
+$lang['gdlib_o_0'] = 'GD Lib nie beskibaar nie';
+$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';
+$lang['compression_o_0'] = 'niks';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'moet nie gebrake nie';
+$lang['useheading_o_0'] = 'Noit';
+$lang['useheading_o_1'] = 'Altyde';
diff --git a/lib/plugins/config/lang/ar/intro.txt b/lib/plugins/config/lang/ar/intro.txt
new file mode 100644
index 000000000..d447ec315
--- /dev/null
+++ b/lib/plugins/config/lang/ar/intro.txt
@@ -0,0 +1,7 @@
+====== مدير الضبط ======
+
+استخدم هذه الصفحة للتحكم باعدادات دوكو ويكي المثبتة عندك. للمساعدة في أمر ما أشر إلى [[doku>config]]. لمعلومات اكثر عن هذه الاضافة انظر [[doku>plugin:config]].
+
+الاعدادات الظاهرة بخلفية حمراء فاتحة اعدادات محمية ولا يمكن تغييرها بهذه الاضافة. الاعدادات الظاهرة بخلفية زرقاء هي القيم الافتراضية والاعدادات الظاهرة بخلفية بيضاء خصصت لهذا التثبيت محليا. الاعدادات الزرقاء والبيضاء يمكن تغييرها.
+
+تأكد من ضغط زر **SAVE** قبل ترك الصفحة وإلا ستضيع تعديلاتك. \ No newline at end of file
diff --git a/lib/plugins/config/lang/ar/lang.php b/lib/plugins/config/lang/ar/lang.php
new file mode 100644
index 000000000..63d258485
--- /dev/null
+++ b/lib/plugins/config/lang/ar/lang.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['menu'] = 'الإعدادات';
+$lang['error'] = 'لم تحدث الاعدادات بسبب قيمة غير صالحة، رجاء راجع تغييراتك ثم ارسلها.
+<br />القيم الخاطئة ستظهر محاطة بحدود حمراء.';
+$lang['updated'] = 'رفعت الاعدادات بنجاح.';
+$lang['nochoice'] = '(لا خيارات اخرى متاحة)';
+$lang['locked'] = 'تعذر تحديث ملف الاعدادات، إن لم يكن ذلك مقصودا، <br />
+تأكد من صحة اسم و صلاحيات ملف الاعدادات المحلي.';
+$lang['danger'] = 'خطر: تغيير هذا الخيار قد يؤدي إلى تعذر الوصول للويكي و قائمة الاعدادات.';
+$lang['warning'] = 'تحذير: تغييرهذا الخيار قد يؤدي لسلوك غير متوقع.';
+$lang['security'] = 'تحذير أمني: تغيير هذا الخيار قد يؤدي إلى مخاطرة أمنية.';
+$lang['_configuration_manager'] = 'مدير الاعدادات';
+$lang['_header_dokuwiki'] = 'اعدادات دوكو ويكي';
+$lang['_header_plugin'] = 'اعدادات الملحقات';
+$lang['_header_template'] = 'اعدادات القوالب';
+$lang['_header_undefined'] = 'اعدادات غير محددة';
+$lang['_basic'] = 'اعدادات اساسية';
+$lang['_display'] = 'اعدادات العرض';
+$lang['_authentication'] = 'اعدادات المواثقة';
+$lang['_anti_spam'] = 'اعدادات مضاد النفاية';
+$lang['_editing'] = 'اعدادات التحرير';
+$lang['_links'] = 'اعدادات الروابط';
+$lang['_media'] = 'اعدادات الوسائط';
+$lang['_advanced'] = 'اعدادات متقدمة';
+$lang['_network'] = 'اعدادات الشبكة';
+$lang['_plugin_sufix'] = 'اعدادات الملحقات';
+$lang['_template_sufix'] = 'اعدادات القوالب';
+$lang['_msg_setting_undefined'] = 'لا بيانات إعدادات.';
+$lang['_msg_setting_no_class'] = 'لا صنف إعدادات.';
+$lang['_msg_setting_no_default'] = 'لا قيمة افتراضية.';
+$lang['fmode'] = 'نمط انشاء الملفات';
+$lang['dmode'] = 'نمط انشاء المجلدات';
+$lang['lang'] = 'لغة الواجهة';
+$lang['basedir'] = 'مسار الخادوم (مثال. <code>/dokuwiki/</code>) اترك فارغا للاكتشاف التلقائي.';
+$lang['baseurl'] = 'عنوان الخادوم (مثال. <code>http://www.yourserver.com</code>). اترك فارغا للاكتشاف التلقائي.';
+$lang['savedir'] = 'دليل حفظ البيانات';
+$lang['start'] = 'اسم صفحة البداية';
+$lang['title'] = 'عنوان الويكي';
+$lang['template'] = 'القالب';
+$lang['license'] = 'تحت أي رخصة تريد اصدار المحتوى؟';
+$lang['fullpath'] = 'اظهر المحتوى الكامل للصفحات في ';
+$lang['recent'] = 'أحدث التغييرات';
+$lang['breadcrumbs'] = 'عدد العناقيد للزيارات';
+$lang['youarehere'] = 'عناقيد هرمية';
+$lang['typography'] = 'اعمل استبدالات طبوغرافية';
+$lang['htmlok'] = 'مكّن تضمين HTML';
+$lang['phpok'] = 'مكّن تضمين PHP';
+$lang['dformat'] = 'تنسيق التاريخ (انظر وظيفة PHP,s <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'التوقيع';
+$lang['toptoclevel'] = 'المستوى الأعلى لمحتويات الجدول';
+$lang['tocminheads'] = 'الحد الأدنى من الترويسات لبناء جدول المحتويات';
+$lang['maxtoclevel'] = 'المستوى الأقصى لمحتويات الجدول';
+$lang['maxseclevel'] = 'المستوى الأقصى لتحرير القسم';
+$lang['camelcase'] = 'استخدم CamelCase للروابط';
+$lang['deaccent'] = 'نظّف اسماء الصفحات';
+$lang['useheading'] = 'استخدم اول ترويسة كأسم للصفحة';
+$lang['refcheck'] = 'التحقق من مرجع الوسائط';
+$lang['refshow'] = 'عدد مراجع الوسائط لتعرض';
+$lang['allowdebug'] = 'مكّن التنقيح <b>عطّلها إن لم تكن بحاجلة لها!</b>';
+$lang['usewordblock'] = 'احجز الغثاء بناء على قائمة كلمات';
+$lang['indexdelay'] = 'التأخير قبل الفهرسة (ثوان)';
+$lang['relnofollow'] = 'استخدم rel="nofollow" للروابط الخارجية';
+$lang['mailguard'] = 'عناوين بريدية مبهمة';
+$lang['iexssprotect'] = 'تحقق الملفات المرفوعة من احتمال وجود أكواد جافاسكربت أو HTML ضارة';
+$lang['showuseras'] = 'الذي يعرض لاظهار المستخدم الذي قام بآخر تحرير لصفحة';
+$lang['useacl'] = 'استخدم قائمة التحم بالوصول';
+$lang['autopasswd'] = 'ولد كلمات سر تلقائيا';
+$lang['authtype'] = 'آلية المواثقة';
+$lang['passcrypt'] = 'نمط تشفير كلمة السر';
+$lang['defaultgroup'] = 'المجموعة الافتراضية';
+$lang['superuser'] = 'مجموعة المستخدم المتفوق أو مستخدم أو قائمة مفصولة بالفاصلة مستخدم1،@مجموعة، مستخدم2 صلاحيتهم الوصول الكامل لكل الصفحات و الوظائف بغض النظر عن اعدادات ACL';
+$lang['manager'] = 'مجموعة المدراء أو مستخدم أو قائمة مفصولة بالفاصلة مستخدم1،@مجموعة، مستخدم2 صلاحيتهم بعض الوظائف الادارية';
+$lang['profileconfirm'] = 'اكد تغيير اللاحة بكلمة المرور';
+$lang['disableactions'] = 'عطّل اجراءات دوكو ويكي';
+$lang['disableactions_check'] = 'تحقق';
+$lang['disableactions_subscription'] = 'اشترك/الغ الاشتراك';
+$lang['disableactions_wikicode'] = 'اعرض المصدر/صدّر صرفا';
+$lang['disableactions_other'] = 'اجراءات أخرى (مفصولة بالفاصلة)';
+$lang['sneaky_index'] = 'افتراضيا، ستعرض دوكو ويكي كل اسماء النطاقات في عرض الفهرس. تفعيل هذا الخيار سيخفي مالا يملك المستخدم صلاحية قراءته. قد يؤدي هذا إلى اخفاء نطاقات فرعية متاحة. وقد يؤدي لجعل صفحة الفهرس معطلة في بعض اعدادات ACL.';
+$lang['auth_security_timeout'] = 'زمن انتهاء أمان المواثقة (ثوان)';
+$lang['securecookie'] = 'هل يفرض على كعكات التصفح المعدة عبر HTTPS ان ترسل فقط عبر HTTPS من قبل المتصفح؟ عطل هذا إن كان الولوج للويكي مؤمنا فقط عبر SSL لكن تصفح الويكي غير مؤمن.';
+$lang['xmlrpc'] = 'مكّن/عطل واجهة XML-RPC.';
+$lang['xmlrpcuser'] = 'احصر الوصول لـ XML-RPC بمستخدمين أو مجموعات مفصولة بالفاصلة هنا. اتركها فارغة لتمكين الوصول للجميع.';
+$lang['updatecheck'] = 'تحقق من التحديثات و تنبيهات الأمان؟ دوكو ويكي ستحتاج للاتصال ب update.dokuwiki.org لأجل ذلك';
+$lang['userewrite'] = 'استعمل عناوين URLs جميلة';
+$lang['useslash'] = 'استخدم الشرطة كفاصل النطاق في العناوين';
+$lang['usedraft'] = 'احفظ المسودة تلقائيا أثناء التحرير';
+$lang['sepchar'] = 'فاصل كلمة اسم الصفحة';
+$lang['canonical'] = 'استخدم العناوين الشائعة كاملة';
+$lang['fnencode'] = 'نظام ترميز اسماء الملفات بغير الأسكي.';
+$lang['autoplural'] = 'تحقق من صيغ الجمع في الروابط';
+$lang['compression'] = 'طريقة الغضط لملفات attic';
+$lang['cachetime'] = 'الحد الأعظم لعمر المخُبأ (ثوان)';
+$lang['locktime'] = 'الحد الأعظمي لقفل الملف (ثوان)';
+$lang['fetchsize'] = 'الحجم الأعظمي (بايت) ل fetch.php لتنزيله من الخارج';
+$lang['notify'] = 'ارسل تنبيهات التغيير لهذا البريد';
+$lang['registernotify'] = 'ارسل بيانات عن المستخدمين المسجلين جديدا لهذا البريد';
+$lang['mailfrom'] = 'البريد الالكتروني ليستخدم للرسائل الآلية';
+$lang['mailprefix'] = 'بادئة موضوع البريد لتستخدم مع الرسائل الآلية';
+$lang['gzip_output'] = 'استخدم ترميز-محتوى gzip ل xhtml';
+$lang['gdlib'] = 'اصدار مكتبة GD';
+$lang['im_convert'] = 'المسار إلى اداة تحويل ImageMagick';
+$lang['jpg_quality'] = 'دقة ضغط JPG (0-100)';
+$lang['subscribers'] = 'مكن دعم اشتراك الصفحة';
+$lang['subscribe_time'] = 'المهلة بعد ارسال قوائم الاشتراكات والملخصات (ثوان); هذا يجب أن يكون أقل من الوقت المخصص في أيام أحدث التغييرات.';
+$lang['compress'] = 'رُص مخرجات CSS و جافا سكربت';
+$lang['hidepages'] = 'أخف الصفحات المنطبق عليها (تعابير شرطية)';
+$lang['send404'] = 'ارسل "HTTP 404/Page Not Found" للصفحات غير الموجودة';
+$lang['sitemap'] = 'ولد خرائط موقع جوجل (أيام)';
+$lang['xsendfile'] = 'استخدم ترويسة X-Sendfile لتمكين خادم الوب من تقديم ملفات ثابتة؟ يجب أن يكون خادم الوب داعما له.';
+$lang['renderer__core'] = '%s (نواة دوكو ويكي)';
+$lang['renderer__plugin'] = '%s (ملحق)';
+$lang['rememberme'] = 'اسمح بكعكات الدخول الدائم (تذكرني)';
+$lang['rss_type'] = 'نوع تلقيمات XML';
+$lang['rss_linkto'] = 'تلقيمات XML توصل إلى';
+$lang['rss_content'] = 'مالذي يعرض في عناصر تلقيمات XML؟';
+$lang['rss_update'] = 'تحديث تلقيم XML (ثوان)';
+$lang['recent_days'] = 'مدة إبقاء أحدث التغييرات (ايام)';
+$lang['rss_show_summary'] = 'تلقيم XML يظهر ملخصا في العنوان';
+$lang['target____wiki'] = 'النافذة الهدف للروابط الداخلية';
+$lang['target____interwiki'] = 'النافذة الهدف للروابط الممرة interwiki';
+$lang['target____extern'] = 'النافذة الهدف للروابط الخارجية';
+$lang['target____media'] = 'النافذة الهدف لروابط الوسائط';
+$lang['target____windows'] = 'النافذة الهدف لروابط النوافذ';
+$lang['proxy____host'] = 'اسم خادوم الوكيل';
+$lang['proxy____port'] = 'منفذ الوكيل';
+$lang['proxy____user'] = 'اسم مستخدم الوكيل';
+$lang['proxy____pass'] = 'كلمة سر الوكيل';
+$lang['proxy____ssl'] = 'استخدم ssl للاتصال بالوكيل';
+$lang['proxy____except'] = 'تعبير شرطي لمقابلة العناوين التي ستتجاوز البروكسي.';
+$lang['safemodehack'] = 'مكّن hack الوضع الآمن';
+$lang['ftp____host'] = 'خادوم FTP ل hack الوضع الآمن';
+$lang['ftp____port'] = 'منفذ FTP ل hack الوضع الآمن';
+$lang['ftp____user'] = 'اسم مستخدم FTP ل hack الوضع الآمن';
+$lang['ftp____pass'] = 'كلمة سر FTP ل hack الوضع الآمن';
+$lang['ftp____root'] = 'دليل الجذر ل FTP لأجل hack الوضع الآمن';
+$lang['license_o_'] = 'غير مختار';
+$lang['typography_o_0'] = 'لاشيء';
+$lang['typography_o_1'] = 'استبعاد الاقتباس المفرد';
+$lang['typography_o_2'] = 'تضمين علامات اقتباس مفردة (قد لا يعمل دائما)';
+$lang['userewrite_o_0'] = 'لاشيء';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'دو';
+$lang['deaccent_o_0'] = 'معطل';
+$lang['deaccent_o_1'] = 'أزل اللهجة';
+$lang['deaccent_o_2'] = 'اجعلها لاتينية';
+$lang['gdlib_o_0'] = 'مكتبة GD غير متوفرة';
+$lang['gdlib_o_1'] = 'الاصدار 1.x';
+$lang['gdlib_o_2'] = 'اكتشاف تلقائي';
+$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'] = 'أتوم 0.3';
+$lang['rss_type_o_atom1'] = 'أتوم 1.0';
+$lang['rss_content_o_abstract'] = 'خلاصة';
+$lang['rss_content_o_diff'] = 'الفروق الموحدة';
+$lang['rss_content_o_htmldiff'] = 'جدول الفروق بهيئة HTML';
+$lang['rss_content_o_html'] = 'محتوى HTML الكامل للصفحة';
+$lang['rss_linkto_o_diff'] = 'عرض الاختلافات';
+$lang['rss_linkto_o_page'] = 'الصفحة المعدلة';
+$lang['rss_linkto_o_rev'] = 'قائمة بالمراجعات';
+$lang['rss_linkto_o_current'] = 'الصفحة الحالية';
+$lang['compression_o_0'] = 'لا شيء';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'لا تستخدم';
+$lang['xsendfile_o_1'] = 'ترويسة lighttpd مملوكة (قبل الاصدار 1.5)';
+$lang['xsendfile_o_2'] = 'ترويسة X-Sendfile قياسية';
+$lang['xsendfile_o_3'] = 'ترويسة Nginx X-Accel-Redirect مملوكة';
+$lang['showuseras_o_loginname'] = 'اسم الدخول';
+$lang['showuseras_o_username'] = 'اسم المستخدم الكامل';
+$lang['showuseras_o_email'] = 'عنوان بريد المستخدم (مبهم تبعا لاعدادات حارس_البريد)';
+$lang['showuseras_o_email_link'] = 'عنوان بريد المستخدم كـ مالتيو: رابط';
+$lang['useheading_o_0'] = 'أبدا';
+$lang['useheading_o_navigation'] = 'التنقل فقط';
+$lang['useheading_o_content'] = 'محتوى الويكي فقط';
+$lang['useheading_o_1'] = 'دائما';
+$lang['readdircache'] = 'المدة القصوى لتخزين ';
diff --git a/lib/plugins/config/lang/bg/intro.txt b/lib/plugins/config/lang/bg/intro.txt
new file mode 100644
index 000000000..db09e6838
--- /dev/null
+++ b/lib/plugins/config/lang/bg/intro.txt
@@ -0,0 +1,7 @@
+====== Диспечер на настройките ======
+
+От тук можете да управлявате настройките на вашето Dokuwiki. За отделните настройки вижте [[doku>config]]. За повече информация относно тази приставка вижте [[doku>plugin:config]].
+
+Настройките изобразени със светло червен фон са защитени и не могат да бъдат променяни с тази приставка. Настройките показани със син фон са стандартните стойности, а настройките с бял фон са били настроени локално за тази конкретна инсталация. Можете да променяте както сините, така и белите настройки.
+
+Не забравяйте да натиснете бутона **ЗАПИС** преди да напуснете страницата, в противен случай промените няма да бъдат приложени.
diff --git a/lib/plugins/config/lang/bg/lang.php b/lib/plugins/config/lang/bg/lang.php
new file mode 100644
index 000000000..ed29c079b
--- /dev/null
+++ b/lib/plugins/config/lang/bg/lang.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * bulgarian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['menu'] = 'Настройки';
+$lang['error'] = 'Обновяването на настройките не е възможно, поради невалидна стойност, моля, прегледайте промените си и пробвайте отново.
+<br />Неверните стойности ще бъдат обградени с червена рамка.';
+$lang['updated'] = 'Обновяването на настройките е успешно.';
+$lang['nochoice'] = '(няма друг възможен избор)';
+$lang['locked'] = 'Обновяването на файла с настройките не е възможно, ако това не е нарочно, проверете,<br /> дали името на локалния файл с настройки и правата са верни.';
+$lang['danger'] = 'Внимание: промяна на опцията може да направи wiki-то и менюто за настройване недостъпни.';
+$lang['warning'] = 'Предупреждение: промяна на опцията може предизвика нежелани последици.';
+$lang['security'] = 'Предупреждение: промяна на опцията може да представлява риск за сигурността.';
+$lang['_configuration_manager'] = 'Диспечер на настройките';
+$lang['_header_dokuwiki'] = 'Настройки на DokuWiki';
+$lang['_header_plugin'] = 'Настройки на приставки';
+$lang['_header_template'] = 'Настройки на шаблони';
+$lang['_header_undefined'] = 'Неопределени настройки';
+$lang['_basic'] = 'Основни настройки';
+$lang['_display'] = 'Настройки за изобразяване';
+$lang['_authentication'] = 'Настройки за удостоверяване';
+$lang['_anti_spam'] = 'Настройки за борба със SPAM-ма';
+$lang['_editing'] = 'Настройки за редактиране';
+$lang['_links'] = 'Настройки на препратките';
+$lang['_media'] = 'Настройки на медията';
+$lang['_advanced'] = 'Допълнителни настройки';
+$lang['_network'] = 'Мрежови настройки';
+$lang['_plugin_sufix'] = ' - настройки на приставката';
+$lang['_template_sufix'] = ' - настройки на шаблона';
+$lang['_msg_setting_undefined'] = 'Няма метаданни за настройките.';
+$lang['_msg_setting_no_class'] = 'Няма клас настройки.';
+$lang['_msg_setting_no_default'] = 'Няма стандартна стойност.';
+$lang['fmode'] = 'Режим (права) за създаване на файлове';
+$lang['dmode'] = 'Режим (права) за създаване на директории';
+$lang['lang'] = 'Език';
+$lang['basedir'] = 'Главна директория (напр. <code>/dokuwiki/</code>). Оставете празно, за да бъде засечена автоматично.';
+$lang['baseurl'] = 'URL адрес (напр. <code>http://www.yourserver.com</code>). Оставете празно, за да бъде засечен автоматично.';
+$lang['savedir'] = 'Директория за записване на данните';
+$lang['cookiedir'] = 'Път за бисквитките. Оставите ли полето празно ще се ползва горния URL адрес.';
+$lang['start'] = 'Име на началната страница';
+$lang['title'] = 'Име на Wiki-то';
+$lang['template'] = 'Шаблон';
+$lang['license'] = 'Под какъв лиценз да бъде публикувано съдържанието?';
+$lang['fullpath'] = 'Показване на пълния път до страниците в долния колонтитул.';
+$lang['recent'] = 'Скорошни промени';
+$lang['breadcrumbs'] = 'Брой на следите';
+$lang['youarehere'] = 'Йерархични следи';
+$lang['typography'] = 'Замяна на последователност от символи с типографски еквивалент';
+$lang['htmlok'] = 'Разрешаване вграждането на HTML код';
+$lang['phpok'] = 'Разрешаване вграждането на PHP код';
+$lang['dformat'] = 'Формат на датата (виж. <a href="http://www.php.net/strftime">strftime</a> функцията на PHP)';
+$lang['signature'] = 'Подпис';
+$lang['toptoclevel'] = 'Главно ниво (заглавие) за съдържанието';
+$lang['tocminheads'] = 'Минимален брой заглавия, определящ дали да бъде създадено съдържание';
+$lang['maxtoclevel'] = 'Максимален брой нива (заглавия) за включване в съдържанието';
+$lang['maxseclevel'] = 'Максимален брой нива предоставяни за самостоятелно редактиране';
+$lang['camelcase'] = 'Ползване на CamelCase за линкове';
+$lang['deaccent'] = 'Почистване имената на страниците (на файловете)';
+$lang['useheading'] = 'Ползване на първото заглавие за име на страница';
+$lang['refcheck'] = 'Проверка за препратка към медия, преди да бъде изтрита';
+$lang['refshow'] = 'Брой на показваните медийни препратки';
+$lang['allowdebug'] = 'Включване на режи debug - <b>изключете, ако не е нужен!</b>';
+$lang['mediarevisions'] = 'Да се пазят ли стари версии на качените файлове (Mediarevisions)?';
+$lang['usewordblock'] = 'Блокиране на SPAM въз основа на на списък от думи';
+$lang['indexdelay'] = 'Забавяне преди индексиране (сек)';
+$lang['relnofollow'] = 'Ползване на rel="nofollow" за външни препратки';
+$lang['mailguard'] = 'Промяна на адресите на ел. поща (във форма непозволяваща пращането на SPAM)';
+$lang['iexssprotect'] = 'Проверяване на качените файлове за вероятен зловреден JavaScript и HTML код';
+$lang['showuseras'] = 'Какво да се показва за потребителя, който последно е променил страницата';
+$lang['useacl'] = 'Ползване на списъци за достъп';
+$lang['autopasswd'] = 'Автоматично генериране на пароли, на нови потребители и пращане по пощата';
+$lang['authtype'] = 'Метод за удостоверяване';
+$lang['passcrypt'] = 'Метод за криптиране на паролите';
+$lang['defaultgroup'] = 'Стандартна група';
+$lang['superuser'] = 'Супер потребител - група, потребител или списък със стойности разделени чрез запетая (user1,@group1,user2) с пълен достъп до всички страници и функции без значение от настройките на списъците за достъп (ACL)';
+$lang['manager'] = 'Управител - група, потребител или списък със стойности разделени чрез запетая (user1,@group1,user2) с достъп до определени управленски функции ';
+$lang['profileconfirm'] = 'Потвърждаване на промени в профила с парола';
+$lang['disableactions'] = 'Изключване функции на DokuWiki';
+$lang['disableactions_check'] = 'Проверка';
+$lang['disableactions_subscription'] = 'Абониране/Отписване';
+$lang['disableactions_wikicode'] = 'Преглед на кода/Експортиране на оригинална версия';
+$lang['disableactions_other'] = 'Други действия (разделени със запетая)';
+$lang['sneaky_index'] = 'Стандартно DokuWiki ще показва всички именни пространства в индекса. Опцията скрива тези, за които потребителят няма права за четене. Това може да доведе и до скриване на иначе достъпни подименни пространства. С определени настройки на списъците за контрол на достъпа (ACL) може да направи индекса неизползваем. ';
+$lang['auth_security_timeout'] = 'Автоматично проверяване на удостоверяването всеки (сек)';
+$lang['securecookie'] = 'Да се изпращат ли бисквитките зададени чрез HTTPS, само чрез HTTPS от браузъра? Изключете опцията, когато SSL се ползва само за вписване, а четенето е без SSL.
+';
+$lang['xmlrpc'] = 'Включване/Изключване на интерфейса XML-RPC.';
+$lang['xmlrpcuser'] = 'Ограничаване на XML-RPC достъпа до отделени със запетая групи или потребители. Оставете празно, за да даде достъп на всеки.';
+$lang['updatecheck'] = 'Проверяване за за нови версии и предупреждения за сигурността? Необходимо е Dokiwiki да може да се свързва със update.dokuwiki.org за тази функционалност.';
+$lang['userewrite'] = 'Ползване на nice URL адреси';
+$lang['useslash'] = 'Ползване на наклонена черта за разделител на именните пространства в URL';
+$lang['usedraft'] = 'Автоматично запазване на чернова по време на редактиране';
+$lang['sepchar'] = 'Разделител между думите в имената на страници';
+$lang['canonical'] = 'Ползване на напълно уеднаквени URL адреси (абсолютни адреси - http://server/path)';
+$lang['fnencode'] = 'Метод за кодиране на не-ASCII именуваните файлове.';
+$lang['autoplural'] = 'Проверяване за множествено число в препратките';
+$lang['compression'] = 'Метод за компресия на attic файлове';
+$lang['cachetime'] = 'Макс. период за съхраняване на кеша (сек)';
+$lang['locktime'] = 'Макс. период за съхраняване на заключените файлове (сек)';
+$lang['fetchsize'] = 'Максимален размер (байтове), който fetch.php може да сваля';
+$lang['notify'] = 'Пращане на съобщения за промени по страниците на следната eл. поща';
+$lang['registernotify'] = 'Пращане на информация за нови потребители на следната ел. поща';
+$lang['mailfrom'] = 'Ел. поща, която да се ползва за автоматично изпращане на ел. писма';
+$lang['mailprefix'] = 'Представка за темите (поле subject) на автоматично изпращаните ел. писма';
+$lang['gzip_output'] = 'Кодиране на съдържанието с gzip за xhtml';
+$lang['gdlib'] = 'Версия на GD Lib';
+$lang['im_convert'] = 'Път до инструмента за трансформация на ImageMagick';
+$lang['jpg_quality'] = 'Качество на JPG компресията (0-100)';
+$lang['subscribers'] = 'Включване на поддръжката за абониране към страници';
+$lang['subscribe_time'] = 'Време след което абонаментните списъци и обобщения се изпращат (сек); Трябва да е по-малко от времето определено в recent_days.';
+$lang['compress'] = 'Компактен CSS и javascript изглед';
+$lang['cssdatauri'] = 'Максимален размер, в байтове, до който изображенията посочени в .CSS файл ще бъдат вграждани в стила (stylesheet), за да се намали броя на HTTP заявките. Техниката не работи за версиите на IE преди 8! Препоръчителни стойности: <code>400</code> до <code>600</code> байта. Въведете <code>0</code> за изключване.';
+$lang['hidepages'] = 'Скриване на съвпадащите страници (regular expressions)';
+$lang['send404'] = 'Пращане на "HTTP 404/Page Not Found" за несъществуващи страници';
+$lang['sitemap'] = 'Генериране на Google sitemap (дни)';
+$lang['broken_iua'] = 'Отметнете, ако ignore_user_abort функцията не работи. Може да попречи на търсенето в страниците. Знае се, че комбинацията IIS+PHP/CGI е лоша. Вижте <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Грешка 852</a> за повече информация.';
+$lang['xsendfile'] = 'Ползване на Х-Sendfile header, за да може уебсървъра да дава статични файлове? Вашият уебсървър трябва да го поддържа.';
+$lang['renderer_xhtml'] = 'Представяне на основните изходни данни (xhtml) от wiki-то с';
+$lang['renderer__core'] = '%s (ядрото на DokuWiki)';
+$lang['renderer__plugin'] = '%s (приставка)';
+$lang['rememberme'] = 'Ползване на постоянни бисквитки за вписване (за функцията "Запомни ме")';
+$lang['rss_type'] = 'Тип на XML емисията';
+$lang['rss_linkto'] = 'XML емисията препраща към';
+$lang['rss_content'] = 'Какво да показват елементите на XML емисията?';
+$lang['rss_update'] = 'Интервал на актуализиране на XML емисията (сек)';
+$lang['recent_days'] = 'Колко от скорошните промени да се пазят (дни)';
+$lang['rss_show_summary'] = 'Показване на обобщение в заглавието на XML емисията';
+$lang['target____wiki'] = 'Прозорец за вътрешни препратки';
+$lang['target____interwiki'] = 'Прозорец за препратки в wiki-то';
+$lang['target____extern'] = 'Прозорец за външни препратки';
+$lang['target____media'] = 'Прозорец за медийни препратки';
+$lang['target____windows'] = 'Прозорец за препратки към Windows';
+$lang['proxy____host'] = 'Име на прокси сървър';
+$lang['proxy____port'] = 'Порт за проксито';
+$lang['proxy____user'] = 'Потребител за проксито';
+$lang['proxy____pass'] = 'Парола за проксито';
+$lang['proxy____ssl'] = 'Ползване на SSL при свързване с проксито';
+$lang['proxy____except'] = 'Регулярен израз определящ за кои URL адреси да не се ползва прокси сървър.';
+$lang['safemodehack'] = 'Ползване на хака safemode';
+$lang['ftp____host'] = 'FTP сървър за хака safemode';
+$lang['ftp____port'] = 'FTP порт за хака safemode';
+$lang['ftp____user'] = 'FTP потребител за хака safemode';
+$lang['ftp____pass'] = 'FTP парола за хака safemode';
+$lang['ftp____root'] = 'FTP главна директория за хака safemode';
+$lang['license_o_'] = 'Нищо не е избрано';
+$lang['typography_o_0'] = 'без';
+$lang['typography_o_1'] = 'с изключение на единични кавички';
+$lang['typography_o_2'] = 'включително единични кавички (не винаги работи)';
+$lang['userewrite_o_0'] = 'без';
+$lang['userewrite_o_1'] = 'файлът .htaccess';
+$lang['userewrite_o_2'] = 'вътрешно от DokuWiki ';
+$lang['deaccent_o_0'] = 'изключено';
+$lang['deaccent_o_1'] = 'премахване на акценти';
+$lang['deaccent_o_2'] = 'транслитерация';
+$lang['gdlib_o_0'] = 'GD Lib не е достъпна';
+$lang['gdlib_o_1'] = 'Версия 1.x';
+$lang['gdlib_o_2'] = 'Автоматично разпознаване';
+$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';
+$lang['rss_content_o_abstract'] = 'Извлечение';
+$lang['rss_content_o_diff'] = 'Обединени разлики';
+$lang['rss_content_o_htmldiff'] = 'Таблица с разликите в HTML формат';
+$lang['rss_content_o_html'] = 'Цялото съдържание на HTML страницата';
+$lang['rss_linkto_o_diff'] = 'изглед на разликите';
+$lang['rss_linkto_o_page'] = 'променената страница';
+$lang['rss_linkto_o_rev'] = 'списък на версиите';
+$lang['rss_linkto_o_current'] = 'текущата страница';
+$lang['compression_o_0'] = 'без';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'не използвайте';
+$lang['xsendfile_o_1'] = 'Специфичен lighttpd header (преди версия 1.5)';
+$lang['xsendfile_o_2'] = 'Стандартен X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Специфичен Nginx X-Accel-Redirect header за пренасочване';
+$lang['showuseras_o_loginname'] = 'Име за вписване';
+$lang['showuseras_o_username'] = 'Пълно потребителско име';
+$lang['showuseras_o_email'] = 'Ел, поща (променени според настройките на mailguard)';
+$lang['showuseras_o_email_link'] = 'Ел. поща под формата на връзка тип mailto:';
+$lang['useheading_o_0'] = 'Никога';
+$lang['useheading_o_navigation'] = 'Само за навигация';
+$lang['useheading_o_content'] = 'Само за съдържанието на Wiki-то';
+$lang['useheading_o_1'] = 'Винаги';
+$lang['readdircache'] = 'Максимален период за съхраняване кеша на readdir (сек)';
diff --git a/lib/plugins/config/lang/ca-valencia/intro.txt b/lib/plugins/config/lang/ca-valencia/intro.txt
new file mode 100644
index 000000000..40729e5fe
--- /dev/null
+++ b/lib/plugins/config/lang/ca-valencia/intro.txt
@@ -0,0 +1,10 @@
+====== Gestor de configuració ======
+
+Controle des d'esta pàgina els ajusts de DokuWiki.
+Per a obtindre ajuda sobre cada ajust vaja a [[doku>config]].
+Per a més informació al voltant d'este plúgin vaja a [[doku>config]].
+
+Els ajusts mostrats en un fondo roig claret estan protegits i no els pot
+modificar en este plúgin. Els ajusts mostrats en un fondo blau tenen els valors predeterminats i els ajusts mostrats en un fondo blanc han segut modificats localment per ad esta instalació. Abdós ajusts, blaus i blancs, es poden modificar.
+
+Recorde pulsar el botó **GUARDAR** ans d'anar-se'n d'esta pàgina o perdrà els canvis que haja fet. \ No newline at end of file
diff --git a/lib/plugins/config/lang/ca-valencia/lang.php b/lib/plugins/config/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..76f11a4a5
--- /dev/null
+++ b/lib/plugins/config/lang/ca-valencia/lang.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * valencian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bernat Arlandis i Mañó <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['menu'] = 'Ajusts de configuració';
+$lang['error'] = 'Els ajusts no s\'han actualisat per algun valor invàlit, per favor, revise els canvis i torne a guardar.
+<br />Els valors incorrectes es mostraran en una vora roja.';
+$lang['updated'] = 'Els ajusts s\'han actualisat correctament.';
+$lang['nochoice'] = '(no n\'hi ha atres opcions disponibles)';
+$lang['locked'] = 'L\'archiu de configuració no es pot actualisar, si açò no és intencionat,<br /> comprove que els permissos de l\'archiu de configuració local estiguen be.';
+$lang['danger'] = 'Perill: canviant esta opció pot fer inaccessibles el wiki i el menú de configuració.';
+$lang['warning'] = 'Advertència: canviar esta opció pot causar un comportament imprevist.';
+$lang['security'] = 'Advertència de seguritat: canviar esta opció pot presentar un risc de seguritat.';
+$lang['_configuration_manager'] = 'Gestor de configuració';
+$lang['_header_dokuwiki'] = 'Ajusts de DokuWiki';
+$lang['_header_plugin'] = 'Configuració de plúgins';
+$lang['_header_template'] = 'Configuració de plantilles';
+$lang['_header_undefined'] = 'Atres configuracions';
+$lang['_basic'] = 'Ajusts bàsics';
+$lang['_display'] = 'Ajusts de visualisació';
+$lang['_authentication'] = 'Ajusts d\'autenticació';
+$lang['_anti_spam'] = 'Ajusts anti-spam';
+$lang['_editing'] = 'Ajusts d\'edició';
+$lang['_links'] = 'Ajusts de vínculs';
+$lang['_media'] = 'Ajusts de mijos';
+$lang['_advanced'] = 'Ajusts alvançats';
+$lang['_network'] = 'Ajusts de ret';
+$lang['_plugin_sufix'] = 'Ajusts de plúgins';
+$lang['_template_sufix'] = '(ajusts de la plantilla)';
+$lang['_msg_setting_undefined'] = 'Ajust sense informació.';
+$lang['_msg_setting_no_class'] = 'Ajust sense classe.';
+$lang['_msg_setting_no_default'] = 'Sense valor predeterminat.';
+$lang['fmode'] = 'Modo de creació d\'archius';
+$lang['dmode'] = 'Modo de creació de directoris';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Directori base';
+$lang['baseurl'] = 'URL base';
+$lang['savedir'] = 'Directori per a guardar senyes';
+$lang['start'] = 'Nom de la pàgina inicial';
+$lang['title'] = 'Títul del Wiki';
+$lang['template'] = 'Plantilla';
+$lang['license'] = '¿Baix quina llicència deuen publicar-se els continguts?';
+$lang['fullpath'] = 'Mostrar en el peu el camí complet a les pàgines';
+$lang['recent'] = 'Canvis recents';
+$lang['breadcrumbs'] = 'Llongitut del rastre';
+$lang['youarehere'] = 'Rastre jeràrquic';
+$lang['typography'] = 'Fer substitucions tipogràfiques';
+$lang['htmlok'] = 'Permetre HTML';
+$lang['phpok'] = 'Permetre PHP';
+$lang['dformat'] = 'Format de data (vore la funció <a href="http://www.php.net/date">date</a> de PHP)';
+$lang['signature'] = 'Firma';
+$lang['toptoclevel'] = 'Nivell superior de la taula de continguts';
+$lang['tocminheads'] = 'Número mínim de titulars que generen una TDC';
+$lang['maxtoclevel'] = 'Nivell màxim de la taula de continguts';
+$lang['maxseclevel'] = 'Nivell màxim d\'edició de seccions';
+$lang['camelcase'] = 'Utilisar CamelCase per als vínculs';
+$lang['deaccent'] = 'Depurar els noms de pàgines';
+$lang['useheading'] = 'Utilisar el primer titular per al nom de pàgina';
+$lang['refcheck'] = 'Comprovar referències a mijos';
+$lang['refshow'] = 'Número de referències a mijos a mostrar';
+$lang['allowdebug'] = 'Permetre depurar (<b>¡desactivar quan no es necessite!</b>)';
+$lang['usewordblock'] = 'Bloquejar spam basant-se en una llista de paraules';
+$lang['indexdelay'] = 'Retart abans d\'indexar (seg.)';
+$lang['relnofollow'] = 'Utilisar rel="nofollow" en vínculs externs';
+$lang['mailguard'] = 'Ofuscar les direccions de correu';
+$lang['iexssprotect'] = 'Comprovar que els archius pujats no tinguen possible còdic Javascript o HTML maliciós';
+$lang['showuseras'] = 'Qué mostrar quan aparega l\'últim usuari que ha editat la pàgina';
+$lang['useacl'] = 'Utilisar llistes de control d\'accés';
+$lang['autopasswd'] = 'Generar contrasenyes automàticament';
+$lang['authtype'] = 'Sistema d\'autenticació';
+$lang['passcrypt'] = 'Método de sifrat de la contrasenya';
+$lang['defaultgroup'] = 'Grup predeterminat';
+$lang['superuser'] = 'Super-usuari - grup, usuari o llista separada per comes (usuari1,@grup1,usuari2) en accés total a totes les pàgines i funcions independentment dels ajusts ACL';
+$lang['manager'] = 'Manager - grup, usuari o llista separada per comes (usuari1,@grup1,usuari2) en accés a certes funcions d\'administració';
+$lang['profileconfirm'] = 'Confirmar canvis al perfil en la contrasenya';
+$lang['disableactions'] = 'Desactivar accions de DokuWiki';
+$lang['disableactions_check'] = 'Comprovar';
+$lang['disableactions_subscription'] = 'Subscriure\'s/Desubscriure\'s';
+$lang['disableactions_wikicode'] = 'Vore font/exportar còdic';
+$lang['disableactions_other'] = 'Atres accions (separades per comes)';
+$lang['sneaky_index'] = 'Normalment, DokuWiki mostra tots els espais de noms en la vista d\'índex. Activant esta opció s\'ocultaran aquells per als que l\'usuari no tinga permís de llectura. Açò pot ocultar subespais accessibles i inutilisar l\'índex per a certes configuracions del ACL.';
+$lang['auth_security_timeout'] = 'Temps de seguritat màxim per a l\'autenticació (segons)';
+$lang['securecookie'] = '¿El navegador deuria enviar per HTTPS només les galletes que s\'han generat per HTTPS? Desactive esta opció quan utilise SSL només en la pàgina d\'inici de sessió.';
+$lang['xmlrpc'] = 'Activar/desactivar interfaç XML-RPC.';
+$lang['xmlrpcuser'] = 'Restringir l\'accés XML-RPC a la llista d\'usuaris i grups separada per comes definida ací. Deixar buit per a donar accés a tots.';
+$lang['updatecheck'] = '¿Buscar actualisacions i advertències de seguritat? DokuWiki necessita conectar a update.dokuwiki.org per ad açò.';
+$lang['userewrite'] = 'Utilisar URL millorades';
+$lang['useslash'] = 'Utilisar \'/\' per a separar espais de noms en les URL';
+$lang['usedraft'] = 'Guardar automàticament un borrador mentres edite';
+$lang['sepchar'] = 'Separador de paraules en els noms de pàgines';
+$lang['canonical'] = 'Utilisar URL totalment canòniques';
+$lang['autoplural'] = 'Buscar formes en plural en els vínculs';
+$lang['compression'] = 'Método de compressió per als archius de l\'àtic';
+$lang['cachetime'] = 'Edat màxima de la caché (seg.)';
+$lang['locktime'] = 'Edat màxima d\'archius de bloqueig (seg.)';
+$lang['fetchsize'] = 'Tamany màxim (bytes) que fetch.php pot descarregar externament';
+$lang['notify'] = 'Enviar notificacions de canvis ad esta direcció de correu';
+$lang['registernotify'] = 'Enviar informació d\'usuaris recentment registrats ad esta direcció de correu';
+$lang['mailfrom'] = 'Direcció de correu a utilisar per a mensages automàtics';
+$lang['gzip_output'] = 'Utilisar Content-Encoding gzip per a xhtml';
+$lang['gdlib'] = 'Versió de GD Lib';
+$lang['im_convert'] = 'Ruta a la ferramenta de conversió ImageMagick';
+$lang['jpg_quality'] = 'Calitat de compressió JPG (0-100)';
+$lang['subscribers'] = 'Activar la subscripció a pàgines';
+$lang['compress'] = 'Compactar l\'eixida CSS i Javascript';
+$lang['hidepages'] = 'Amagar les pàgines coincidents (expressions regulars)';
+$lang['send404'] = 'Enviar "HTTP 404/Page Not Found" per a les pàgines que no existixen';
+$lang['sitemap'] = 'Generar sitemap de Google (dies)';
+$lang['broken_iua'] = '¿La funció ignore_user_abort funciona mal en este sistema? Podria ser la causa d\'un índex de busca que no funcione. Es sap que IIS+PHP/CGI té este problema. Veja <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> per a més informació.';
+$lang['xsendfile'] = '¿Utilisar l\'encapçalat X-Sendfile per a que el servidor web servixca archius estàtics? El servidor web ho ha d\'admetre.';
+$lang['renderer_xhtml'] = 'Visualisador a utilisar per a l\'eixida principal del wiki (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plúgin)';
+$lang['rememberme'] = 'Permetre recordar permanentment la sessió (recordar-me)';
+$lang['rss_type'] = 'Tipo de canal XML';
+$lang['rss_linkto'] = 'El canal XML vincula a';
+$lang['rss_content'] = '¿Qué mostrar en els ítems del canal XML?';
+$lang['rss_update'] = 'Interval d\'actualisació del canal XML (seg.)';
+$lang['recent_days'] = 'Quànts canvis recents guardar (dies)';
+$lang['rss_show_summary'] = 'Que el canal XML mostre el sumari en el títul';
+$lang['target____wiki'] = 'Finestra destí per a vínculs interns';
+$lang['target____interwiki'] = 'Finestra destí per a vínculs d\'interwiki';
+$lang['target____extern'] = 'Finestra destí per a vínculs externs';
+$lang['target____media'] = 'Finestra destí per a vinculs a mijos';
+$lang['target____windows'] = 'Finestra destí per a vínculs a finestres';
+$lang['proxy____host'] = 'Nom del servidor proxy';
+$lang['proxy____port'] = 'Port del proxy';
+$lang['proxy____user'] = 'Nom d\'usuari del proxy';
+$lang['proxy____pass'] = 'Contrasenya del proxy';
+$lang['proxy____ssl'] = 'Utilisar SSL per a conectar al proxy';
+$lang['safemodehack'] = 'Activar \'hack\' de modo segur';
+$lang['ftp____host'] = 'Servidor FTP per al \'hack\' de modo segur';
+$lang['ftp____port'] = 'Port FTP per al \'hack\' de modo segur';
+$lang['ftp____user'] = 'Nom de l\'usuari per al \'hack\' de modo segur';
+$lang['ftp____pass'] = 'Contrasenya FTP per al \'hack\' de modo segur';
+$lang['ftp____root'] = 'Directori base FTP per al \'hack\' de modo segur';
+$lang['license_o_'] = 'Cap triada';
+$lang['typography_o_0'] = 'cap';
+$lang['typography_o_1'] = 'Excloure cometes simples';
+$lang['typography_o_2'] = 'Incloure cometes simples (podria no funcionar sempre)';
+$lang['userewrite_o_0'] = 'cap';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Interna de DokuWiki';
+$lang['deaccent_o_0'] = 'desactivat';
+$lang['deaccent_o_1'] = 'llevar accents';
+$lang['deaccent_o_2'] = 'romanisar';
+$lang['gdlib_o_0'] = 'GD Lib no està disponible';
+$lang['gdlib_o_1'] = 'Versió 1.x';
+$lang['gdlib_o_2'] = 'Autodetecció';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstracte';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'Taula de diferències en format HTML';
+$lang['rss_content_o_html'] = 'Contingut complet de la pàgina en HTML';
+$lang['rss_linkto_o_diff'] = 'mostrar diferències';
+$lang['rss_linkto_o_page'] = 'la pàgina revisada';
+$lang['rss_linkto_o_rev'] = 'llista de revisions';
+$lang['rss_linkto_o_current'] = 'la pàgina actual';
+$lang['compression_o_0'] = 'cap';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'No utilisar';
+$lang['xsendfile_o_1'] = 'Encapçalat propietari lighttpd (abans de la versió 1.5)';
+$lang['xsendfile_o_2'] = 'Encapçalat Standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'Encapçalat propietari Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Nom d\'inici de sessió';
+$lang['showuseras_o_username'] = 'Nom complet de l\'usuari';
+$lang['showuseras_o_email'] = 'Direcció de correu de l\'usuari (oculta segons la configuració)';
+$lang['showuseras_o_email_link'] = 'Direcció de correu de l\'usuari com un víncul mailto:';
+$lang['useheading_o_0'] = 'Mai';
+$lang['useheading_o_navigation'] = 'Només navegació';
+$lang['useheading_o_content'] = 'Només contingut del wiki';
+$lang['useheading_o_1'] = 'Sempre';
diff --git a/lib/plugins/config/lang/ca/intro.txt b/lib/plugins/config/lang/ca/intro.txt
new file mode 100644
index 000000000..9ce4e6605
--- /dev/null
+++ b/lib/plugins/config/lang/ca/intro.txt
@@ -0,0 +1,7 @@
+====== Gestió de la configuració ======
+
+Utilitzeu aquesta pàgina per controlar els paràmetres de la vostra instal·lació de DokuWiki. Ajuda sobre paràmetres individuals en [[doku>config]]. Més detalls sobre aquest connector en [[doku>plugin:config]].
+
+Els paràmetres que es visualitzen sobre fons vermell clar estan protegits i no es poden modificar amb aquest connector. Els paràmetres que es visualitzen sobre fons blau tenen valors per defecte. Els de fons blanc s'han configurat localment per a aquesta instal·lació. Tant els blaus com els blanc es poden modificar.
+
+Recordeu que cal prémer el botó **DESA** abans de sortir d'aquesta pàgina, o si no es perdrien els canvis.
diff --git a/lib/plugins/config/lang/ca/lang.php b/lib/plugins/config/lang/ca/lang.php
new file mode 100644
index 000000000..1a2a22881
--- /dev/null
+++ b/lib/plugins/config/lang/ca/lang.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ */
+$lang['menu'] = 'Paràmetres de configuració';
+$lang['error'] = 'Els paràmetres no s\'han pogut actualitzar per causa d\'un valor incorrecte Reviseu els canvis i torneu a enviar-los.<br />Els valors incorrectes es ressaltaran amb un marc vermell.';
+$lang['updated'] = 'Els paràmetres s\'han actualitzat amb èxit.';
+$lang['nochoice'] = '(no hi altres opcions disponibles)';
+$lang['locked'] = 'El fitxer de paràmetres no es pot actualitzar. Si això és involuntari, <br />
+assegureu-vos que el nom i els permisos del fitxer local de paràmetres són correctes.';
+$lang['danger'] = 'Alerta: si canvieu aquesta opció podeu fer que el wiki i el menú de configuració no siguin accessibles.';
+$lang['warning'] = 'Avís: modificar aquesta opció pot provocar un comportament no desitjat.';
+$lang['security'] = 'Avís de seguretat: modificar aquesta opció pot implicar un risc de seguretat.';
+$lang['_configuration_manager'] = 'Gestió de la configuració';
+$lang['_header_dokuwiki'] = 'Paràmetres de DokuWiki';
+$lang['_header_plugin'] = 'Paràmetres de connectors';
+$lang['_header_template'] = 'Paràmetres de plantilles';
+$lang['_header_undefined'] = 'Paràmetres no definits';
+$lang['_basic'] = 'Paràmetres bàsics';
+$lang['_display'] = 'Paràmetres de visualització';
+$lang['_authentication'] = 'Paràmetres d\'autenticació';
+$lang['_anti_spam'] = 'Paràmetres anti-brossa';
+$lang['_editing'] = 'Paràmetres d\'edició';
+$lang['_links'] = 'Paràmetres d\'enllaços';
+$lang['_media'] = 'Paràmetres de mitjans';
+$lang['_advanced'] = 'Paràmetres avançats';
+$lang['_network'] = 'Paràmetres de xarxa';
+$lang['_plugin_sufix'] = 'Paràmetres de connectors';
+$lang['_template_sufix'] = 'Paràmetres de plantilla';
+$lang['_msg_setting_undefined'] = 'Falten metadades de paràmetre.';
+$lang['_msg_setting_no_class'] = 'Falta classe de paràmetre.';
+$lang['_msg_setting_no_default'] = 'No hi ha valor per defecte.';
+$lang['fmode'] = 'Mode de creació de fitxers';
+$lang['dmode'] = 'Mode de creació de directoris';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Directori base';
+$lang['baseurl'] = 'URL base';
+$lang['savedir'] = 'Directori per desar les dades';
+$lang['start'] = 'Nom de la pàgina d\'inici';
+$lang['title'] = 'Títol del wiki';
+$lang['template'] = 'Plantilla';
+$lang['license'] = 'Amb quina llicència voleu publicar el contingut?';
+$lang['fullpath'] = 'Mostra el camí complet de les pàgines al peu';
+$lang['recent'] = 'Canvis recents';
+$lang['breadcrumbs'] = 'Nombre d\'engrunes';
+$lang['youarehere'] = 'Camí d\'engrunes jeràrquic';
+$lang['typography'] = 'Substitucions tipogràfiques';
+$lang['htmlok'] = 'Permet HTML incrustat';
+$lang['phpok'] = 'Permet PHP incrustat';
+$lang['dformat'] = 'Format de data (vg. la funció PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Signatura';
+$lang['toptoclevel'] = 'Nivell superior per a la taula de continguts';
+$lang['tocminheads'] = 'Quantitat mínima d\'encapçalaments que determina si es construeix o no la taula de continguts.';
+$lang['maxtoclevel'] = 'Nivell màxim per a la taula de continguts';
+$lang['maxseclevel'] = 'Nivell màxim d\'edició de seccions';
+$lang['camelcase'] = 'Utilitza CamelCase per als enllaços';
+$lang['deaccent'] = 'Noms de pàgina nets';
+$lang['useheading'] = 'Utilitza el primer encapçalament per als noms de pàgina';
+$lang['refcheck'] = 'Comprova la referència en els fitxers de mitjans';
+$lang['refshow'] = 'Nombre de referències de mitjans per mostrar';
+$lang['allowdebug'] = 'Permet depuració <strong>inhabiliteu si no és necessari</strong>';
+$lang['usewordblock'] = 'Bloca brossa per llista de paraules';
+$lang['indexdelay'] = 'Retard abans d\'indexar (segons)';
+$lang['relnofollow'] = 'Utilitza rel="nofollow" en enllaços externs';
+$lang['mailguard'] = 'Ofusca les adreces de correu';
+$lang['iexssprotect'] = 'Comprova codi HTML o Javascript maligne en els fitxers penjats';
+$lang['showuseras'] = 'Què cal visualitzar quan es mostra el darrer usuari que ha editat la pàgina';
+$lang['useacl'] = 'Utilitza llistes de control d\'accés';
+$lang['autopasswd'] = 'Generació automàtica de contrasenyes';
+$lang['authtype'] = 'Rerefons d\'autenticació';
+$lang['passcrypt'] = 'Mètode d\'encriptació de contrasenyes';
+$lang['defaultgroup'] = 'Grup per defecte';
+$lang['superuser'] = 'Superusuari: un grup o usuari amb accés complet a totes les pàgines i funcions independentment dels paràmetres ACL';
+$lang['manager'] = 'Administrador: un grup o usuari amb accés a certes funcions d\'administració';
+$lang['profileconfirm'] = 'Confirma amb contrasenya els canvis en el perfil';
+$lang['disableactions'] = 'Inhabilita accions DokuWiki';
+$lang['disableactions_check'] = 'Revisa';
+$lang['disableactions_subscription'] = 'Subscripció/cancel·lació';
+$lang['disableactions_wikicode'] = 'Mostra/exporta font';
+$lang['disableactions_other'] = 'Altres accions (separades per comes)';
+$lang['sneaky_index'] = 'Per defecte, DokuWiki mostrarà tots els espai en la visualització d\'índex. Si activeu aquest paràmetre, s\'ocultaran aquells espais en els quals l\'usuari no té accés de lectura. Això pot fer que s\'ocultin subespais que sí que són accessibles. En algunes configuracions ACL pot fer que l\'índex resulti inutilitzable.';
+$lang['auth_security_timeout'] = 'Temps d\'espera de seguretat en l\'autenticació (segons)';
+$lang['securecookie'] = 'Les galetes que s\'han creat via HTTPS, només s\'han d\'enviar des del navegador per HTTPS? Inhabiliteu aquesta opció si només l\'inici de sessió del wiki es fa amb SSL i la navegació del wiki es fa sense seguretat.';
+$lang['xmlrpc'] = 'Habilita/inhabilita la interfície XML-RPC';
+$lang['xmlrpcuser'] = 'Restringeix l\'accés per XML-RPC als usuaris o grups següents, separats per comes. Deixeu aquest camp en blanc per donar accés a tothom.';
+$lang['updatecheck'] = 'Comprova actualitzacions i avisos de seguretat. DokuWiki necessitarà contactar amb update.dokuwiki.org per utilitzar aquesta característica.';
+$lang['userewrite'] = 'Utilitza URL nets';
+$lang['useslash'] = 'Utilitza la barra / com a separador d\'espais en els URL';
+$lang['usedraft'] = 'Desa automàticament un esborrany mentre s\'edita';
+$lang['sepchar'] = 'Separador de paraules en els noms de pàgina';
+$lang['canonical'] = 'Utilitza URL canònics complets';
+$lang['autoplural'] = 'Comprova formes plurals en els enllaços';
+$lang['compression'] = 'Mètode de compressió per als fitxers de les golfes';
+$lang['cachetime'] = 'Durada màxima de la memòria cau (segons)';
+$lang['locktime'] = 'Durada màxima dels fitxers de bloqueig (segons)';
+$lang['fetchsize'] = 'Mida màxima (bytes) que fetch.php pot baixar d\'un lloc extern';
+$lang['notify'] = 'Envia notificacions de canvis a aquesta adreça de correu';
+$lang['registernotify'] = 'Envia informació sobre nous usuaris registrats a aquesta adreça de correu';
+$lang['mailfrom'] = 'Adreça de correu remitent per a missatges automàtics';
+$lang['gzip_output'] = 'Codifica contingut xhtml com a gzip';
+$lang['gdlib'] = 'Versió GD Lib';
+$lang['im_convert'] = 'Camí de la utilitat convert d\'ImageMagick';
+$lang['jpg_quality'] = 'Qualitat de compressió JPEG (0-100)';
+$lang['subscribers'] = 'Habilita la subscripció a pàgines';
+$lang['compress'] = 'Sortida CSS i Javascript compacta';
+$lang['hidepages'] = 'Oculta pàgines coincidents (expressions regulars)';
+$lang['send404'] = 'Envia "HTTP 404/Page Not Found" per a les pàgines inexistents';
+$lang['sitemap'] = 'Genera mapa del lloc en format Google (dies)';
+$lang['broken_iua'] = 'No funciona en el vostre sistema la funció ignore_user_abort? Això podria malmetre l\'índex de cerques. Amb IIS+PHP/CGI se sap que no funciona. Vg. <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> per a més informació.';
+$lang['xsendfile'] = 'Utilitza la capçalera X-Sendfile perquè el servidor web distribueixi fitxers estàtics. No funciona amb tots els servidors web.';
+$lang['renderer_xhtml'] = 'Renderitzador que cal utilitzar per a la sortida principal (xhtml) del wiki';
+$lang['renderer__core'] = '%s (ànima del dokuwiki)';
+$lang['renderer__plugin'] = '%s (connector)';
+$lang['rememberme'] = 'Permet galetes de sessió permanents ("recorda\'m")';
+$lang['rss_type'] = 'Tipus de canal XML';
+$lang['rss_linkto'] = 'Destinació dels enllaços en el canal XML';
+$lang['rss_content'] = 'Què es mostrarà en els elements del canal XML?';
+$lang['rss_update'] = 'Interval d\'actualització del canal XML (segons)';
+$lang['recent_days'] = 'Quantitat de canvis recents que es mantenen (dies)';
+$lang['rss_show_summary'] = 'Mostra resum en els títols del canal XML';
+$lang['target____wiki'] = 'Finestra de destinació en enllaços interns';
+$lang['target____interwiki'] = 'Finestra de destinació en enllaços interwiki';
+$lang['target____extern'] = 'Finestra de destinació en enllaços externs';
+$lang['target____media'] = 'Finestra de destinació en enllaços de mitjans';
+$lang['target____windows'] = 'Finestra de destinació en enllaços de Windows';
+$lang['proxy____host'] = 'Nom del servidor intermediari';
+$lang['proxy____port'] = 'Port del servidor intermediari';
+$lang['proxy____user'] = 'Nom d\'usuari del servidor intermediari';
+$lang['proxy____pass'] = 'Contrasenya del servidor intermediari';
+$lang['proxy____ssl'] = 'Utilitza SSL per connectar amb el servidor intermediari';
+$lang['safemodehack'] = 'Utilitza el hack per a safemode';
+$lang['ftp____host'] = 'Servidor FTP per al hack de safemode';
+$lang['ftp____port'] = 'Port FTP per al hack de safemode';
+$lang['ftp____user'] = 'Nom d\'usuari FTP per al hack de safemode';
+$lang['ftp____pass'] = 'Contrasenya FTP per al hack de safemode';
+$lang['ftp____root'] = 'Directori arrel FTP per al hack de safemode';
+$lang['license_o_'] = 'Cap selecció';
+$lang['typography_o_0'] = 'cap';
+$lang['typography_o_1'] = 'només cometes dobles';
+$lang['typography_o_2'] = 'totes les cometes (podria no funcionar sempre)';
+$lang['userewrite_o_0'] = 'cap';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'intern del DokuWiki';
+$lang['deaccent_o_0'] = 'desactivat';
+$lang['deaccent_o_1'] = 'treure accents';
+$lang['deaccent_o_2'] = 'romanització';
+$lang['gdlib_o_0'] = 'GD Lib no està disponible';
+$lang['gdlib_o_1'] = 'Versió 1.x';
+$lang['gdlib_o_2'] = 'Detecció automàtica';
+$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';
+$lang['rss_content_o_abstract'] = 'Resum';
+$lang['rss_content_o_diff'] = 'Diff unificat';
+$lang['rss_content_o_htmldiff'] = 'Taula de diferències en format HTML';
+$lang['rss_content_o_html'] = 'Contingut complet de la pàgina en format HTML';
+$lang['rss_linkto_o_diff'] = 'Visualització de diferències';
+$lang['rss_linkto_o_page'] = 'pàgina modificada';
+$lang['rss_linkto_o_rev'] = 'llista de revisions';
+$lang['rss_linkto_o_current'] = 'revisió actual';
+$lang['compression_o_0'] = 'cap';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'no utilitzis';
+$lang['xsendfile_o_1'] = 'Capçalera pròpia de lighttpd (anterior a la versió 1.5)';
+$lang['xsendfile_o_2'] = 'Capçalera X-Sendfile estàndard';
+$lang['xsendfile_o_3'] = 'Capçalera X-Accel-Redirect de propietat de Nginx ';
+$lang['showuseras_o_loginname'] = 'Nom d\'usuari';
+$lang['showuseras_o_username'] = 'Nom complet de l\'usuari';
+$lang['showuseras_o_email'] = 'Adreça de correu electrònic de l\'usuari (ofuscada segons el paràmetre de configuració corresponent)';
+$lang['showuseras_o_email_link'] = 'Adreça de correu electrònic amb enllaç mailto:';
+$lang['useheading_o_0'] = 'Mai';
+$lang['useheading_o_navigation'] = 'Només navegació';
+$lang['useheading_o_content'] = 'Només contingut wiki';
+$lang['useheading_o_1'] = 'Sempre';
diff --git a/lib/plugins/config/lang/cs/intro.txt b/lib/plugins/config/lang/cs/intro.txt
new file mode 100644
index 000000000..63381b84e
--- /dev/null
+++ b/lib/plugins/config/lang/cs/intro.txt
@@ -0,0 +1,8 @@
+====== Správa nastavení ======
+
+Tuto stránku můžete používat ke správě nastavení vaší instalace DokuWiki. Nápovědu pro konkrétní položky nastavení naleznete na [[doku>config]]. Pro další detaily o tomto pluginu viz [[doku>plugin:config]].
+
+Položky se světle červeným pozadím jsou chráněné a nelze je upravovat tímto pluginem. Položky s modrým pozadím jsou výchozí hodnoty a položky s bílým pozadím byly nastaveny lokálně v této konkrétní instalaci. Modré i bílé položky je možné upravovat.
+
+Než opustíte tuto stránku, nezapomeňte stisknout tlačítko **Uložit**, jinak budou změny ztraceny.
+
diff --git a/lib/plugins/config/lang/cs/lang.php b/lib/plugins/config/lang/cs/lang.php
new file mode 100644
index 000000000..bf87e99d5
--- /dev/null
+++ b/lib/plugins/config/lang/cs/lang.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['menu'] = 'Správa nastavení';
+$lang['error'] = 'Nastavení nebyla změněna kvůli alespoň jedné neplatné položce,
+zkontrolujte prosím své úpravy a odešlete je znovu.<br />
+Neplatné hodnoty se zobrazí v červeném rámečku.';
+$lang['updated'] = 'Nastavení byla úspěšně upravena.';
+$lang['nochoice'] = '(nejsou k dispozici žádné další volby)';
+$lang['locked'] = 'Nelze upravovat soubor s nastavením. Pokud to není záměrné,
+ujistěte se, <br /> že název a přístupová práva souboru s lokálním
+nastavením jsou v pořádku.';
+$lang['danger'] = 'Pozor: Změna tohoto nastavení může způsobit nedostupnost wiki a konfiguračních menu.';
+$lang['warning'] = 'Varování: Změna nastavení může mít za následek chybné chování.';
+$lang['security'] = 'Bezpečnostní varování: Změna tohoto nastavení může způsobit bezpečnostní riziko.';
+$lang['_configuration_manager'] = 'Správa nastavení';
+$lang['_header_dokuwiki'] = 'Nastavení DokuWiki';
+$lang['_header_plugin'] = 'Nastavení pluginů';
+$lang['_header_template'] = 'Nastavení šablon';
+$lang['_header_undefined'] = 'Další nastavení';
+$lang['_basic'] = 'Základní nastavení';
+$lang['_display'] = 'Nastavení zobrazení';
+$lang['_authentication'] = 'Nastavení autentizace';
+$lang['_anti_spam'] = 'Protispamová nastavení';
+$lang['_editing'] = 'Nastavení editace';
+$lang['_links'] = 'Nastavení odkazů';
+$lang['_media'] = 'Nastavení médií';
+$lang['_advanced'] = 'Pokročilá nastavení';
+$lang['_network'] = 'Nastavení sítě';
+$lang['_plugin_sufix'] = 'Nastavení pluginů ';
+$lang['_template_sufix'] = 'Nastavení šablon';
+$lang['_msg_setting_undefined'] = 'Chybí metadata položky.';
+$lang['_msg_setting_no_class'] = 'Chybí třída položky.';
+$lang['_msg_setting_no_default'] = 'Chybí výchozí hodnota položky.';
+$lang['fmode'] = 'Přístupová práva pro vytváření souborů';
+$lang['dmode'] = 'Přístupová práva pro vytváření adresářů';
+$lang['lang'] = 'Jazyk';
+$lang['basedir'] = 'Kořenový adresář (např. <code>/dokuwiki/</code>). Pro autodetekci nechte prázdné.';
+$lang['baseurl'] = 'Kořenové URL (např. <code>http://www.yourserver.com</code>). Pro autodetekci nechte prázdné.';
+$lang['savedir'] = 'Adresář pro ukládání dat';
+$lang['cookiedir'] = 'Cesta pro cookie. Není-li vyplněno, použije se kořenové URL.';
+$lang['start'] = 'Název úvodní stránky';
+$lang['title'] = 'Název celé wiki';
+$lang['template'] = 'Šablona';
+$lang['license'] = 'Pod jakou licencí má být tento obsah publikován?';
+$lang['fullpath'] = 'Ukazovat plnou cestu ke stránkám v patičce';
+$lang['recent'] = 'Nedávné změny';
+$lang['breadcrumbs'] = 'Počet odkazů na navštívené stránky';
+$lang['youarehere'] = 'Hierarchická "drobečková" navigace';
+$lang['typography'] = 'Provádět typografické nahrazování';
+$lang['htmlok'] = 'Povolit vložené HTML';
+$lang['phpok'] = 'Povolit vložené PHP';
+$lang['dformat'] = 'Formát data (viz PHP funkci <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Podpis';
+$lang['toptoclevel'] = 'Nejvyšší úroveň, kterou začít automaticky generovaný obsah';
+$lang['tocminheads'] = 'Nejnižší počet hlavních nadpisů, aby se vygeneroval obsah';
+$lang['maxtoclevel'] = 'Maximální počet úrovní v automaticky generovaném obsahu';
+$lang['maxseclevel'] = 'Nejnižší úroveň pro editaci i po sekcích';
+$lang['camelcase'] = 'Používat CamelCase v odkazech';
+$lang['deaccent'] = 'Čistit názvy stránek';
+$lang['useheading'] = 'Používat první nadpis jako název stránky';
+$lang['refcheck'] = 'Kontrolovat odkazy na média (před vymazáním)';
+$lang['refshow'] = 'Počet zobrazených odkazů na média';
+$lang['allowdebug'] = 'Povolit debugování. <b>Vypněte, pokud to nepotřebujete!</b>';
+$lang['usewordblock'] = 'Blokovat spam za použití seznamu známých spamových slov';
+$lang['indexdelay'] = 'Časová prodleva před indexací (v sekundách)';
+$lang['relnofollow'] = 'Používat rel="nofollow" na externí odkazy';
+$lang['mailguard'] = 'Metoda "zamaskování" emailových adres';
+$lang['iexssprotect'] = 'Zkontrolovat nahrané soubory vůči možnému škodlivému JavaScriptu či HTML';
+$lang['showuseras'] = 'Co se má přesně zobrazit, když se ukazuje uživatel, který naposledy editoval stránku';
+$lang['useacl'] = 'Používat přístupová práva (ACL)';
+$lang['autopasswd'] = 'Generovat hesla automaticky';
+$lang['authtype'] = 'Metoda autentizace';
+$lang['passcrypt'] = 'Metoda šifrování hesel';
+$lang['defaultgroup'] = 'Výchozí skupina';
+$lang['superuser'] = 'Superuživatel - skupina nebo uživatel s plnými právy pro přístup ke všem stránkách bez ohledu na nastavení ACL';
+$lang['manager'] = 'Manažer - skupina nebo uživatel s přístupem k některým správcovským funkcím';
+$lang['profileconfirm'] = 'Potvrdit změny v profilu zadáním hesla';
+$lang['disableactions'] = 'Vypnout DokuWiki akce';
+$lang['disableactions_check'] = 'Zkontrolovat';
+$lang['disableactions_subscription'] = 'Přihlásit se/Odhlásit se ze seznamu pro odběr změn';
+$lang['disableactions_wikicode'] = 'Prohlížet zdrojové kódy/Export wiki textu';
+$lang['disableactions_other'] = 'Další akce (oddělené čárkou)';
+$lang['sneaky_index'] = 'Ve výchozím nastavení DokuWiki zobrazuje v indexu všechny
+jmenné prostory. Zapnutím této volby se skryjí ty jmenné prostory,
+k nimž uživatel nemá právo pro čtení, což může ale způsobit, že
+vnořené jmenné prostory, k nimž právo má, budou přesto skryty.
+To může mít za následek, že index bude při některých
+nastaveních ACL nepoužitelný.';
+$lang['auth_security_timeout'] = 'Časový limit pro autentikaci (v sekundách)';
+$lang['securecookie'] = 'Má prohlížeč posílat cookies nastavené přes HTTPS opět jen přes HTTPS? Vypněte tuto volbu, pokud chcete, aby bylo pomocí SSL zabezpečeno pouze přihlašování do wiki, ale obsah budete prohlížet nezabezpečeně.';
+$lang['xmlrpc'] = 'Povolit/Zakázat rozhraní XML-RPC.';
+$lang['xmlrpcuser'] = 'Omezit přístup pomocí XML-RPC pouze na zde zadané skupiny či uživatele (oddělené čárkami). Necháte-li pole prázdné, dáte přístup komukoliv.';
+$lang['updatecheck'] = 'Kontrolovat aktualizace a bezpečnostní varování? DokuWiki potřebuje pro tuto funkci přístup k update.dokuwiki.org';
+$lang['userewrite'] = 'Používat "pěkná" URL';
+$lang['useslash'] = 'Používat lomítko jako oddělovač jmenných prostorů v URL';
+$lang['usedraft'] = 'Během editace ukládat koncept automaticky';
+$lang['sepchar'] = 'Znak pro oddělování slov v názvech stránek';
+$lang['canonical'] = 'Používat plně kanonická URL';
+$lang['fnencode'] = 'Metoda pro kódování ne-ASCII názvů souborů';
+$lang['autoplural'] = 'Kontrolovat plurálové tvary v odkazech';
+$lang['compression'] = 'Metoda komprese pro staré verze';
+$lang['cachetime'] = 'Maximální životnost cache (v sekundách)';
+$lang['locktime'] = 'Maximální životnost zámkových souborů (v sekundách)';
+$lang['fetchsize'] = 'Maximální velikost souboru (v bajtech), co ještě fetch.php bude stahovat z externích zdrojů';
+$lang['notify'] = 'Posílat oznámení o změnách na následující emailovou adresu';
+$lang['registernotify'] = 'Posílat informace o nově registrovaných uživatelích na tuto mailovou adresu';
+$lang['mailfrom'] = 'E-mailová adresa, která se bude používat pro automatické maily';
+$lang['mailprefix'] = 'Předpona předmětu e-mailu, která se bude používat pro automatické maily';
+$lang['gzip_output'] = 'Používat pro xhtml Content-Encoding gzip';
+$lang['gdlib'] = 'Verze GD knihovny';
+$lang['im_convert'] = 'Cesta k nástroji convert z balíku ImageMagick';
+$lang['jpg_quality'] = 'Kvalita komprese JPEG (0-100)';
+$lang['subscribers'] = 'Možnost přihlásit se k odběru novinek stránky';
+$lang['subscribe_time'] = 'Časový interval v sekundách, ve kterém jsou posílány změny a souhrny změn. Interval by neměl být kratší než čas uvedený v recent_days.';
+$lang['compress'] = 'Zahustit CSS a JavaScript výstup';
+$lang['cssdatauri'] = 'Velikost [v bajtech] obrázků odkazovaných v CSS souborech, které budou pro ušetření HTTP požadavku vestavěny do stylu. Tato technika nefunguje v IE 7 a starším. Doporučená hodnota je mezi <code>400</code> a <code>600</code> bajty. Pro vypnutí nastavte na <code>0</code>.';
+$lang['hidepages'] = 'Skrýt stránky odpovídající vzoru (regulární výrazy)';
+$lang['send404'] = 'Posílat "HTTP 404/Page Not Found" pro neexistují stránky';
+$lang['sitemap'] = 'Generovat Google sitemap (interval ve dnech)';
+$lang['broken_iua'] = 'Je na vašem systému funkce ignore_user_abort porouchaná? To může způsobovat nefunkčnost vyhledávacího indexu. O kombinaci IIS+PHP/CGI je známo, že nefunguje správně. Viz <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> pro více informací.';
+$lang['xsendfile'] = 'Používat X-Sendfile hlavničky pro download statických souborů z webserveru? Je však požadována podpora této funkce na straně Vašeho webserveru.';
+$lang['renderer_xhtml'] = 'Vykreslovací jádro pro hlavní (xhtml) výstup wiki';
+$lang['renderer__core'] = '%s (jádro DokuWiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Povolit trvaté přihlašovací cookies (zapamatuj si mě)';
+$lang['rss_type'] = 'Typ XML kanálu';
+$lang['rss_linkto'] = 'XML kanál odkazuje na';
+$lang['rss_content'] = 'Co zobrazovat v položkách XML kanálu?';
+$lang['rss_update'] = 'Interval aktualizace XML kanálu (v sekundách)';
+$lang['recent_days'] = 'Jak staré nedávných změny uchovávat (ve dnech)';
+$lang['rss_show_summary'] = 'XML kanál ukazuje souhrn v titulku';
+$lang['target____wiki'] = 'Cílové okno pro interní odkazy';
+$lang['target____interwiki'] = 'Cílové okno pro interwiki odkazy';
+$lang['target____extern'] = 'Cílové okno pro externí odkazy';
+$lang['target____media'] = 'Cílové okno pro odkazy na média';
+$lang['target____windows'] = 'Cílové okno pro odkazy na windows sdílení';
+$lang['proxy____host'] = 'Název proxy serveru';
+$lang['proxy____port'] = 'Proxy port';
+$lang['proxy____user'] = 'Proxy uživatelské jméno';
+$lang['proxy____pass'] = 'Proxy heslo';
+$lang['proxy____ssl'] = 'Použít SSL při připojení k proxy';
+$lang['proxy____except'] = 'Regulární výrazy pro URL, pro které bude přeskočena proxy.';
+$lang['safemodehack'] = 'Zapnout safemode hack';
+$lang['ftp____host'] = 'FTP server pro safemode hack';
+$lang['ftp____port'] = 'FTP port pro safemode hack';
+$lang['ftp____user'] = 'FTP uživatelské jméno pro safemode hack';
+$lang['ftp____pass'] = 'FTP heslo pro safemode hack';
+$lang['ftp____root'] = 'FTP kořenový adresář pro safemode hack';
+$lang['license_o_'] = 'Nic nevybráno';
+$lang['typography_o_0'] = 'vypnuto';
+$lang['typography_o_1'] = 'Pouze uvozovky';
+$lang['typography_o_2'] = 'Všechny typy uvozovek a apostrofů (nemusí vždy fungovat)';
+$lang['userewrite_o_0'] = 'vypnuto';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'interní metoda DokuWiki';
+$lang['deaccent_o_0'] = 'vypnuto';
+$lang['deaccent_o_1'] = 'odstranit diakritiku';
+$lang['deaccent_o_2'] = 'převést na latinku';
+$lang['gdlib_o_0'] = 'GD knihovna není k dispozici';
+$lang['gdlib_o_1'] = 'Verze 1.x';
+$lang['gdlib_o_2'] = 'Autodetekce';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstraktní';
+$lang['rss_content_o_diff'] = 'Sjednocený Diff';
+$lang['rss_content_o_htmldiff'] = 'diff tabulka v HTML formátu';
+$lang['rss_content_o_html'] = 'Úplný HTML obsah stránky';
+$lang['rss_linkto_o_diff'] = 'přehled změn';
+$lang['rss_linkto_o_page'] = 'stránku samotnou';
+$lang['rss_linkto_o_rev'] = 'seznam revizí';
+$lang['rss_linkto_o_current'] = 'nejnovější revize';
+$lang['compression_o_0'] = 'vypnuto';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nepoužívat';
+$lang['xsendfile_o_1'] = 'Proprietární hlavička lighttpd (před releasem 1.5)';
+$lang['xsendfile_o_2'] = 'Standardní hlavička X-Sendfile';
+$lang['xsendfile_o_3'] = 'Proprietární hlavička Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Přihlašovací jméno';
+$lang['showuseras_o_username'] = 'Celé jméno uživatele';
+$lang['showuseras_o_email'] = 'E-mailová adresa uživatele ("zamaskována" aktuálně nastavenou metodou)';
+$lang['showuseras_o_email_link'] = 'E-mailová adresa uživatele jako mailto: odkaz';
+$lang['useheading_o_0'] = 'Nikdy';
+$lang['useheading_o_navigation'] = 'Pouze pro navigaci';
+$lang['useheading_o_content'] = 'Pouze pro wiki obsah';
+$lang['useheading_o_1'] = 'Vždy';
+$lang['readdircache'] = 'Maximální stáří readdir cache (sec)';
diff --git a/lib/plugins/config/lang/da/intro.txt b/lib/plugins/config/lang/da/intro.txt
new file mode 100644
index 000000000..f20961b98
--- /dev/null
+++ b/lib/plugins/config/lang/da/intro.txt
@@ -0,0 +1,8 @@
+====== Opsætningsstyring ======
+
+Brug denne side til at kontrollere indstillingerne for din Dokuwiki-opsætning. For at få hjælp med specifikke indstillinger, se [[doku>config]]. For flere detaljer om denne udvidelse, se [[doku>plugin:config]].
+
+Indstillinger vist med lys rød baggrund er beskyttede og kan ikke ændres med denne udvidelse. Indstillinger vist med blå baggrund er standardindstillinger og indstillinger vist med hvid baggrund er blevet sat lokalt denne konkrete opsætning. Både blå og hvide indstillinger kan ændres.
+
+Husk at trykke på **Gem**-knappen før du forlader siden, for at du ikke mister dine ændringer.
+
diff --git a/lib/plugins/config/lang/da/lang.php b/lib/plugins/config/lang/da/lang.php
new file mode 100644
index 000000000..a4c0bba75
--- /dev/null
+++ b/lib/plugins/config/lang/da/lang.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Lars Næsbye Christensen <larsnaesbye@stud.ku.dk>
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['menu'] = 'Opsætningsindstillinger';
+$lang['error'] = 'Indstillingerne blev ikke opdateret på grund af en ugyldig værdi, Gennemse venligst dine ændringer og gem dem igen.
+ <br />Ugyldige værdier vil blive rammet ind med rødt.';
+$lang['updated'] = 'Indstillingerne blev opdateret korrekt.';
+$lang['nochoice'] = '(ingen andre valgmuligheder)';
+$lang['locked'] = 'Indstillingsfilen kunne ikke opdateres, Hvis dette er en fejl, <br />
+sørg da for at navnet på den lokale indstillingsfil samt dens rettigheder er korrekte.';
+$lang['danger'] = 'Fare: Ændring af denne mulighed kan gøre din wiki og opsætningsoversigt utilgængelige.';
+$lang['warning'] = 'Advarsel: Ændring af denne mulighed kan forårsage utilsigtet opførsel.';
+$lang['security'] = 'Sikkerhedsadvarsel: Ændring af denne mulighed kan forårsage en sikkerhedsrisiko.';
+$lang['_configuration_manager'] = 'Opsætningsstyring';
+$lang['_header_dokuwiki'] = 'DokuWiki indstillinger';
+$lang['_header_plugin'] = 'Udvidelsesindstillinger';
+$lang['_header_template'] = 'Skabelonindstillinger';
+$lang['_header_undefined'] = 'Ikke satte indstillinger';
+$lang['_basic'] = 'Grundindstillinger';
+$lang['_display'] = 'Synlighedsindstillinger';
+$lang['_authentication'] = 'Bekræftelsesindstillinger';
+$lang['_anti_spam'] = 'Trafikkontrolsindstillinger';
+$lang['_editing'] = 'Redigeringsindstillinger';
+$lang['_links'] = 'Henvisningsindstillinger';
+$lang['_media'] = 'Medieindstillinger';
+$lang['_advanced'] = 'Avancerede indstillinger';
+$lang['_network'] = 'Netværksindstillinger';
+$lang['_plugin_sufix'] = 'Udvidelsesindstillinger';
+$lang['_template_sufix'] = 'Skabelonindstillinger';
+$lang['_msg_setting_undefined'] = 'Ingen indstillingsmetadata.';
+$lang['_msg_setting_no_class'] = 'Ingen indstillingsklasse.';
+$lang['_msg_setting_no_default'] = 'Ingen standardværdi.';
+$lang['fmode'] = 'Filoprettelsestilstand';
+$lang['dmode'] = 'Katalogoprettelsestilstand';
+$lang['lang'] = 'Sprog';
+$lang['basedir'] = 'Grundkatalog';
+$lang['baseurl'] = 'Grundadresse';
+$lang['savedir'] = 'Katalog til opbevaring af data';
+$lang['start'] = 'Startsidens navn';
+$lang['title'] = 'Wiki titel';
+$lang['template'] = 'Skabelon';
+$lang['license'] = 'Under hvilken licens skal dit indhold frigives?';
+$lang['fullpath'] = 'Vis den fulde sti til siderne i bundlinjen';
+$lang['recent'] = 'Nylige ændringer';
+$lang['breadcrumbs'] = 'Stilængde';
+$lang['youarehere'] = 'Hierarkisk sti';
+$lang['typography'] = 'Typografiske erstatninger';
+$lang['htmlok'] = 'Tillad indlejret HTML';
+$lang['phpok'] = 'Tillad indlejret PHP';
+$lang['dformat'] = 'Datoformat (se PHP\'s <a href="http://www.php.net/strftime">strftime</a>-funktion)';
+$lang['signature'] = 'Underskrift';
+$lang['toptoclevel'] = 'Øverste niveau for indholdsfortegnelse';
+$lang['tocminheads'] = 'Mindste antal overskrifter for at danne Indholdsfortegnelsen';
+$lang['maxtoclevel'] = 'Højeste niveau for indholdsfortegnelse';
+$lang['maxseclevel'] = 'Højeste niveau for redigering af sektioner';
+$lang['camelcase'] = 'Brug KamelKasse til henvisninger';
+$lang['deaccent'] = 'Pæne sidenavne';
+$lang['useheading'] = 'Brug første overskrift til sidenavne';
+$lang['refcheck'] = 'Mediehenvisningerkontrol';
+$lang['refshow'] = 'Antal viste mediehenvisninger';
+$lang['allowdebug'] = 'Tillad fejlretning <b>slå fra hvis unødvendig!</b>';
+$lang['usewordblock'] = 'Hindr uønsket brug med en ordliste';
+$lang['indexdelay'] = 'Tidsforsinkelse før katalogisering (sek.)';
+$lang['relnofollow'] = 'Brug rel="nofollow" til udadgående henvisninger';
+$lang['mailguard'] = 'Slør elektroniske adresser';
+$lang['iexssprotect'] = 'Gennemse oplagte filer for mulig skadelig JavaScript- eller HTML-kode.';
+$lang['showuseras'] = 'Hvad skal vises når den sidste bruger, der har ændret siden, fremstilles';
+$lang['useacl'] = 'Benyt adgangskontrollister';
+$lang['autopasswd'] = 'Generer adgangskoder automatisk';
+$lang['authtype'] = 'Bekræftelsesgrundlag';
+$lang['passcrypt'] = 'Krypteringsmetode for adgangskoder';
+$lang['defaultgroup'] = 'Standardgruppe';
+$lang['superuser'] = 'Superbruger';
+$lang['manager'] = 'Bestyrer - en gruppe eller bruger med adgang til bestemte styrende funktioner';
+$lang['profileconfirm'] = 'Bekræft profilændringer med kodeord';
+$lang['disableactions'] = 'Slå DokuWiki-muligheder fra';
+$lang['disableactions_check'] = 'Tjek';
+$lang['disableactions_subscription'] = 'Tliføj/Fjern opskrivning';
+$lang['disableactions_wikicode'] = 'Vis kilde/Eksporter grundkode';
+$lang['disableactions_other'] = 'Andre muligheder (kommasepareret)';
+$lang['sneaky_index'] = 'DokuWiki vil som standard vise alle navnerum i indholdsfortegnelsen. Ved at slå denne valgmulighed til vil skjule de navnerum, hvor brugeren ikke har læsetilladelse. Dette kan føre til, at tilgængelige undernavnerum bliver skjult. Ligeledes kan det også gøre indholdsfortegnelsen ubrugelig med visse ACL-opsætninger.';
+$lang['auth_security_timeout'] = 'Tidsudløb for bekræftelse (sekunder)';
+$lang['securecookie'] = 'Skal datafiler skabt af HTTPS kun sendes af HTTPS gennem browseren? Slå denne valgmulighed fra hvis kun brugen af din wiki er SSL-beskyttet, mens den almindelige tilgang udefra ikke er sikret.';
+$lang['xmlrpc'] = 'Slå XML-RPC-grænseflade til/fra.';
+$lang['xmlrpcuser'] = 'Begræns XML-RPC-adgang til de nævnte og med komma adskilte grupper eller brugere. Lad den stå tom for at give alle adgang.';
+$lang['updatecheck'] = 'Kig efter opdateringer og sikkerhedsadvarsler? DokuWiki er nødt til at kontakte update.dokuwiki.org for at tilgå denne funktion.';
+$lang['userewrite'] = 'Brug pæne netadresser';
+$lang['useslash'] = 'Brug skråstreg som navnerumsdeler i netadresser';
+$lang['usedraft'] = 'Gem automatisk en kladde under redigering';
+$lang['sepchar'] = 'Orddelingstegn til sidenavne';
+$lang['canonical'] = 'Benyt fuldt kanoniske netadresser';
+$lang['fnencode'] = 'Metode for indkodning af ikke ASCII filnavne';
+$lang['autoplural'] = 'Tjek for flertalsendelser i henvisninger';
+$lang['compression'] = 'Pakningsmetode for attic-filer';
+$lang['cachetime'] = 'Længste levetid for "cache" (sek)';
+$lang['locktime'] = 'Længste levetid for låsefiler (sek)';
+$lang['fetchsize'] = 'Største antal (bytes) fetch.php må hente udefra';
+$lang['notify'] = 'Send ændringsmeddelelser til denne e-adresse';
+$lang['registernotify'] = 'Send info om nyoprettede brugere til denne e-adresse';
+$lang['mailfrom'] = 'E-adresse til brug for automatiske meddelelser';
+$lang['gzip_output'] = 'Benyt gzip-Content-Encoding (indholdskryptering) til XHTML';
+$lang['gdlib'] = 'Udgave af GD Lib';
+$lang['im_convert'] = 'Sti til ImageMagick\'s omdannerværktøj';
+$lang['jpg_quality'] = 'JPG komprimeringskvalitet (0-100)';
+$lang['subscribers'] = 'Slå understøttelse af abonnement på sider til';
+$lang['subscribe_time'] = 'Tid der går før abonnementlister og nyhedsbreve er sendt (i sekunder). Denne værdi skal være mindre end den tid specificeret under recent_days.';
+$lang['compress'] = 'Komprimer CSS- og JavaScript-filer';
+$lang['hidepages'] = 'Skjul lignende sider (almindelige udtryk)';
+$lang['send404'] = 'Send "HTTP 404/Page Not Found" for ikke-eksisterende sider';
+$lang['sitemap'] = 'Generer Google-"sitemap" (dage)';
+$lang['broken_iua'] = 'Er funktionen "ignore_user_abort" uvirksom på dit system? Dette kunne forårsage en ikke virkende søgeoversigt. IIS+PHP/CGI er kendt for ikke at virke. Se <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Fejl 852</a> for flere oplysninger.';
+$lang['xsendfile'] = 'Brug hovedfilen til X-Sendfile for at få netserveren til at sende statiske filer? Din netserver skal understøtte dette for at bruge det.';
+$lang['renderer_xhtml'] = 'Udskriver der skal bruges til størstedelen af wiki-udskriften (XHTML)';
+$lang['renderer__core'] = '%s (dokuwiki-kerne)';
+$lang['renderer__plugin'] = '%s (udvidelse)';
+$lang['rememberme'] = 'Tillad varige datafiler for brugernavne (husk mig)';
+$lang['rss_type'] = 'Type af XML-liste';
+$lang['rss_linkto'] = 'XML-liste henviser til';
+$lang['rss_content'] = 'Hvad skal der vises i XML-listepunkteren?';
+$lang['rss_update'] = 'XML-listens opdateringsinterval (sek)';
+$lang['recent_days'] = 'Hvor mange nye ændringer der skal beholdes (dage)';
+$lang['rss_show_summary'] = 'XML-liste vis referat i overskriften';
+$lang['target____wiki'] = 'Målvindue for indre henvisninger';
+$lang['target____interwiki'] = 'Målvindue for egne wikihenvisninger ';
+$lang['target____extern'] = 'Målvindue for udadgående henvisninger';
+$lang['target____media'] = 'Målvindue for mediehenvisninger';
+$lang['target____windows'] = 'Målvindue til Windows-henvisninger';
+$lang['proxy____host'] = 'Proxy-servernavn';
+$lang['proxy____port'] = 'Proxy-port';
+$lang['proxy____user'] = 'Proxy-brugernavn';
+$lang['proxy____pass'] = 'Proxy-kodeord';
+$lang['proxy____ssl'] = 'Brug SSL til at forbinde til proxy';
+$lang['proxy____except'] = 'Regular expression til at matche URL\'er for hvilke proxier der skal ignores';
+$lang['safemodehack'] = 'Slå "safemode hack" til ';
+$lang['ftp____host'] = 'FTP-server til "safemode hack"';
+$lang['ftp____port'] = 'FTP-port til "safemode hack"';
+$lang['ftp____user'] = 'FTP-brugernavn til "safemode hack"';
+$lang['ftp____pass'] = 'FTP-adgangskode til "safemode hack"';
+$lang['ftp____root'] = 'FTP-rodmappe til "safemode hack"';
+$lang['license_o_'] = 'Ingen valgt';
+$lang['typography_o_0'] = 'ingen';
+$lang['typography_o_1'] = 'Kun gåseøjne';
+$lang['typography_o_2'] = 'Tillader enkelttegnscitering (vil måske ikke altid virke)';
+$lang['userewrite_o_0'] = 'ingen';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Dokuwiki indre';
+$lang['deaccent_o_0'] = 'fra';
+$lang['deaccent_o_1'] = 'fjern accenttegn';
+$lang['deaccent_o_2'] = 'romaniser';
+$lang['gdlib_o_0'] = 'GD Lib ikke tilstede';
+$lang['gdlib_o_1'] = 'Udgave 1.x';
+$lang['gdlib_o_2'] = 'automatisk sondering';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstrakt';
+$lang['rss_content_o_diff'] = '"Unified Diff" (Sammensat)';
+$lang['rss_content_o_htmldiff'] = 'HTML-formateret diff-tabel';
+$lang['rss_content_o_html'] = 'Fuldt HTML-sideindhold';
+$lang['rss_linkto_o_diff'] = 'liste over forskelle';
+$lang['rss_linkto_o_page'] = 'den redigerede side';
+$lang['rss_linkto_o_rev'] = 'liste over ændringer';
+$lang['rss_linkto_o_current'] = 'den nuværende side';
+$lang['compression_o_0'] = 'ingen';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'brug ikke';
+$lang['xsendfile_o_1'] = 'Proprietær lighttpd-hovedfil (før udgave 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile-hovedfil';
+$lang['xsendfile_o_3'] = 'Proprietær Nginx X-Accel-Redirect hovedfil';
+$lang['showuseras_o_loginname'] = 'Brugernavn';
+$lang['showuseras_o_username'] = 'Brugerens fulde navn';
+$lang['showuseras_o_email'] = 'Brugerens e-adresse (ændret i forhold til mailguard-indstillingerne)';
+$lang['showuseras_o_email_link'] = 'Brugers e-adresse som en mailto:-henvisning';
+$lang['useheading_o_0'] = 'Aldrig';
+$lang['useheading_o_navigation'] = 'Kun navigering';
+$lang['useheading_o_content'] = 'Kun wiki-indhold';
+$lang['useheading_o_1'] = 'Altid';
+$lang['readdircache'] = 'Maksimum alder for readdir hukommelse (sek)';
diff --git a/lib/plugins/config/lang/de-informal/intro.txt b/lib/plugins/config/lang/de-informal/intro.txt
new file mode 100644
index 000000000..7ac1b47d9
--- /dev/null
+++ b/lib/plugins/config/lang/de-informal/intro.txt
@@ -0,0 +1,7 @@
+===== Einstellungs-Manager =====
+
+Benutze diese Seite zur Kontrolle der Einstellungen deiner DokuWiki-Installation. Für Hilfe zu individuellen Einstellungen gehe zu [[doku>config]]. Für mehr Details über diese Erweiterungen siehe [[doku>plugin:config]].
+
+Einstellungen die mit einem hellroten Hintergrund angezeigt werden, können mit dieser Erweiterung nicht verändert werden. Einstellungen mit einem blauen Hintergrund sind Standardwerte und Einstellungen mit einem weißen Hintergrund wurden lokal gesetzt für diese Installation. Sowohl blaue als auch weiße Einstellungen können angepasst werden.
+
+Denke dran **Speichern** zu drücken bevor du die Seite verlässt, andernfalls werden deine Änderungen nicht übernommen. \ No newline at end of file
diff --git a/lib/plugins/config/lang/de-informal/lang.php b/lib/plugins/config/lang/de-informal/lang.php
new file mode 100644
index 000000000..1a66c4a8e
--- /dev/null
+++ b/lib/plugins/config/lang/de-informal/lang.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Einstellungen';
+$lang['error'] = 'Einstellungen wurden nicht aktualisiert auf Grund eines ungültigen Wertes. Bitte überprüfe deine Änderungen und versuche es erneut.<br />Die/der ungültige(n) Wert(e) werden durch eine rote Umrandung hervorgehoben.';
+$lang['updated'] = 'Einstellungen erfolgreich aktualisiert.';
+$lang['nochoice'] = '(keine andere Option möglich)';
+$lang['locked'] = 'Die Einstellungsdatei kann nicht aktualisiert werden. Wenn dies unbeabsichtigt ist stelle sicher, dass der Name und die Zugriffsrechte der Einstellungsdatei richtig sind.';
+$lang['danger'] = '**Achtung**: Eine Änderung dieser Einstellung kann dein Wiki und das Einstellungsmenü unerreichbar machen.';
+$lang['warning'] = 'Achtung: Eine Änderungen dieser Option kann zu unbeabsichtigtem Verhalten führen.';
+$lang['security'] = 'Sicherheitswarnung: Eine Änderungen dieser Option können ein Sicherheitsrisiko bedeuten.';
+$lang['_configuration_manager'] = 'Einstellungen';
+$lang['_header_dokuwiki'] = 'DokuWiki-Einstellungen';
+$lang['_header_plugin'] = 'Plugin-Einstellungen';
+$lang['_header_template'] = 'Vorlageneinstellungen';
+$lang['_header_undefined'] = 'unbestimmte Einstellungen';
+$lang['_basic'] = 'Grundeinstellungen';
+$lang['_display'] = 'Darstellungs-Einstellungen';
+$lang['_authentication'] = 'Bestätigungseinstellungen';
+$lang['_anti_spam'] = 'Anti-Spam-Einstellungen';
+$lang['_editing'] = 'Bearbeitungseinstellungen';
+$lang['_links'] = 'Link-Einstellungen';
+$lang['_media'] = 'Media-Einstellungen';
+$lang['_advanced'] = 'erweiterte Einstellungen';
+$lang['_network'] = 'Netzwerk-Einstellungen';
+$lang['_plugin_sufix'] = 'Plugin-Einstellungen';
+$lang['_template_sufix'] = 'Vorlageneinstellungen';
+$lang['_msg_setting_undefined'] = 'Keine Konfigurationsmetadaten.';
+$lang['_msg_setting_no_class'] = 'Keine Konfigurationsklasse.';
+$lang['_msg_setting_no_default'] = 'Kein Standardwert.';
+$lang['fmode'] = 'Zugriffsrechte bei Dateierstellung';
+$lang['dmode'] = 'Zugriffsrechte bei Verzeichniserstellung';
+$lang['lang'] = 'Sprache';
+$lang['basedir'] = 'Installationsverzeichnis';
+$lang['baseurl'] = 'Installationspfad (URL)';
+$lang['savedir'] = 'Ordner zum Speichern von Daten';
+$lang['cookiedir'] = 'Cookie Pfad. Leer lassen, um die Standard-Url zu belassen.';
+$lang['start'] = 'Name der Startseite';
+$lang['title'] = 'Wiki Titel';
+$lang['template'] = 'Vorlage';
+$lang['license'] = 'Unter welcher Lizenz sollte Ihr Inhalt veröffentlicht werden?';
+$lang['fullpath'] = 'Zeige vollen Pfad der Datei in Fußzeile an';
+$lang['recent'] = 'letzte Änderungen';
+$lang['breadcrumbs'] = 'Anzahl der Einträge im "Krümelpfad"';
+$lang['youarehere'] = 'Hierarchische Pfadnavigation verwenden';
+$lang['typography'] = 'Mach drucktechnische Ersetzungen';
+$lang['htmlok'] = 'Erlaube eingebettetes HTML';
+$lang['phpok'] = 'Erlaube eingebettetes PHP';
+$lang['dformat'] = 'Datumsformat (siehe PHPs <a href="http://www.php.net/strftime">strftime</a> Funktion)';
+$lang['signature'] = 'Signatur';
+$lang['toptoclevel'] = 'Inhaltsverzeichnis bei dieser Überschriftengröße beginnen';
+$lang['tocminheads'] = 'Mindestanzahl der Überschriften die entscheidet, ob ein Inhaltsverzeichnis erscheinen soll';
+$lang['maxtoclevel'] = 'Maximale Überschriftsgröße für Inhaltsverzeichnis';
+$lang['maxseclevel'] = 'Abschnitte bis zu dieser Stufe einzeln editierbar machen';
+$lang['camelcase'] = 'CamelCase-Verlinkungen verwenden';
+$lang['deaccent'] = 'Seitennamen bereinigen';
+$lang['useheading'] = 'Erste Überschrift als Seitennamen verwenden';
+$lang['refcheck'] = 'Auf Verwendung beim Löschen von Media-Dateien testen';
+$lang['refshow'] = 'Wie viele Verwendungsorte der Media-Datei zeigen';
+$lang['allowdebug'] = 'Debug-Ausgaben erlauben <b>Abschalten wenn nicht benötigt!</b>';
+$lang['mediarevisions'] = 'Media-Revisionen (ältere Versionen) aktivieren?';
+$lang['usewordblock'] = 'Blockiere Spam basierend auf der Wortliste';
+$lang['indexdelay'] = 'Zeit bevor Suchmaschinenindexierung erlaubt ist';
+$lang['relnofollow'] = 'rel="nofollow" verwenden';
+$lang['mailguard'] = 'E-Mail-Adressen schützen';
+$lang['iexssprotect'] = 'Hochgeladene Dateien auf bösartigen JavaScript- und HTML-Code untersuchen';
+$lang['showuseras'] = 'Was angezeigt werden soll, wenn der Benutzer, der zuletzt eine Seite bearbeitet hat, angezeigt wird';
+$lang['useacl'] = 'Benutze Zugangskontrollliste';
+$lang['autopasswd'] = 'Automatisch erzeugte Passwörter';
+$lang['authtype'] = 'Authentifizierungsmethode';
+$lang['passcrypt'] = 'Passwortverschlüsselungsmethode';
+$lang['defaultgroup'] = 'Standardgruppe';
+$lang['superuser'] = 'Administrator - Eine Gruppe oder Nutzer mit vollem Zugriff auf alle Seiten und Administrationswerkzeuge.';
+$lang['manager'] = 'Manager - Eine Gruppe oder Nutzer mit Zugriff auf einige Administrationswerkzeuge.';
+$lang['profileconfirm'] = 'Änderungen am Benutzerprofil mit Passwort bestätigen';
+$lang['disableactions'] = 'Deaktiviere DokuWiki\'s Zugriffe';
+$lang['disableactions_check'] = 'Check';
+$lang['disableactions_subscription'] = 'Bestellen/Abbestellen';
+$lang['disableactions_wikicode'] = 'Zeige Quelle/Exportiere Rohdaten';
+$lang['disableactions_other'] = 'Weitere Aktionen (durch Komma getrennt)';
+$lang['sneaky_index'] = 'Standardmäßig zeigt DokuWiki alle Namensräume in der Indexansicht an. Bei Aktivierung dieser Einstellung werden alle Namensräume versteckt, in welchen der Benutzer keine Leserechte hat. Dies könnte dazu führen, dass lesbare Unternamensräume versteckt werden. Dies kann die Indexansicht bei bestimmten Zugangskontrolleinstellungen unbenutzbar machen.';
+$lang['auth_security_timeout'] = 'Zeitüberschreitung bei der Authentifizierung (Sekunden)';
+$lang['securecookie'] = 'Sollen Cookies, die via HTTPS gesetzt wurden nur per HTTPS versendet werden? Deaktiviere diese Option, wenn nur der Login deines Wikis mit SSL gesichert ist, aber das Betrachten des Wikis ungesichert geschieht.';
+$lang['xmlrpc'] = 'Aktiviere/Deaktiviere die XML-RPC-Schnittstelle';
+$lang['xmlrpcuser'] = 'XML-RPC-Zugriff auf folgende Gruppen oder Benutzer (kommasepariert) beschränken. Wenn du dieses Feld leer lässt, wir der Zugriff jedem gewährt.';
+$lang['updatecheck'] = 'Automatisch auf Updates und Sicherheitswarnungen prüfen? DokuWiki muss sich dafür mit update.dokuwiki.org verbinden.';
+$lang['userewrite'] = 'Benutze schöne URLs';
+$lang['useslash'] = 'Benutze Schrägstrich als Namensraumtrenner in URLs';
+$lang['usedraft'] = 'Speichere automatisch Entwürfe während der Bearbeitung';
+$lang['sepchar'] = 'Worttrenner für Seitennamen in URLs';
+$lang['canonical'] = 'Immer Links mit vollständigen URLs erzeugen';
+$lang['fnencode'] = 'Methode um nicht-ASCII Dateinamen zu kodieren.';
+$lang['autoplural'] = 'Bei Links automatisch nach vorhandenen Pluralformen suchen';
+$lang['compression'] = 'Komprimierungsmethode für alte Seitenrevisionen';
+$lang['cachetime'] = 'Maximale Cachespeicherung (Sekunden)';
+$lang['locktime'] = 'Maximales Alter für Seitensperren (Sekunden)';
+$lang['fetchsize'] = 'Maximale Größe (in Bytes), die fetch.php von extern herunterladen darf';
+$lang['notify'] = 'Sende Änderungsbenachrichtigungen an diese E-Mail-Adresse.';
+$lang['registernotify'] = 'Sende Information bei neu registrierten Benutzern an diese E-Mail-Adresse.';
+$lang['mailfrom'] = 'Absenderadresse für automatisch erzeugte E-Mails';
+$lang['mailprefix'] = 'Präfix für E-Mail-Betreff beim automatischen Versand von Benachrichtigungen';
+$lang['gzip_output'] = 'Seiten mit gzip komprimiert ausliefern';
+$lang['gdlib'] = 'GD Lib Version';
+$lang['im_convert'] = 'Pfad zu ImageMagicks-Konvertierwerkzeug';
+$lang['jpg_quality'] = 'JPEG Kompressionsqualität (0-100)';
+$lang['subscribers'] = 'E-Mail-Abos zulassen';
+$lang['subscribe_time'] = 'Zeit nach der Zusammenfassungs- und Änderungslisten-E-Mails verschickt werden; Dieser Wert sollte kleiner als die in recent_days konfigurierte Zeit sein.';
+$lang['compress'] = 'JavaScript und Stylesheets komprimieren';
+$lang['cssdatauri'] = 'Größe in Bytes, bis zu der Bilder in css-Dateien referenziert werden können, um HTTP-Anfragen zu minimieren. Diese Technik funktioniert nicht im IE 7 und älter! <code>400</code> bis <code>600</code> Bytes sind gute Werte. Setze <code>0</code> für inaktive Funktion.';
+$lang['hidepages'] = 'Seiten verstecken (Regulärer Ausdruck)';
+$lang['send404'] = 'Sende "HTTP 404/Seite nicht gefunden" für nicht existierende Seiten';
+$lang['sitemap'] = 'Erzeuge Google Sitemaps (Tage)';
+$lang['broken_iua'] = 'Falls die Funktion ignore_user_abort auf deinem System nicht funktioniert, könnte der Such-Index nicht funktionieren. IIS+PHP/CGI ist bekannt dafür. Siehe auch <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>.';
+$lang['xsendfile'] = 'Den X-Sendfile-Header nutzen, um Dateien direkt vom Webserver ausliefern zu lassen? Dein Webserver muss dies unterstützen!';
+$lang['renderer_xhtml'] = 'Standard-Renderer für die normale (XHTML) Wiki-Ausgabe.';
+$lang['renderer__core'] = '%s (DokuWiki Kern)';
+$lang['renderer__plugin'] = '%s (Erweiterung)';
+$lang['rememberme'] = 'Permanente Login-Cookies erlauben (Auf diesem Computer eingeloggt bleiben)';
+$lang['rss_type'] = 'XML-Feed-Format';
+$lang['rss_linkto'] = 'XML-Feed verlinken auf';
+$lang['rss_content'] = 'Was soll in XML-Feedinhalten angezeigt werden?';
+$lang['rss_update'] = 'Aktualisierungsintervall für XML-Feeds (Sekunden)';
+$lang['recent_days'] = 'Wie viele Änderungen sollen vorgehalten werden? (Tage)';
+$lang['rss_show_summary'] = 'Bearbeitungs-Zusammenfassung im XML-Feed anzeigen';
+$lang['target____wiki'] = 'Zielfenstername für interne Links';
+$lang['target____interwiki'] = 'Zielfenstername für InterWiki-Links';
+$lang['target____extern'] = 'Zielfenstername für externe Links';
+$lang['target____media'] = 'Zielfenstername für Medienlinks';
+$lang['target____windows'] = 'Zielfenstername für Windows-Freigaben-Links';
+$lang['proxy____host'] = 'Proxyadresse';
+$lang['proxy____port'] = 'Proxyport';
+$lang['proxy____user'] = 'Benutzername für den Proxy';
+$lang['proxy____pass'] = 'Passwort von dem Proxybenutzer';
+$lang['proxy____ssl'] = 'SSL verwenden um auf den Proxy zu zugreifen';
+$lang['proxy____except'] = 'Regulärer Ausdruck um Adressen zu beschreiben, für die kein Proxy verwendet werden soll';
+$lang['safemodehack'] = 'Aktiviere safemode Hack';
+$lang['ftp____host'] = 'FTP Server für safemode Hack';
+$lang['ftp____port'] = 'FTP Port für safemode Hack';
+$lang['ftp____user'] = 'FTP Benutzername für safemode Hack';
+$lang['ftp____pass'] = 'FTP Passwort für safemode Hack';
+$lang['ftp____root'] = 'FTP Wurzelverzeichnis für Safemodehack';
+$lang['license_o_'] = 'Nichts ausgewählt';
+$lang['typography_o_0'] = 'nichts';
+$lang['typography_o_1'] = 'ohne einfache Anführungszeichen';
+$lang['typography_o_2'] = 'mit einfachen Anführungszeichen (funktioniert nicht immer)';
+$lang['userewrite_o_0'] = 'nichts';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki intern';
+$lang['deaccent_o_0'] = 'aus';
+$lang['deaccent_o_1'] = 'Entferne Akzente';
+$lang['deaccent_o_2'] = 'romanisieren';
+$lang['gdlib_o_0'] = 'GD lib ist nicht verfügbar';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Autoerkennung';
+$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';
+$lang['rss_content_o_abstract'] = 'Zusammenfassung';
+$lang['rss_content_o_diff'] = 'Vereinigtes Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatierte Diff-Tabelle';
+$lang['rss_content_o_html'] = 'Vollständiger HTML-Inhalt';
+$lang['rss_linkto_o_diff'] = 'Ansicht der Unterschiede';
+$lang['rss_linkto_o_page'] = 'geänderte Seite';
+$lang['rss_linkto_o_rev'] = 'Liste der Revisionen';
+$lang['rss_linkto_o_current'] = 'Die aktuelle Seite';
+$lang['compression_o_0'] = 'nichts';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'Nicht benutzen';
+$lang['xsendfile_o_1'] = 'Proprietärer lighttpd-Header (vor Release 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile-Header';
+$lang['xsendfile_o_3'] = 'Proprietärer Nginx X-Accel-Redirect-Header';
+$lang['showuseras_o_loginname'] = 'Login-Name';
+$lang['showuseras_o_username'] = 'Voller Name des Nutzers';
+$lang['showuseras_o_email'] = 'E-Mail-Adresse des Benutzers (je nach Mailguard-Einstellung verschleiert)';
+$lang['showuseras_o_email_link'] = 'E-Mail-Adresse des Benutzers als mailto:-Link';
+$lang['useheading_o_0'] = 'Niemals';
+$lang['useheading_o_navigation'] = 'Nur Navigation';
+$lang['useheading_o_content'] = 'Nur Wiki-Inhalt';
+$lang['useheading_o_1'] = 'Immer';
+$lang['readdircache'] = 'Maximales Alter des readdir-Caches (Sekunden)';
diff --git a/lib/plugins/config/lang/de/intro.txt b/lib/plugins/config/lang/de/intro.txt
new file mode 100644
index 000000000..efb807738
--- /dev/null
+++ b/lib/plugins/config/lang/de/intro.txt
@@ -0,0 +1,10 @@
+====== Konfiguration ======
+
+Dieses Plugin hilft Ihnen bei der Konfiguration von DokuWiki. Hilfe zu den einzelnen Einstellungen finden Sie unter [[doku>config]]. Mehr Information zu diesem Plugin ist unter [[doku>plugin:config]] erhältlich.
+
+Einstellungen mit einem hellroten Hintergrund sind gesichert und können nicht mit diesem Plugin verändert werden, Einstellungen mit hellblauem Hintergrund sind Voreinstellungen, weiß hinterlegte Felder zeigen lokal veränderte Werte an. Sowohl die blauen als auch die weißen Felder können verändert werden.
+
+Bitte vergessen Sie nicht **Speichern** zu drücken bevor Sie die Seite verlassen, andernfalls gehen Ihre Änderungen verloren.
+
+
+
diff --git a/lib/plugins/config/lang/de/lang.php b/lib/plugins/config/lang/de/lang.php
new file mode 100644
index 000000000..a9a275349
--- /dev/null
+++ b/lib/plugins/config/lang/de/lang.php
@@ -0,0 +1,202 @@
+<?php
+/**
+ * German language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Konfiguration';
+$lang['error'] = 'Die Einstellungen wurden wegen einer fehlerhaften Eingabe nicht gespeichert.
+<br />Bitte überprüfen sie die rot umrandeten Eingaben und speichern Sie erneut.';
+$lang['updated'] = 'Einstellungen erfolgreich gespeichert.';
+$lang['nochoice'] = '(keine Auswahlmöglichkeiten vorhanden)';
+$lang['locked'] = 'Die Konfigurationsdatei kann nicht geändert werden, wenn dies unbeabsichtigt ist
+ <br />überprüfen Sie, dass die Dateiberechtigungen korrekt gesetzt sind.';
+$lang['danger'] = 'Vorsicht: Die Änderung dieser Option könnte Ihr Wiki und das Konfigurationsmenü unzugänglich machen.';
+$lang['warning'] = 'Hinweis: Die Änderung dieser Option könnte unbeabsichtigtes Verhalten hervorrufen.';
+$lang['security'] = 'Sicherheitswarnung: Die Änderung dieser Option könnte ein Sicherheitsrisiko darstellen.';
+$lang['_configuration_manager'] = 'Konfiguration';
+$lang['_header_dokuwiki'] = 'DokuWiki-Konfiguration';
+$lang['_header_plugin'] = 'Plugin-Konfiguration';
+$lang['_header_template'] = 'Template-Konfiguration';
+$lang['_header_undefined'] = 'Unbekannte Einstellungen';
+$lang['_basic'] = 'Grund-Konfiguration';
+$lang['_display'] = 'Anzeige-Konfiguration';
+$lang['_authentication'] = 'Authentifizierungs-Konfiguration';
+$lang['_anti_spam'] = 'Anti-Spam-Konfiguration';
+$lang['_editing'] = 'Bearbeitungs-Konfiguration';
+$lang['_links'] = 'Link-Konfiguration';
+$lang['_media'] = 'Medien-Konfiguration';
+$lang['_advanced'] = 'Erweiterte Konfiguration';
+$lang['_network'] = 'Netzwerk-Konfiguration';
+$lang['_plugin_sufix'] = 'Plugin-Konfiguration';
+$lang['_template_sufix'] = 'Template-Konfiguration';
+$lang['_msg_setting_undefined'] = 'Keine Konfigurationsmetadaten.';
+$lang['_msg_setting_no_class'] = 'Keine Konfigurationsklasse.';
+$lang['_msg_setting_no_default'] = 'Kein Standardwert.';
+$lang['fmode'] = 'Rechte für neue Dateien';
+$lang['dmode'] = 'Rechte für neue Verzeichnisse';
+$lang['lang'] = 'Sprache';
+$lang['basedir'] = 'Installationsverzeichnis';
+$lang['baseurl'] = 'Installationspfad (URL)';
+$lang['savedir'] = 'Speicherverzeichnis';
+$lang['cookiedir'] = 'Cookiepfad. Frei lassen, um den gleichen Pfad wie "baseurl" zu benutzen.';
+$lang['start'] = 'Startseitenname';
+$lang['title'] = 'Titel des Wikis';
+$lang['template'] = 'Designvorlage (Template)';
+$lang['license'] = 'Unter welcher Lizenz sollen Ihre Inhalte veröffentlicht werden?';
+$lang['fullpath'] = 'Den kompletten Dateipfad im Footer anzeigen';
+$lang['recent'] = 'Anzahl der Einträge in der Änderungsliste';
+$lang['breadcrumbs'] = 'Anzahl der Einträge im "Krümelpfad"';
+$lang['youarehere'] = 'Hierarchische Pfadnavigation verwenden';
+$lang['typography'] = 'Typographische Ersetzungen';
+$lang['htmlok'] = 'HTML erlauben';
+$lang['phpok'] = 'PHP erlauben';
+$lang['dformat'] = 'Datumsformat (Siehe PHP <a href="http://www.php.net/strftime">strftime</a> Funktion)';
+$lang['signature'] = 'Signatur';
+$lang['toptoclevel'] = 'Inhaltsverzeichnis bei dieser Überschriftengröße beginnen';
+$lang['tocminheads'] = 'Mindestanzahl der Überschriften die entscheidet, ob ein Inhaltsverzeichnis erscheinen soll';
+$lang['maxtoclevel'] = 'Maximale Überschriftsgröße für Inhaltsverzeichnis';
+$lang['maxseclevel'] = 'Abschnitte bis zu dieser Stufe einzeln editierbar machen';
+$lang['camelcase'] = 'CamelCase-Verlinkungen verwenden';
+$lang['deaccent'] = 'Seitennamen bereinigen';
+$lang['useheading'] = 'Erste Überschrift als Seitennamen verwenden';
+$lang['refcheck'] = 'Auf Verwendung beim Löschen von Media-Dateien testen';
+$lang['refshow'] = 'Wiev iele Verwendungsorte der Media-Datei zeigen';
+$lang['allowdebug'] = 'Debug-Ausgaben erlauben <b>Abschalten wenn nicht benötigt!</b>';
+$lang['mediarevisions'] = 'Media-Revisionen (ältere Versionen) aktivieren?';
+$lang['usewordblock'] = 'Spam-Blocking benutzen';
+$lang['indexdelay'] = 'Zeit bevor Suchmaschinenindexierung erlaubt ist';
+$lang['relnofollow'] = 'rel="nofollow" verwenden';
+$lang['mailguard'] = 'E-Mail-Adressen schützen';
+$lang['iexssprotect'] = 'Hochgeladene Dateien auf bösartigen JavaScript- und HTML-Code untersuchen';
+$lang['showuseras'] = 'Was angezeigt werden soll, wenn der Benutzer, der zuletzt eine Seite bearbeitet hat, angezeigt wird';
+$lang['useacl'] = 'Zugangskontrolle verwenden';
+$lang['autopasswd'] = 'Passwort automatisch generieren';
+$lang['authtype'] = 'Authentifizierungsmechanismus';
+$lang['passcrypt'] = 'Verschlüsselungsmechanismus';
+$lang['defaultgroup'] = 'Standardgruppe';
+$lang['superuser'] = 'Administrator - Eine Gruppe oder Nutzer mit vollem Zugriff auf alle Seiten und Administrationswerkzeuge.';
+$lang['manager'] = 'Manager - Eine Gruppe oder Nutzer mit Zugriff auf einige Administrationswerkzeuge.';
+$lang['profileconfirm'] = 'Profiländerung nur nach Passwortbestätigung';
+$lang['disableactions'] = 'DokuWiki-Aktionen deaktivieren';
+$lang['disableactions_check'] = 'Check';
+$lang['disableactions_subscription'] = 'Seiten-Abonnements';
+$lang['disableactions_wikicode'] = 'Quelltext betrachten/exportieren';
+$lang['disableactions_other'] = 'Andere Aktionen (durch Komma getrennt)';
+$lang['sneaky_index'] = 'Standardmäßig zeigt DokuWiki alle Namensräume in der Übersicht. Wenn diese Option aktiviert wird, werden alle Namensräume, für die der Benutzer keine Lese-Rechte hat, nicht angezeigt. Dies kann unter Umständen dazu führen, das lesbare Unter-Namensräume nicht angezeigt werden und macht die Übersicht evtl. unbrauchbar in Kombination mit bestimmten ACL Einstellungen.';
+$lang['auth_security_timeout'] = 'Authentifikations-Timeout (Sekunden)';
+$lang['securecookie'] = 'Sollen Cookies, die via HTTPS gesetzt wurden nur per HTTPS versendet werden? Deaktivieren Sie diese Option, wenn nur der Login Ihres Wikis mit SSL gesichert ist, aber das Betrachten des Wikis ungesichert geschieht.';
+$lang['xmlrpc'] = 'XML-RPC-Zugriff erlauben.';
+$lang['xmlrpcuser'] = 'XML-RPC-Zugriff auf folgende Gruppen oder Benutzer (kommasepariert) beschränken. Wenn Sie dieses Feld leer lassen, wir der Zugriff jedem gewährt.';
+$lang['updatecheck'] = 'Automatisch auf Updates und Sicherheitswarnungen prüfen? DokuWiki muss sich dafür mit update.dokuwiki.org verbinden.';
+$lang['userewrite'] = 'URL rewriting';
+$lang['useslash'] = 'Schrägstrich (/) als Namensraumtrenner in URLs verwenden';
+$lang['usedraft'] = 'Während des Bearbeitens automatisch Zwischenentwürfe speichern';
+$lang['sepchar'] = 'Worttrenner für Seitennamen in URLs';
+$lang['canonical'] = 'Immer Links mit vollständigen URLs erzeugen';
+$lang['fnencode'] = 'Methode um nicht-ASCII Dateinamen zu kodieren.';
+$lang['autoplural'] = 'Bei Links automatisch nach vorhandenen Pluralformen suchen';
+$lang['compression'] = 'Komprimierungsmethode für alte Seitenrevisionen';
+$lang['cachetime'] = 'Maximale Cachespeicherung (Sekunden)';
+$lang['locktime'] = 'Maximales Alter für Seitensperren (Sekunden)';
+$lang['fetchsize'] = 'Maximale Größe (in Bytes), die fetch.php von extern herunterladen darf';
+$lang['notify'] = 'Änderungsmitteilungen an diese E-Mail-Adresse versenden';
+$lang['registernotify'] = 'Information über neu registrierte Nutzer an diese E-Mail-Adresse senden';
+$lang['mailfrom'] = 'Absender-E-Mail-Adresse für automatische Mails';
+$lang['mailprefix'] = 'Präfix für E-Mail-Betreff beim automatischen Versand von Benachrichtigungen';
+$lang['gzip_output'] = 'Seiten mit gzip komprimiert ausliefern';
+$lang['gdlib'] = 'GD Lib Version';
+$lang['im_convert'] = 'Pfad zu ImageMagicks-Konvertierwerkzeug';
+$lang['jpg_quality'] = 'JPEG Kompressionsqualität (0-100)';
+$lang['subscribers'] = 'E-Mail-Abos zulassen';
+$lang['subscribe_time'] = 'Zeit nach der Zusammenfassungs- und Änderungslisten-E-Mails verschickt werden; Dieser Wert sollte kleiner als die in recent_days konfigurierte Zeit sein.';
+$lang['compress'] = 'JavaScript und Stylesheets komprimieren';
+$lang['cssdatauri'] = 'Größe in Bytes, bis zu der Bilder in css-Dateien referenziert werden können, um HTTP-Anfragen zu minimieren. Diese Technik funktioniert nicht im IE 7 und älter! Empfohlene Einstellung: <code>400</code> to <code>600</code> Bytes. Setzen Sie die Einstellung auf <code>0</code> um die Funktion zu deaktivieren.';
+$lang['hidepages'] = 'Seiten verstecken (Regulärer Ausdruck)';
+$lang['send404'] = 'Bei nicht vorhandenen Seiten mit 404 Fehlercode antworten';
+$lang['sitemap'] = 'Google Sitemap erzeugen (Tage)';
+$lang['broken_iua'] = 'Falls die Funktion ignore_user_abort auf Ihrem System nicht funktioniert, könnte der Such-Index nicht funktionieren. IIS+PHP/CGI ist bekannt dafür. Siehe auch <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>.';
+$lang['xsendfile'] = 'Den X-Sendfile-Header nutzen, um Dateien direkt vom Webserver ausliefern zu lassen? Ihr Webserver muss dies unterstützen!';
+$lang['renderer_xhtml'] = 'Standard-Renderer für die normale (XHTML) Wiki-Ausgabe.';
+$lang['renderer__core'] = '%s (DokuWiki Kern)';
+$lang['renderer__plugin'] = '%s (Plugin)';
+$lang['rememberme'] = 'Permanente Login-Cookies erlauben (Auf diesem Computer eingeloggt bleiben)';
+$lang['rss_type'] = 'XML-Feed-Format';
+$lang['rss_linkto'] = 'XML-Feed verlinken auf';
+$lang['rss_content'] = 'Welche Inhalte sollen im XML-Feed dargestellt werden?';
+$lang['rss_update'] = 'XML-Feed Aktualisierungsintervall (Sekunden)';
+$lang['recent_days'] = 'Wieviele letzte Änderungen sollen einsehbar bleiben? (Tage)';
+$lang['rss_show_summary'] = 'Bearbeitungs-Zusammenfassung im XML-Feed anzeigen';
+$lang['target____wiki'] = 'Zielfenster für interne Links (target Attribut)';
+$lang['target____interwiki'] = 'Zielfenster für InterWiki-Links (target Attribut)';
+$lang['target____extern'] = 'Zielfenster für Externe Links (target Attribut)';
+$lang['target____media'] = 'Zielfenster für (Bild-)Dateien (target Attribut)';
+$lang['target____windows'] = 'Zielfenster für Windows Freigaben (target Attribut)';
+$lang['proxy____host'] = 'Proxy-Server';
+$lang['proxy____port'] = 'Proxy-Port';
+$lang['proxy____user'] = 'Proxy Nutzername';
+$lang['proxy____pass'] = 'Proxy Passwort';
+$lang['proxy____ssl'] = 'SSL bei Verbindung zum Proxy verwenden';
+$lang['proxy____except'] = 'Regulärer Ausdruck um Adressen zu beschreiben, für die kein Proxy verwendet werden soll';
+$lang['safemodehack'] = 'Safemodehack verwenden';
+$lang['ftp____host'] = 'FTP-Host für Safemodehack';
+$lang['ftp____port'] = 'FTP-Port für Safemodehack';
+$lang['ftp____user'] = 'FTP Nutzername für Safemodehack';
+$lang['ftp____pass'] = 'FTP Passwort für Safemodehack';
+$lang['ftp____root'] = 'FTP Wurzelverzeichnis für Safemodehack';
+$lang['license_o_'] = 'Keine gewählt';
+$lang['typography_o_0'] = 'keine';
+$lang['typography_o_1'] = 'ohne einfache Anführungszeichen';
+$lang['typography_o_2'] = 'mit einfachen Anführungszeichen (funktioniert nicht immer)';
+$lang['userewrite_o_0'] = 'keines';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki';
+$lang['deaccent_o_0'] = 'aus';
+$lang['deaccent_o_1'] = 'Akzente und Umlaute umwandeln';
+$lang['deaccent_o_2'] = 'Umschrift';
+$lang['gdlib_o_0'] = 'GD Lib nicht verfügbar';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Automatisch finden';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstrakt';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatierte Diff-Tabelle';
+$lang['rss_content_o_html'] = 'Vollständiger HTML-Inhalt';
+$lang['rss_linkto_o_diff'] = 'Änderungen zeigen';
+$lang['rss_linkto_o_page'] = 'geänderte Seite';
+$lang['rss_linkto_o_rev'] = 'Liste aller Änderungen';
+$lang['rss_linkto_o_current'] = 'Aktuelle Seite';
+$lang['compression_o_0'] = 'keine';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nicht benutzen';
+$lang['xsendfile_o_1'] = 'Proprietärer lighttpd-Header (vor Release 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile-Header';
+$lang['xsendfile_o_3'] = 'Proprietärer Nginx X-Accel-Redirect-Header';
+$lang['showuseras_o_loginname'] = 'Loginname';
+$lang['showuseras_o_username'] = 'Vollständiger Name des Benutzers';
+$lang['showuseras_o_email'] = 'E-Mail-Adresse des Benutzers (je nach Mailguard-Einstellung verschleiert)';
+$lang['showuseras_o_email_link'] = 'E-Mail-Adresse des Benutzers als mailto:-Link';
+$lang['useheading_o_0'] = 'Nie';
+$lang['useheading_o_navigation'] = 'Nur Navigation';
+$lang['useheading_o_content'] = 'Nur Wikiinhalt';
+$lang['useheading_o_1'] = 'Immer';
+$lang['readdircache'] = 'Maximales Alter des readdir-Caches (Sekunden)';
diff --git a/lib/plugins/config/lang/el/intro.txt b/lib/plugins/config/lang/el/intro.txt
new file mode 100644
index 000000000..f10636720
--- /dev/null
+++ b/lib/plugins/config/lang/el/intro.txt
@@ -0,0 +1,7 @@
+====== Ρυθμίσεις ======
+
+Χρησιμοποιήστε αυτή την σελίδα για να ρυθμίσετε την λειτουργία του Dokuwiki σας. Για βοήθεια σχετικά με τις ρυθμίσεις δείτε την σελίδα [[doku>config]]. Για περισσότερες λεπτομέρειες σχετικά με αυτή την επέκταση δείτε την σελίδα [[doku>plugin:config]].
+
+Οι ρυθμίσεις που εμφανίζονται σε απαλό κόκκινο φόντο είναι κλειδωμένες και δεν μπορούν να τροποποιηθούν μέσω αυτής της επέκτασης. Οι ρυθμίσεις που εμφανίζονται σε μπλε φόντο είναι οι προεπιλεγμένες ενώ οι ρυθμίσεις που εμφανίζονται σε λευκό φόντο είναι αυτές που διαφέρουν από τις προεπιλεγμένες. Και οι ρυθμίσεις που εμφανίζονται σε μπλε φόντο και οι ρυθμίσεις που εμφανίζονται σε λευκό φόντο μπορούν να τροποποιηθούν.
+
+Θυμηθείτε να επιλέξετε **Αποθήκευση** αφού κάνετε τις αλλαγές που θέλετε.
diff --git a/lib/plugins/config/lang/el/lang.php b/lib/plugins/config/lang/el/lang.php
new file mode 100644
index 000000000..9f5d121de
--- /dev/null
+++ b/lib/plugins/config/lang/el/lang.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['menu'] = 'Ρυθμίσεις';
+$lang['error'] = 'Οι ρυθμίσεις σας δεν έγιναν δεκτές λόγω λανθασμένης τιμής κάποιας ρύθμισης. Διορθώστε την λάθος τιμή και προσπαθήστε ξανά.
+ <br />Η λανθασμένη τιμή υποδεικνύεται με κόκκινο πλαίσιο.';
+$lang['updated'] = 'Επιτυχής τροποποίηση ρυθμίσεων.';
+$lang['nochoice'] = '(δεν υπάρχουν άλλες διαθέσιμες επιλογές)';
+$lang['locked'] = 'Το αρχείο ρυθμίσεων δεν μπορεί να τροποποιηθεί. <br />Εάν αυτό δεν είναι επιθυμητό, διορθώστε τα δικαιώματα πρόσβασης του αρχείου ρυθμίσεων';
+$lang['danger'] = 'Κίνδυνος: Η αλλαγή αυτής της επιλογής θα μπορούσε να αποτρέψει την πρόσβαση στο wiki και στις ρυθμίσεις του.';
+$lang['warning'] = 'Προσοχή: Η αλλαγή αυτής της επιλογής θα μπορούσε να προκαλέσει ανεπιθύμητη συμπεριφορά.';
+$lang['security'] = 'Προσοχή: Η αλλαγή αυτής της επιλογής θα μπορούσε να προκαλέσει προβλήματα ασφαλείας.';
+$lang['_configuration_manager'] = 'Ρυθμίσεις';
+$lang['_header_dokuwiki'] = 'Ρυθμίσεις DokuWiki';
+$lang['_header_plugin'] = 'Ρυθμίσεις Επεκτάσεων';
+$lang['_header_template'] = 'Ρυθμίσεις Προτύπων παρουσίασης';
+$lang['_header_undefined'] = 'Διάφορες Ρυθμίσεις';
+$lang['_basic'] = 'Βασικές Ρυθμίσεις';
+$lang['_display'] = 'Ρυθμίσεις Εμφάνισης';
+$lang['_authentication'] = 'Ρυθμίσεις Ασφαλείας';
+$lang['_anti_spam'] = 'Ρυθμίσεις Anti-Spam';
+$lang['_editing'] = 'Ρυθμίσεις Σύνταξης σελίδων';
+$lang['_links'] = 'Ρυθμίσεις Συνδέσμων';
+$lang['_media'] = 'Ρυθμίσεις Αρχείων';
+$lang['_advanced'] = 'Ρυθμίσεις για Προχωρημένους';
+$lang['_network'] = 'Ρυθμίσεις Δικτύου';
+$lang['_plugin_sufix'] = 'Ρυθμίσεις Επεκτάσεων';
+$lang['_template_sufix'] = 'Ρυθμίσεις Προτύπων παρουσίασης';
+$lang['_msg_setting_undefined'] = 'Δεν έχουν οριστεί metadata.';
+$lang['_msg_setting_no_class'] = 'Δεν έχει οριστεί κλάση.';
+$lang['_msg_setting_no_default'] = 'Δεν υπάρχει τιμή εξ ορισμού.';
+$lang['fmode'] = 'Δικαιώματα πρόσβασης δημιουργούμενων αρχείων';
+$lang['dmode'] = 'Δικαιώματα πρόσβασης δημιουργούμενων φακέλων';
+$lang['lang'] = 'Γλώσσα';
+$lang['basedir'] = 'Αρχικός Φάκελος';
+$lang['baseurl'] = 'Αρχικό URL';
+$lang['savedir'] = 'Φάκελος για την αποθήκευση δεδομένων';
+$lang['cookiedir'] = 'Διαδρομή cookie. Αφήστε την κενή για την χρησιμοποίηση της αρχικής URL.';
+$lang['start'] = 'Ονομασία αρχικής σελίδας';
+$lang['title'] = 'Τίτλος Wiki';
+$lang['template'] = 'Πρότυπο προβολής';
+$lang['license'] = 'Κάτω από ποια άδεια θέλετε να δημοσιευτεί το υλικό σας?';
+$lang['fullpath'] = 'Εμφάνιση πλήρους διαδρομής σελίδας στην υποκεφαλίδα';
+$lang['recent'] = 'Αριθμός πρόσφατων αλλαγών ανά σελίδα';
+$lang['breadcrumbs'] = 'Αριθμός συνδέσμων ιστορικού';
+$lang['youarehere'] = 'Εμφάνιση ιεραρχικής προβολής τρέχουσας σελίδας';
+$lang['typography'] = 'Μετατροπή ειδικών χαρακτήρων στο τυπογραφικό ισοδύναμό τους';
+$lang['htmlok'] = 'Να επιτρέπεται η ενσωμάτωση HTML';
+$lang['phpok'] = 'Να επιτρέπεται η ενσωμάτωση PHP';
+$lang['dformat'] = 'Μορφή ημερομηνίας (βλέπε την <a href="http://www.php.net/strftime">strftime</a> function της PHP)';
+$lang['signature'] = 'Υπογραφή';
+$lang['toptoclevel'] = 'Ανώτατο επίπεδο πίνακα περιεχομένων σελίδας';
+$lang['tocminheads'] = 'Ελάχιστος αριθμός κεφαλίδων για την δημιουργία πίνακα περιεχομένων - TOC';
+$lang['maxtoclevel'] = 'Μέγιστο επίπεδο για πίνακα περιεχομένων σελίδας';
+$lang['maxseclevel'] = 'Μέγιστο επίπεδο για εμφάνιση της επιλογής τροποποίησης επιπέδου';
+$lang['camelcase'] = 'Χρήση CamelCase στους συνδέσμους';
+$lang['deaccent'] = 'Αφαίρεση σημείων στίξης από ονόματα σελίδων';
+$lang['useheading'] = 'Χρήση κεφαλίδας πρώτου επιπέδου σαν τίτλο συνδέσμων';
+$lang['refcheck'] = 'Πριν τη διαγραφή ενός αρχείου να ελέγχεται η ύπαρξη σελίδων που το χρησιμοποιούν';
+$lang['refshow'] = 'Εμφανιζόμενος αριθμός σελίδων που χρησιμοποιούν ένα αρχείο';
+$lang['allowdebug'] = 'Δεδομένα εκσφαλμάτωσης (debug) <b>απενεργοποιήστε τα εάν δεν τα έχετε ανάγκη!</b>';
+$lang['usewordblock'] = 'Χρήστη λίστα απαγορευμένων λέξεων για καταπολέμηση του spam';
+$lang['indexdelay'] = 'Χρόνος αναμονής προτού επιτραπεί σε μηχανές αναζήτησης να ευρετηριάσουν μια τροποποιημένη σελίδα (sec)';
+$lang['relnofollow'] = 'Χρήση rel="nofollow"';
+$lang['mailguard'] = 'Κωδικοποίηση e-mail διευθύνσεων';
+$lang['iexssprotect'] = 'Έλεγχος μεταφορτώσεων για πιθανώς επικίνδυνο κώδικα JavaScript ή HTML';
+$lang['showuseras'] = 'Τι να εμφανίζεται όταν φαίνεται ο χρήστης που τροποποίησε τελευταίος μία σελίδα';
+$lang['useacl'] = 'Χρήση Λίστας Δικαιωμάτων Πρόσβασης (ACL)';
+$lang['autopasswd'] = 'Αυτόματη δημιουργία κωδικού χρήστη';
+$lang['authtype'] = 'Τύπος πιστοποίησης στοιχείων χρήστη';
+$lang['passcrypt'] = 'Μέθοδος κρυπτογράφησης κωδικού χρήστη';
+$lang['defaultgroup'] = 'Προεπιλεγμένη ομάδα χρηστών';
+$lang['superuser'] = 'Υπερ-χρήστης - μία ομάδα ή ένας χρήστης με πλήρη δικαιώματα πρόσβασης σε όλες τις σελίδες και όλες τις λειτουργίες ανεξάρτητα από τις ρυθμίσεις των Λιστών Δικαιωμάτων Πρόσβασης (ACL)';
+$lang['manager'] = 'Διαχειριστής - μία ομάδα ή ένας χρήστης με δικαιώματα πρόσβασης σε ορισμένες από τις λειτουργίες της εφαρμογής';
+$lang['profileconfirm'] = 'Να απαιτείται ο κωδικός χρήστη για την επιβεβαίωση αλλαγών στο προφίλ χρήστη';
+$lang['disableactions'] = 'Απενεργοποίηση λειτουργιών DokuWiki';
+$lang['disableactions_check'] = 'Έλεγχος';
+$lang['disableactions_subscription'] = 'Εγγραφή/Διαγραφή χρήστη';
+$lang['disableactions_wikicode'] = 'Προβολή κώδικα σελίδας';
+$lang['disableactions_other'] = 'Άλλες λειτουργίες (διαχωρίστε τις με κόμμα)';
+$lang['sneaky_index'] = 'Εξ ορισμού, η εφαρμογή DokuWiki δείχνει όλους τους φακέλους στην προβολή Καταλόγου. Ενεργοποιώντας αυτή την επιλογή, δεν θα εμφανίζονται οι φάκελοι για τους οποίους ο χρήστης δεν έχει δικαιώματα ανάγνωσης αλλά και οι υπο-φάκελοί τους ανεξαρτήτως δικαιωμάτων πρόσβασης.';
+$lang['auth_security_timeout'] = 'Διάρκεια χρόνου για ασφάλεια πιστοποίησης (δευτερόλεπτα)';
+$lang['securecookie'] = 'Τα cookies που έχουν οριστεί μέσω HTTPS πρέπει επίσης να αποστέλλονται μόνο μέσω HTTPS από τον φυλλομετρητή? Απενεργοποιήστε αυτή την επιλογή όταν μόνο η είσοδος στο wiki σας διασφαλίζεται μέσω SSL αλλά η περιήγηση γίνεται και χωρίς αυτό.';
+$lang['xmlrpc'] = 'Ενεργοποίηση/Απενεργοποίηση της διασύνδεσης XML-RPC ';
+$lang['xmlrpcuser'] = 'Περιορισμός XML-RPC πρόσβασης στις ομάδες η τους χρήστες (διαχωριζόμενοι με κόμμα). Αφήστε το κενό για πρόσβαση από όλους.';
+$lang['updatecheck'] = 'Έλεγχος για ύπαρξη νέων εκδόσεων και ενημερώσεων ασφαλείας της εφαρμογής? Απαιτείται η σύνδεση με το update.dokuwiki.org για να λειτουργήσει σωστά αυτή η επιλογή.';
+$lang['userewrite'] = 'Χρήση ωραίων URLs';
+$lang['useslash'] = 'Χρήση slash σαν διαχωριστικό φακέλων στα URLs';
+$lang['usedraft'] = 'Αυτόματη αποθήκευση αντιγράφων κατά την τροποποίηση σελίδων';
+$lang['sepchar'] = 'Διαχωριστικός χαρακτήρας για κανονικοποίηση ονόματος σελίδας';
+$lang['canonical'] = 'Πλήρη και κανονικοποιημένα URLs';
+$lang['fnencode'] = 'Μέθοδος κωδικοποίησης για ονόματα αρχείων μη-ASCII';
+$lang['autoplural'] = 'Ταίριασμα πληθυντικού στους συνδέσμους';
+$lang['compression'] = 'Μέθοδος συμπίεσης για αρχεία attic';
+$lang['cachetime'] = 'Μέγιστη ηλικία cache (sec)';
+$lang['locktime'] = 'Μέγιστος χρόνος κλειδώματος αρχείου υπό τροποποίηση (sec)';
+$lang['fetchsize'] = 'Μέγιστο μέγεθος (σε bytes) εξωτερικού αρχείου που επιτρέπεται να μεταφέρει η fetch.php';
+$lang['notify'] = 'Αποστολή ενημέρωσης για αλλαγές σε αυτή την e-mail διεύθυνση';
+$lang['registernotify'] = 'Αποστολή ενημερωτικών μηνυμάτων σε αυτή την e-mail διεύθυνση κατά την εγγραφή νέων χρηστών';
+$lang['mailfrom'] = 'e-mail διεύθυνση αποστολέα για μηνύματα από την εφαρμογή';
+$lang['mailprefix'] = 'Πρόθεμα θέματος που να χρησιμοποιείται για τα αυτόματα μηνύματα ηλεκτρονικού ταχυδρομείου.';
+$lang['gzip_output'] = 'Χρήση gzip Content-Encoding για την xhtml';
+$lang['gdlib'] = 'Έκδοση βιβλιοθήκης GD';
+$lang['im_convert'] = 'Διαδρομή προς το εργαλείο μετατροπής εικόνων του ImageMagick';
+$lang['jpg_quality'] = 'Ποιότητα συμπίεσης JPG (0-100)';
+$lang['subscribers'] = 'Να επιτρέπεται η εγγραφή στην ενημέρωση αλλαγών σελίδας';
+$lang['subscribe_time'] = 'Χρόνος μετά τον οποίο οι λίστες ειδοποιήσεων και τα συνοπτικά θα αποστέλλονται (δευτερόλεπτα). Αυτό θα πρέπει να είναι μικρότερο από τον χρόνο που έχει η ρύθμιση recent_days.';
+$lang['compress'] = 'Συμπίεση αρχείων CSS και javascript';
+$lang['cssdatauri'] = 'Το μέγεθος σε bytes στο οποίο οι εικόνες που αναφέρονται σε CSS αρχεία θα πρέπει να είναι ενσωματωμένες για τη μείωση των απαιτήσεων μιας κεφαλίδας αίτησης HTTP . Αυτή η τεχνική δεν θα λειτουργήσει σε IE <8! <code> 400 </ code> με <code> 600 </ code> bytes είναι μια καλή τιμή. Ορίστε την τιμή <code> 0 </ code> για να το απενεργοποιήσετε.';
+$lang['hidepages'] = 'Φίλτρο απόκρυψης σελίδων (regular expressions)';
+$lang['send404'] = 'Αποστολή "HTTP 404/Page Not Found" για σελίδες που δεν υπάρχουν';
+$lang['sitemap'] = 'Δημιουργία Google sitemap (ημέρες)';
+$lang['broken_iua'] = 'Η συνάρτηση ignore_user_abort δεν λειτουργεί σωστά στο σύστημά σας? Σε αυτή την περίπτωση μπορεί να μην δουλεύει σωστά η λειτουργία Καταλόγου. Ο συνδυασμός IIS+PHP/CGI είναι γνωστό ότι έχει τέτοιο πρόβλημα. Δείτε και <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> για λεπτομέρειες.';
+$lang['xsendfile'] = 'Χρήση της κεφαλίδας X-Sendfile από τον εξυπηρετητή κατά την φόρτωση στατικών αρχείων? Ο εξυπηρετητής σας πρέπει να υποστηρίζει αυτή την δυνατότητα.';
+$lang['renderer_xhtml'] = 'Πρόγραμμα δημιουργίας βασικής (xhtml) εξόδου wiki.';
+$lang['renderer__core'] = '%s (βασικός κώδικας dokuwiki)';
+$lang['renderer__plugin'] = '%s (επέκταση)';
+$lang['rememberme'] = 'Να επιτρέπονται τα cookies λογαρισμού χρήστη αορίστου χρόνου (Απομνημόνευση στοιχείων λογαριασμού)';
+$lang['rss_type'] = 'Τύπος XML feed';
+$lang['rss_linkto'] = 'Τύπος συνδέσμων στο XML feed';
+$lang['rss_content'] = 'Τι να εμφανίζεται στα XML feed items?';
+$lang['rss_update'] = 'Χρόνος ανανέωσης XML feed (sec)';
+$lang['recent_days'] = 'Πόσο παλιές αλλαγές να εμφανίζονται (ημέρες)';
+$lang['rss_show_summary'] = 'Να εμφανίζεται σύνοψη του XML feed στον τίτλο';
+$lang['target____wiki'] = 'Παράθυρο-στόχος για εσωτερικούς συνδέσμους';
+$lang['target____interwiki'] = 'Παράθυρο-στόχος για συνδέσμους interwiki';
+$lang['target____extern'] = 'Παράθυρο-στόχος για εξωτερικούς σθνδέσμους';
+$lang['target____media'] = 'Παράθυρο-στόχος για συνδέσμους αρχείων';
+$lang['target____windows'] = 'Παράθυρο-στόχος για συνδέσμους σε Windows shares';
+$lang['proxy____host'] = 'Διακομιστής Proxy';
+$lang['proxy____port'] = 'Θύρα Proxy';
+$lang['proxy____user'] = 'Όνομα χρήστη Proxy';
+$lang['proxy____pass'] = 'Κωδικός χρήστη Proxy';
+$lang['proxy____ssl'] = 'Χρήση ssl για σύνδεση με διακομιστή Proxy';
+$lang['proxy____except'] = 'Regular expression για να πιάνει τα URLs για τα οποία θα παρακάμπτεται το proxy.';
+$lang['safemodehack'] = 'Ενεργοποίηση safemode hack';
+$lang['ftp____host'] = 'Διακομιστής FTP για safemode hack';
+$lang['ftp____port'] = 'Θύρα FTP για safemode hack';
+$lang['ftp____user'] = 'Όνομα χρήστη FTP για safemode hack';
+$lang['ftp____pass'] = 'Κωδικός χρήστη FTP για safemode hack';
+$lang['ftp____root'] = 'Αρχικός φάκελος FTP για safemode hack';
+$lang['license_o_'] = 'Δεν επελέγει άδεια';
+$lang['typography_o_0'] = 'κανένα';
+$lang['typography_o_1'] = 'μόνο διπλά εισαγωγικά';
+$lang['typography_o_2'] = 'όλα τα εισαγωγικά (μπορεί να μην λειτουργεί πάντα)';
+$lang['userewrite_o_0'] = 'κανένα';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'από DokuWiki';
+$lang['deaccent_o_0'] = 'όχι';
+$lang['deaccent_o_1'] = 'αφαίρεση σημείων στίξης';
+$lang['deaccent_o_2'] = 'λατινοποίηση';
+$lang['gdlib_o_0'] = 'Δεν υπάρχει βιβλιοθήκη GD στο σύστημα';
+$lang['gdlib_o_1'] = 'Έκδοση 1.x';
+$lang['gdlib_o_2'] = 'Αυτόματος εντοπισμός';
+$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';
+$lang['rss_content_o_abstract'] = 'Περίληψη';
+$lang['rss_content_o_diff'] = 'Ενοποιημένο Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML διαμορφωμένος πίνακας diff';
+$lang['rss_content_o_html'] = 'Περιεχόμενο Σελίδας μόνο με HTML';
+$lang['rss_linkto_o_diff'] = 'προβολή αλλαγών';
+$lang['rss_linkto_o_page'] = 'τροποποιημένη σελίδα';
+$lang['rss_linkto_o_rev'] = 'εκδόσεις σελίδας';
+$lang['rss_linkto_o_current'] = 'τρέχουσα σελίδα';
+$lang['compression_o_0'] = 'none';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'να μην χρησιμοποιείται';
+$lang['xsendfile_o_1'] = 'Ιδιοταγής κεφαλίδα lighttpd (πριν από την έκδοση 1.5)';
+$lang['xsendfile_o_2'] = 'Τυπική κεφαλίδα X-Sendfile';
+$lang['xsendfile_o_3'] = 'Ιδιοταγής κεφαλίδα Nginx X-Accel-Redirect ';
+$lang['showuseras_o_loginname'] = 'Όνομα χρήστη';
+$lang['showuseras_o_username'] = 'Ονοματεπώνυμο χρήστη';
+$lang['showuseras_o_email'] = 'e-mail διεύθυνση χρήστη (εμφανίζεται σύμφωνα με την ρύθμιση για την κωδικοποίηση e-mail διευθύνσεων)';
+$lang['showuseras_o_email_link'] = 'Εμφάνιση e-mail διεύθυνσης χρήστη σαν σύνδεσμος mailto:';
+$lang['useheading_o_0'] = 'Ποτέ';
+$lang['useheading_o_navigation'] = 'Μόνο κατά την πλοήγηση';
+$lang['useheading_o_content'] = 'Μόνο για τα περιεχόμενα του wiki';
+$lang['useheading_o_1'] = 'Πάντα';
+$lang['readdircache'] = 'Μέγιστος χρόνος διατήρησης για το cache του readdir (δευτερόλεπτα)';
diff --git a/lib/plugins/config/lang/en/intro.txt b/lib/plugins/config/lang/en/intro.txt
new file mode 100644
index 000000000..c83a80205
--- /dev/null
+++ b/lib/plugins/config/lang/en/intro.txt
@@ -0,0 +1,9 @@
+====== 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/lib/plugins/config/lang/en/lang.php b/lib/plugins/config/lang/en/lang.php
new file mode 100644
index 000000000..74ec56345
--- /dev/null
+++ b/lib/plugins/config/lang/en/lang.php
@@ -0,0 +1,245 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+
+// 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 Settings';
+$lang['_header_plugin'] = 'Plugin Settings';
+$lang['_header_template'] = 'Template Settings';
+$lang['_header_undefined'] = 'Undefined Settings';
+
+/* --- Config Setting Groups --- */
+$lang['_basic'] = 'Basic Settings';
+$lang['_display'] = 'Display Settings';
+$lang['_authentication'] = 'Authentication Settings';
+$lang['_anti_spam'] = 'Anti-Spam Settings';
+$lang['_editing'] = 'Editing Settings';
+$lang['_links'] = 'Link Settings';
+$lang['_media'] = 'Media Settings';
+$lang['_advanced'] = 'Advanced Settings';
+$lang['_network'] = 'Network Settings';
+// The settings group name for plugins and templates can be set with
+// plugin_settings_name and template_settings_name respectively. If one
+// of these lang properties is not set, the group name will be generated
+// from the plugin or template name and the localized suffix.
+$lang['_plugin_sufix'] = 'Plugin Settings';
+$lang['_template_sufix'] = 'Template Settings';
+
+/* --- Undefined Setting Messages --- */
+$lang['_msg_setting_undefined'] = 'No setting metadata.';
+$lang['_msg_setting_no_class'] = 'No setting class.';
+$lang['_msg_setting_no_default'] = 'No default value.';
+
+/* -------------------- Config Options --------------------------- */
+
+$lang['fmode'] = 'File creation mode';
+$lang['dmode'] = 'Directory creation mode';
+$lang['lang'] = 'Interface language';
+$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['savedir'] = 'Directory for saving data';
+$lang['cookiedir'] = 'Cookie path. Leave blank for using baseurl.';
+$lang['start'] = 'Start page name';
+$lang['title'] = 'Wiki title';
+$lang['template'] = 'Template';
+$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['fullpath'] = 'Reveal full path of pages in the footer';
+$lang['recent'] = 'Recent changes';
+$lang['breadcrumbs'] = 'Number of breadcrumbs';
+$lang['youarehere'] = 'Hierarchical breadcrumbs';
+$lang['typography'] = 'Do typographical replacements';
+$lang['htmlok'] = 'Allow embedded HTML';
+$lang['phpok'] = 'Allow embedded PHP';
+$lang['dformat'] = 'Date format (see PHP\'s <a href="http://www.php.net/strftime">strftime</a> function)';
+$lang['signature'] = 'Signature';
+$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'] = 'Clean pagenames';
+$lang['useheading'] = 'Use first heading for pagenames';
+$lang['refcheck'] = 'Media reference check';
+$lang['refshow'] = 'Number of media references to show';
+$lang['allowdebug'] = 'Allow debug <b>disable if not needed!</b>';
+$lang['mediarevisions'] = 'Enable Mediarevisions?';
+
+$lang['usewordblock']= 'Block spam based on wordlist';
+$lang['indexdelay'] = 'Time delay before indexing (sec)';
+$lang['relnofollow'] = 'Use rel="nofollow" on external links';
+$lang['mailguard'] = 'Obfuscate email addresses';
+$lang['iexssprotect']= 'Check uploaded files for possibly malicious JavaScript or HTML code';
+$lang['showuseras'] = 'What to display when showing the user that last edited a page';
+
+/* Authentication Options */
+$lang['useacl'] = 'Use access control lists';
+$lang['autopasswd'] = 'Autogenerate passwords';
+$lang['authtype'] = 'Authentication backend';
+$lang['passcrypt'] = 'Password encryption method';
+$lang['defaultgroup']= 'Default 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['disableactions'] = 'Disable DokuWiki actions';
+$lang['disableactions_check'] = 'Check';
+$lang['disableactions_subscription'] = 'Subscribe/Unsubscribe';
+$lang['disableactions_wikicode'] = 'View source/Export Raw';
+$lang['disableactions_other'] = 'Other actions (comma separated)';
+$lang['sneaky_index'] = 'By default, DokuWiki will show all namespaces in the index view. Enabling this option will hide those where the user doesn\'t have read permissions. This might result in hiding of accessable subnamespaces. This may make the index unusable with certain ACL setups.';
+$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['xmlrpc'] = 'Enable/disable XML-RPC interface.';
+$lang['xmlrpcuser'] = 'Restrict XML-RPC access to the comma separated groups or users given here. Leave empty to give access to everyone.';
+
+/* 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['usedraft'] = 'Automatically save a draft while editing';
+$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['cachetime'] = 'Maximum age for cache (sec)';
+$lang['locktime'] = 'Maximum age for lock files (sec)';
+$lang['fetchsize'] = 'Maximum size (bytes) fetch.php may download from extern';
+$lang['notify'] = 'Send change notifications to this email address';
+$lang['registernotify'] = 'Send info on newly registered users to this email address';
+$lang['mailfrom'] = 'Email address to use for automatic mails';
+$lang['mailprefix'] = 'Email subject prefix to use for automatic mails';
+$lang['gzip_output'] = 'Use gzip Content-Encoding for xhtml';
+$lang['gdlib'] = 'GD Lib version';
+$lang['im_convert'] = 'Path to ImageMagick\'s convert tool';
+$lang['jpg_quality'] = 'JPG compression quality (0-100)';
+$lang['subscribers'] = 'Enable page subscription support';
+$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['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. This technique won\'t work in IE 7 and below! <code>400</code> to <code>600</code> bytes is a good value. Set <code>0</code> to disable.';
+$lang['hidepages'] = 'Hide matching pages (regular expressions)';
+$lang['send404'] = 'Send "HTTP 404/Page Not Found" for non existing pages';
+$lang['sitemap'] = 'Generate Google sitemap (days)';
+$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.splitbrain.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['rememberme'] = 'Allow permanent login cookies (remember me)';
+
+$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['recent_days'] = 'How many recent changes to keep (days)';
+$lang['rss_show_summary'] = 'XML feed show summary in title';
+
+/* Target options */
+$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';
+
+/* 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 for.';
+
+/* Safemode Hack */
+$lang['safemodehack'] = 'Enable safemode hack';
+$lang['ftp____host'] = 'FTP server for safemode hack';
+$lang['ftp____port'] = 'FTP port for safemode hack';
+$lang['ftp____user'] = 'FTP user name for safemode hack';
+$lang['ftp____pass'] = 'FTP password for safemode hack';
+$lang['ftp____root'] = 'FTP root directory for safemode hack';
+
+$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_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/lib/plugins/config/lang/eo/intro.txt b/lib/plugins/config/lang/eo/intro.txt
new file mode 100644
index 000000000..c717d9a4d
--- /dev/null
+++ b/lib/plugins/config/lang/eo/intro.txt
@@ -0,0 +1,7 @@
+====== Administrilo de Agordoj ======
+
+Uzu tiun ĉi paĝon por kontroli la difinojn de via DokuWiki-instalo. Por helpo pri specifaj difinoj aliru al [[doku&gt;config]]. Por pli detaloj pri tiu ĉi kromaĵo, vidu [[doku&gt;plugin:config]].
+
+Difinoj montrataj kun hela ruĝa fono estas protektitaj kaj ne povas esti modifataj per tiu ĉi kromaĵo. Difinoj kun blua fono estas aprioraj valoroj kaj difinoj montrataj kun blanka fono estis iam difinataj por tiu ĉi specifa instalo. Ambaŭ blua kaj blanka difinoj povas esti modifataj.
+
+Memoru premi la butonon **Registri** antaŭ ol eliri tiun ĉi paĝon, male viaj modifoj perdiĝus.
diff --git a/lib/plugins/config/lang/eo/lang.php b/lib/plugins/config/lang/eo/lang.php
new file mode 100644
index 000000000..b0411ec14
--- /dev/null
+++ b/lib/plugins/config/lang/eo/lang.php
@@ -0,0 +1,196 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas (cxe) gmail (punkto) com>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['menu'] = 'Agordaj Difinoj';
+$lang['error'] = 'La difinoj ne estas ĝisdatigitaj pro malvalida valoro: bonvolu revizii viajn ŝanĝojn kaj resubmeti ilin.
+&lt;br /&gt;La malkorekta(j) valoro(j) estas ĉirkaŭita(j) de ruĝa kadro.';
+$lang['updated'] = 'La difinoj estis sukcese ĝisdatigitaj.';
+$lang['nochoice'] = '(neniu alia elekto disponeblas)';
+$lang['locked'] = 'La difin-dosiero ne povas esti ĝisdatigita; se tio ne estas intenca, &lt;br /&gt; certiĝu, ke la dosieroj de lokaj difinoj havas korektajn nomojn kaj permesojn.';
+$lang['danger'] = 'Danĝero: ŝanĝo tiun opcion povus igi vian vikion kaj la agordan menuon neatingebla.';
+$lang['warning'] = 'Averto: ŝanĝi tiun opcion povus rezulti en neatendita konduto.';
+$lang['security'] = 'Sekureca averto: ŝanĝi tiun opcion povus krei sekurecan riskon.';
+$lang['_configuration_manager'] = 'Administrilo de agordoj';
+$lang['_header_dokuwiki'] = 'Difinoj por DokuWiki';
+$lang['_header_plugin'] = 'Difinoj por kromaĵoj';
+$lang['_header_template'] = 'Difinoj por ŝablonoj';
+$lang['_header_undefined'] = 'Ceteraj difinoj';
+$lang['_basic'] = 'Bazaj difinoj';
+$lang['_display'] = 'Difinoj por montrado';
+$lang['_authentication'] = 'Difinoj por identiĝo';
+$lang['_anti_spam'] = 'Kontraŭ-spamaj difinoj';
+$lang['_editing'] = 'Difinoj por redakto';
+$lang['_links'] = 'Difinoj por ligiloj';
+$lang['_media'] = 'Difinoj por aŭdvidaĵoj';
+$lang['_advanced'] = 'Fakaj difinoj';
+$lang['_network'] = 'Difinoj por reto';
+$lang['_plugin_sufix'] = 'Difinoj por kromaĵoj';
+$lang['_template_sufix'] = 'Difinoj por ŝablonoj';
+$lang['_msg_setting_undefined'] = 'Neniu difinanta metadatenaro.';
+$lang['_msg_setting_no_class'] = 'Neniu difinanta klaso.';
+$lang['_msg_setting_no_default'] = 'Neniu apriora valoro.';
+$lang['fmode'] = 'Reĝimo de dosiero-kreado';
+$lang['dmode'] = 'Reĝimo de dosierujo-kreado';
+$lang['lang'] = 'Lingvo';
+$lang['basedir'] = 'Baza dosierujo';
+$lang['baseurl'] = 'Baza URL';
+$lang['savedir'] = 'Dosierujo por konservi datenaron';
+$lang['cookiedir'] = 'Kuketopado. Lasu malplena por uzi baseurl.';
+$lang['start'] = 'Nomo de la hejmpaĝo';
+$lang['title'] = 'Titolo de la vikio';
+$lang['template'] = 'Ŝablono';
+$lang['license'] = 'Laŭ kiu permesilo via enhavo devus esti publikigita?';
+$lang['fullpath'] = 'Montri la kompletan padon de la paĝoj en la piedlinio';
+$lang['recent'] = 'Freŝaj ŝanĝoj';
+$lang['breadcrumbs'] = 'Nombro da paderoj';
+$lang['youarehere'] = 'Hierarkiaj paderoj';
+$lang['typography'] = 'Fari tipografiajn anstataŭigojn';
+$lang['htmlok'] = 'Ebligi enmeton de HTML-aĵoj';
+$lang['phpok'] = 'Ebligi enmeton de PHP-aĵoj';
+$lang['dformat'] = 'Formato de datoj (vidu la PHP-an funkcion &lt;a href=&quot;http://www.php.net/strftime&quot;&gt;strftime&lt;/a&gt;)';
+$lang['signature'] = 'Subskribo';
+$lang['toptoclevel'] = 'Supera nivelo por la enhavtabelo';
+$lang['tocminheads'] = 'Minimuma kvanto da ĉeftitoloj, kiu difinas ĉu la TOC estas kreita.';
+$lang['maxtoclevel'] = 'Maksimuma nivelo por la enhavtabelo';
+$lang['maxseclevel'] = 'Maksimuma nivelo por redakti sekciojn';
+$lang['camelcase'] = 'Uzi KamelUsklecon por ligiloj';
+$lang['deaccent'] = 'Netaj paĝnomoj';
+$lang['useheading'] = 'Uzi unuan titolon por paĝnomoj';
+$lang['refcheck'] = 'Kontrolo por referencoj al aŭdvidaĵoj';
+$lang['refshow'] = 'Nombro da referencoj al aŭdvidaĵoj por montri';
+$lang['allowdebug'] = 'Ebligi kodumpurigadon &lt;b&gt;malebligu se ne necese!&lt;/b&gt;';
+$lang['usewordblock'] = 'Bloki spamon surbaze de vortlisto';
+$lang['indexdelay'] = 'Prokrasto antaŭ ol indeksi (en sekundoj)';
+$lang['relnofollow'] = 'Uzi rel=&quot;nofollow&quot; kun eksteraj ligiloj';
+$lang['mailguard'] = 'Nebuligi retadresojn';
+$lang['iexssprotect'] = 'Ekzameni elŝutaĵojn kontraŭ eblaj malicaj ĴavaSkripto aŭ HTML-a kodumaĵo';
+$lang['showuseras'] = 'Kion montrigi dum indiko al la uzanto kiu laste redaktis paĝon.';
+$lang['useacl'] = 'Uzi alirkontrolajn listojn';
+$lang['autopasswd'] = 'Aŭtomate krei pasvortojn';
+$lang['authtype'] = 'Tipo de identiĝo';
+$lang['passcrypt'] = 'Metodo por ĉifri pasvortojn';
+$lang['defaultgroup'] = 'Antaŭdifinita grupo';
+$lang['superuser'] = 'Superanto - grupo, uzanto aŭ listo (apartite per komoj), kiu plene alireblas al ĉiuj paĝoj kaj funkcioj, sendepende de la reguloj ACL';
+$lang['manager'] = 'Administranto - grupo, uzanto aŭ listo (apartite per komoj), kiu havas alirpermeson al kelkaj administraj funkcioj';
+$lang['profileconfirm'] = 'Konfirmi ŝanĝojn en la trajtaro per pasvorto';
+$lang['disableactions'] = 'Malebligi DokuWiki-ajn agojn';
+$lang['disableactions_check'] = 'Kontroli';
+$lang['disableactions_subscription'] = 'Aliĝi/Malaliĝi';
+$lang['disableactions_wikicode'] = 'Rigardi vikitekston/Eksporti krudaĵon';
+$lang['disableactions_other'] = 'Aliaj agoj (apartite per komoj)';
+$lang['sneaky_index'] = 'Apriore, DokuWiki montras ĉiujn nomspacojn en la indeksa modo. Ebligi tiun ĉi elekteblon kaŝus tion, kion la uzanto ne rajtas legi laŭ ACL. Tio povus rezulti ankaŭan kaŝon de alireblaj subnomspacoj. Kaj tiel la indekso estus neuzebla por kelkaj agordoj de ACL.';
+$lang['auth_security_timeout'] = 'Sekureca Templimo por aŭtentigo (sekundoj)';
+$lang['securecookie'] = 'Ĉu kuketoj difinitaj per HTTPS nur estu senditaj de la foliumilo per HTTPS? Malebligu tiun ĉi opcion kiam nur la ensaluto al via vikio estas sekurigita per SSL, sed foliumado de la vikio estas farita malsekure.';
+$lang['xmlrpc'] = 'Ebligi/malebligi la interfacon XML-RPC.';
+$lang['xmlrpcuser'] = 'Permesi XML-RPC-an aliron al certaj grupoj aŭ uzantoj, bonvolu meti iliajn komoseparitajn nomojn tie ĉi. Alirebli de ĉiu, ĝin lasu malplena.';
+$lang['updatecheck'] = 'Ĉu kontroli aktualigojn kaj sekurecajn avizojn? DokuWiki bezonas kontakti update.dokuwiki.org por tiu ĉi trajto.';
+$lang['userewrite'] = 'Uzi netajn URL-ojn';
+$lang['useslash'] = 'Uzi frakcistrekon kiel apartigsignaĵo por nomspacoj en URL-oj';
+$lang['usedraft'] = 'Aŭtomate konservi skizon dum redaktado';
+$lang['sepchar'] = 'Apartigsignaĵo de vortoj en paĝnomoj';
+$lang['canonical'] = 'Uzi tute evidentajn URL-ojn';
+$lang['fnencode'] = 'Kodiga metodo por ne-ASCII-aj dosiernomoj.';
+$lang['autoplural'] = 'Kontroli pluralajn formojn en ligiloj';
+$lang['compression'] = 'Kompaktigmetodo por arkivaj dosieroj';
+$lang['cachetime'] = 'Maksimuma aĝo por provizmemoro (sek.)';
+$lang['locktime'] = 'Maksimuma aĝo por serurdosieroj (sek.)';
+$lang['fetchsize'] = 'Maksimuma grandeco (bitokoj), kiun fetch.php rajtas elŝuti el ekstere';
+$lang['notify'] = 'Sendi avizojn pri ŝanĝoj al tiu ĉi retadreso';
+$lang['registernotify'] = 'Sendi informon pri ĵusaj aliĝintoj al tiu ĉi retadreso';
+$lang['mailfrom'] = 'Retadreso uzota por aŭtomataj retmesaĝoj ';
+$lang['mailprefix'] = 'Retpoŝta temo-prefikso por uzi en aŭtomataj mesaĝoj';
+$lang['gzip_output'] = 'Uzi gzip-an enhav-enkodigon por XHTML';
+$lang['gdlib'] = 'Versio de GD-Lib';
+$lang['im_convert'] = 'Pado al la konvertilo de ImageMagick';
+$lang['jpg_quality'] = 'Kompaktiga kvalito de JPG (0-100)';
+$lang['subscribers'] = 'Ebligi subtenon de avizoj pri ŝanĝoj sur paĝoj';
+$lang['subscribe_time'] = 'Tempo, post kiu abonlistoj kaj kolektaĵoj sendiĝas (sek); Tio estu pli malgranda ol la tempo indikita en recent_days.';
+$lang['compress'] = 'Kompaktigi CSS-ajn kaj ĵavaskriptajn elmetojn';
+$lang['cssdatauri'] = 'Grandeco en bitokoj, ĝis kiom en CSS-dosieroj referencitaj bildoj estu enmetataj rekte en la stilfolion por malgrandigi vanan HTTP-kapan trafikon. Tiu tekniko ne funkcias en IE 7 aŭ pli frua!
+&lt;code&gt;400&lt;/code&gt; ĝis &lt;code&gt;600&lt;/code&gt; bitokoj estas bona grandeco. Indiku &lt;code&gt;0&lt;/code&gt; por malebligi enmeton.';
+$lang['hidepages'] = 'Kaŝi kongruantajn paĝojn (laŭ regulaj esprimoj)';
+$lang['send404'] = 'Sendi la mesaĝon &quot;HTTP 404/Paĝo ne trovita&quot; por ne ekzistantaj paĝoj';
+$lang['sitemap'] = 'Krei Guglan paĝarmapon &quot;sitemap&quot; (po kiom tagoj)';
+$lang['broken_iua'] = 'Ĉu la funkcio &quot;ignore_user_abort&quot; difektas en via sistemo? Tio povus misfunkciigi la serĉindekson. IIS+PHP/CGI estas konata kiel fuŝaĵo. Vidu &lt;a href=&quot;http://bugs.splitbrain.org/?do=details&amp;task_id=852&quot;&gt;Cimon 852&lt;/a&gt; por pli da informoj.';
+$lang['xsendfile'] = 'Ĉu uzi la kaplinion X-Sendfile por ebligi al la retservilo liveri fiksajn dosierojn? Via retservilo bezonus subteni tion.';
+$lang['renderer_xhtml'] = 'Prezentilo por la ĉefa vikia rezulto (xhtml)';
+$lang['renderer__core'] = '%s (DokuWiki-a kerno)';
+$lang['renderer__plugin'] = '%s (kromaĵo)';
+$lang['rememberme'] = 'Permesi longdaŭran ensalutajn kuketojn (rememoru min)';
+$lang['rss_type'] = 'XML-a tipo de novaĵ-fluo';
+$lang['rss_linkto'] = 'La novaĵ-fluo de XML ligiĝas al';
+$lang['rss_content'] = 'Kion montri en la XML-aj novaĵ-flueroj?';
+$lang['rss_update'] = 'Intertempo por ĝisdatigi XML-an novaĵ-fluon (sek.)';
+$lang['recent_days'] = 'Kiom da freŝaj ŝanĝoj por teni (tagoj)';
+$lang['rss_show_summary'] = 'XML-a novaĵ-fluo montras resumon en la titolo';
+$lang['target____wiki'] = 'Parametro &quot;target&quot; (celo) por internaj ligiloj';
+$lang['target____interwiki'] = 'Parametro &quot;target&quot; (celo) por intervikiaj ligiloj';
+$lang['target____extern'] = 'Parametro &quot;target&quot; (celo) por eksteraj ligiloj';
+$lang['target____media'] = 'Parametro &quot;target&quot; (celo) por aŭdvidaĵaj ligiloj';
+$lang['target____windows'] = 'Parametro &quot;target&quot; (celo) por Vindozaj ligiloj';
+$lang['proxy____host'] = 'Retservilnomo de la &quot;Proxy&quot;';
+$lang['proxy____port'] = 'Pordo ĉe la &quot;Proxy&quot;';
+$lang['proxy____user'] = 'Uzantonomo ĉe la &quot;Proxy&quot;';
+$lang['proxy____pass'] = 'Pasvorto ĉe la &quot;Proxy&quot;';
+$lang['proxy____ssl'] = 'Uzi SSL por konekti al la &quot;Proxy&quot;';
+$lang['proxy____except'] = 'Regula esprimo por URL-oj, kiujn la servilo preterrigardu.';
+$lang['safemodehack'] = 'Ebligi sekuran modon';
+$lang['ftp____host'] = 'FTP-a servilo por sekura modo';
+$lang['ftp____port'] = 'FTP-a pordo por sekura modo';
+$lang['ftp____user'] = 'FTP-a uzantonomo por sekura modo';
+$lang['ftp____pass'] = 'FTP-a pasvorto por sekura modo';
+$lang['ftp____root'] = 'FTP-a superuzanta (root) subdosierujo por sekura modo';
+$lang['license_o_'] = 'Nenio elektite';
+$lang['typography_o_0'] = 'nenio';
+$lang['typography_o_1'] = 'Nur duoblaj citiloj';
+$lang['typography_o_2'] = 'Ĉiaj citiloj (eble ne ĉiam funkcios)';
+$lang['userewrite_o_0'] = 'nenio';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Interne de DokuWiki';
+$lang['deaccent_o_0'] = 'ne';
+$lang['deaccent_o_1'] = 'forigi supersignojn';
+$lang['deaccent_o_2'] = 'latinigi';
+$lang['gdlib_o_0'] = 'GD-Lib ne disponeblas';
+$lang['gdlib_o_1'] = 'Versio 1.x';
+$lang['gdlib_o_2'] = 'Aŭtomata detekto';
+$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';
+$lang['rss_content_o_abstract'] = 'Resumo';
+$lang['rss_content_o_diff'] = 'Unuigita &quot;Diff&quot;';
+$lang['rss_content_o_htmldiff'] = '&quot;Diff&quot;-tabelo formatita laŭ HTML';
+$lang['rss_content_o_html'] = 'Enhavo laŭ kompleta HTML-paĝo';
+$lang['rss_linkto_o_diff'] = 'diferenca rigardo';
+$lang['rss_linkto_o_page'] = 'la reviziita paĝo';
+$lang['rss_linkto_o_rev'] = 'listo de revizioj';
+$lang['rss_linkto_o_current'] = 'la aktuala paĝo';
+$lang['compression_o_0'] = 'nenio';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ne uzi';
+$lang['xsendfile_o_1'] = 'Propra kaplinio &quot;lighttpd&quot; (antaŭ versio 1.5)';
+$lang['xsendfile_o_2'] = 'Ordinara kaplinio X-Sendfile';
+$lang['xsendfile_o_3'] = 'Propra kaplinio Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Ensalut-nomo';
+$lang['showuseras_o_username'] = 'Kompleta nomo de uzanto';
+$lang['showuseras_o_email'] = 'Retadreso de uzanto (sekur-montrita laŭ agordo de mailguard)';
+$lang['showuseras_o_email_link'] = 'Retadreso de uzanto kiel mailto:-ligilo';
+$lang['useheading_o_0'] = 'Neniam';
+$lang['useheading_o_navigation'] = 'Nur foliumado';
+$lang['useheading_o_content'] = 'Nur vikia enhavo';
+$lang['useheading_o_1'] = 'Ĉiam';
+$lang['readdircache'] = 'Maksimuma daŭro de la dosieruja kaŝmemoro (sekundoj)';
diff --git a/lib/plugins/config/lang/es/intro.txt b/lib/plugins/config/lang/es/intro.txt
new file mode 100644
index 000000000..0b42c6ba9
--- /dev/null
+++ b/lib/plugins/config/lang/es/intro.txt
@@ -0,0 +1,7 @@
+====== Administrador de configuración ======
+
+Usa esta página para controlar los parámetros de tu instalación de Dokuwiki. Ayuda sobre [[doku>config|parámetros individuales]]. Más detalles sobre este [[doku>plugin:config|plugin]].
+
+Los parámetros que se muestran sobre un fondo rosado están protegidos y no pueden ser modificados usando este plugin. Los parámetros que se muestran sobre un fondo azul tienen los valores por defecto, y los parámetros mostrados sobre un fondo blanco han sido establecidos para esta instalación en particular. Tanto los parámetros sobre fondo azul y los que están sobre fondo blanco pueden ser modificados.
+
+Recuerda cliquear el boton **Guardar** antes de abandonar la página, sino se perderán los cambios que hayas hecho.
diff --git a/lib/plugins/config/lang/es/lang.php b/lib/plugins/config/lang/es/lang.php
new file mode 100644
index 000000000..9146633cf
--- /dev/null
+++ b/lib/plugins/config/lang/es/lang.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * spanish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Miguel Pagano <miguel.pagano@gmail.com>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['menu'] = 'Parámetros de configuración';
+$lang['error'] = 'Los parámetros no han sido actualizados a causa de un valor inválido, por favor revise los cambios y re-envíe el formulario. <br /> Los valores incorrectos se mostrarán con un marco rojo alrededor.';
+$lang['updated'] = 'Los parámetros se actualizaron con éxito.';
+$lang['nochoice'] = '(no hay otras alternativas disponibles)';
+$lang['locked'] = 'El archivo de configuración no ha podido ser actualizado, si esto no es lo deseado, <br /> asegúrese que el nombre del archivo local de configuraciones y los permisos sean los correctos.';
+$lang['danger'] = 'Atención: Cambiar esta opción podría hacer inaccesible el wiki y su menú de configuración.';
+$lang['warning'] = 'Advertencia: Cambiar esta opción podría causar comportamientos no deseados.';
+$lang['security'] = 'Advertencia de Seguridad: Cambiar esta opción podría representar un riesgo de seguridad.';
+$lang['_configuration_manager'] = 'Administrador de configuración';
+$lang['_header_dokuwiki'] = 'Parámetros de DokuWiki';
+$lang['_header_plugin'] = 'Parámetros de Plugin';
+$lang['_header_template'] = 'Parámetros de Plantillas';
+$lang['_header_undefined'] = 'Parámetros sin categoría';
+$lang['_basic'] = 'Parámetros Básicos';
+$lang['_display'] = 'Parámetros de Presentación';
+$lang['_authentication'] = 'Parámetros de Autenticación';
+$lang['_anti_spam'] = 'Parámetros Anti-Spam';
+$lang['_editing'] = 'Parámetros de Edición';
+$lang['_links'] = 'Parámetros de Enlaces';
+$lang['_media'] = 'Parámetros de Medios';
+$lang['_advanced'] = 'Parámetros Avanzados';
+$lang['_network'] = 'Parámetros de Red';
+$lang['_plugin_sufix'] = 'Parámetros de Plugins';
+$lang['_template_sufix'] = 'Parámetros de Plantillas';
+$lang['_msg_setting_undefined'] = 'Sin parámetros de metadata.';
+$lang['_msg_setting_no_class'] = 'Sin clase establecida.';
+$lang['_msg_setting_no_default'] = 'Sin valor por defecto.';
+$lang['fmode'] = 'Modo de creación de ficheros';
+$lang['dmode'] = 'Modo de creación de directorios';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Directorio de base';
+$lang['baseurl'] = 'URL de base';
+$lang['savedir'] = 'Directorio para guardar los datos';
+$lang['cookiedir'] = 'Ruta para las Cookie. Dejar en blanco para usar la ruta básica.';
+$lang['start'] = 'Nombre de la página inicial';
+$lang['title'] = 'Título del wiki';
+$lang['template'] = 'Plantilla';
+$lang['license'] = '¿Bajo qué licencia será liberado tu contenido?';
+$lang['fullpath'] = 'Mostrar ruta completa en el pie de página';
+$lang['recent'] = 'Cambios recientes';
+$lang['breadcrumbs'] = 'Número de pasos de traza';
+$lang['youarehere'] = 'Traza jerárquica';
+$lang['typography'] = 'Realizar reemplazos tipográficos';
+$lang['htmlok'] = 'Permitir HTML embebido';
+$lang['phpok'] = 'Permitir PHP embebido';
+$lang['dformat'] = 'Formato de fecha (ver la función de PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Firma';
+$lang['toptoclevel'] = 'Nivel superior para la tabla de contenidos';
+$lang['tocminheads'] = 'La cantidad mínima de titulares que determina si el TOC es construido';
+$lang['maxtoclevel'] = 'Máximo nivel para la tabla de contenidos';
+$lang['maxseclevel'] = 'Máximo nivel para edición de sección';
+$lang['camelcase'] = 'Usar CamelCase para enlaces';
+$lang['deaccent'] = 'Nombres de páginas "limpios"';
+$lang['useheading'] = 'Usar el primer encabezado para nombres de páginas';
+$lang['refcheck'] = 'Control de referencia a medios';
+$lang['refshow'] = 'Número de referencias a medios a mostrar';
+$lang['allowdebug'] = 'Permitir debug <b>deshabilítelo si no lo necesita!</b>';
+$lang['mediarevisions'] = '¿Habilitar Mediarevisions?';
+$lang['usewordblock'] = 'Bloquear spam usando una lista de palabras';
+$lang['indexdelay'] = 'Intervalo de tiempo antes de indexar (segundos)';
+$lang['relnofollow'] = 'Usar rel="nofollow" en enlaces externos';
+$lang['mailguard'] = 'Ofuscar direcciones de correo electrónico';
+$lang['iexssprotect'] = 'Comprobar posible código malicioso (JavaScript ó HTML) en archivos subidos';
+$lang['showuseras'] = 'Qué ver al mostrar el último usuario que editó una página';
+$lang['useacl'] = 'Usar listas de control de acceso (ACL)';
+$lang['autopasswd'] = 'Autogenerar contraseñas';
+$lang['authtype'] = 'Método de Autenticación';
+$lang['passcrypt'] = 'Método de cifrado de contraseñas';
+$lang['defaultgroup'] = 'Grupo por defecto';
+$lang['superuser'] = 'Super-usuario - grupo ó usuario con acceso total a todas las páginas y funciones, configuraciones ACL';
+$lang['manager'] = 'Manager - grupo o usuario con acceso a ciertas tareas de mantenimiento';
+$lang['profileconfirm'] = 'Confirmar cambios en perfil con contraseña';
+$lang['disableactions'] = 'Deshabilitar acciones DokuWiki';
+$lang['disableactions_check'] = 'Controlar';
+$lang['disableactions_subscription'] = 'Suscribirse/Cancelar suscripción';
+$lang['disableactions_wikicode'] = 'Ver la fuente/Exportar en formato raw';
+$lang['disableactions_other'] = 'Otras acciones (separadas por coma)';
+$lang['sneaky_index'] = 'Por defecto, DokuWiki mostrará todos los namespaces en el index. Habilitando esta opción los ocultará si el usuario no tiene permisos de lectura. Los sub-namespaces pueden resultar inaccesibles. El index puede hacerse poco usable dependiendo de las configuraciones ACL.';
+$lang['auth_security_timeout'] = 'Tiempo de Autenticación (en segundos), por motivos de seguridad';
+$lang['securecookie'] = 'Las cookies establecidas por HTTPS, ¿el naveagdor solo puede enviarlas por HTTPS? Inhabilite esta opción cuando solo se asegure con SSL la entrada, pero no la navegación de su wiki.';
+$lang['xmlrpc'] = 'Habilitar/Deshabilitar interfaz XML-RPC';
+$lang['xmlrpcuser'] = 'Restringir el acceso XML-RPC a los grupos o usuarios separados por coma mencionados aquí. Dejar en blanco para dar acceso a todo el mundo. ';
+$lang['updatecheck'] = '¿Comprobar actualizaciones y advertencias de seguridad? Esta característica requiere que DokuWiki se conecte a update.dokuwiki.org.';
+$lang['userewrite'] = 'Usar URLs bonitas';
+$lang['useslash'] = 'Usar barra (/) como separador de espacios de nombres en las URLs';
+$lang['usedraft'] = 'Guardar automáticamente un borrador mientras se edita';
+$lang['sepchar'] = 'Separador de palabras en nombres de páginas';
+$lang['canonical'] = 'Usar URLs totalmente canónicas';
+$lang['fnencode'] = 'Método para codificar nombres de archivo no-ASCII.';
+$lang['autoplural'] = 'Controlar plurales en enlaces';
+$lang['compression'] = 'Método de compresión para archivos en el ático';
+$lang['cachetime'] = 'Edad máxima para caché (segundos)';
+$lang['locktime'] = 'Edad máxima para archivos de bloqueo (segundos)';
+$lang['fetchsize'] = 'Tamaño máximo (bytes) que fetch.php puede descargar de sitios externos';
+$lang['notify'] = 'Enviar notificación de cambios a esta dirección de correo electrónico';
+$lang['registernotify'] = 'Enviar información cuando se registran nuevos usuarios a esta dirección de correo electrónico';
+$lang['mailfrom'] = 'Dirección de correo electrónico para emails automáticos';
+$lang['mailprefix'] = 'Asunto por defecto que se utilizará en mails automáticos.';
+$lang['gzip_output'] = 'Usar gzip Content-Encoding para xhtml';
+$lang['gdlib'] = 'Versión de GD Lib';
+$lang['im_convert'] = 'Ruta a la herramienta de conversión de ImageMagick';
+$lang['jpg_quality'] = 'Calidad de compresión de JPG (0-100)';
+$lang['subscribers'] = 'Habilitar soporte para suscripción a páginas';
+$lang['subscribe_time'] = 'Tiempo después que alguna lista de suscripción fue enviada (seg); Debe ser menor que el tiempo especificado en días recientes.';
+$lang['compress'] = 'Compactar la salida de CSS y javascript';
+$lang['cssdatauri'] = 'Tamaño en bytes hasta el cual las imágenes referenciadas en archivos CSS deberían ir incrustadas en la hoja de estilos para reducir el número de cabeceras de petición HTTP. ¡Esta técnica no funcionará en IE < 8! De <code>400</code> a <code>600</code> bytes es un valor adecuado. Establezca <code>0</code> para deshabilitarlo.';
+$lang['hidepages'] = 'Ocultar páginas con coincidencias (expresiones regulares)';
+$lang['send404'] = 'Enviar "HTTP 404/Page Not Found" para páginas no existentes';
+$lang['sitemap'] = 'Generar sitemap de Google (días)';
+$lang['broken_iua'] = '¿Se ha roto (broken) la función ignore_user_abort en su sistema? Esto puede causar que no funcione el index de búsqueda. Se sabe que IIS+PHP/CGI está roto. Vea <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>para más información.';
+$lang['xsendfile'] = '¿Utilizar la cabecera X-Sendfile para permitirle al servidor web enviar archivos estáticos? Su servidor web necesita tener la capacidad para hacerlo.';
+$lang['renderer_xhtml'] = 'Visualizador a usar para salida (xhtml) principal del wiki';
+$lang['renderer__core'] = '%s (núcleo dokuwiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permitir cookies para acceso permanente (recordarme)';
+$lang['rss_type'] = 'Tipo de resumen (feed) XML';
+$lang['rss_linkto'] = 'Feed XML enlaza a';
+$lang['rss_content'] = '¿Qué mostrar en los items del archivo XML?';
+$lang['rss_update'] = 'Intervalo de actualización de feed XML (segundos)';
+$lang['recent_days'] = 'Cuántos cambios recientes mantener (días)';
+$lang['rss_show_summary'] = 'Feed XML muestra el resumen en el título';
+$lang['target____wiki'] = 'Ventana para enlaces internos';
+$lang['target____interwiki'] = 'Ventana para enlaces interwikis';
+$lang['target____extern'] = 'Ventana para enlaces externos';
+$lang['target____media'] = 'Ventana para enlaces a medios';
+$lang['target____windows'] = 'Ventana para enlaces a ventanas';
+$lang['proxy____host'] = 'Nombre del servidor Proxy';
+$lang['proxy____port'] = 'Puerto del servidor Proxy';
+$lang['proxy____user'] = 'Nombre de usuario para el servidor Proxy';
+$lang['proxy____pass'] = 'Contraseña para el servidor Proxy';
+$lang['proxy____ssl'] = 'Usar ssl para conectarse al servidor Proxy';
+$lang['proxy____except'] = 'Expresiones regulares para encontrar URLs que el proxy debería omitir.';
+$lang['safemodehack'] = 'Habilitar edición (hack) de modo seguro';
+$lang['ftp____host'] = 'Nombre del servidor FTP para modo seguro';
+$lang['ftp____port'] = 'Puerto del servidor FTP para modo seguro';
+$lang['ftp____user'] = 'Nombre de usuario para el servidor FTP para modo seguro';
+$lang['ftp____pass'] = 'Contraseña para el servidor FTP para modo seguro';
+$lang['ftp____root'] = 'Directorio raiz para el servidor FTP para modo seguro';
+$lang['license_o_'] = 'No se eligió ninguna';
+$lang['typography_o_0'] = 'ninguno';
+$lang['typography_o_1'] = 'Dobles comillas solamente';
+$lang['typography_o_2'] = 'Todas las comillas (puede ser que no siempre funcione)';
+$lang['userewrite_o_0'] = 'ninguno';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Interno de DokuWiki';
+$lang['deaccent_o_0'] = 'apagado';
+$lang['deaccent_o_1'] = 'eliminar tildes';
+$lang['deaccent_o_2'] = 'romanizar';
+$lang['gdlib_o_0'] = 'GD Lib no está disponible';
+$lang['gdlib_o_1'] = 'Versión 1.x';
+$lang['gdlib_o_2'] = 'Autodetección';
+$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';
+$lang['rss_content_o_abstract'] = 'Resumen';
+$lang['rss_content_o_diff'] = 'Diferencias unificadas';
+$lang['rss_content_o_htmldiff'] = 'Tabla de diferencias en formato HTML';
+$lang['rss_content_o_html'] = 'Página que solo contiene código HTML';
+$lang['rss_linkto_o_diff'] = 'ver las diferencias';
+$lang['rss_linkto_o_page'] = 'la página revisada';
+$lang['rss_linkto_o_rev'] = 'lista de revisiones';
+$lang['rss_linkto_o_current'] = 'la página actual';
+$lang['compression_o_0'] = 'ninguna';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'no utilizar';
+$lang['xsendfile_o_1'] = 'Encabezado propietario de lighttpd (antes de la versión 1.5)';
+$lang['xsendfile_o_2'] = 'Encabezado X-Sendfile estándar';
+$lang['xsendfile_o_3'] = 'Encabezado propietario Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Nombre de entrada';
+$lang['showuseras_o_username'] = 'Nombre completo del usuario';
+$lang['showuseras_o_email'] = 'Dirección de correo electrónico del usuario (ofuscada según la configuración de "mailguard")';
+$lang['showuseras_o_email_link'] = 'Dirección de correo de usuario como enlace de envío de correo';
+$lang['useheading_o_0'] = 'Nunca';
+$lang['useheading_o_navigation'] = 'Solamente Navegación';
+$lang['useheading_o_content'] = 'Contenido wiki solamente';
+$lang['useheading_o_1'] = 'Siempre';
+$lang['readdircache'] = 'Tiempo máximo para la cache readdir (en segundos)';
diff --git a/lib/plugins/config/lang/et/lang.php b/lib/plugins/config/lang/et/lang.php
new file mode 100644
index 000000000..27f2e87ac
--- /dev/null
+++ b/lib/plugins/config/lang/et/lang.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
+$lang['menu'] = 'Seadete haldamine';
+$lang['_configuration_manager'] = 'Seadete haldamine';
+$lang['_basic'] = 'Peamised seaded';
+$lang['_display'] = 'Näitamise seaded';
+$lang['_authentication'] = 'Audentimise seaded';
+$lang['_anti_spam'] = 'Spämmitõrje seaded';
+$lang['_editing'] = 'Muutmise seaded';
+$lang['_links'] = 'Lingi seaded';
+$lang['_media'] = 'Meedia seaded';
+$lang['_advanced'] = 'Laiendatud seaded';
+$lang['_network'] = 'Võrgu seaded';
+$lang['_plugin_sufix'] = 'Plugina seaded';
+$lang['_template_sufix'] = 'Kujunduse seaded';
+$lang['title'] = 'Wiki pealkiri';
+$lang['template'] = 'Kujundus';
+$lang['recent'] = 'Viimased muudatused';
+$lang['signature'] = 'Allkiri';
+$lang['defaultgroup'] = 'Vaikimisi grupp';
+$lang['disableactions_check'] = 'Kontrolli';
+$lang['compression_o_0'] = 'pole';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ära kasuta';
+$lang['useheading_o_0'] = 'Mitte kunagi';
+$lang['useheading_o_1'] = 'Alati';
diff --git a/lib/plugins/config/lang/eu/intro.txt b/lib/plugins/config/lang/eu/intro.txt
new file mode 100644
index 000000000..17edb3e3e
--- /dev/null
+++ b/lib/plugins/config/lang/eu/intro.txt
@@ -0,0 +1,7 @@
+====== Konfigurazio Kudeatzailea ======
+
+Erabili orri hau zure DokiWiki instalazioaren aukerak kontrolatzeko. Aukera zehatzei buruz laguntza eskuratzeko ikusi [[doku>config]]. Plugin honi buruzko xehetasun gehiago eskuratzeko ikusi [[doku>plugin:config]].
+
+Atzealde gorri argi batez erakusten diren aukerak babestuak daude eta ezin dira plugin honekin aldatu. Atzealde urdin batez erakusten diren aukerak balio lehenetsiak dira eta atzealde zuriz erakutsiak modu lokalean ezarriak izan dira instalazio honentzat. Aukera urdin eta zuriak aldatuak izan daitezke.
+
+Gogoratu **GORDE** botoia sakatzeaz orri hau utzi baino lehen, bestela zure aldaketak galdu egingo baitira.
diff --git a/lib/plugins/config/lang/eu/lang.php b/lib/plugins/config/lang/eu/lang.php
new file mode 100644
index 000000000..9d001d494
--- /dev/null
+++ b/lib/plugins/config/lang/eu/lang.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['menu'] = 'Konfigurazio Ezarpenak';
+$lang['error'] = 'Ezarpenak ez dira eguneratu balio oker bat dela eta, mesedez errepasatu aldaketak eta berriz bidali. <br />Balio okerra(k) ertz gorriz inguratuak erakutsiko dira. ';
+$lang['updated'] = 'Ezarpenak arrakastaz eguneratuak.';
+$lang['nochoice'] = '(ez dago beste aukerarik)';
+$lang['locked'] = 'Ezarpenen fitxategia ezin da eguneratu, eta intentzioa hau ez bada, <br />
+ziurtatu ezarpen lokalen izena eta baimenak zuzenak direla.';
+$lang['danger'] = 'Kontuz: Aukera hau aldatzeak zure wikia eta konfigurazio menua eskuraezin utzi dezake.';
+$lang['warning'] = 'Oharra: Aukera hau aldatzeak ustekabeko portaera bat sortu dezake.';
+$lang['security'] = 'Segurtasun Oharra: Aukera hau aldatzeak segurtasun arrisku bat sortu dezake.';
+$lang['_configuration_manager'] = 'Konfigurazio Kudeatzailea';
+$lang['_header_dokuwiki'] = 'DokuWiki Ezarpenak';
+$lang['_header_plugin'] = 'Plugin Ezarpenak';
+$lang['_header_template'] = 'Txantiloi Ezarpenak';
+$lang['_header_undefined'] = 'Zehaztu gabeko Ezarpenak';
+$lang['_basic'] = 'Oinarrizko Ezarpenak';
+$lang['_display'] = 'Aurkezpen Ezarpenak';
+$lang['_authentication'] = 'Kautotze Ezarpenak';
+$lang['_anti_spam'] = 'Anti-Spam Ezarpenak';
+$lang['_editing'] = 'Edizio Ezarpenak';
+$lang['_links'] = 'Esteken Ezarpenak';
+$lang['_media'] = 'Multimedia Ezarpenak';
+$lang['_advanced'] = 'Ezarpen Aurreratuak';
+$lang['_network'] = 'Sare Ezarpenak';
+$lang['_plugin_sufix'] = 'Plugin Ezarpenak';
+$lang['_template_sufix'] = 'Txantiloi Ezarpenak';
+$lang['_msg_setting_undefined'] = 'Ezarpen metadaturik ez.';
+$lang['_msg_setting_no_class'] = 'Ezarpen klaserik ez.';
+$lang['_msg_setting_no_default'] = 'Balio lehenetsirik ez.';
+$lang['fmode'] = 'Fitxategi sortze modua';
+$lang['dmode'] = 'Direktorio sortze modua';
+$lang['lang'] = 'Hizkuntza';
+$lang['basedir'] = 'Oinarri direktorioa';
+$lang['baseurl'] = 'Oinarri URLa';
+$lang['savedir'] = 'Datuak gordetzeko direktorioa';
+$lang['start'] = 'Hasiera orriaren izena';
+$lang['title'] = 'Wiki-aren izenburua';
+$lang['template'] = 'Txantiloia';
+$lang['license'] = 'Zein lizentziapean argitaratu beharko lirateke edukiak?';
+$lang['fullpath'] = 'Orri oinean orrien bide osoa erakutsi';
+$lang['recent'] = 'Azken aldaketak';
+$lang['breadcrumbs'] = 'Arrasto pauso kopurua';
+$lang['youarehere'] = 'Arrasto pauso hierarkikoak';
+$lang['typography'] = 'Ordezkapen tipografikoak egin';
+$lang['htmlok'] = 'Enbotatutako HTMLa baimendu';
+$lang['phpok'] = 'Enbotatutako PHPa baimendu';
+$lang['dformat'] = 'Data formatua (ikusi PHPren <a href="http://www.php.net/strftime">strftime</a> funtzioa)';
+$lang['signature'] = 'Sinadura';
+$lang['toptoclevel'] = 'Eduki taularen goiko maila';
+$lang['tocminheads'] = 'Gutxiengo izenburu kopuru minimoa Edukien Taula-ren sortu dadin.';
+$lang['maxtoclevel'] = 'Eduki taularen maila maximoa';
+$lang['maxseclevel'] = 'Sekzio edizio mailaren maximoa';
+$lang['camelcase'] = 'Estekentzat CamelCase erabili';
+$lang['deaccent'] = 'Orri izen garbiak';
+$lang['useheading'] = 'Erabili lehen izenburua orri izen moduan';
+$lang['refcheck'] = 'Multimedia erreferentzia kontrolatu';
+$lang['refshow'] = 'Erakusteko multimedia erreferentzia kopurua';
+$lang['allowdebug'] = 'Baimendu debug-a <b>ezgaitu behar ez bada!</b>';
+$lang['usewordblock'] = 'Blokeatu spam-a hitz zerrenda batean oinarrituta';
+$lang['indexdelay'] = 'Denbora atzerapena indexatu baino lehen (seg)';
+$lang['relnofollow'] = 'Erabili rel="nofollow" kanpo esteketan';
+$lang['mailguard'] = 'Ezkutatu posta-e helbidea';
+$lang['iexssprotect'] = 'Egiaztatu igotako fitxategiak JavaScript edo HTML kode maltzurra detektatzeko';
+$lang['showuseras'] = 'Zer azaldu orri bat editatu duen azken erabiltzailea erakusterakoan';
+$lang['useacl'] = 'Erabili atzipen kontrol listak';
+$lang['autopasswd'] = 'Pasahitzak automatikoki sortu';
+$lang['authtype'] = 'Kautotze backend-a';
+$lang['passcrypt'] = 'Pasahitz enkriptatze metodoa';
+$lang['defaultgroup'] = 'Talde lehenetsia';
+$lang['superuser'] = 'Supererabiltzailea - taldea, erabiltzailea edo komaz bereiztutako zerrenda user1,@group1,user2 orri eta funtzio guztietara atzipen osoarekin, AKL-ren ezarpenetan zehaztutakoa kontutan hartu gabe';
+$lang['manager'] = 'Kudeatzailea - talde, erabiltzaile edo komaz bereiztutako zerrenda user1,@group1,user2 kudeatze funtzio zehatz batzuetara atzipenarekin';
+$lang['profileconfirm'] = 'Profil aldaketak pasahitzaz berretsi';
+$lang['disableactions'] = 'DokuWiki ekintzak ezgaitu';
+$lang['disableactions_check'] = 'Egiaztatu';
+$lang['disableactions_subscription'] = 'Harpidetu/Harpidetza utzi';
+$lang['disableactions_wikicode'] = 'Ikusi iturburua/Esportatu Raw';
+$lang['disableactions_other'] = 'Beste ekintzak (komaz bereiztuak)';
+$lang['sneaky_index'] = 'Lehenespenez, DokuWiki-k izen-espazio guztiak indize bistan erakutsiko ditu. Aukera hau gaituta, erabiltzaieak irakurtzeko baimenik ez dituen izen-espazioak ezkutatuko dira. Honek atzigarriak diren azpi izen-espazioak ezkutatzen ditu. Agian honek indizea erabili ezin ahal izatea eragingo du AKL ezarpen batzuetan.';
+$lang['auth_security_timeout'] = 'Kautotze Segurtasun Denbora-Muga (segunduak)';
+$lang['securecookie'] = 'HTTPS bidez ezarritako cookie-ak HTTPS bidez bakarrik bidali beharko lituzke nabigatzaileak? Ezgaitu aukera hau bakarrik saio hasierak SSL bidezko segurtasuna badu baina wiki-areb nabigazioa modu ez seguruan egiten bada. ';
+$lang['xmlrpc'] = 'Gaitu/ezgaitu XML-RPC interfazea.';
+$lang['xmlrpcuser'] = 'XML-RPC atzipena mugatu hemen emandako komaz bereiztutako talde eta erabiltzaileei. Utzi hutsik atzipena guztiei emateko.';
+$lang['updatecheck'] = 'Konprobatu eguneratze eta segurtasun oharrak? DokuWiki-k honetarako update.dokuwiki.org kontaktatu behar du.';
+$lang['userewrite'] = 'Erabili URL politak';
+$lang['useslash'] = 'Erabili barra (/) izen-espazio banatzaile moduan URLetan';
+$lang['usedraft'] = 'Automatikoki zirriborroa gorde editatze garaian';
+$lang['sepchar'] = 'Orri izenaren hitz banatzailea';
+$lang['canonical'] = 'Erabili URL erabat kanonikoak';
+$lang['fnencode'] = 'Non-ASCII fitxategi izenak kodetzeko metodoa.';
+$lang['autoplural'] = 'Kontrolatu forma pluralak esteketan';
+$lang['compression'] = 'Trinkotze metodoa attic fitxategientzat';
+$lang['cachetime'] = 'Adin maximoa cachearentzat (seg)';
+$lang['locktime'] = 'Adin maximoa lock fitxategientzat (seg)';
+$lang['fetchsize'] = 'Kanpo esteketatik fetch.php-k deskargatu dezakeen tamaina maximoa (byteak)';
+$lang['notify'] = 'Aldaketen jakinarazpenak posta-e helbide honetara bidali';
+$lang['registernotify'] = 'Erregistratu berri diren erabiltzaileei buruzko informazioa post-e helbide honetara bidali';
+$lang['mailfrom'] = 'Posta automatikoentzat erabiliko den posta-e helbidea';
+$lang['mailprefix'] = 'Posta automatikoen gaientzat erabili beharreko aurrizkia';
+$lang['gzip_output'] = 'Gzip Eduki-Kodeketa erabili xhtml-rentzat';
+$lang['gdlib'] = 'GD Lib bertsioa';
+$lang['im_convert'] = 'ImageMagick-en aldaketa tresnara bidea';
+$lang['jpg_quality'] = 'JPG konprimitze kalitatea (0-100)';
+$lang['subscribers'] = 'Gaitu orri harpidetza euskarria';
+$lang['subscribe_time'] = 'Harpidetza zerrendak eta laburpenak bidali aurretik pasa beharreko denbora (seg); Denbora honek, recent_days-en ezarritakoa baino txikiagoa behar luke.';
+$lang['compress'] = 'Trinkotu CSS eta javascript irteera';
+$lang['hidepages'] = 'Ezkutatu kointzidentziak dituzten orriak (espresio erregularrak)';
+$lang['send404'] = 'Bidali "HTTP 404/Ez Da Orria Aurkitu" existitzen ez diren orrientzat';
+$lang['sitemap'] = 'Sortu Google gune-mapa (egunak)';
+$lang['broken_iua'] = 'Zure sisteman ignore_user_abort (erabiltzailearen bertan behera uztea kontuan ez hartu) funtzioa hautsia al dago? Honek funtzionatzen ez duen bilaketa indize bat eragin dezake. ISS+PHP/CGI hautsiak daude. Ikusi <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> informazio gehiago jasotzeko.';
+$lang['xsendfile'] = 'X-Sendfile goiburua erabili web zerbitzariari fitxategi estatikoak bidaltzen uzteko? Zure web zerbitzariak hau ahalbidetuta eduki beharko du.';
+$lang['renderer_xhtml'] = 'Erabiliko den errenderizatzailea wiki irteera (xhtml) nagusiarentzat';
+$lang['renderer__core'] = '%s (dokuwiki-ren nukleoa)';
+$lang['renderer__plugin'] = '%s (plugina)';
+$lang['rememberme'] = 'Baimendu saio hasiera cookie iraunkorrak (gogoratu iezaidazu)';
+$lang['rss_type'] = 'XML jario mota';
+$lang['rss_linkto'] = 'XML jarioak hona estekatzen du';
+$lang['rss_content'] = 'Zer erakutsi XML jarioetan?';
+$lang['rss_update'] = 'XML jarioaren eguneratze tartea (seg)';
+$lang['recent_days'] = 'Zenbat azken aldaketa gordeko dira (egunak)';
+$lang['rss_show_summary'] = 'XML jarioak laburpena erakusten du izenburuan';
+$lang['target____wiki'] = 'Barne estekentzat helburu leihoa';
+$lang['target____interwiki'] = 'Interwiki estekentzat helburu leihoa';
+$lang['target____extern'] = 'Kanpo estekentzat helburu leihoa';
+$lang['target____media'] = 'Multimedia estekentzat helburu leihoa';
+$lang['target____windows'] = 'Leihoen estekentzat helburu leihoa';
+$lang['proxy____host'] = 'Proxy zerbitzari izena';
+$lang['proxy____port'] = 'Proxy portua';
+$lang['proxy____user'] = 'Proxyaren erabiltzaile izena';
+$lang['proxy____pass'] = 'Proxyaren pasahitza ';
+$lang['proxy____ssl'] = 'Erabili SSL Proxyra konektatzeko';
+$lang['proxy____except'] = 'URLak detektatzeko espresio erregularra, zeinentzat Proxy-a sahiestu beharko litzatekeen.';
+$lang['safemodehack'] = 'Gaitu modu segurua hack-a';
+$lang['ftp____host'] = 'FTP zerbitzaria modu seguruarentzat';
+$lang['ftp____port'] = 'FTP portua modu seguruarentzat';
+$lang['ftp____user'] = 'FTP erabiltzailea modu seguruarentzat';
+$lang['ftp____pass'] = 'FTP pasahitza modu seguruarentzat';
+$lang['ftp____root'] = 'FTP erro direktorioa modu seguruarentzat';
+$lang['license_o_'] = 'Bat ere ez hautaturik';
+$lang['typography_o_0'] = 'ezer';
+$lang['typography_o_1'] = 'Komatxo bikoitzak bakarrik';
+$lang['typography_o_2'] = 'Komatxo guztiak (gerta daiteke beti ez funtzionatzea)';
+$lang['userewrite_o_0'] = 'ezer';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWikiren barnekoa';
+$lang['deaccent_o_0'] = 'Izalita';
+$lang['deaccent_o_1'] = 'azentu-markak kendu';
+$lang['deaccent_o_2'] = 'erromanizatu ';
+$lang['gdlib_o_0'] = 'GD Lib ez dago eskuragarri';
+$lang['gdlib_o_1'] = '1.x bertsioa';
+$lang['gdlib_o_2'] = 'Automatikoki detektatu';
+$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';
+$lang['rss_content_o_abstract'] = 'Laburpena';
+$lang['rss_content_o_diff'] = 'Bateratutako Diferentziak';
+$lang['rss_content_o_htmldiff'] = 'HTML formatuko diferentzia taula';
+$lang['rss_content_o_html'] = 'Orri edukia guztiz HTML';
+$lang['rss_linkto_o_diff'] = 'Desberdintasunak ikusi';
+$lang['rss_linkto_o_page'] = 'Berrikusitako orria';
+$lang['rss_linkto_o_rev'] = 'Berrikuspen zerrenda';
+$lang['rss_linkto_o_current'] = 'Uneko orria';
+$lang['compression_o_0'] = 'ezer';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ez erabili';
+$lang['xsendfile_o_1'] = 'Jabegodun lighttpd goiburua (1.5 bertsioa baino lehen)';
+$lang['xsendfile_o_2'] = 'X-Sendfile goiburu estandarra';
+$lang['xsendfile_o_3'] = 'Jabegodun Nginx X-Accel-Redirect goiburua';
+$lang['showuseras_o_loginname'] = 'Saio izena';
+$lang['showuseras_o_username'] = 'Erabiltzailearen izen osoa';
+$lang['showuseras_o_email'] = 'Erabiltzailearen posta-e helbidea (ezkutatua posta babeslearen aukeren arabera)';
+$lang['showuseras_o_email_link'] = 'Erabiltzailearen posta-e helbidea mailto: esteka moduan';
+$lang['useheading_o_0'] = 'Inoiz';
+$lang['useheading_o_navigation'] = 'Nabigazioa Bakarrik';
+$lang['useheading_o_content'] = 'Wiki Edukia Bakarrik';
+$lang['useheading_o_1'] = 'Beti';
+$lang['readdircache'] = 'Aintzintasun maximoa readdir cache-rentzat (seg)';
diff --git a/lib/plugins/config/lang/fa/intro.txt b/lib/plugins/config/lang/fa/intro.txt
new file mode 100644
index 000000000..f5b6ba235
--- /dev/null
+++ b/lib/plugins/config/lang/fa/intro.txt
@@ -0,0 +1,8 @@
+====== تنظیمات پیکربندی ======
+
+از این صفحه برای مدیریت تنظیمات DokuWiki استفاده کنید. برای راهنمایی بیش‌تر به [[doku>config]] مراجعه نماید.
+برای جزییات در مورد این افزونه نیز می‌توانید به [[doku>plugin:config]] مراجعه کنید.
+
+تنظیماتی که با پیش‌زمینه‌ی قرمز مشخص شده‌اند، غیرقابل تغییر می‌باشند. تنظیماتی که به پیش‌زمینه‌ی آبی مشخص شده‌اند نیز حامل مقادیر پیش‌فرض می‌باشند و تنظیماتی که پیش‌زمینه‌ی سفید دارند به طور محلی برای این سیستم تنظیم شده‌اند. تمامی مقادیر آبی و سفید قابلیت تغییر دارند.
+
+به یاد داشته باشید که قبل از ترک صفحه، دکمه‌ی **ذخیره** را بفشارید، در غیر این صورت تنظیمات شما از بین خواهد رفت. \ No newline at end of file
diff --git a/lib/plugins/config/lang/fa/lang.php b/lib/plugins/config/lang/fa/lang.php
new file mode 100644
index 000000000..42cc3ed05
--- /dev/null
+++ b/lib/plugins/config/lang/fa/lang.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['menu'] = 'تنظیمات پیکر‌بندی';
+$lang['error'] = 'به دلیل ایراد در مقادیر وارد شده، تنظیمات اعمال نشد، خواهشمندیم تغییرات را مجددن کنترل نمایید و دوباره ارسال کنید.<br/> مقادیر مشکل‌دار با کادر قرمز مشخص شده‌اند.';
+$lang['updated'] = 'تنظیمات با موفقیت به روز رسانی شد.';
+$lang['nochoice'] = '(گزینه‌های دیگری موجود نیست)';
+$lang['locked'] = 'تنظیمات قابلیت به روز رسانی ندارند، اگر نباید چنین باشد، <br/> نام فایل تنظیمات و دسترسی‌های آن را بررسی کنید.';
+$lang['danger'] = 'خطر: ممکن است با تغییر این گزینه دسترسی به منوی تنظیمات قطع شود.';
+$lang['warning'] = 'هشدار: ممکن است با تغییر این گزینه رفتارهای غیرمترقبه‌ای مشاهده کنید.';
+$lang['security'] = 'هشدار امنیتی: تغییر این گزینه ممکن است با خطرات امنیتی همراه باشد.';
+$lang['_configuration_manager'] = 'مدیریت تنظیمات';
+$lang['_header_dokuwiki'] = 'تنظیمات DokuWiki';
+$lang['_header_plugin'] = 'تنظیمات افزونه';
+$lang['_header_template'] = 'تنظیمات قالب';
+$lang['_header_undefined'] = 'تنظیمات تعریف نشده';
+$lang['_basic'] = 'تنظیمات مقدماتی';
+$lang['_display'] = 'تنظیمات نمایش';
+$lang['_authentication'] = 'تنظیمات معتبرسازی';
+$lang['_anti_spam'] = 'تنظیمات ضد-اسپم';
+$lang['_editing'] = 'تنظیمات ویرایش';
+$lang['_links'] = 'تنظیمات پیوند';
+$lang['_media'] = 'تنظیمات رسانه‌ها (فایل‌ها)';
+$lang['_advanced'] = 'تنظیمات پیشرفته';
+$lang['_network'] = 'تنظیمات شبکه';
+$lang['_plugin_sufix'] = 'تنظیمات افزونه';
+$lang['_template_sufix'] = 'تنظیمات قالب';
+$lang['_msg_setting_undefined'] = 'داده‌نمایی برای تنظیمات وجود ندارد';
+$lang['_msg_setting_no_class'] = 'هیچ دسته‌ای برای تنظیمات وجود ندارد.';
+$lang['_msg_setting_no_default'] = 'بدون مقدار پیش‌فرض';
+$lang['fmode'] = 'دسترسی پیش‌فرض فایل‌ها در زمان ایجاد';
+$lang['dmode'] = 'زبان';
+$lang['lang'] = 'زبان';
+$lang['basedir'] = 'شاخه‌ی اصلی';
+$lang['baseurl'] = 'آدرس اصلی';
+$lang['savedir'] = 'شاخه‌ی ذخیره‌سازی داده‌ها';
+$lang['start'] = 'نام صفحه‌ی آغازین';
+$lang['title'] = 'عنوان ویکی';
+$lang['template'] = 'قالب';
+$lang['license'] = 'لایسنس مطالب ویکی';
+$lang['fullpath'] = 'نمایش دادن مسیر کامل صفحات در پایین صفحه';
+$lang['recent'] = 'تغییرات اخیر';
+$lang['breadcrumbs'] = 'تعداد ردپاها';
+$lang['youarehere'] = 'ردپای درختی';
+$lang['typography'] = 'جای‌گزاری متن‌ها انجام شود';
+$lang['htmlok'] = 'امکان افزودن HTML باشد';
+$lang['phpok'] = 'امکان افزودن PHP باشد';
+$lang['dformat'] = 'فرمت تاریخ (راهنمای تابع <a href="http://www.php.net/strftime">strftime</a> را مشاهده کنید)';
+$lang['signature'] = 'امضا';
+$lang['toptoclevel'] = 'بیشترین عمق برای «فهرست مطالب»';
+$lang['tocminheads'] = 'حداقل مقدار عنوان‌های یک صفحه، برای تشخیص این‌که «فهرست مطالب» (TOC) ایجاد شود';
+$lang['maxtoclevel'] = 'حداکثر عمق «فهرست مطالب»';
+$lang['maxseclevel'] = 'بیش‌ترین سطح ویرایش بخش‌ها';
+$lang['camelcase'] = 'از «حالت شتری» (CamelCase) برای پیوندها استفاده شود';
+$lang['deaccent'] = 'تمیز کردن نام صفحات';
+$lang['useheading'] = 'استفاده از اولین عنوان برای نام صفحه';
+$lang['refcheck'] = 'بررسی کردن مرجع رسانه‌ها';
+$lang['refshow'] = 'تعداد مراجعی که برای یک رسانه نمایش داده شود';
+$lang['allowdebug'] = 'امکان کرم‌زدایی (debug) <b>اگر نیازی ندارید، غیرفعال کنید</b>';
+$lang['usewordblock'] = 'اسپم‌ها را براساس لیست کلمات مسدود کن';
+$lang['indexdelay'] = 'مقدار تاخیر پیش از فهرست‌بندی (ثانیه)';
+$lang['relnofollow'] = 'از «rel=nofollow» در پیوندهای خروجی استفاده شود';
+$lang['mailguard'] = 'مبهم کردن آدرس‌های ایمیل';
+$lang['iexssprotect'] = 'بررسی کردن فایل‌های ارسال شده را برای کدهای HTML یا JavaScript مخرب';
+$lang['showuseras'] = 'چگونه آخرین کاربر ویرایش کننده، یک صفحه نمایش داده شود';
+$lang['useacl'] = 'استفاده از مدیریت دسترسی‌ها';
+$lang['autopasswd'] = 'ایجاد خودکار گذرواژه‌ها';
+$lang['authtype'] = 'روش معتبرسازی';
+$lang['passcrypt'] = 'روش کد کردن گذرواژه';
+$lang['defaultgroup'] = 'گروه پیش‌فرض';
+$lang['superuser'] = 'کاربر اصلی - گروه، کاربر یا لیستی که توسط ویرگول جدا شده از کاربرها و گروه‌ها (مثل user1,@group1,user2) با دسترسی کامل به همه‌ی صفحات و امکانات سیستم، فارغ از دسترسی‌های آن کاربر.';
+$lang['manager'] = 'مدیر - گروه، کاربر یا لیستی که توسط ویرگول جدا شده از کاربرها و گروه‌ها (مثل user1,@group1,user2) با دسترسی‌های خاص به بخش‌های متفاوت';
+$lang['profileconfirm'] = 'تغییرات پروفایل با وارد کردن گذرواژه تایید شود';
+$lang['disableactions'] = 'غیرفعال کردن فعالیت‌های DokuWiki';
+$lang['disableactions_check'] = 'بررسی';
+$lang['disableactions_subscription'] = 'عضویت/عدم عضویت';
+$lang['disableactions_wikicode'] = 'نمایش سورس/برون‌بری خام';
+$lang['disableactions_other'] = 'فعالیت‌های دیگر (با ویرگول انگلیسی «,» از هم جدا کنید)';
+$lang['sneaky_index'] = 'به طور پیش‌فرض، DokuWiki در فهرست تمامی فضای‌نام‌ها را نمایش می‌دهد. فعال کردن این گزینه، مواردی را که کاربر حق خواندنشان را ندارد مخفی می‌کند. این گزینه ممکن است باعث دیده نشدن زیرفضای‌نام‌هایی شود که دسترسی خواندن به آن‌ها وجود دارد. و ممکن است باعث شود که فهرست در حالاتی از دسترسی‌ها، غیرقابل استفاده شود.';
+$lang['auth_security_timeout'] = 'زمان انقضای معتبرسازی به ثانیه';
+$lang['securecookie'] = 'آیا کوکی‌ها باید با قرارداد HTTPS ارسال شوند؟ این گزینه را زمانی که فقط صفحه‌ی ورود ویکی‌تان با SSL امن شده است، اما ویکی را ناامن مرور می‌کنید، غیرفعال نمایید.';
+$lang['xmlrpc'] = 'فعال/غیرفعال کردن XML-RPC';
+$lang['xmlrpcuser'] = 'محمدود کردن دسترسی به XML-RPC توسط گروه های جدا شده توسط ویرگول ویا اعضای داده شده در اینجا. این مکان را خالی بگزارید تا به همه دسترسی داده شود.';
+$lang['updatecheck'] = 'هشدارهای به روز رسانی و امنیتی بررسی شود؟ برای این‌کار DokuWiki با سرور update.dokuwiki.org تماس خواهد گرفت.';
+$lang['userewrite'] = 'از زیباکننده‌ی آدرس‌ها استفاده شود';
+$lang['useslash'] = 'از اسلش «/» برای جداکننده‌ی آدرس فضای‌نام‌ها استفاده شود';
+$lang['usedraft'] = 'ایجاد خودکار چرک‌نویس در زمان نگارش';
+$lang['sepchar'] = 'کلمه‌ی جداکننده‌ی نام صفحات';
+$lang['canonical'] = 'استفاده از آدرس‌های استاندارد';
+$lang['fnencode'] = 'روش تغییر نام فایل‌هایی با فرمتی غیر از اسکی';
+$lang['autoplural'] = 'بررسی جمع بودن در پیوندها';
+$lang['compression'] = 'روش فشرده‌سازی برای فایل‌های خُرد';
+$lang['cachetime'] = 'بیشینه‌ی زمان حافظه‌ی موقت (cache) به ثانیه';
+$lang['locktime'] = 'بیشینه‌ی زمان قفل شدن فایل‌ها به ثانیه';
+$lang['fetchsize'] = 'بیشینه‌ی حجمی که فایل fetch.php می‌تواند دریافت کند (به بایت)';
+$lang['notify'] = 'تغییرات به این ایمیل ارسال شود';
+$lang['registernotify'] = 'اطلاعات کاربران تازه وارد به این ایمیل ارسال شود';
+$lang['mailfrom'] = 'آدرس ایمیلی که برای ایمیل‌های خودکار استفاده می‌شود';
+$lang['mailprefix'] = 'پیشوند تیتر ایمیل (جهت ایمیل های خودکار)';
+$lang['gzip_output'] = 'استفاده از gzip برای xhtmlها';
+$lang['gdlib'] = 'نگارش کتاب‌خانه‌ی GD';
+$lang['im_convert'] = 'مسیر ابزار convert از برنامه‌ی ImageMagick';
+$lang['jpg_quality'] = 'کیفیت فشرده سازی JPEG (از 0 تا 100)';
+$lang['subscribers'] = 'توانایی عضویت در صفحات باشد';
+$lang['subscribe_time'] = 'زمان مورد نیاز برای ارسال خبر نامه ها (ثانیه); این مقدار می بایست کمتر زمانی باشد که در recent_days تعریف شده است.';
+$lang['compress'] = 'فشرده‌سازی کد‌های CSS و JavaScript';
+$lang['hidepages'] = 'مخفی کردن صفحات با فرمت زیر (از عبارات منظم استفاده شود)';
+$lang['send404'] = 'ارسال «HTTP 404/Page Not Found» برای صفحاتی که وجود ندارند';
+$lang['sitemap'] = 'تولید کردن نقشه‌ی سایت توسط گوگل (روز)';
+$lang['broken_iua'] = 'آیا تابع ignore_user_about در ویکی شما کار نمی‌کند؟ ممکن است فهرست جستجوی شما کار نکند. IIS به همراه PHP/CGI باعث خراب شدن این گزینه می‌شود. برای اطلاعات بیشتر <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">باگ ۸۵۲</a> را مشاهده کنید.';
+$lang['xsendfile'] = 'استفاده از هدر X-Sendfile، تا به وب‌سرور توانایی ارسال فایل‌های ثابت را بدهد. وب‌سرور شما باید این مورد را پشتیبانی کند.';
+$lang['renderer_xhtml'] = 'مفسری که برای خروجی اصلی ویکی استفاده شود';
+$lang['renderer__core'] = '%s (هسته‌ی dokuwiki)';
+$lang['renderer__plugin'] = '%s (افزونه)';
+$lang['rememberme'] = 'امکان ورود دایم، توسط کوکی، وجود داشته باشد (مرا به خاطر بسپار)';
+$lang['rss_type'] = 'نوع خوراک';
+$lang['rss_linkto'] = 'خوراک به کجا لینک شود';
+$lang['rss_content'] = 'چه چیزی در تکه‌های خوراک نمایش داده شود؟';
+$lang['rss_update'] = 'زمان به روز رسانی خوراک به ثانیه';
+$lang['recent_days'] = 'چند تغییر در خوراک نمایش داده شود به روز';
+$lang['rss_show_summary'] = 'خوراک مختصری از مطلب را در عنوان نمایش دهد';
+$lang['target____wiki'] = 'پنجره‌ی هدف در پیوند‌های داخلی';
+$lang['target____interwiki'] = 'پنجره‌ی هدف در پیوند‌های داخل ویکی';
+$lang['target____extern'] = 'پنجره‌ی هدف در پیوند‌های خارجی';
+$lang['target____media'] = 'پنجره‌ی هدف در پیوند‌های رسانه‌ها';
+$lang['target____windows'] = 'پنجره‌ی هدف در پیوند‌های پنجره‌ای';
+$lang['proxy____host'] = 'آدرس سرور پروکسی';
+$lang['proxy____port'] = 'پورت پروکسی';
+$lang['proxy____user'] = 'نام کاربری پروکسی';
+$lang['proxy____pass'] = 'گذرواژهي پروکسی';
+$lang['proxy____ssl'] = 'استفاده از SSL برای اتصال به پروکسی';
+$lang['proxy____except'] = 'عبارت منظم برای تطبیق با URLها برای این‌که دریابیم که از روی چه پروکسی‌ای باید بپریم!';
+$lang['safemodehack'] = 'فعال کردن safemode hack';
+$lang['ftp____host'] = 'آدرس FTP برای safemode hack';
+$lang['ftp____port'] = 'پورت FTP برای safemode hack';
+$lang['ftp____user'] = 'نام کاربری FTP برای safemode hack';
+$lang['ftp____pass'] = 'گذرواژه‌ی FTP برای safemode hack';
+$lang['ftp____root'] = 'شاخه‌ی FTP برای safemode hack';
+$lang['license_o_'] = 'هیچ کدام';
+$lang['typography_o_0'] = 'هیچ';
+$lang['typography_o_1'] = 'حذف کردن single-quote';
+$lang['typography_o_2'] = 'به همراه داشتن single-quote (ممکن است همیشه کار نکند)';
+$lang['userewrite_o_0'] = 'هیچ';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'از طریق DokuWiki';
+$lang['deaccent_o_0'] = 'خاموش';
+$lang['deaccent_o_1'] = 'برداشتن تلفظ‌ها';
+$lang['deaccent_o_2'] = 'لاتین کردن (romanize)';
+$lang['gdlib_o_0'] = 'کتاب‌خانه‌ی GD موجود نیست';
+$lang['gdlib_o_1'] = 'نسخه‌ی 1.X';
+$lang['gdlib_o_2'] = 'انتخاب خودکار';
+$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';
+$lang['rss_content_o_abstract'] = 'انتزاعی';
+$lang['rss_content_o_diff'] = 'یکی کردن تفاوت‌ها';
+$lang['rss_content_o_htmldiff'] = 'جدول تفاوت‌ها با ساختار HTML';
+$lang['rss_content_o_html'] = 'تمامی محتویات صفحه، با ساختار HTML';
+$lang['rss_linkto_o_diff'] = 'نمایه‌های متفاوت';
+$lang['rss_linkto_o_page'] = 'صفحه‌ی تجدید نظر شده';
+$lang['rss_linkto_o_rev'] = 'لیست نگارش‌ها';
+$lang['rss_linkto_o_current'] = 'صفحه‌ی کنونی';
+$lang['compression_o_0'] = 'هیچ';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'استفاده نکنید';
+$lang['xsendfile_o_1'] = 'هدر اختصاصی lighttpd (پیش از نگارش ۱.۵)';
+$lang['xsendfile_o_2'] = 'هدر استاندارد X-Sendfile';
+$lang['xsendfile_o_3'] = 'هدر اختصاصی X-Accel-Redirect در وب سرور Nginx';
+$lang['showuseras_o_loginname'] = 'نام کاربری';
+$lang['showuseras_o_username'] = 'نام کامل کاربران';
+$lang['showuseras_o_email'] = 'آدرس ایمیل کاربران (با تنظیمات «نگهبان ایمیل» مبهم می‌شود)';
+$lang['showuseras_o_email_link'] = 'نمایش ایمیل کاربران با افزودن mailto';
+$lang['useheading_o_0'] = 'هرگز';
+$lang['useheading_o_navigation'] = 'فقط ناوبری (navigation)';
+$lang['useheading_o_content'] = 'فقط محتویات ویکی';
+$lang['useheading_o_1'] = 'همیشه';
+$lang['readdircache'] = 'بیش‌ترین عمر برای حافظه‌ی موقت readdir (ثانیه)';
diff --git a/lib/plugins/config/lang/fi/intro.txt b/lib/plugins/config/lang/fi/intro.txt
new file mode 100644
index 000000000..f6eedb50c
--- /dev/null
+++ b/lib/plugins/config/lang/fi/intro.txt
@@ -0,0 +1,7 @@
+====== Asetusten hallinta ======
+
+Käytä tätä sivua hallitaksesi DokuWikisi asetuksia. Apua yksittäisiin asetuksiin löytyy sivulta [[doku>config]]. Lisätietoa tästä liitännäisestä löytyy sivulta [[doku>plugin:config]].
+
+Asetukset, jotka näkyvät vaaleanpunaisella taustalla ovat suojattuja, eikä niitä voi muutta tämän liitännäisen avulla. Asetukset, jotka näkyvät sinisellä taustalla ovat oletusasetuksia. Asetukset valkoisella taustalla ovat asetettu paikallisesti tätä asennusta varten. Sekä sinisiä että valkoisia asetuksia voi muokata.
+
+Muista painaa **TALLENNA**-nappia ennen kuin poistut sivulta. Muuten muutoksesi häviävät. \ No newline at end of file
diff --git a/lib/plugins/config/lang/fi/lang.php b/lib/plugins/config/lang/fi/lang.php
new file mode 100644
index 000000000..9598a0d93
--- /dev/null
+++ b/lib/plugins/config/lang/fi/lang.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['menu'] = 'Asetukset';
+$lang['error'] = 'Asetuksia ei päivitetty väärän arvon vuoksi. Tarkista muutokset ja lähetä sivu uudestaan.
+<br />Väärät arvot on merkitty punaisella reunuksella.';
+$lang['updated'] = 'Asetukset päivitetty onnistuneesti.';
+$lang['nochoice'] = '(ei muita valintoja saatavilla)';
+$lang['locked'] = 'Asetustiedosta ei voi päivittää. Jos tämä ei ole tarkoitus <br />
+niin varmista, että paikallisten asetusten tiedoston nimi ja oikeudet ovat kunnossa.';
+$lang['danger'] = 'Vaara: tämän asetuksen muuttaminen saattaa estää wikisi ja asetusvalikon toimimisen.';
+$lang['warning'] = 'Varoitus: tämän asetuksen muuttaminen saattaa aiheuttaa olettamattomia toimintoja.';
+$lang['security'] = 'Turvallisuusvaroitus: tämän asetuksen muuttaminen saattaa aiheuttaa tietoturva-aukon.';
+$lang['_configuration_manager'] = 'Asetusten hallinta';
+$lang['_header_dokuwiki'] = 'DokuWikin asetukset';
+$lang['_header_plugin'] = 'Liitännäisten asetukset';
+$lang['_header_template'] = 'Sivumallin asetukset';
+$lang['_header_undefined'] = 'Määritetelettömät asetukset';
+$lang['_basic'] = 'Perusasetukset';
+$lang['_display'] = 'Näyttöasetukset';
+$lang['_authentication'] = 'Sisäänkirjoittautumisen asetukset';
+$lang['_anti_spam'] = 'Anti-Spam asetukset';
+$lang['_editing'] = 'Sivumuokkauksen asetukset';
+$lang['_links'] = 'Linkkien asetukset';
+$lang['_media'] = 'Media-asetukset';
+$lang['_advanced'] = 'Lisäasetukset';
+$lang['_network'] = 'Verkkoasetukset';
+$lang['_plugin_sufix'] = 'liitännäisen asetukset';
+$lang['_template_sufix'] = 'Sivumallin asetukset';
+$lang['_msg_setting_undefined'] = 'Ei asetusten metadataa.';
+$lang['_msg_setting_no_class'] = 'Ei asetusluokkaa.';
+$lang['_msg_setting_no_default'] = 'Ei oletusarvoa';
+$lang['fmode'] = 'Tiedoston luontioikeudet';
+$lang['dmode'] = 'Hakemiston luontioikeudet';
+$lang['lang'] = 'Kieli';
+$lang['basedir'] = 'Perushakemisto';
+$lang['baseurl'] = 'Perus URL';
+$lang['savedir'] = 'Hakemisto tietojen tallennukseen.';
+$lang['cookiedir'] = 'Cookien path. Jätä tyhjäksi käyttääksesi baseurl arvoa';
+$lang['start'] = 'Alkusivun nimi';
+$lang['title'] = 'Wikin nimi';
+$lang['template'] = 'Sivumalli';
+$lang['license'] = 'Millä lisenssillä sisältö pitäisi julkaista?';
+$lang['fullpath'] = 'Näytä sivun koko polku sivun alareunassa';
+$lang['recent'] = 'Viime muutokset';
+$lang['breadcrumbs'] = 'Leivänmurujen määrä';
+$lang['youarehere'] = 'Hierarkkiset leivänmurut';
+$lang['typography'] = 'Tee typografiset korvaukset';
+$lang['htmlok'] = 'Salli upotettu HTML';
+$lang['phpok'] = 'Salli upotettu PHP';
+$lang['dformat'] = 'Päivämäärän muoto (katso PHPn <a href="http://www.php.net/strftime">strftime</a> funktiota)';
+$lang['signature'] = 'Allekirjoitus';
+$lang['toptoclevel'] = 'Ylätason sisällysluettelo';
+$lang['tocminheads'] = 'Pienin otsikkorivien määrä, jotta sisällysluettelo tehdään';
+$lang['maxtoclevel'] = 'Sisällysluettelon suurin syvyys';
+$lang['maxseclevel'] = 'Kappale-editoinnin suurin syvyys.';
+$lang['camelcase'] = 'Käytä CamelCase linkkejä';
+$lang['deaccent'] = 'Siivoa sivun nimet';
+$lang['useheading'] = 'Käytä ensimmäistä otsikkoriviä sivun nimenä.';
+$lang['refcheck'] = 'Mediaviitteen tarkistus';
+$lang['refshow'] = 'Montako mediaviitettä näytetään';
+$lang['allowdebug'] = 'Salli debuggaus <b>pois, jos ei tarvita!</b>';
+$lang['usewordblock'] = 'Estä spam sanalistan avulla';
+$lang['indexdelay'] = 'Aikaraja indeksoinnille (sek)';
+$lang['relnofollow'] = 'Käytä rel="nofollow" ulkoisille linkeille';
+$lang['mailguard'] = 'Häivytä email osoite';
+$lang['iexssprotect'] = 'Tarkista lähetetyt tiedostot pahojen javascript- ja html-koodien varalta';
+$lang['showuseras'] = 'Mitä näytetään, kun kerrotaan viimeisen editoijan tiedot';
+$lang['useacl'] = 'Käytä käyttöoikeuksien hallintaa';
+$lang['autopasswd'] = 'Luo salasana automaattisesti';
+$lang['authtype'] = 'Autentikointijärjestelmä';
+$lang['passcrypt'] = 'Salasanan suojausmenetelmä';
+$lang['defaultgroup'] = 'Oletusryhmä';
+$lang['superuser'] = 'Pääkäyttäjä. Ryhmä tai käyttäjä, jolla on täysi oikeus kaikkiin sivuihin ja toimintoihin käyttöoikeuksista huolimatta';
+$lang['manager'] = 'Ylläpitäjä. Ryhmä tai käyttäjä, jolla on pääsy joihinkin ylläpitotoimintoihin';
+$lang['profileconfirm'] = 'Vahvista profiilin päivitys salasanan avulla';
+$lang['disableactions'] = 'Estä DokuWiki-toimintojen käyttö';
+$lang['disableactions_check'] = 'Tarkista';
+$lang['disableactions_subscription'] = 'Tilaa/Peruuta tilaus';
+$lang['disableactions_wikicode'] = 'Näytä lähdekoodi/Vie raakana';
+$lang['disableactions_other'] = 'Muut toiminnot (pilkulla erotettuna)';
+$lang['sneaky_index'] = 'Oletuksena DokuWiki näyttää kaikki nimiavaruudet index-näkymäsä. Tämä asetus piilottaa ne, joihin käyttäjällä ei ole lukuoikeuksia. Tämä voi piilottaa joitakin sallittuja alinimiavaruuksia. Tästä johtuen index-näkymä voi olla käyttökelvoton joillakin ACL-asetuksilla';
+$lang['auth_security_timeout'] = 'Autentikoinnin aikakatkaisu (sekunteja)';
+$lang['securecookie'] = 'Lähetetäänkö HTTPS:n kautta asetetut evästetiedot HTTPS-yhteydellä? Kytke pois, jos vain wikisi kirjautuminen on suojattu SSL:n avulla, mutta muuten wikiä käytetään ilman suojausta.';
+$lang['xmlrpc'] = 'Käytä/poista XML-RPC liityntää';
+$lang['xmlrpcuser'] = 'Estä XML-RPC:n käyttö pilkulla erotetun listan ryhmille tai käyttäjille. Jätä tyhjäksi salliaksesi käyttö kaikille.';
+$lang['updatecheck'] = 'Tarkista päivityksiä ja turvavaroituksia? Tätä varten DokuWikin pitää ottaa yhteys update.dokuwiki.orgiin.';
+$lang['userewrite'] = 'Käytä siivottuja URLeja';
+$lang['useslash'] = 'Käytä kauttaviivaa nimiavaruuksien erottimena URL-osoitteissa';
+$lang['usedraft'] = 'Tallenna vedos muokkaustilassa automaattisesti ';
+$lang['sepchar'] = 'Sivunimen sanaerotin';
+$lang['canonical'] = 'Käytä kanonisoituja URLeja';
+$lang['fnencode'] = 'Muita kuin ASCII merkkejä sisältävien tiedostonimien koodaustapa.';
+$lang['autoplural'] = 'Etsi monikkomuotoja linkeistä';
+$lang['compression'] = 'Attic-tiedostojen pakkausmenetelmä';
+$lang['cachetime'] = 'Välimuisti-tiedostojen maksimi-ikä (sek)';
+$lang['locktime'] = 'Lukitustiedostojen maksimi-ikä (sek)';
+$lang['fetchsize'] = 'Suurin koko (bytejä), jonka fetch.php voi ladata ulkopuolisesta lähteestä';
+$lang['notify'] = 'Lähetä muutosilmoitukset tähän osoitteeseen';
+$lang['registernotify'] = 'Lähetä ilmoitus uusista rekisteröitymisistä tähän osoitteeseen';
+$lang['mailfrom'] = 'Sähköpostiosoite automaattisia postituksia varten';
+$lang['mailprefix'] = 'Etuliite automaattisesti lähetettyihin dähköposteihin';
+$lang['gzip_output'] = 'Käytä gzip "Content-Encoding"-otsaketta xhtml-tiedostojen lähettämiseen';
+$lang['gdlib'] = 'GD Lib versio';
+$lang['im_convert'] = 'ImageMagick-muunnostyökalun polku';
+$lang['jpg_quality'] = 'JPG pakkauslaatu (0-100)';
+$lang['subscribers'] = 'Salli tuki sivujen tilaamiselle';
+$lang['subscribe_time'] = 'Aika jonka jälkeen tilauslinkit ja yhteenveto lähetetään (sek). Tämän pitäisi olla pienempi, kuin recent_days aika.';
+$lang['compress'] = 'Pakkaa CSS ja javascript';
+$lang['cssdatauri'] = 'Maksimikoko tavuina jossa kuvat joihin viitataan CSS-tiedostoista olisi sisällytettynä suoraan tyylitiedostoon jotta HTTP-kyselyjen kaistaa saataisiin kutistettua. Tämä tekniikka ei toimi IE versiossa aikasempi kuin 8! <code>400:sta</code> <code>600:aan</code> tavua on hyvä arvo. Aseta <code>0</code> kytkeäksesi ominaisuuden pois.';
+$lang['hidepages'] = 'Piilota seuraavat sivut (säännönmukainen lauseke)';
+$lang['send404'] = 'Lähetä "HTTP 404/Page Not Found" puuttuvista sivuista';
+$lang['sitemap'] = 'Luo Google sitemap (päiviä)';
+$lang['broken_iua'] = 'Onko "ignore_user_abort" toiminto rikki järjestelmässäsi? Tämä voi aiheuttaa toimimattoman index-näkymän.
+IIS+PHP/CGI on tunnetusti rikki. Katso <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> lisätietoja varten.';
+$lang['xsendfile'] = 'Käytä X-Sendfile otsikkoa, kun web-palvelin lähettää staattisia tiedostoja? Palvelimesi pitää tukea tätä.';
+$lang['renderer_xhtml'] = 'Renderöinti, jota käytetään wikin pääasialliseen (xhtml) tulostukseen';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (liitännäinen)';
+$lang['rememberme'] = 'Salli pysyvät kirjautumis-cookiet (muista minut)';
+$lang['rss_type'] = 'XML-syötteen tyyppi';
+$lang['rss_linkto'] = 'XML-syöte kytkeytyy';
+$lang['rss_content'] = 'Mitä XML-syöte näyttää?';
+$lang['rss_update'] = 'XML-syötteen päivitystahti (sek)';
+$lang['recent_days'] = 'Montako edellistä muutosta säilytetään (päiviä)';
+$lang['rss_show_summary'] = 'XML-syöte näyttää yhteenvedon otsikossa';
+$lang['target____wiki'] = 'Kohdeikkuna sisäisissä linkeissä';
+$lang['target____interwiki'] = 'Kohdeikkuna interwiki-linkeissä';
+$lang['target____extern'] = 'Kohdeikkuna ulkoisissa linkeissä';
+$lang['target____media'] = 'Kohdeikkuna media-linkeissä';
+$lang['target____windows'] = 'Kohdeikkuna Windows-linkeissä';
+$lang['proxy____host'] = 'Proxy-palvelimen nimi';
+$lang['proxy____port'] = 'Proxy portti';
+$lang['proxy____user'] = 'Proxy käyttäjän nimi';
+$lang['proxy____pass'] = 'Proxy salasana';
+$lang['proxy____ssl'] = 'Käytä ssl-yhteyttä kytkeytyäksesi proxy-palvelimeen';
+$lang['proxy____except'] = 'Säännönmukainen lause, URLiin, jolle proxy ohitetaan.';
+$lang['safemodehack'] = 'Käytä safemode kiertoa';
+$lang['ftp____host'] = 'FTP-palvelin safemode kiertoa varten';
+$lang['ftp____port'] = 'FTP-portti safemode kiertoa varten';
+$lang['ftp____user'] = 'FTP-käyttäjä safemode kiertoa varten';
+$lang['ftp____pass'] = 'FTP-salasana safemode kiertoa varten';
+$lang['ftp____root'] = 'FTP-juurihakemisto safemode kiertoa varten';
+$lang['license_o_'] = 'ei mitään valittuna';
+$lang['typography_o_0'] = 'ei mitään';
+$lang['typography_o_1'] = 'ilman yksinkertaisia lainausmerkkejä';
+$lang['typography_o_2'] = 'myös yksinkertaiset lainausmerkit (ei aina toimi)';
+$lang['userewrite_o_0'] = 'ei mitään';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWikin sisäinen';
+$lang['deaccent_o_0'] = 'pois';
+$lang['deaccent_o_1'] = 'Poista aksenttimerkit';
+$lang['deaccent_o_2'] = 'translitteroi';
+$lang['gdlib_o_0'] = 'GD Lib ei ole saatavilla';
+$lang['gdlib_o_1'] = 'Versio 1.x';
+$lang['gdlib_o_2'] = 'Automaattitunnistus';
+$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';
+$lang['rss_content_o_abstract'] = 'Yhteenveto';
+$lang['rss_content_o_diff'] = 'Yhdistetty erot';
+$lang['rss_content_o_htmldiff'] = 'HTML-muotoiltu eroavuuslista';
+$lang['rss_content_o_html'] = 'Täysi HTML-sivu';
+$lang['rss_linkto_o_diff'] = 'erot-näkymä';
+$lang['rss_linkto_o_page'] = 'muutettu sivu';
+$lang['rss_linkto_o_rev'] = 'versiolista';
+$lang['rss_linkto_o_current'] = 'nykyinen sivu';
+$lang['compression_o_0'] = 'ei mitään';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'älä käytä';
+$lang['xsendfile_o_1'] = 'Oma lighttpd otsikko (ennen 1.5 julkaisua)';
+$lang['xsendfile_o_2'] = 'Standardi X-sendfile header';
+$lang['xsendfile_o_3'] = 'Oma Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Kirjautumisnimi';
+$lang['showuseras_o_username'] = 'Käyttäjän koko nimi';
+$lang['showuseras_o_email'] = 'Käyttäjän sähköpostiosoite (sumennettu mailguard-asetusten mukaisesti)';
+$lang['showuseras_o_email_link'] = 'Käyttäjän sähköpostiosoite mailto: linkkinä';
+$lang['useheading_o_0'] = 'Ei koskaan';
+$lang['useheading_o_navigation'] = 'Vain Navigointi';
+$lang['useheading_o_content'] = 'Vain Wiki-sisältö';
+$lang['useheading_o_1'] = 'Aina';
+$lang['readdircache'] = 'Maksimiaika readdir cachelle (sek)';
diff --git a/lib/plugins/config/lang/fr/intro.txt b/lib/plugins/config/lang/fr/intro.txt
new file mode 100644
index 000000000..2a59b34d1
--- /dev/null
+++ b/lib/plugins/config/lang/fr/intro.txt
@@ -0,0 +1,9 @@
+====== Gestionnaire de configuration ======
+
+Utilisez cette page pour contrôler les paramètres de votre installation de DokuWiki. Pour de l'aide sur chaque paramètre, reportez vous à [[doku>fr:config]]. Pour d'autres détails concernant ce module, reportez vous à [[doku>fr:plugin:config]].
+
+Les paramètres affichés sur un fond rouge sont protégés et ne peuvent être modifiés avec ce module. Les paramètres affichés sur un fond bleu sont les valeurs par défaut et les valeurs affectées à votre installation sont affichées sur un fond blanc. Les paramètres bleus et blancs peuvent être modifiés.
+
+N'oubliez pas d'utiliser le bouton **Enregistrer** avant de quitter cette page, sinon vos modifications seront perdues.
+
+
diff --git a/lib/plugins/config/lang/fr/lang.php b/lib/plugins/config/lang/fr/lang.php
new file mode 100644
index 000000000..8dcd21032
--- /dev/null
+++ b/lib/plugins/config/lang/fr/lang.php
@@ -0,0 +1,201 @@
+<?php
+/**
+ * french language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Guy Brand <gb@unistra.fr>
+ * @author Delassaux Julien <julien@delassaux.fr>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['menu'] = 'Paramètres de configuration';
+$lang['error'] = 'Paramètres non modifiés en raison d\'une valeur non valide, vérifiez vos réglages et réessayez. <br />Les valeurs erronées sont entourées d\'une bordure rouge.';
+$lang['updated'] = 'Paramètres mis à jour avec succès.';
+$lang['nochoice'] = '(aucun autre choix possible)';
+$lang['locked'] = 'Le fichier des paramètres ne peut être modifié, si ceci n\'est pas intentionnel, <br /> vérifiez que le nom et les droits du fichier sont corrects.';
+$lang['danger'] = 'Danger : Modifier cette option pourrait rendre inaccessible votre wiki et son menu de configuration.';
+$lang['warning'] = 'Attention : Modifier cette option pourrait engendrer un comportement indésirable.';
+$lang['security'] = 'Avertissement de sécurité : Modifier cette option pourrait induire un risque de sécurité.';
+$lang['_configuration_manager'] = 'Gestionnaire de configuration';
+$lang['_header_dokuwiki'] = 'Paramètres de DokuWiki';
+$lang['_header_plugin'] = 'Paramètres des modules externes';
+$lang['_header_template'] = 'Paramètres des modèles';
+$lang['_header_undefined'] = 'Paramètres indéfinis';
+$lang['_basic'] = 'Paramètres de base';
+$lang['_display'] = 'Paramètres d\'affichage';
+$lang['_authentication'] = 'Paramètres d\'authentification';
+$lang['_anti_spam'] = 'Paramètres anti-spam';
+$lang['_editing'] = 'Paramètres d\'édition';
+$lang['_links'] = 'Paramètres des liens';
+$lang['_media'] = 'Paramètres média';
+$lang['_advanced'] = 'Paramètres avancés';
+$lang['_network'] = 'Paramètres réseaux';
+$lang['_plugin_sufix'] = 'Paramètres de module';
+$lang['_template_sufix'] = 'Paramètres de modèle';
+$lang['_msg_setting_undefined'] = 'Pas de métadonnée de paramètres.';
+$lang['_msg_setting_no_class'] = 'Pas de classe de paramètres.';
+$lang['_msg_setting_no_default'] = 'Pas de valeur par défaut.';
+$lang['fmode'] = 'Mode de création des fichiers';
+$lang['dmode'] = 'Mode de création des répertoires';
+$lang['lang'] = 'Langue';
+$lang['basedir'] = 'Répertoire de base (ex. : <code>/dokuwiki/</code>). Laisser vide pour une détection automatique.';
+$lang['baseurl'] = 'URL de base. Laisser vide pour une détection automatique.';
+$lang['savedir'] = 'Répertoire de stockage';
+$lang['cookiedir'] = 'Chemin des cookies. Laissez vide pour utiliser l\'URL de base.';
+$lang['start'] = 'Nom de la page d\'accueil';
+$lang['title'] = 'Titre du wiki';
+$lang['template'] = 'Modèle';
+$lang['license'] = 'Sous quelle licence doit être placé le contenu ?';
+$lang['fullpath'] = 'Utiliser le chemin complet dans le pied de page';
+$lang['recent'] = 'Nombre de derniers changements à afficher';
+$lang['breadcrumbs'] = 'Nombre de traces à afficher';
+$lang['youarehere'] = 'Traces hiérarchiques';
+$lang['typography'] = 'Effectuer des améliorations typographiques';
+$lang['htmlok'] = 'Permettre HTML dans les pages';
+$lang['phpok'] = 'Permettre PHP dans les pages';
+$lang['dformat'] = 'Format de date (cf. fonction <a href="http://fr.php.net/strftime">strftime</a> de PHP)';
+$lang['signature'] = 'Signature';
+$lang['toptoclevel'] = 'Niveau le plus haut à afficher dans la table des matières';
+$lang['tocminheads'] = 'Nombre minimum de titres pour qu\'une table des matières soit construite';
+$lang['maxtoclevel'] = 'Niveau maximum pour figurer dans la table des matières';
+$lang['maxseclevel'] = 'Niveau maximum pour modifier des sections';
+$lang['camelcase'] = 'Utiliser CamelCase pour les liens';
+$lang['deaccent'] = 'Retirer les accents dans les noms de pages';
+$lang['useheading'] = 'Utiliser le titre de premier niveau';
+$lang['refcheck'] = 'Vérifier les références de média';
+$lang['refshow'] = 'Nombre de références de média à montrer';
+$lang['allowdebug'] = 'Debug (<strong>Ne l\'activez que si vous en avez besoin !</strong>)';
+$lang['mediarevisions'] = 'Activer les révisions (gestion de versions) des médias';
+$lang['usewordblock'] = 'Bloquer le spam selon les mots utilisés';
+$lang['indexdelay'] = 'Délai avant l\'indexation (en secondes)';
+$lang['relnofollow'] = 'Utiliser rel="nofollow" sur les liens extérieurs';
+$lang['mailguard'] = 'Brouiller les adresses de courriel';
+$lang['iexssprotect'] = 'Vérifier la présence de code JavaScript ou HTML malveillant dans les fichiers envoyés';
+$lang['showuseras'] = 'Qu\'afficher en montrant les utilisateurs qui ont récemment modifié la page';
+$lang['useacl'] = 'Utiliser les listes de contrôle d\'accès (ACL)';
+$lang['autopasswd'] = 'Auto-générer les mots de passe';
+$lang['authtype'] = 'Mécanisme d\'authentification';
+$lang['passcrypt'] = 'Méthode de chiffrement des mots de passe';
+$lang['defaultgroup'] = 'Groupe par défaut';
+$lang['superuser'] = 'Superuser - groupe, utilisateur ou liste séparée par des virgules user1,@group1,user2 ayant un accès complet à toutes les pages quelque soit le paramétrage des ACL';
+$lang['manager'] = 'Manager - groupe, utilisateur ou liste séparée par des virgules user1,@group1,user2 ayant accès à certaines fonctions de gestion';
+$lang['profileconfirm'] = 'Confirmer par mot de passe les modifications de profil';
+$lang['disableactions'] = 'Actions à désactiver dans DokuWiki';
+$lang['disableactions_check'] = 'Vérifier';
+$lang['disableactions_subscription'] = 'Abonnement aux pages';
+$lang['disableactions_wikicode'] = 'Afficher le texte source';
+$lang['disableactions_other'] = 'Autres actions (séparées par des virgules)';
+$lang['sneaky_index'] = 'Par défaut, DokuWiki affichera toutes les catégories dans la vue par index. Activer cette option permet de cacher celles pour lesquelles l\'utilisateur n\'a pas la permission de lecture. Il peut en résulter le masquage de sous-catégories accessibles. Ceci peut rendre l\'index inutilisable avec certaines ACL.';
+$lang['auth_security_timeout'] = 'Délai d\'expiration de sécurité (secondes)';
+$lang['securecookie'] = 'Les cookies mis via HTTPS doivent-ils n\'être envoyé par le navigateur que via HTTPS ? Ne désactivez cette option que si la connexion à votre wiki est sécurisée avec SSL mais que la navigation sur le wiki n\'est pas sécurisée.';
+$lang['xmlrpc'] = 'Activer l\'interface XML-RPC.';
+$lang['xmlrpcuser'] = 'Restreindre l\'accès à XML-RPC aux groupes et utilisateurs indiqués ici. Laisser vide afin que tout le monde y ait accès.';
+$lang['updatecheck'] = 'Vérifier les mises à jour ? DokuWiki doit pouvoir contacter update.dokuwiki.org.';
+$lang['userewrite'] = 'URL esthétiques';
+$lang['useslash'] = 'Utiliser « / » comme séparateur de catégorie dans les URL';
+$lang['usedraft'] = 'Enregistrer automatiquement un brouillon pendant l\'édition';
+$lang['sepchar'] = 'Séparateur de mots dans les noms de page';
+$lang['canonical'] = 'Utiliser des URL canoniques';
+$lang['fnencode'] = 'Méthode pour l\'encodage des fichiers non-ASCII';
+$lang['autoplural'] = 'Rechercher les formes plurielles dans les liens';
+$lang['compression'] = 'Méthode de compression pour les fichiers dans attic';
+$lang['cachetime'] = 'Âge maximum d\'un fichier en cache (en secondes)';
+$lang['locktime'] = 'Âge maximum des fichiers verrous (en secondes)';
+$lang['fetchsize'] = 'Taille maximale (en octets) du fichier que fetch.php peut télécharger';
+$lang['notify'] = 'Notifier les modifications à cette adresse de courriel';
+$lang['registernotify'] = 'Envoyer un courriel annonçant les nouveaux utilisateurs enregistrés à cette adresse';
+$lang['mailfrom'] = 'Expéditeur des notifications par courriel du wiki';
+$lang['mailprefix'] = 'Préfixe à utiliser dans les objets des courriels automatiques';
+$lang['gzip_output'] = 'Utiliser Content-Encoding gzip pour XHTML';
+$lang['gdlib'] = 'Version de GD Lib';
+$lang['im_convert'] = 'Chemin vers l\'outil de conversion d\'ImageMagick';
+$lang['jpg_quality'] = 'Qualité de la compression JPEG (0-100)';
+$lang['subscribers'] = 'Activer l\'abonnement aux pages';
+$lang['subscribe_time'] = 'Délai après lequel les listes d\'abonnement et résumés sont envoyés (en secondes). Devrait être plus petit que le délai précisé dans recent_days.';
+$lang['compress'] = 'Compresser CSS et JavaScript';
+$lang['cssdatauri'] = 'Taille maximale en octets pour inclure dans les feuilles de styles CSS, les images qui y sont référencées. Cette technique minimise les requêtes HTTP. Pour IE, ceci ne fonctionne qu\'à partir de la version 8 ! Valeurs correctes entre <code>400</code> et <code>600</code>. <code>0</code> pour désactiver.';
+$lang['hidepages'] = 'Cacher les pages correspondant à (expression régulière)';
+$lang['send404'] = 'Renvoyer "HTTP 404/Page Non Trouvée" pour les pages introuvables';
+$lang['sitemap'] = 'Fréquence de génération une carte Google du site (en jours)';
+$lang['broken_iua'] = 'La fonction ignore_user_abort est-elle opérationnelle sur votre système ? Ceci peut empêcher le fonctionnement de l\'index de recherche. IIS+PHP/
+CGI dysfonctionne. Voir le <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">bug 852</a> pour plus d\'info.';
+$lang['xsendfile'] = 'Utiliser l\'en-tête X-Sendfile pour permettre au serveur Web de délivrer des fichiers statiques ? Votre serveur Web doit supporter cette fonctionnalité.';
+$lang['renderer_xhtml'] = 'Moteur de rendu du format de sortie principal (XHTML)';
+$lang['renderer__core'] = '%s (cœur de dokuwiki)';
+$lang['renderer__plugin'] = '%s (module externe)';
+$lang['rememberme'] = 'Permettre de conserver de manière permanente les cookies de connexion (mémoriser)';
+$lang['rss_type'] = 'Type de flux RSS';
+$lang['rss_linkto'] = 'Lien du flux RSS vers';
+$lang['rss_content'] = 'Quel contenu afficher dans le flux RSS ?';
+$lang['rss_update'] = 'Fréquence de mise à jour du flux RSS (en secondes)';
+$lang['recent_days'] = 'Signaler les pages modifiées depuis (en jours)';
+$lang['rss_show_summary'] = 'Le flux XML affiche le résumé dans le titre';
+$lang['target____wiki'] = 'Cible pour liens internes';
+$lang['target____interwiki'] = 'Cible pour liens interwiki';
+$lang['target____extern'] = 'Cible pour liens externes';
+$lang['target____media'] = 'Cible pour liens média';
+$lang['target____windows'] = 'Cible pour liens vers partages Windows';
+$lang['proxy____host'] = 'Proxy - Serveur hôte';
+$lang['proxy____port'] = 'Proxy - Numéro de port';
+$lang['proxy____user'] = 'Proxy - Identifiant';
+$lang['proxy____pass'] = 'Proxy - Mot de passe';
+$lang['proxy____ssl'] = 'Proxy - Utilisation de SSL';
+$lang['proxy____except'] = 'Expression régulière de test des URLs pour lesquelles le proxy ne devrait pas être utilisé.';
+$lang['safemodehack'] = 'Activer l\'option Mode sans échec';
+$lang['ftp____host'] = 'FTP - Serveur hôte pour Mode sans échec';
+$lang['ftp____port'] = 'FTP - Numéro de port pour Mode sans échec';
+$lang['ftp____user'] = 'FTP - Identifiant pour Mode sans échec';
+$lang['ftp____pass'] = 'FTP - Mot de passe pour Mode sans échec';
+$lang['ftp____root'] = 'FTP - Répertoire racine pour Mode sans échec';
+$lang['license_o_'] = 'Aucune choisie';
+$lang['typography_o_0'] = 'aucun';
+$lang['typography_o_1'] = 'guillemets uniquement';
+$lang['typography_o_2'] = 'tout signe typographique (peut ne pas fonctionner)';
+$lang['userewrite_o_0'] = 'aucun';
+$lang['userewrite_o_1'] = 'Fichier .htaccess';
+$lang['userewrite_o_2'] = 'Interne à DokuWiki';
+$lang['deaccent_o_0'] = 'off';
+$lang['deaccent_o_1'] = 'supprimer les accents';
+$lang['deaccent_o_2'] = 'convertir en roman';
+$lang['gdlib_o_0'] = 'Librairie GD non disponible';
+$lang['gdlib_o_1'] = 'version 1.x';
+$lang['gdlib_o_2'] = 'auto-détectée';
+$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';
+$lang['rss_content_o_abstract'] = 'Résumé';
+$lang['rss_content_o_diff'] = 'Diff. unifié';
+$lang['rss_content_o_htmldiff'] = 'Diff. formaté en table HTML';
+$lang['rss_content_o_html'] = 'page complète au format HTML';
+$lang['rss_linkto_o_diff'] = 'liste des différences';
+$lang['rss_linkto_o_page'] = 'page révisée';
+$lang['rss_linkto_o_rev'] = 'liste des révisions';
+$lang['rss_linkto_o_current'] = 'page actuelle';
+$lang['compression_o_0'] = 'aucune';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ne pas utiliser';
+$lang['xsendfile_o_1'] = 'Entête propriétaire lighttpd (avant la version 1.5)';
+$lang['xsendfile_o_2'] = 'Entête standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'En-tête propriétaire Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Identifiant de l\'utilisateur';
+$lang['showuseras_o_username'] = 'Nom de l\'utilisateur';
+$lang['showuseras_o_email'] = 'Courriel de l\'utilisateur (brouillé suivant les paramètres de brouillage sélectionnés)';
+$lang['showuseras_o_email_link'] = 'Courriel de l\'utilisateur en tant que lien mailto:';
+$lang['useheading_o_0'] = 'Jamais';
+$lang['useheading_o_navigation'] = 'Navigation seulement';
+$lang['useheading_o_content'] = 'Contenu du wiki seulement';
+$lang['useheading_o_1'] = 'Toujours';
+$lang['readdircache'] = 'Durée de vie maximale du cache pour readdir (sec)';
diff --git a/lib/plugins/config/lang/gl/intro.txt b/lib/plugins/config/lang/gl/intro.txt
new file mode 100644
index 000000000..cafe28e13
--- /dev/null
+++ b/lib/plugins/config/lang/gl/intro.txt
@@ -0,0 +1,7 @@
+====== Xestor de Configuración ======
+
+Usa esta páxina para controlares a configuración da túa instalación do Dokuwiki. Para atopares axuda verbo de cada opción da configuración vai a [[doku>config]]. Para obteres pormenores desta extensión bota un ollo a [[doku>plugin:config]].
+
+As opcións que amosan un fondo de cor vermella clara están protexidas e non poden ser alteradas con esta extensión. As opcións que amosan un fondo de cor azul son valores predeterminados e as opcións que teñen fondo branco foron configuradas de xeito local para esta instalación en concreto. Ámbalas dúas, as opcións azuis e brancas, poden ser alteradas.
+
+Lembra premer no boton **GARDAR** denantes de saíres desta páxina ou, en caso contrario, os teus trocos perderanse.
diff --git a/lib/plugins/config/lang/gl/lang.php b/lib/plugins/config/lang/gl/lang.php
new file mode 100644
index 000000000..da40b44e6
--- /dev/null
+++ b/lib/plugins/config/lang/gl/lang.php
@@ -0,0 +1,188 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['menu'] = 'Opcións de Configuración';
+$lang['error'] = 'Configuración non actualizada debido a un valor inválido, por favor revisa os teus trocos e volta envialos de novo.
+<br />O(s) valor(es) incorrecto(s) amosanse cinguidos por un borde vermello.';
+$lang['updated'] = 'Configuración actualizada correctamente.';
+$lang['nochoice'] = '(non hai outras escollas dispoñibles)';
+$lang['locked'] = 'Non se puido actualizar o arquivo de configuración, se non ocorre como debería ser, <br />
+asegúrate de que o nome do arquivo de configuración local e os permisos son correctos.';
+$lang['danger'] = 'Perigo: mudando esta opción podes facer inaccesíbeis o teu wiki e máis o menú de configuración.';
+$lang['warning'] = 'Ollo: mudando esta opción poden aparecer comportamentos do aplicativo non agardados.';
+$lang['security'] = 'Aviso de seguranza: mudando esta opción poden aparecer riscos de seguranza.';
+$lang['_configuration_manager'] = 'Xestor de Configuración';
+$lang['_header_dokuwiki'] = 'Configuración do DokuWiki';
+$lang['_header_plugin'] = 'Configuración de Extensións';
+$lang['_header_template'] = 'Configuración de Sobreplanta';
+$lang['_header_undefined'] = 'Configuración Indefinida';
+$lang['_basic'] = 'Configuración Básica';
+$lang['_display'] = 'Configuración de Visualización';
+$lang['_authentication'] = 'Configuración de Autenticación';
+$lang['_anti_spam'] = 'Configuración de Anti-Correo-lixo';
+$lang['_editing'] = 'Configuración de Edición';
+$lang['_links'] = 'Configuración de Ligazóns';
+$lang['_media'] = 'Configuración de Media';
+$lang['_advanced'] = 'Configuración Avanzada';
+$lang['_network'] = 'Configuración de Rede';
+$lang['_plugin_sufix'] = 'Configuración de Extensións';
+$lang['_template_sufix'] = 'Configuración de Sobreplanta';
+$lang['_msg_setting_undefined'] = 'Non hai configuración de metadatos.';
+$lang['_msg_setting_no_class'] = 'Non hai configuración de clase.';
+$lang['_msg_setting_no_default'] = 'Non hai valor predeterminado.';
+$lang['fmode'] = 'Modo de creación de arquivos';
+$lang['dmode'] = 'Modo de creación de directorios';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Directorio base';
+$lang['baseurl'] = 'URL base';
+$lang['savedir'] = 'Directorio no que se gardarán os datos';
+$lang['cookiedir'] = 'Ruta das cookies. Deixar en blanco para usar a url de base.';
+$lang['start'] = 'Nome da páxina inicial';
+$lang['title'] = 'Título do Wiki';
+$lang['template'] = 'Sobreplanta';
+$lang['license'] = 'Baixo de que licenza será ceibado o teu contido?';
+$lang['fullpath'] = 'Amosar a ruta completa das páxinas no pé das mesmas';
+$lang['recent'] = 'Trocos recentes';
+$lang['breadcrumbs'] = 'Número de niveis da estrutura de navegación';
+$lang['youarehere'] = 'Niveis xerárquicos da estrutura de navegación';
+$lang['typography'] = 'Facer substitucións tipográficas';
+$lang['htmlok'] = 'Permitir a inserción de HTML';
+$lang['phpok'] = 'Permitir a inserción de PHP';
+$lang['dformat'] = 'Formato de Data (bótalle un ollo á función <a href="http://www.php.net/strftime">strftime</a> do PHP)';
+$lang['signature'] = 'Sinatura';
+$lang['toptoclevel'] = 'Nivel superior para a táboa de contidos';
+$lang['tocminheads'] = 'Cantidade mínima de liñas de cabeceira que determinará se a TDC vai ser xerada';
+$lang['maxtoclevel'] = 'Nivel máximo para a táboa de contidos';
+$lang['maxseclevel'] = 'Nivel máximo de edición da sección';
+$lang['camelcase'] = 'Utilizar CamelCase para as ligazóns';
+$lang['deaccent'] = 'Limpar nomes de páxina';
+$lang['useheading'] = 'Utilizar a primeira cabeceira para os nomes de páxina';
+$lang['refcheck'] = 'Comprobar a referencia media';
+$lang['refshow'] = 'Número de referencias media a amosar';
+$lang['allowdebug'] = 'Permitir o depurado <b>desactívao se non o precisas!</b>';
+$lang['mediarevisions'] = 'Habilitar revisións dos arquivos-media?';
+$lang['usewordblock'] = 'Bloquear correo-lixo segundo unha lista de verbas';
+$lang['indexdelay'] = 'Retardo denantes de indexar (seg)';
+$lang['relnofollow'] = 'Utilizar rel="nofollow" nas ligazóns externas';
+$lang['mailguard'] = 'Ofuscar enderezos de correo-e';
+$lang['iexssprotect'] = 'Comprobar arquivos subidos na procura de posíbel código JavaScript ou HTML malicioso';
+$lang['showuseras'] = 'Que amosar cando se informe do usuario que fixo a última modificación dunha páxina';
+$lang['useacl'] = 'Utilizar lista de control de acceso';
+$lang['autopasswd'] = 'Xerar contrasinais automaticamente';
+$lang['authtype'] = 'Backend de autenticación';
+$lang['passcrypt'] = 'Método de encriptado do contrasinal';
+$lang['defaultgroup'] = 'Grupo por defecto';
+$lang['superuser'] = 'Super-usuario - un grupo ou usuario con acceso completo a todas as páxinas e funcións independentemente da configuración da ACL';
+$lang['manager'] = 'Xestor - un grupo ou usuario con acceso a certas funcións de xestión';
+$lang['profileconfirm'] = 'Confirmar trocos de perfil mediante contrasinal';
+$lang['disableactions'] = 'Desactivar accións do DokuWiki';
+$lang['disableactions_check'] = 'Comprobar';
+$lang['disableactions_subscription'] = 'Subscribir/Desubscribir';
+$lang['disableactions_wikicode'] = 'Ver fonte/Exportar Datos Raw';
+$lang['disableactions_other'] = 'Outras accións (separadas por comas)';
+$lang['sneaky_index'] = 'O DokuWiki amosará por defecto todos os nomes de espazo na vista de índice. Se activas isto agocharanse aqueles onde o usuario non teña permisos de lectura.';
+$lang['auth_security_timeout'] = 'Tempo Límite de Seguridade de Autenticación (segundos)';
+$lang['securecookie'] = 'Deben enviarse só vía HTTPS polo navegador as cookies configuradas vía HTTPS? Desactiva esta opción cando só o inicio de sesión do teu wiki estea asegurado con SSL pero a navegación do mesmo se faga de xeito inseguro.';
+$lang['xmlrpc'] = 'Activar/Desactivar interface XML-RPC';
+$lang['xmlrpcuser'] = 'Restrinxir o acceso mediante XML-RPC á lista separada por comas dos grupos e/ou usuarios proporcionados aquí. Déixao baleiro para darlle acceso a todas as persoas.';
+$lang['updatecheck'] = 'Comprobar se hai actualizacións e avisos de seguridade? O DokuWiki precisa contactar con update.dokuwiki.org para executar esta característica.';
+$lang['userewrite'] = 'Utilizar URLs amigábeis';
+$lang['useslash'] = 'Utilizar a barra inclinada (/) como separador de nome de espazo nos URLs';
+$lang['usedraft'] = 'Gardar un borrador automaticamente no tempo da edición';
+$lang['sepchar'] = 'Verba separadora do nome de páxina';
+$lang['canonical'] = 'Utilizar URLs completamente canónicos';
+$lang['fnencode'] = 'Método para codificar os nomes de arquivo non-ASCII.';
+$lang['autoplural'] = 'Comprobar formas plurais nas ligazóns';
+$lang['compression'] = 'Método de compresión para arquivos attic';
+$lang['cachetime'] = 'Tempo máximo para a caché (seg.)';
+$lang['locktime'] = 'Tempo máximo para o bloqueo de arquivos (seg.)';
+$lang['fetchsize'] = 'Tamaño máximo (en bytes) que pode descargar fetch.php dende fontes externas';
+$lang['notify'] = 'Enviar notificacións de trocos a este enderezo de correo-e';
+$lang['registernotify'] = 'Enviar información de novos usuarios rexistrados a este enderezo de correo-e';
+$lang['mailfrom'] = 'Enderezo de correo-e a usar para as mensaxes automáticas';
+$lang['mailprefix'] = 'Prefixo de asunto de correo-e para as mensaxes automáticas';
+$lang['gzip_output'] = 'Utilizar Contido-Codificación gzip para o xhtml';
+$lang['gdlib'] = 'Versión da Libraría GD';
+$lang['im_convert'] = 'Ruta deica a ferramenta de conversión ImageMagick';
+$lang['jpg_quality'] = 'Calidade de compresión dos JPG (0-100)';
+$lang['subscribers'] = 'Activar posibilidade de subscrición á páxina';
+$lang['subscribe_time'] = 'Tempo despois do cal se enviarán os resumos e listas de subscrición (seg.): isto debe ser inferior ao tempo especificado en recent_days.';
+$lang['compress'] = 'Saída compacta de CSS e Javascript';
+$lang['hidepages'] = 'Agochar páxinas que coincidan (expresións regulares)';
+$lang['send404'] = 'Enviar "HTTP 404/Páxina non atopada" para as páxinas inexistentes';
+$lang['sitemap'] = 'Xerar mapa do sitio co Google (días)';
+$lang['broken_iua'] = 'Rachou a función ignore_user_abort no teu sistema? Isto podería causar que o índice de procura non funcione. Coñécese que o IIS+PHP/CGI ráchaa. Bótalle un ollo ao <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> para obter máis información.';
+$lang['xsendfile'] = 'Empregar a cabeceira X-Sendfile para que o servidor web envie arquivos estáticos? O teu servidor web precisa soportar isto.';
+$lang['renderer_xhtml'] = 'Intérprete a empregar para a saída principal (XHTML) do Wiki';
+$lang['renderer__core'] = '%s (núcleo do Dokuwiki)';
+$lang['renderer__plugin'] = '%s (extensión)';
+$lang['rememberme'] = 'Permitir cookies permanentes de inicio de sesión (lembrarme)';
+$lang['rss_type'] = 'Tipo de corrente RSS XML';
+$lang['rss_linkto'] = 'A corrente XML liga para';
+$lang['rss_content'] = 'Que queres amosar nos elementos da corrente XML?';
+$lang['rss_update'] = 'Intervalo de actualización da corrente XML (seg.)';
+$lang['recent_days'] = 'Número de trocos recentes a manter (días)';
+$lang['rss_show_summary'] = 'Amosar sumario no título da corrente XML';
+$lang['target____wiki'] = 'Fiestra de destino para as ligazóns internas';
+$lang['target____interwiki'] = 'Fiestra de destino para as ligazóns interwiki';
+$lang['target____extern'] = 'Fiestra de destino para as ligazóns externas';
+$lang['target____media'] = 'Fiestra de destino para as ligazóns de media';
+$lang['target____windows'] = 'Fiestra de destino para as ligazóns de fiestras';
+$lang['proxy____host'] = 'Nome do servidor Proxy';
+$lang['proxy____port'] = 'Porto do Proxy';
+$lang['proxy____user'] = 'Nome de usuario do Proxy';
+$lang['proxy____pass'] = 'Contrasinal do Proxy';
+$lang['proxy____ssl'] = 'Utilizar ssl para conectar ao Proxy';
+$lang['proxy____except'] = 'Expresión regular para atopar URLs que deban ser omitidas polo Proxy.';
+$lang['safemodehack'] = 'Activar hack de modo seguro (safemode)';
+$lang['ftp____host'] = 'Servidor FTP para o hack de modo seguro (safemode)';
+$lang['ftp____port'] = 'Porto FTP para o hack de modo seguro(safemode)';
+$lang['ftp____user'] = 'Nome de usuario FTP para o hack de modo seguro(safemode)';
+$lang['ftp____pass'] = 'Contrasinal FTP para o hack de modo seguro(safemode)';
+$lang['ftp____root'] = 'Directorio raigaña do FTP para o hack de modo seguro(safemode)';
+$lang['license_o_'] = 'Non se escolleu nada';
+$lang['typography_o_0'] = 'ningunha';
+$lang['typography_o_1'] = 'Só dobres aspas';
+$lang['typography_o_2'] = 'Todas as aspas (pode que non funcione sempre)';
+$lang['userewrite_o_0'] = 'ningún';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Interno do DokuWiki';
+$lang['deaccent_o_0'] = 'desconectado';
+$lang['deaccent_o_1'] = 'Eliminar acentos';
+$lang['deaccent_o_2'] = 'romanizar';
+$lang['gdlib_o_0'] = 'Libraría GD non dispoñíbel';
+$lang['gdlib_o_1'] = 'Versión 1.x';
+$lang['gdlib_o_2'] = 'Detección automática';
+$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';
+$lang['rss_content_o_abstract'] = 'Sumario';
+$lang['rss_content_o_diff'] = 'Formato Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'Táboa diff formatada en HTML';
+$lang['rss_content_o_html'] = 'Contido HTML completo da páxina';
+$lang['rss_linkto_o_diff'] = 'vista de diferenzas';
+$lang['rss_linkto_o_page'] = 'a páxina revisada';
+$lang['rss_linkto_o_rev'] = 'listaxe de revisións';
+$lang['rss_linkto_o_current'] = 'a páxina actual';
+$lang['compression_o_0'] = 'ningunha';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'non o empregues';
+$lang['xsendfile_o_1'] = 'Cabeceira lighttpd propietaria (denantes da versión 1.5)';
+$lang['xsendfile_o_2'] = 'Cabeceira X-Sendfile estándar';
+$lang['xsendfile_o_3'] = 'Cabeceira X-Accel-Redirect propia de Nginx';
+$lang['showuseras_o_loginname'] = 'Nome de inicio de sesión';
+$lang['showuseras_o_username'] = 'Nome completo do usuario';
+$lang['showuseras_o_email'] = 'Enderezo de correo-e do usuario (ofuscado segundo a configuración mailguard)';
+$lang['showuseras_o_email_link'] = 'Enderezo de correo-e do usuario como ligazón mailto:';
+$lang['useheading_o_0'] = 'Endexamais';
+$lang['useheading_o_navigation'] = 'Só Navegación';
+$lang['useheading_o_content'] = 'Só Contido do Wiki';
+$lang['useheading_o_1'] = 'Sempre';
+$lang['readdircache'] = 'Edad máxima para o directorio de caché (seg)';
diff --git a/lib/plugins/config/lang/he/intro.txt b/lib/plugins/config/lang/he/intro.txt
new file mode 100644
index 000000000..010c69018
--- /dev/null
+++ b/lib/plugins/config/lang/he/intro.txt
@@ -0,0 +1,9 @@
+====== מנהל תצורה ======
+
+ניתן להשתמש בדף זה לשליטה על הגדרות התקנת ה-Dokuwiki שלך. לעזרה בנוגע להגדרות ספציפיות ניתן לפנות אל [[doku>config]]. למידע נוסף אודות תוסף זה ניתן לפנות אל [[doku>plugin:config]].
+
+הגדרות עם רקע אדום-בהיר מוגנות ואין אפשרות לשנותן עם תוסף זה. הגדרות עם רקע כחול הן בעלות ערך ברירת המחדל והגדרות עם רקע לבן הוגדרו באופן מקומי עבור התקנה זו. ההגדרות בעלות הרקעים הכחול והלבן הן ברות שינוי.
+
+יש לזכור ללחוץ על כפתור ה**שמירה** טרם עזיבת דף זה פן יאבדו השינויים.
+
+
diff --git a/lib/plugins/config/lang/he/lang.php b/lib/plugins/config/lang/he/lang.php
new file mode 100644
index 000000000..e80a1bd7a
--- /dev/null
+++ b/lib/plugins/config/lang/he/lang.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * hebrew language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author DoK <kamberd@yahoo.com>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['menu'] = 'הגדרות תצורה';
+$lang['error'] = 'ההגדרות לא עודכנו בגלל ערך לא תקף, נא לעיין בשינויים ולשלוח שנית.
+ <br />הערכים שאינם נכונים יסומנו בגבול אדום.';
+$lang['updated'] = 'ההגדרות עודכנו בהצלחה.';
+$lang['nochoice'] = '(אין אפשרויות זמינות נוספות)';
+$lang['locked'] = 'קובץ ההגדרות אינו בר עידכון, אם הדבר אינו מכוון, <br />
+ יש לודא כי קובץ ההגדרות המקומי וההרשאות נכונים.';
+$lang['_configuration_manager'] = 'מנהל תצורה';
+$lang['_header_dokuwiki'] = 'הגדרות DokuWiki';
+$lang['_header_plugin'] = 'הגדרות תוסף';
+$lang['_header_template'] = 'הגדרות תבנית';
+$lang['_header_undefined'] = 'הגדרות שונות';
+$lang['_basic'] = 'הגדרות בסיסיות';
+$lang['_display'] = 'הגדרות תצוגה';
+$lang['_authentication'] = 'הגדרות הזדהות';
+$lang['_anti_spam'] = 'הגדרות נגד דואר זבל';
+$lang['_editing'] = 'הגדרות עריכה';
+$lang['_links'] = 'הגדרות קישורים';
+$lang['_media'] = 'הגדרות מדיה';
+$lang['_advanced'] = 'הגדרות מתקדמות';
+$lang['_network'] = 'הגדרות רשת';
+$lang['_plugin_sufix'] = 'הגדרות תוסף';
+$lang['_template_sufix'] = 'הגדרות תבנית';
+$lang['_msg_setting_undefined'] = 'אין מידע-על להגדרה.';
+$lang['_msg_setting_no_class'] = 'אין קבוצה להגדרה.';
+$lang['_msg_setting_no_default'] = 'אין ערך ברירת מחדל.';
+$lang['fmode'] = 'מצב יצירת קובץ';
+$lang['dmode'] = 'מצב יצירת ספריה';
+$lang['lang'] = 'שפה';
+$lang['basedir'] = 'ספרית בסיס';
+$lang['baseurl'] = 'כתובת URL בסיסית';
+$lang['savedir'] = 'ספריה לשמירת מידע';
+$lang['start'] = 'שם דף הפתיחה';
+$lang['title'] = 'כותרת הויקי';
+$lang['template'] = 'תבנית';
+$lang['fullpath'] = 'הצגת נתיב מלא לדפים בתחתית';
+$lang['recent'] = 'שינויים אחרונים';
+$lang['breadcrumbs'] = 'מספר עקבות להיסטוריה';
+$lang['youarehere'] = 'עקבות היררכיות להיסטוריה';
+$lang['typography'] = 'שימוש בחלופות טיפוגרפיות';
+$lang['htmlok'] = 'אישור שיבוץ HTML';
+$lang['phpok'] = 'אישור שיבוץ PHP';
+$lang['dformat'] = 'תסדיר תאריך (נא לפנות לפונקציה <a href="http://www.php.net/strftime">strftime</a> של PHP)';
+$lang['signature'] = 'חתימה';
+$lang['toptoclevel'] = 'רמה עליונה בתוכן הענינים';
+$lang['maxtoclevel'] = 'רמה מירבית בתוכן הענינים';
+$lang['maxseclevel'] = 'רמה מירבית בעריכת קטעים';
+$lang['camelcase'] = 'השתמש בראשיות גדולות לקישורים';
+$lang['deaccent'] = 'נקה שמות דפים';
+$lang['useheading'] = 'השתמש בכותרת הראשונה לשם הדף';
+$lang['refcheck'] = 'בדוק שיוך מדיה';
+$lang['refshow'] = 'מספר שיוכי המדיה שיוצגו';
+$lang['allowdebug'] = 'אפשר דיבוג <b>יש לבטל אם אין צורך!</b>';
+$lang['usewordblock'] = 'חסימת דואר זבל לפי רשימת מילים';
+$lang['indexdelay'] = 'השהיה בטרם הכנסה לאינדקס (שניות)';
+$lang['relnofollow'] = 'השתמש ב- rel="nofollow" לקישורים חיצוניים';
+$lang['mailguard'] = 'הגן על כתובות דוא"ל';
+$lang['iexssprotect'] = 'בדוק את הדפים המועלים לחשד ל-JavaScript או קוד HTML זדוני';
+$lang['useacl'] = 'השתמש ברשימות בקרת גישה';
+$lang['autopasswd'] = 'צור סיסמאות באופן אוטומטי';
+$lang['authtype'] = 'מנוע הזדהות';
+$lang['passcrypt'] = 'שיטת הצפנת סיסמאות';
+$lang['defaultgroup'] = 'קבוצת ברירת המחדל';
+$lang['superuser'] = 'משתמש-על';
+$lang['manager'] = 'מנהל - קבוצה, משתמש או רשימה מופרדת בפסיקים משתמש1, @קבוצה1, משתמש2 עם גישה לפעולות ניהול מסוימות.';
+$lang['profileconfirm'] = 'אשר שינוי פרופילים עם סיסמה';
+$lang['disableactions'] = 'בטל פעולות DokuWiki';
+$lang['disableactions_check'] = 'בדיקה';
+$lang['disableactions_subscription'] = 'הרשמה/הסרה מרשימה';
+$lang['disableactions_wikicode'] = 'הצגת המקור/יצוא גולמי';
+$lang['disableactions_other'] = 'פעולות אחרות (מופרדות בפסיק)';
+$lang['sneaky_index'] = 'כברירת מחדל, דוקוויקי יציג את כל מרחבי השמות בתצוגת תוכן הענינים. בחירה באפשרות זאת תסתיר את אלו שבהם למשתמש אין הרשאות קריאה. התוצאה עלולה להיות הסתרת תת מרחבי שמות אליהם יש למשתמש גישה. באופן זה תוכן הענינים עלול להפוך לחסר תועלת עם הגדרות ACL מסוימות';
+$lang['auth_security_timeout'] = 'מגבלת אבטח פסק הזמן להזדהות (שניות)';
+$lang['xmlrpc'] = 'לאפשר.לחסום את מנשק XML-RPC';
+$lang['updatecheck'] = 'בדיקת עידכוני אבטחה והתראות? על DokuWiki להתקשר אל update.dokuwiki.org לצורך כך.';
+$lang['userewrite'] = 'השתמש בכתובות URL יפות';
+$lang['useslash'] = 'השתמש בלוכסן להגדרת מרחבי שמות בכתובות';
+$lang['usedraft'] = 'שמור טיוטות באופן אוטומטי בעת עריכה';
+$lang['sepchar'] = 'מפריד בין מילות שם-דף';
+$lang['canonical'] = 'השתמש בכתובות URL מלאות';
+$lang['autoplural'] = 'בדוק לצורת רבים בקישורים';
+$lang['compression'] = 'אופן דחיסת קבצים ב-attic';
+$lang['cachetime'] = 'גיל מירבי לזכרון מטמון (שניות)';
+$lang['locktime'] = 'גיל מירבי לקבצי נעילה (שניות)';
+$lang['fetchsize'] = 'גודל הקובץ המירבי (bytes) ש-fetch.php יכול להוריד מבחוץ';
+$lang['notify'] = 'שלח התראות על שינויים לכתובת דוא"ל זו';
+$lang['registernotify'] = 'שלח מידע על משתמשים רשומים חדשים לכתובת דוא"ל זו';
+$lang['mailfrom'] = 'כתובת הדוא"ל לשימוש בדברי דוא"ל אוטומטיים';
+$lang['gzip_output'] = 'השתמש בקידוד תוכן של gzip עבור xhtml';
+$lang['gdlib'] = 'גרסת ספרית ה-GD';
+$lang['im_convert'] = 'נתיב לכלי ה-convert של ImageMagick';
+$lang['jpg_quality'] = 'איכות הדחיסה של JPG (0-100)';
+$lang['subscribers'] = 'התר תמיכה ברישום לדפים';
+$lang['compress'] = 'פלט קומפקטי של CSS ו-javascript';
+$lang['hidepages'] = 'הסתר דפים תואמים (ביטויים רגולריים)';
+$lang['send404'] = 'שלח "HTTP 404/Page Not Found" עבור דפים שאינם קיימים';
+$lang['sitemap'] = 'צור מפת אתר של Google (ימים)';
+$lang['broken_iua'] = 'האם הפעולה ignore_user_abort תקולה במערכת שלך? הדבר עלול להביא לתוכן חיפוש שאינו תקין. IIS+PHP/CGI ידוע כתקול. ראה את <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">באג 852</a> למידע נוסף';
+$lang['xsendfile'] = 'להשתמש בכותר X-Sendfile כדי לאפשר לשרת לספק קבצים סטטיים? על השרת שלך לתמוך באפשרות זאת.';
+$lang['renderer_xhtml'] = 'מחולל לשימוש עבור פלט הויקי העיקרי (xhtml)';
+$lang['renderer__core'] = '%s (ליבת דוקוויקי)';
+$lang['renderer__plugin'] = '%s (הרחבות)';
+$lang['rss_type'] = 'סוג פלט XML';
+$lang['rss_linkto'] = 'פלט ה-XML מקשר אל';
+$lang['rss_content'] = 'מה להציג בפרטי פלט ה-XML';
+$lang['rss_update'] = 'פלט ה-XML מתעדכן כל (שניות)';
+$lang['recent_days'] = 'כמה שינויים אחרונים לשמור (ימים)';
+$lang['rss_show_summary'] = 'פלט ה-XML מציג תקציר בכותרת';
+$lang['target____wiki'] = 'חלון יעד לקישורים פנימיים';
+$lang['target____interwiki'] = 'חלון יעד לקישורים בין מערכות ויקי';
+$lang['target____extern'] = 'חלון יעד לקישורים חיצוניים';
+$lang['target____media'] = 'חלון יעד לקישור למדיה';
+$lang['target____windows'] = 'חלון יעד לתיקיות משותפות';
+$lang['proxy____host'] = 'שם השרת המתווך';
+$lang['proxy____port'] = 'שער השרת המתווך';
+$lang['proxy____user'] = 'שם המשתמש בשרת המתווך';
+$lang['proxy____pass'] = 'סיסמת ההשרת המתווך';
+$lang['proxy____ssl'] = 'השתמש ב-ssl כדי להתחבר לשרת המתווך';
+$lang['safemodehack'] = 'אפשר שימוש בפתרון ל-safemode';
+$lang['ftp____host'] = 'שרת FTP עבור פתרון ה-safemode';
+$lang['ftp____port'] = 'שער ה-FTP עבור פתרון ה-safemode';
+$lang['ftp____user'] = 'שם המשתמש ב-FTPעבור פתרון ה-safemode';
+$lang['ftp____pass'] = 'סיסמת ה-FTP לפתרון ה-safemode';
+$lang['ftp____root'] = 'ספרית השורש ב-FTP עבור פתרון ה-safemode';
+$lang['typography_o_0'] = 'ללא';
+$lang['typography_o_1'] = 'רק גרשיים כפולים';
+$lang['typography_o_2'] = 'כל הגרשים (עלול שלא לעבוד לעיתים)';
+$lang['userewrite_o_0'] = 'ללא';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'פנימי של DokuWiki';
+$lang['deaccent_o_0'] = 'כבוי';
+$lang['deaccent_o_1'] = 'הסר ניבים';
+$lang['deaccent_o_2'] = 'הסב ללטינית';
+$lang['gdlib_o_0'] = 'ספרית ה-GD אינה זמינה';
+$lang['gdlib_o_1'] = 'גרסה 1.x';
+$lang['gdlib_o_2'] = 'זיהוי אוטומטי';
+$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';
+$lang['rss_content_o_abstract'] = 'תקציר';
+$lang['rss_content_o_diff'] = 'הבדלים מאוחדים';
+$lang['rss_content_o_htmldiff'] = 'טבלת HTML של ההבדלים';
+$lang['rss_content_o_html'] = 'מלוא תוכן דף HTML';
+$lang['rss_linkto_o_diff'] = 'תצוגת הבדלים';
+$lang['rss_linkto_o_page'] = 'הדף שהשתנה';
+$lang['rss_linkto_o_rev'] = 'גרסאות קודמות';
+$lang['rss_linkto_o_current'] = 'הדף הנוכחי';
+$lang['compression_o_0'] = 'ללא';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'אל תשתמש';
+$lang['xsendfile_o_1'] = 'כותר lighttpd קנייני (לפני גרסה 1.5)';
+$lang['xsendfile_o_2'] = 'כותר X-Sendfile רגיל';
+$lang['xsendfile_o_3'] = 'כותר Nginx X-Accel-Redirect קנייני';
+$lang['useheading_o_navigation'] = 'ניווט בלבד';
+$lang['useheading_o_1'] = 'תמיד';
diff --git a/lib/plugins/config/lang/hi/lang.php b/lib/plugins/config/lang/hi/lang.php
new file mode 100644
index 000000000..a224fdf7c
--- /dev/null
+++ b/lib/plugins/config/lang/hi/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
+$lang['sepchar'] = 'पृष्ठ का नाम शब्द प्रथक्कर';
+$lang['sitemap'] = 'गूगल का सूचना पटल नक्शा बनायें (दिन)';
+$lang['license_o_'] = 'कुछ नहीं चुना';
+$lang['typography_o_0'] = 'कुछ नहीं';
+$lang['showuseras_o_username'] = 'उपयोगकर्ता का पूर्ण नाम';
+$lang['useheading_o_0'] = 'कभी नहीं';
+$lang['useheading_o_1'] = 'हमेशा';
diff --git a/lib/plugins/config/lang/hr/lang.php b/lib/plugins/config/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/config/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/config/lang/hu/intro.txt b/lib/plugins/config/lang/hu/intro.txt
new file mode 100644
index 000000000..b6b914902
--- /dev/null
+++ b/lib/plugins/config/lang/hu/intro.txt
@@ -0,0 +1,9 @@
+====== Beállító központ ======
+
+Ezzel az oldallal finomhangolhatod a DokuWiki rendszeredet. Az egyes beállításokhoz [[doku>config|itt]] kaphatsz segítséget. A bővítmények (pluginek) beállításaihoz [[doku>plugin:config|ezt]] az oldalt látogasd meg.
+
+A világospiros hátterű beállítások védettek, ezzel a bővítménnyel nem módosíthatóak.
+
+A kék hátterű beállítások az alapértelmezett értékek, a fehér hátterűek módosítva lettek ebben a rendszerben. Mindkét hátterű beállítások módosíthatóak.
+
+Ne felejtsd a **Mentés** gombot megnyomni, mielőtt elhagyod az oldalt, különben a módosításaid elvesznek!
diff --git a/lib/plugins/config/lang/hu/lang.php b/lib/plugins/config/lang/hu/lang.php
new file mode 100644
index 000000000..f991b7c95
--- /dev/null
+++ b/lib/plugins/config/lang/hu/lang.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['menu'] = 'Beállító Központ';
+$lang['error'] = 'Helytelen érték miatt a módosítások nem mentődtek. Nézd át a módosításokat, és ments újra.
+<br />A helytelen érték(ek)et piros kerettel jelöljük.';
+$lang['updated'] = 'A módosítások sikeresen beállítva.';
+$lang['nochoice'] = '(nincs egyéb lehetőség)';
+$lang['locked'] = 'A beállításokat tartalmazó fájlt nem tudtam frissíteni.<br />
+Nézd meg, hogy a fájl neve és jogosultságai helyesen vannak-e beállítva!';
+$lang['danger'] = 'Figyelem: ezt a beállítást megváltoztatva a konfigurációs menü hozzáférhetetlenné válhat.';
+$lang['warning'] = 'Figyelmeztetés: a beállítás megváltoztatása nem kívánt viselkedést okozhat.';
+$lang['security'] = 'Biztonsági figyelmeztetés: a beállítás megváltoztatása biztonsági veszélyforrást okozhat.';
+$lang['_configuration_manager'] = 'Beállító Központ';
+$lang['_header_dokuwiki'] = 'DokuWiki beállítások';
+$lang['_header_plugin'] = 'Bővítmények beállításai';
+$lang['_header_template'] = 'Sablon beállítások';
+$lang['_header_undefined'] = 'Nem definiált értékek';
+$lang['_basic'] = 'Alap beállítások';
+$lang['_display'] = 'Megjelenítés beállításai';
+$lang['_authentication'] = 'Azonosítás beállításai';
+$lang['_anti_spam'] = 'Anti-Spam beállítások';
+$lang['_editing'] = 'Szerkesztési beállítások';
+$lang['_links'] = 'Link beállítások';
+$lang['_media'] = 'Media beállítások';
+$lang['_advanced'] = 'Haladó beállítások';
+$lang['_network'] = 'Hálózati beállítások';
+$lang['_plugin_sufix'] = 'Bővítmények beállításai';
+$lang['_template_sufix'] = 'Sablon beállítások';
+$lang['_msg_setting_undefined'] = 'Nincs beállított meta-adat.';
+$lang['_msg_setting_no_class'] = 'Nincs beállított osztály.';
+$lang['_msg_setting_no_default'] = 'Nincs alapértelmezett érték.';
+$lang['fmode'] = 'Fájl létrehozási maszk';
+$lang['dmode'] = 'Könyvtár létrehozási maszk';
+$lang['lang'] = 'Nyelv';
+$lang['basedir'] = 'Báziskönyvtár';
+$lang['baseurl'] = 'Alap URL';
+$lang['savedir'] = 'Könyvtár az adatok mentésére';
+$lang['start'] = 'Kezdőoldal neve';
+$lang['title'] = 'Wiki címe';
+$lang['template'] = 'Sablon';
+$lang['license'] = 'Milyen licenc alatt érhető el a tartalom?';
+$lang['fullpath'] = 'Az oldalak teljes útvonalának mutatása a láblécben';
+$lang['recent'] = 'Utolsó változatok száma';
+$lang['breadcrumbs'] = 'Nyomvonal elemszám';
+$lang['youarehere'] = 'Hierarchikus nyomvonal';
+$lang['typography'] = 'Legyen-e tipográfiai csere';
+$lang['htmlok'] = 'Beágyazott HTML engedélyezése';
+$lang['phpok'] = 'Beágyazott PHP engedélyezése';
+$lang['dformat'] = 'Dátum formázás (lásd a PHP <a href="http://www.php.net/strftime">strftime</a> függvényt)';
+$lang['signature'] = 'Aláírás';
+$lang['toptoclevel'] = 'A tartalomjegyzék felső szintje';
+$lang['tocminheads'] = 'Legalább ennyi címsor hatására generálódjon tartalomjegyzék';
+$lang['maxtoclevel'] = 'A tartalomjegyzék mélysége';
+$lang['maxseclevel'] = 'A szakasz-szerkesztés maximális szintje';
+$lang['camelcase'] = 'CamelCase használata hivatkozásként';
+$lang['deaccent'] = 'Oldalnevek ékezettelenítése';
+$lang['useheading'] = 'Az első fejléc legyen az oldalnév';
+$lang['refcheck'] = 'Médiafájlok hivatkozásainak ellenőrzése';
+$lang['refshow'] = 'Média-hivatkozások maximálisan mutatott szintje';
+$lang['allowdebug'] = 'Debug üzemmód <b>Kapcsold ki, hacsak biztos nem szükséges!</b>';
+$lang['usewordblock'] = 'Szólista alapú spam-szűrés';
+$lang['indexdelay'] = 'Várakozás indexelés előtt (másodperc)';
+$lang['relnofollow'] = 'rel="nofollow" beállítás használata külső hivatkozásokra';
+$lang['mailguard'] = 'Email címek olvashatatlanná tétele címgyűjtők számára';
+$lang['iexssprotect'] = 'Feltöltött fájlok ellenőrzése kártékony JavaScript vagy HTML kód elkerülésére';
+$lang['showuseras'] = 'A felhasználó melyik adatát mutassunk az utolsó változtatás adatainál?';
+$lang['useacl'] = 'Hozzáférési listák (ACL) használata';
+$lang['autopasswd'] = 'Jelszavak automatikus generálása';
+$lang['authtype'] = 'Authentikációs háttérrendszer';
+$lang['passcrypt'] = 'Jelszó titkosítási módszer';
+$lang['defaultgroup'] = 'Alapértelmezett csoport';
+$lang['superuser'] = 'Szuper-felhasználó (Wiki-gazda) - csoport vagy felhasználó, aki teljes hozzáférési joggal rendelkezik az oldalakhoz és funkciókhoz, a hozzáférési jogosultságoktól függetlenül';
+$lang['manager'] = 'Menedzser - csoport vagy felhasználó, aki bizonyos menedzsment funkciókhoz hozzáfér';
+$lang['profileconfirm'] = 'Beállítások változtatásának megerősítése jelszóval';
+$lang['disableactions'] = 'Bizonyos DokuWiki tevékenységek (action) tiltása';
+$lang['disableactions_check'] = 'Ellenőrzés';
+$lang['disableactions_subscription'] = 'Feliratkozás/Leiratkozás';
+$lang['disableactions_wikicode'] = 'Forrás megtekintése/Nyers adat exportja';
+$lang['disableactions_other'] = 'Egyéb tevékenységek (vesszővel elválasztva)';
+$lang['sneaky_index'] = 'Alapértelmezetten minden névtér látszik a DokuWiki áttekintő (index) oldalán. Ezen opció bekapcsolása után azok nem jelennek meg, melyekhez a felhasználónak nincs olvasás joga. De ezzel eltakarhatunk egyébként elérhető al-névtereket is, így bizonyos ACL beállításoknál használhatatlan indexet eredményez ez a beállítás.';
+$lang['auth_security_timeout'] = 'Authentikációs biztonsági időablak (másodperc)';
+$lang['securecookie'] = 'A böngészők a HTTPS felett beállított sütijüket csak HTTPS felett küldhetik? Kapcsoljuk ki ezt az opciót, ha csak a bejelentkezést védjük SSL-lel, a wiki tartalmának böngészése nyílt forgalommal történik.';
+$lang['xmlrpc'] = 'XML-RPC interfész engedélyezése/tiltása';
+$lang['xmlrpcuser'] = 'Korlátozza XML-RPC hozzáférést az itt megadott vesszővel elválasztott csoportok vagy felhasználók számára. Hagyja üresen, ha mindenki számára biztosítja a hozzáférést.';
+$lang['updatecheck'] = 'Frissítések és biztonsági figyelmeztetések figyelése. Ehhez a DokuWikinek kapcsolatba kell lépnie a update.dokuwiki.org-gal.';
+$lang['userewrite'] = 'Szép URL-ek használata';
+$lang['useslash'] = 'Per-jel használata névtér-elválasztóként az URL-ekben';
+$lang['usedraft'] = 'Piszkozat automatikus mentése szerkesztés alatt';
+$lang['sepchar'] = 'Szó elválasztó az oldalnevekben';
+$lang['canonical'] = 'Teljesen kanonikus URL-ek használata';
+$lang['fnencode'] = 'A nem ASCII fájlnevek dekódolási módja';
+$lang['autoplural'] = 'Többes szám ellenőrzés a hivatkozásokban (angol)';
+$lang['compression'] = 'Tömörítés használata a törölt lapokhoz';
+$lang['cachetime'] = 'A gyorsítótár maximális élettartama (másodperc)';
+$lang['locktime'] = 'Oldal-zárolás maximális időtartama (másodperc)';
+$lang['fetchsize'] = 'Maximális méret (bájtban), amit a fetch.php letölthet kívülről';
+$lang['notify'] = 'Az oldal-változásokat erre az e-mail címre küldje';
+$lang['registernotify'] = 'Értesítés egy újonnan regisztrált felhasználóról erre az e-mail címre';
+$lang['mailfrom'] = 'Az automatikusan küldött levelekben használt e-mail cím';
+$lang['mailprefix'] = 'Előtag az automatikus e-mailek tárgyában';
+$lang['gzip_output'] = 'gzip tömörítés használata xhtml-hez (Content-Encoding)';
+$lang['gdlib'] = 'GD Lib verzió';
+$lang['im_convert'] = 'Útvonal az ImageMagick csomag convert parancsához';
+$lang['jpg_quality'] = 'JPG tömörítés minősége (0-100)';
+$lang['subscribers'] = 'Oldalváltozás-listára feliratkozás engedélyezése';
+$lang['subscribe_time'] = 'Az értesítések kiküldésének késleltetése (másodperc); Érdemes kisebbet választani, mint a változások megőrzésének maximális ideje.';
+$lang['compress'] = 'CSS és JavaScript fájlok tömörítése';
+$lang['hidepages'] = 'Az itt megadott oldalak elrejtése (reguláris kifejezés)';
+$lang['send404'] = '"HTTP 404/Page Not Found" küldése nemlétező oldalak esetén';
+$lang['sitemap'] = 'Hány naponként generáljunk Google sitemap-ot?';
+$lang['broken_iua'] = 'Az ignore_user_abort függvény hibát dob a rendszereden? Ez nem működő keresési indexet eredményezhet. Az IIS+PHP/CGI összeállításról tudjuk, hogy hibát dob. Lásd a <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> oldalt a további infóért.';
+$lang['xsendfile'] = 'Használjuk az X-Sendfile fejlécet, hogy a webszerver statikus állományokat tudjon küldeni? A webszervernek is támogatnia kell ezt a funkciót.';
+$lang['renderer_xhtml'] = 'Az elsődleges (xhtml) wiki kimenet generálója';
+$lang['renderer__core'] = '%s (dokuwiki mag)';
+$lang['renderer__plugin'] = '%s (bővítmény)';
+$lang['rememberme'] = 'Állandó sütik engedélyezése (az "emlékezz rám" funkcióhoz)';
+$lang['rss_type'] = 'XML hírfolyam típus';
+$lang['rss_linkto'] = 'XML hírfolyam hivatkozás';
+$lang['rss_content'] = 'Mit mutassunk az XML hírfolyam elemekben?';
+$lang['rss_update'] = 'Hány másodpercenként frissítsük az XML hírfolyamot?';
+$lang['recent_days'] = 'Hány napig tartsuk meg a korábbi változatokat?';
+$lang['rss_show_summary'] = 'A hírfolyam címébe összefoglaló helyezése';
+$lang['target____wiki'] = 'Cél-ablak belső hivatkozásokhoz';
+$lang['target____interwiki'] = 'Cél-ablak interwiki hivatkozásokhoz';
+$lang['target____extern'] = 'Cél-ablak külső hivatkozásokhoz';
+$lang['target____media'] = 'Cél-ablak média-fájl hivatkozásokhoz';
+$lang['target____windows'] = 'Cél-ablak Windows hivatkozásokhoz';
+$lang['proxy____host'] = 'Proxy szerver neve';
+$lang['proxy____port'] = 'Proxy port';
+$lang['proxy____user'] = 'Proxy felhasználó név';
+$lang['proxy____pass'] = 'Proxy jelszó';
+$lang['proxy____ssl'] = 'SSL használata a proxyhoz csatlakozáskor';
+$lang['proxy____except'] = 'URL szabály azokra a webcímekre, amit szeretnél, hogy ne kezeljen a proxy.';
+$lang['safemodehack'] = 'A PHP safemode beállítás megkerülésének engedélyezése';
+$lang['ftp____host'] = 'FTP szerver a safemode megkerüléshez';
+$lang['ftp____port'] = 'FTP port a safemode megkerüléshez';
+$lang['ftp____user'] = 'FTP felhasználó név a safemode megkerüléshez';
+$lang['ftp____pass'] = 'FTP jelszó a safemode megkerüléshez';
+$lang['ftp____root'] = 'FTP gyökérkönyvtár a safemode megkerüléshez';
+$lang['license_o_'] = 'Nincs kiválasztva';
+$lang['typography_o_0'] = 'nem';
+$lang['typography_o_1'] = 'Csak a dupla idézőjelet';
+$lang['typography_o_2'] = 'Minden idézőjelet (előfordulhat, hogy nem mindig működik)';
+$lang['userewrite_o_0'] = 'nem';
+$lang['userewrite_o_1'] = '.htaccess-szel';
+$lang['userewrite_o_2'] = 'DokuWiki saját módszerével';
+$lang['deaccent_o_0'] = 'kikapcsolva';
+$lang['deaccent_o_1'] = 'ékezetek eltávolítása';
+$lang['deaccent_o_2'] = 'távirati stílus';
+$lang['gdlib_o_0'] = 'GD Lib nem elérhető';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Auto felismerés';
+$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';
+$lang['rss_content_o_abstract'] = 'Kivonat';
+$lang['rss_content_o_diff'] = 'Unified diff formátum';
+$lang['rss_content_o_htmldiff'] = 'HTML formázott változás tábla';
+$lang['rss_content_o_html'] = 'Teljes HTML oldal tartalom';
+$lang['rss_linkto_o_diff'] = 'a változás nézetre';
+$lang['rss_linkto_o_page'] = 'az átdolgozott oldalra';
+$lang['rss_linkto_o_rev'] = 'a változatok listájára';
+$lang['rss_linkto_o_current'] = 'a jelenlegi oldalra';
+$lang['compression_o_0'] = 'nincs tömörítés';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nincs használatban';
+$lang['xsendfile_o_1'] = 'lighttpd saját fejléc (1.5-ös verzió előtti)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile fejléc';
+$lang['xsendfile_o_3'] = 'Nginx saját X-Accel-Redirect fejléce';
+$lang['showuseras_o_loginname'] = 'Azonosító';
+$lang['showuseras_o_username'] = 'Teljes név';
+$lang['showuseras_o_email'] = 'E-mail cím (olvashatatlanná téve az e-mailcím védelem beállítása szerint)';
+$lang['showuseras_o_email_link'] = 'E-mail cím mailto: linkként';
+$lang['useheading_o_0'] = 'Soha';
+$lang['useheading_o_navigation'] = 'Csak navigációhoz';
+$lang['useheading_o_content'] = 'Csak Wiki tartalomhoz';
+$lang['useheading_o_1'] = 'Mindig';
+$lang['readdircache'] = 'A könyvtár olvasás gyorsítótárának maximális tárolási ideje (másodperc)';
diff --git a/lib/plugins/config/lang/ia/intro.txt b/lib/plugins/config/lang/ia/intro.txt
new file mode 100644
index 000000000..37b970c4f
--- /dev/null
+++ b/lib/plugins/config/lang/ia/intro.txt
@@ -0,0 +1,7 @@
+====== Gestion de configurationes ======
+
+Usa iste pagina pro controlar le configurationes de tu installation de DokuWiki. Pro adjuta re configurationes individual, refere te a [[doku>config]].
+
+Le configurationes monstrate super un fundo rubie clar es protegite e non pote esser alterate con iste plug-in. Le configurationes monstrate super un fundo blau es le valores predefinite e le configurationes monstrate super un fundo blanc ha essite definite localmente pro iste particular installation. Le configurationes blau e blanc pote esser alterate.
+
+Rememora de premer le button **SALVEGUARDAR** ante de quitar iste pagina, alteremente tu modificationes essera perdite. \ No newline at end of file
diff --git a/lib/plugins/config/lang/ia/lang.php b/lib/plugins/config/lang/ia/lang.php
new file mode 100644
index 000000000..689869b89
--- /dev/null
+++ b/lib/plugins/config/lang/ia/lang.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['menu'] = 'Configurationes';
+$lang['error'] = 'Le configurationes non poteva esser actualisate a causa de un valor invalide; per favor revide tu cambiamentos e resubmitte los.<br />Le valor(es) incorrecte essera monstrate circumferite per un bordo rubie.';
+$lang['updated'] = 'Actualisation del configurationes succedite.';
+$lang['nochoice'] = '(nulle altere option disponibile)';
+$lang['locked'] = 'Le file de configuration non pote esser actualisate; si isto non es intentional, <br /> assecura te que le nomine e permissiones del file local de configuration es correcte.';
+$lang['danger'] = 'Periculo: Cambiar iste option pote render tu wiki e le menu de configuration inaccessibile!';
+$lang['warning'] = 'Attention: Cambiar iste option pote causar functionamento indesirate.';
+$lang['security'] = 'Advertimento de securitate: Cambiar iste option pote causar un risco de securitate.';
+$lang['_configuration_manager'] = 'Gestion de configurationes';
+$lang['_header_dokuwiki'] = 'Configurationes de DokuWiki';
+$lang['_header_plugin'] = 'Configurationes de plug-ins';
+$lang['_header_template'] = 'Configurationes de patronos';
+$lang['_header_undefined'] = 'Configurationes non definite';
+$lang['_basic'] = 'Configurationes de base';
+$lang['_display'] = 'Configurationes de visualisation';
+$lang['_authentication'] = 'Configurationes de authentication';
+$lang['_anti_spam'] = 'Configurationes anti-spam';
+$lang['_editing'] = 'Configurationes de modification';
+$lang['_links'] = 'Configurationes de ligamines';
+$lang['_media'] = 'Configurationes de multimedia';
+$lang['_advanced'] = 'Configurationes avantiate';
+$lang['_network'] = 'Configurationes de rete';
+$lang['_plugin_sufix'] = 'Configurationes de plug-ins';
+$lang['_template_sufix'] = 'Configurationes de patronos';
+$lang['_msg_setting_undefined'] = 'Nulle metadatos de configuration.';
+$lang['_msg_setting_no_class'] = 'Nulle classe de configuration.';
+$lang['_msg_setting_no_default'] = 'Nulle valor predefinite.';
+$lang['fmode'] = 'Permissiones al creation de files';
+$lang['dmode'] = 'Permissiones al creation de directorios';
+$lang['lang'] = 'Lingua del interfacie';
+$lang['basedir'] = 'Cammino al servitor (p.ex.. <code>/dokuwiki/</code>). Lassa vacue pro autodetection.';
+$lang['baseurl'] = 'URL del servitor (p.ex. <code>http://www.yourserver.com</code>). Lassa vacue pro autodetection.';
+$lang['savedir'] = 'Directorio pro salveguardar datos';
+$lang['start'] = 'Nomine del pagina initial';
+$lang['title'] = 'Titulo del wiki';
+$lang['template'] = 'Patrono';
+$lang['license'] = 'Sub qual licentia debe tu contento esser publicate?';
+$lang['fullpath'] = 'Revelar le cammino complete del paginas in le pede';
+$lang['recent'] = 'Modificationes recente';
+$lang['breadcrumbs'] = 'Numero de micas de pan';
+$lang['youarehere'] = 'Micas de pan hierarchic';
+$lang['typography'] = 'Face substitutiones typographic';
+$lang['htmlok'] = 'Permitter incorporation de HTML';
+$lang['phpok'] = 'Permitter incorporation de PHP';
+$lang['dformat'] = 'Formato del datas (vide le function <a href="http://www.php.net/strftime">strftime</a> de PHP)';
+$lang['signature'] = 'Signatura';
+$lang['toptoclevel'] = 'Nivello principal pro tabula de contento';
+$lang['tocminheads'] = 'Numero minimal de titulos requirite pro inserer tabula de contento';
+$lang['maxtoclevel'] = 'Nivello maximal pro tabula de contento';
+$lang['maxseclevel'] = 'Nivello maximal pro modification de sectiones';
+$lang['camelcase'] = 'Usar CamelCase pro ligamines';
+$lang['deaccent'] = 'Nomines nette de paginas';
+$lang['useheading'] = 'Usar le prime titulo como nomine de pagina';
+$lang['refcheck'] = 'Verification de referentias multimedia';
+$lang['refshow'] = 'Numero de referentias multimedia a monstrar';
+$lang['allowdebug'] = 'Permitter debugging <b>disactiva si non necessari!</b>';
+$lang['usewordblock'] = 'Blocar spam a base de lista de parolas';
+$lang['indexdelay'] = 'Retardo ante generation de indice (secundas)';
+$lang['relnofollow'] = 'Usar rel="nofollow" pro ligamines externe';
+$lang['mailguard'] = 'Offuscar adresses de e-mail';
+$lang['iexssprotect'] = 'Verificar files incargate pro codice HTML o JavaScript possibilemente malitiose';
+$lang['showuseras'] = 'Como monstrar le usator que faceva le ultime modification de un pagina';
+$lang['useacl'] = 'Usar listas de controlo de accesso';
+$lang['autopasswd'] = 'Automaticamente generar contrasignos';
+$lang['authtype'] = 'Servicio de authentication';
+$lang['passcrypt'] = 'Methodo de cryptographia de contrasignos';
+$lang['defaultgroup'] = 'Gruppo predefinite';
+$lang['superuser'] = 'Superusator: le gruppo, usator o lista separate per commas ("usator1,@gruppo1,usator2") con accesso integral a tote le paginas e functiones sin reguardo del ACL';
+$lang['manager'] = 'Administrator: le gruppo, usator o lista separate per commas ("usator1,@gruppo1,usator2") con accesso a certe functiones administrative';
+$lang['profileconfirm'] = 'Confirmar modificationes del profilo con contrasigno';
+$lang['disableactions'] = 'Disactivar actiones DokuWiki';
+$lang['disableactions_check'] = 'Verificar';
+$lang['disableactions_subscription'] = 'Subscriber/Cancellar subscription';
+$lang['disableactions_wikicode'] = 'Vider codice-fonte/Exportar texto crude';
+$lang['disableactions_other'] = 'Altere actiones (separate per commas)';
+$lang['sneaky_index'] = 'Normalmente, DokuWiki monstra tote le spatios de nomines in le vista del indice. Si iste option es active, illos ubi le usator non ha le permission de lectura essera celate. Isto pote resultar in le celamento de subspatios de nomines accessibile. Isto pote render le indice inusabile con certe configurationes de ACL.';
+$lang['auth_security_timeout'] = 'Expiration pro securitate de authentication (secundas)';
+$lang['securecookie'] = 'Debe le cookies definite via HTTPS solmente esser inviate via HTTPS per le navigator? Disactiva iste option si solmente le apertura de sessiones a tu wiki es protegite con SSL ma le navigation del wiki es facite sin securitate.';
+$lang['xmlrpc'] = 'Activar/disactivar interfacie XML-RPC.';
+$lang['xmlrpcuser'] = 'Limitar le accesso a XML-RPC al gruppos o usatores date hic, separate per commas. Lassa isto vacue pro dar accesso a omnes.';
+$lang['updatecheck'] = 'Verificar si existe actualisationes e advertimentos de securitate? DokuWiki debe contactar update.dokuwiki.org pro exequer iste function.';
+$lang['userewrite'] = 'Usar URLs nette';
+$lang['useslash'] = 'Usar le barra oblique ("/") como separator de spatios de nomines in URLs';
+$lang['usedraft'] = 'Automaticamente salveguardar un version provisori durante le modification';
+$lang['sepchar'] = 'Separator de parolas in nomines de paginas';
+$lang['canonical'] = 'Usar URLs completemente canonic';
+$lang['autoplural'] = 'Verificar si il ha formas plural in ligamines';
+$lang['compression'] = 'Methodo de compression pro files a mansarda';
+$lang['cachetime'] = 'Etate maximal pro le cache (secundas)';
+$lang['locktime'] = 'Etate maximal pro le files de serratura (secundas)';
+$lang['fetchsize'] = 'Numero maximal de bytes per file que fetch.php pote discargar de sitos externe';
+$lang['notify'] = 'Inviar notificationes de cambios a iste adresse de e-mail';
+$lang['registernotify'] = 'Inviar informationes super usatores novemente registrate a iste adresse de e-mail';
+$lang['mailfrom'] = 'Adresse de e-mail a usar pro messages automatic';
+$lang['gzip_output'] = 'Usar Content-Encoding gzip pro xhtml';
+$lang['gdlib'] = 'Version de GD Lib';
+$lang['im_convert'] = 'Cammino al programma "convert" de ImageMagick';
+$lang['jpg_quality'] = 'Qualitate del compression JPEG (0-100)';
+$lang['subscribers'] = 'Activar le possibilitate de subscriber se al paginas';
+$lang['subscribe_time'] = 'Tempore post le qual le listas de subscription e le digestos es inviate (in secundas); isto debe esser minor que le tempore specificate in recent_days.';
+$lang['compress'] = 'Compactar le output CSS e JavaScript';
+$lang['hidepages'] = 'Celar paginas correspondente (expressiones regular)';
+$lang['send404'] = 'Inviar "HTTP 404/Pagina non trovate" pro paginas non existente';
+$lang['sitemap'] = 'Generar mappa de sito Google (dies)';
+$lang['broken_iua'] = 'Es le function ignore_user_abort defectuose in tu systema? Isto pote resultar in un indice de recerca que non functiona. Vide <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> pro plus info.';
+$lang['xsendfile'] = 'Usar le capite X-Sendfile pro lassar le servitor web livrar files static? Tu navigator del web debe supportar isto.';
+$lang['renderer_xhtml'] = 'Renditor a usar pro le output wiki principal (xhtml)';
+$lang['renderer__core'] = '%s (nucleo dokuwiki)';
+$lang['renderer__plugin'] = '%s (plug-in)';
+$lang['rememberme'] = 'Permitter cookies de session permanente (memorar me)';
+$lang['rss_type'] = 'Typo de syndication XML';
+$lang['rss_linkto'] = 'Syndication XML liga verso';
+$lang['rss_content'] = 'Que monstrar in le entratas de syndication XML?';
+$lang['rss_update'] = 'Intervallo de actualisation pro syndicationes XML (secundas)';
+$lang['recent_days'] = 'Retener quante modificationes recente? (dies)';
+$lang['rss_show_summary'] = 'Monstrar summario in titulo de syndication XML';
+$lang['target____wiki'] = 'Fenestra de destination pro ligamines interne';
+$lang['target____interwiki'] = 'Fenestra de destination pro ligamines interwiki';
+$lang['target____extern'] = 'Fenestra de destination pro ligamines externe';
+$lang['target____media'] = 'Fenestra de destination pro ligamines multimedia';
+$lang['target____windows'] = 'Fenestra de destination pro ligamines a fenestras';
+$lang['proxy____host'] = 'Nomine de servitor proxy';
+$lang['proxy____port'] = 'Porto del proxy';
+$lang['proxy____user'] = 'Nomine de usator pro le proxy';
+$lang['proxy____pass'] = 'Contrasigno pro le proxy';
+$lang['proxy____ssl'] = 'Usar SSL pro connecter al proxy';
+$lang['safemodehack'] = 'Permitter truco de modo secur';
+$lang['ftp____host'] = 'Servitor FTP pro truco de modo secur';
+$lang['ftp____port'] = 'Porto FTP pro truco de modo secur';
+$lang['ftp____user'] = 'Nomine de usator FTP pro truco de modo secur';
+$lang['ftp____pass'] = 'Contrasigno FTP pro truco de modo secur';
+$lang['ftp____root'] = 'Directorio radice FTP pro truco de modo securr';
+$lang['license_o_'] = 'Nihil seligite';
+$lang['typography_o_0'] = 'nulle';
+$lang['typography_o_1'] = 'excludente ';
+$lang['typography_o_2'] = 'includente virgulettas singule (pote non sempre functionar)';
+$lang['userewrite_o_0'] = 'nulle';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'interne a DokuWIki';
+$lang['deaccent_o_0'] = 'disactivate';
+$lang['deaccent_o_1'] = 'remover accentos';
+$lang['deaccent_o_2'] = 'romanisar';
+$lang['gdlib_o_0'] = 'GD Lib non disponibile';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Autodetection';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstracte';
+$lang['rss_content_o_diff'] = 'In formato Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'Tabella de diff in formato HTML';
+$lang['rss_content_o_html'] = 'Contento complete del pagina in HTML';
+$lang['rss_linkto_o_diff'] = 'vista de differentias';
+$lang['rss_linkto_o_page'] = 'le pagina revidite';
+$lang['rss_linkto_o_rev'] = 'lista de versiones';
+$lang['rss_linkto_o_current'] = 'le pagina actual';
+$lang['compression_o_0'] = 'nulle';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'non usar';
+$lang['xsendfile_o_1'] = 'Capite proprietari "lighttpd" (ante version 1.5)';
+$lang['xsendfile_o_2'] = 'Capite standard "X-Sendfile"';
+$lang['xsendfile_o_3'] = 'Capite proprietari "X-Accel-Redirect" de Nginx';
+$lang['showuseras_o_loginname'] = 'Nomine de usator';
+$lang['showuseras_o_username'] = 'Nomine real del usator';
+$lang['showuseras_o_email'] = 'Adresse de e-mail del usator (offuscate secundo le configuration de Mailguard)';
+$lang['showuseras_o_email_link'] = 'Adresse de e-mail del usator como ligamine "mailto:"';
+$lang['useheading_o_0'] = 'Nunquam';
+$lang['useheading_o_navigation'] = 'Navigation solmente';
+$lang['useheading_o_content'] = 'Contento wiki solmente';
+$lang['useheading_o_1'] = 'Sempre';
diff --git a/lib/plugins/config/lang/id-ni/intro.txt b/lib/plugins/config/lang/id-ni/intro.txt
new file mode 100644
index 000000000..cd77caa99
--- /dev/null
+++ b/lib/plugins/config/lang/id-ni/intro.txt
@@ -0,0 +1,7 @@
+====== Fakake famöfö'ö ======
+
+Plugin da'e itolo ba wangehaogö fakake moroi ba DokuWiki. Fanolo bawamöfö'ö tesöndra tou [[doku>config]]. Lala wangiila Plugin tanöbö'ö tesöndra tou ba [[doku>plugin:config]].
+
+Famöfö'ö zura furi la'a soyo no laproteksi, lötesöndra bakha ba Plugin andre. Famöfö'ö zura furi la'a sobalau ya'ia wamöfö'ö sito'ölö...
+
+Böi olifu ndra'ugö ba wofetugö **Irö'ö** fatua lö öröi fakake wamöfö'ö soguna bawangirö'ö wamöfö'ö safuria.
diff --git a/lib/plugins/config/lang/id-ni/lang.php b/lib/plugins/config/lang/id-ni/lang.php
new file mode 100644
index 000000000..edde733fb
--- /dev/null
+++ b/lib/plugins/config/lang/id-ni/lang.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['xmlrpc'] = 'Orifi/böi\'orifi XML-RPC interface.';
+$lang['renderer_xhtml'] = 'Fake Renderer ba zito\'ölö (XHTML) Wiki-output.';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rss_type'] = 'Tipe XML feed';
+$lang['rss_linkto'] = 'XML feed links khö';
+$lang['rss_content'] = 'Hadia wangoromaö nifake ba XML-Feed?';
+$lang['rss_update'] = 'XML feed (sec) inötö wamohouni';
+$lang['recent_days'] = 'Hawa\'oya laforoma\'ö moroi bazibohou? (Hari)';
+$lang['rss_show_summary'] = 'XML feed foromaö summary ba title';
+$lang['target____wiki'] = 'Lala window ba internal links';
+$lang['target____interwiki'] = 'Lala window ba interwiki links';
+$lang['target____extern'] = 'Lala window ba external links';
+$lang['target____media'] = 'Lala window ba media links';
+$lang['target____windows'] = 'Lala window ba windows links';
+$lang['proxy____host'] = 'Töi server proxy';
+$lang['proxy____port'] = 'Port proxy';
+$lang['proxy____user'] = 'Töi proxy';
+$lang['proxy____pass'] = 'Kode proxy';
+$lang['proxy____ssl'] = 'Fake ssl ba connect awö Proxy';
+$lang['safemodehack'] = 'Orifi safemode hack';
+$lang['ftp____host'] = 'FTP server khö safemode hack';
+$lang['ftp____port'] = 'FTP port khö safemode hack';
+$lang['ftp____user'] = 'Töi FTP khö safemode hack';
+$lang['ftp____pass'] = 'FTP kode khö safemode hack';
+$lang['ftp____root'] = 'FTP root directory for safemode hack';
+$lang['typography_o_0'] = 'lö\'ö';
+$lang['typography_o_1'] = 'Ha sitombua kutip';
+$lang['typography_o_2'] = 'Fefu nikutip (itataria lömohalöwö)';
+$lang['userewrite_o_0'] = 'lö\'ö';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki bakha';
+$lang['deaccent_o_0'] = 'ofolai';
+$lang['deaccent_o_1'] = 'heta aksen';
+$lang['deaccent_o_2'] = 'romanize';
+$lang['gdlib_o_0'] = 'GD Lib lötesöndra';
+$lang['gdlib_o_1'] = 'Versi 1.x';
+$lang['gdlib_o_2'] = 'Otomatis';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstrak';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatted diff table';
+$lang['rss_content_o_html'] = 'Fefu HTML format diff table';
+$lang['rss_linkto_o_diff'] = 'foromaö difference';
+$lang['rss_linkto_o_page'] = 'Refisi nga\'örö';
+$lang['rss_linkto_o_rev'] = 'Daftar nihaogö';
+$lang['rss_linkto_o_current'] = 'Nga\'örö safuria';
+$lang['compression_o_0'] = 'Lö\'ö';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'böi fake';
+$lang['xsendfile_o_1'] = 'Proprieteri lighttpd Header (furi Release 1.5)';
+$lang['xsendfile_o_2'] = 'Standar X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Proprieteri Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Töi';
+$lang['showuseras_o_username'] = 'Töi safönu';
+$lang['showuseras_o_email'] = 'Fake döi imele (obfuscated according to mailguard setting)';
+$lang['showuseras_o_email_link'] = 'Fake döi imele sifao mailto: link';
diff --git a/lib/plugins/config/lang/id/intro.txt b/lib/plugins/config/lang/id/intro.txt
new file mode 100644
index 000000000..296206d02
--- /dev/null
+++ b/lib/plugins/config/lang/id/intro.txt
@@ -0,0 +1,5 @@
+====== Manajemen Konfigurasi ======
+
+Gunakan halaman ini untuk mengatur konfigurasi instalasi DokuWiki Anda. Untuk bantuan dalam konfigurasi, silahkan lihat di [[doku>config]]. Unuk mengetahui lebih lanjut tentang plugin in silahkan lihat [[doku>plugin:config]].
+
+Konfigurasi dengan warna merah dilindungi dan tidak bisa diubah dengan plugin ini. Konfigurasi dengan warna biru adalah nilai default, dan konfigurasi dengan latar putih telah diset khusus untuk instalasi ini. Konfigurasi berwarna putih atau b
diff --git a/lib/plugins/config/lang/id/lang.php b/lib/plugins/config/lang/id/lang.php
new file mode 100644
index 000000000..c3d485930
--- /dev/null
+++ b/lib/plugins/config/lang/id/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Irwan Butar Butar <irwansah.putra@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/config/lang/is/lang.php b/lib/plugins/config/lang/is/lang.php
new file mode 100644
index 000000000..c4905d0f9
--- /dev/null
+++ b/lib/plugins/config/lang/is/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['menu'] = 'Stillingar';
+$lang['error'] = 'Stillingum ekki breitt þar sem rangar upplýsingar voru settar inn, vinsamlegast yfirfarið stillingar merktar með rauðu';
+$lang['updated'] = 'Stillingum breitt';
+$lang['nochoice'] = '(engir aðrir valmöguleikar fyrir hendi)';
+$lang['_display'] = 'Skjástillingar';
+$lang['_anti_spam'] = 'Stillingar gegn ruslpósti';
+$lang['_editing'] = 'Útgáfastillingar';
+$lang['_plugin_sufix'] = 'Viðbótstillingar';
+$lang['lang'] = 'Tungumál';
+$lang['title'] = 'Heiti wikis';
+$lang['template'] = 'Mát';
+$lang['recent'] = 'Nýlegar breytingar';
+$lang['breadcrumbs'] = 'Fjöldi brauðmolar';
+$lang['youarehere'] = 'Stigveldisá brauðmolar';
+$lang['typography'] = 'Gera stað fyrir leturgerðir';
+$lang['htmlok'] = 'Fella HTML inn';
+$lang['phpok'] = 'Fella PHP inn';
+$lang['dformat'] = 'Dagsetningarsnið (sjá PHP-aðgerð <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Undirskrift';
+$lang['passcrypt'] = 'Dulritunaraðferð aðgangsorðs';
+$lang['defaultgroup'] = 'Sjálfgefinn hópur';
+$lang['superuser'] = 'Hópur kerfisstjóra ';
+$lang['profileconfirm'] = 'Staðfestu breytingar með aðgangsorði';
+$lang['mailfrom'] = 'Rafpóstfang fyrir sjálfvirkar póstsendingar';
+$lang['gdlib'] = 'Útgáfa af GD Lib';
+$lang['jpg_quality'] = 'JPG gæðastilling (0-100)';
+$lang['proxy____host'] = 'Heiti staðgengilsþjóns';
+$lang['proxy____port'] = 'Staðgengilstengi';
+$lang['proxy____user'] = 'Staðgengill notendanafn';
+$lang['proxy____pass'] = 'Staðgengilsaðgangsorð';
+$lang['proxy____ssl'] = 'Nýta SSL til að tengjast staðgengill';
+$lang['license_o_'] = 'Ekkert valið';
+$lang['typography_o_0'] = 'engin';
+$lang['userewrite_o_0'] = 'engin';
+$lang['deaccent_o_0'] = 'slökkt';
+$lang['deaccent_o_1'] = 'fjarlægja broddi';
+$lang['deaccent_o_2'] = 'gera rómverskt';
+$lang['gdlib_o_0'] = 'GD Lib ekki til staðar';
+$lang['gdlib_o_1'] = 'Útgáfa 1,x';
+$lang['gdlib_o_2'] = 'Sjálfvirk leit';
+$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';
+$lang['compression_o_0'] = 'engin';
+$lang['showuseras_o_loginname'] = 'Innskránafn';
+$lang['showuseras_o_username'] = 'Fullt notendanafn';
+$lang['useheading_o_0'] = 'Aldrei';
+$lang['useheading_o_1'] = 'Alltaf';
diff --git a/lib/plugins/config/lang/it/intro.txt b/lib/plugins/config/lang/it/intro.txt
new file mode 100644
index 000000000..617e8c7b5
--- /dev/null
+++ b/lib/plugins/config/lang/it/intro.txt
@@ -0,0 +1,9 @@
+====== Configurazione Wiki ======
+
+Usa questa pagina per gestire la configurazione della tua installazione DokuWiki. Per la guida sulle singole impostazioni fai riferimento alla pagina [[doku>config|Configurazione]]. Per ulteriori dettagli su questo plugin vedi [[doku>plugin:config|Plugin di configurazione]].
+
+Le impostazioni con lo sfondo rosso chiaro sono protette e non possono essere modificate con questo plugin. Le impostazioni con lo sfondo blu contengono i valori predefiniti, e le impostazioni con lo sfondo bianco sono relative solo a questa particolare installazione. Sia le impostazioni su sfondo blu che quelle su sfondo bianco possono essere modificate.
+
+Ricordati di premere il pulsante **SALVA** prima di lasciare questa pagina altrimenti le modifiche andranno perse.
+
+
diff --git a/lib/plugins/config/lang/it/lang.php b/lib/plugins/config/lang/it/lang.php
new file mode 100644
index 000000000..c4dd433ed
--- /dev/null
+++ b/lib/plugins/config/lang/it/lang.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Silvia Sargentoni <polinnia@tin.it>
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['menu'] = 'Configurazione Wiki';
+$lang['error'] = 'Impostazioni non aggiornate a causa di un valore non corretto, controlla le modifiche apportate e salva di nuovo.
+<br />I valori non corretti sono evidenziati da un riquadro rosso.';
+$lang['updated'] = 'Aggiornamento impostazioni riuscito.';
+$lang['nochoice'] = '(nessun\'altra scelta disponibile)';
+$lang['locked'] = 'Il file di configurazione non può essere aggiornato, se questo non è intenzionale, <br />
+assicurati che il nome e i permessi del file contenente la configurazione locale siano corretti.';
+$lang['danger'] = 'Attenzione: cambiare questa opzione può rendere inaccessibile il wiki e il menu di configurazione.';
+$lang['warning'] = 'Avviso: cambiare questa opzione può causare comportamenti indesiderati.';
+$lang['security'] = 'Avviso di sicurezza: vambiare questa opzione può esporre a rischi di sicurezza.';
+$lang['_configuration_manager'] = 'Configurazione Wiki';
+$lang['_header_dokuwiki'] = 'Impostazioni DokuWiki';
+$lang['_header_plugin'] = 'Impostazioni Plugin';
+$lang['_header_template'] = 'Impostazioni Modello';
+$lang['_header_undefined'] = 'Impostazioni non definite';
+$lang['_basic'] = 'Impostazioni Base';
+$lang['_display'] = 'Impostazioni Visualizzazione';
+$lang['_authentication'] = 'Impostazioni Autenticazione';
+$lang['_anti_spam'] = 'Impostazioni Anti-Spam';
+$lang['_editing'] = 'Impostazioni Modifica';
+$lang['_links'] = 'Impostazioni Collegamenti';
+$lang['_media'] = 'Impostazioni File';
+$lang['_advanced'] = 'Impostazioni Avanzate';
+$lang['_network'] = 'Impostazioni Rete';
+$lang['_plugin_sufix'] = 'Impostazioni Plugin';
+$lang['_template_sufix'] = 'Impostazioni Modello';
+$lang['_msg_setting_undefined'] = 'Nessun metadato definito.';
+$lang['_msg_setting_no_class'] = 'Nessuna classe definita.';
+$lang['_msg_setting_no_default'] = 'Nessun valore predefinito.';
+$lang['fmode'] = 'Permessi per i nuovi file';
+$lang['dmode'] = 'Permessi per le nuove directory';
+$lang['lang'] = 'Lingua';
+$lang['basedir'] = 'Directory di base';
+$lang['baseurl'] = 'URL di base';
+$lang['savedir'] = 'Directory per il salvataggio dei dati';
+$lang['start'] = 'Nome della pagina iniziale';
+$lang['title'] = 'Titolo del wiki';
+$lang['template'] = 'Modello';
+$lang['license'] = 'Sotto quale licenza vorresti rilasciare il tuo contenuto?';
+$lang['fullpath'] = 'Mostra il percorso completo delle pagine';
+$lang['recent'] = 'Ultime modifiche';
+$lang['breadcrumbs'] = 'Numero di breadcrumb';
+$lang['youarehere'] = 'Breadcrumb gerarchici';
+$lang['typography'] = 'Abilita la sostituzione tipografica';
+$lang['htmlok'] = 'Consenti HTML incorporato';
+$lang['phpok'] = 'Consenti PHP incorporato';
+$lang['dformat'] = 'Formato delle date (vedi la funzione <a href="http://www.php.net/strftime">strftime</a> di PHP)';
+$lang['signature'] = 'Firma';
+$lang['toptoclevel'] = 'Livello superiore per l\'indice';
+$lang['tocminheads'] = 'Ammontare minimo di intestazioni che determinano la creazione del TOC';
+$lang['maxtoclevel'] = 'Numero massimo di livelli per l\'indice';
+$lang['maxseclevel'] = 'Livello massimo per le sezioni modificabili';
+$lang['camelcase'] = 'Usa CamelCase per i collegamenti';
+$lang['deaccent'] = 'Pulizia dei nomi di pagina';
+$lang['useheading'] = 'Usa la prima intestazione come nome di pagina';
+$lang['refcheck'] = 'Controlla i riferimenti ai file';
+$lang['refshow'] = 'Numero di riferimenti da visualizzare';
+$lang['allowdebug'] = 'Abilita il debug <b>(disabilitare se non serve!)</b>';
+$lang['usewordblock'] = 'Blocca lo spam in base alla blacklist';
+$lang['indexdelay'] = 'Intervallo di tempo prima dell\'indicizzazione';
+$lang['relnofollow'] = 'Usa rel="nofollow" nei collegamenti esterni';
+$lang['mailguard'] = 'Oscuramento indirizzi email';
+$lang['iexssprotect'] = 'Controlla i file caricati in cerca di possibile codice JavaScript o HTML maligno.';
+$lang['showuseras'] = 'Cosa visualizzare quando si mostra l\'ultimo utente che ha modificato una pagina';
+$lang['useacl'] = 'Usa lista di controllo accessi (ACL)';
+$lang['autopasswd'] = 'Genera password in automatico';
+$lang['authtype'] = 'Sistema di autenticazione';
+$lang['passcrypt'] = 'Metodo di cifratura password';
+$lang['defaultgroup'] = 'Gruppo predefinito';
+$lang['superuser'] = 'Amministratore - gruppo, utente o elenco di utenti separati da virgole (user1,@group1,user2) con accesso completo a tutte le pagine e le funzioni che riguardano le impostazioni ACL';
+$lang['manager'] = 'Gestore - gruppo, utente o elenco di utenti separati da virgole (user1,@group1,user2) con accesso a determinate funzioni di gestione';
+$lang['profileconfirm'] = 'Richiedi la password per modifiche al profilo';
+$lang['disableactions'] = 'Disabilita azioni DokuWiki';
+$lang['disableactions_check'] = 'Controlla';
+$lang['disableactions_subscription'] = 'Sottoscrivi/Rimuovi sottoscrizione';
+$lang['disableactions_wikicode'] = 'Mostra sorgente/Esporta Raw';
+$lang['disableactions_other'] = 'Altre azioni (separate da virgola)';
+$lang['sneaky_index'] = 'Normalmente, DokuWiki mostra tutte le categorie nella vista indice. Abilitando questa opzione, saranno nascoste quelle per cui l\'utente non ha il permesso in lettura. Questo potrebbe far sì che alcune sottocategorie accessibili siano nascoste. La pagina indice potrebbe quindi diventare inutilizzabile con alcune configurazioni dell\'ACL.';
+$lang['auth_security_timeout'] = 'Tempo di sicurezza per l\'autenticazione (secondi)';
+$lang['securecookie'] = 'Devono i cookies impostati tramite HTTPS essere inviati al browser solo tramite HTTPS? Disattiva questa opzione solo quando l\'accesso al tuo wiki viene effettuato con il protocollo SSL ma la navigazione del wiki non risulta sicura.';
+$lang['xmlrpc'] = 'Abilita/disabilita interfaccia XML-RPC.';
+$lang['xmlrpcuser'] = 'Limita l\'accesso XML-RPC ai gruppi o utenti indicati qui (separati da virgola). Lascia il campo vuoto per dare accesso a tutti.';
+$lang['updatecheck'] = 'Controllare aggiornamenti e avvisi di sicurezza? DokuWiki deve contattare update.dokuwiki.org per questa funzione.';
+$lang['userewrite'] = 'Usa il rewrite delle URL';
+$lang['useslash'] = 'Usa la barra rovescia (slash) come separatore nelle URL';
+$lang['usedraft'] = 'Salva una bozza in automatico in fase di modifica';
+$lang['sepchar'] = 'Separatore di parole nei nomi di pagina';
+$lang['canonical'] = 'Usa URL canoniche';
+$lang['fnencode'] = 'Metodo per codificare i filenames non-ASCII.';
+$lang['autoplural'] = 'Controlla il plurale nei collegamenti';
+$lang['compression'] = 'Usa la compressione per i file dell\'archivio';
+$lang['cachetime'] = 'Durata della cache (sec)';
+$lang['locktime'] = 'Durata dei file di lock (sec)';
+$lang['fetchsize'] = 'Dimensione massima (bytes) scaricabile da fetch.php da extern';
+$lang['notify'] = 'Invia notifiche sulle modifiche a questo indirizzo';
+$lang['registernotify'] = 'Invia informazioni sui nuovi utenti registrati a questo indirizzo email';
+$lang['mailfrom'] = 'Mittente per le mail automatiche';
+$lang['mailprefix'] = 'Prefisso da inserire nell\'oggetto delle mail automatiche';
+$lang['gzip_output'] = 'Usa il Content-Encoding gzip per xhtml';
+$lang['gdlib'] = 'Versione GD Lib ';
+$lang['im_convert'] = 'Percorso per il convertitore di ImageMagick';
+$lang['jpg_quality'] = 'Qualità di compressione JPG (0-100)';
+$lang['subscribers'] = 'Abilita la sottoscrizione alle pagine';
+$lang['subscribe_time'] = 'Tempo dopo il quale le liste di sottoscrizione e i riassunti vengono inviati (sec); Dovrebbe essere inferiore al tempo specificato in recent_days.';
+$lang['compress'] = 'Comprimi i file CSS e javascript';
+$lang['hidepages'] = 'Nascondi le pagine che soddisfano la condizione (inserire un\'espressione regolare)';
+$lang['send404'] = 'Invia "HTTP 404/Pagina non trovata" per le pagine inesistenti';
+$lang['sitemap'] = 'Genera una sitemap Google (giorni)';
+$lang['broken_iua'] = 'La funzione ignore_user_abort non funziona sul tuo sistema? Questo potrebbe far sì che l\'indice di ricerca sia inutilizzabile. È noto che nella configurazione IIS+PHP/CGI non funziona. Vedi il<a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> per maggiori informazioni.';
+$lang['xsendfile'] = 'Usare l\'header X-Sendfile per permettere al webserver di fornire file statici? Questa funzione deve essere supportata dal tuo webserver.';
+$lang['renderer_xhtml'] = 'Renderer da usare per la visualizzazione del wiki (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permetti i cookies di accesso permanenti (ricordami)';
+$lang['rss_type'] = 'Tipo di feed XML';
+$lang['rss_linkto'] = 'Collega i feed XML a';
+$lang['rss_content'] = 'Cosa mostrare negli elementi dei feed XML?';
+$lang['rss_update'] = 'Intervallo di aggiornamento dei feed XML (sec)';
+$lang['recent_days'] = 'Quante modifiche recenti tenere (giorni)';
+$lang['rss_show_summary'] = 'I feed XML riportano un sommario nel titolo';
+$lang['target____wiki'] = 'Finestra di destinazione per i collegamenti interni';
+$lang['target____interwiki'] = 'Finestra di destinazione per i collegamenti interwiki';
+$lang['target____extern'] = 'Finestra di destinazione per i collegamenti esterni';
+$lang['target____media'] = 'Finestra di destinazione per i collegamenti ai file';
+$lang['target____windows'] = 'Finestra di destinazione per i collegamenti alle risorse condivise';
+$lang['proxy____host'] = 'Nome server proxy';
+$lang['proxy____port'] = 'Porta proxy';
+$lang['proxy____user'] = 'Nome utente proxy';
+$lang['proxy____pass'] = 'Password proxy';
+$lang['proxy____ssl'] = 'Usa SSL per connetterti al proxy';
+$lang['proxy____except'] = 'Espressioni regolari per far corrispondere le URLs per i quali i proxy dovrebbero essere ommessi.';
+$lang['safemodehack'] = 'Abilita safemode hack';
+$lang['ftp____host'] = 'Server FTP per safemode hack';
+$lang['ftp____port'] = 'Porta FTP per safemode hack';
+$lang['ftp____user'] = 'Nome utente FTP per safemode hack';
+$lang['ftp____pass'] = 'Password FTP per safemode hack';
+$lang['ftp____root'] = 'Directory principale FTP per safemode hack';
+$lang['license_o_'] = 'Nessuna scelta';
+$lang['typography_o_0'] = 'nessuno';
+$lang['typography_o_1'] = 'Solo virgolette';
+$lang['typography_o_2'] = 'Tutti (potrebbe non funzionare sempre)';
+$lang['userewrite_o_0'] = 'nessuno';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki';
+$lang['deaccent_o_0'] = 'disabilitata';
+$lang['deaccent_o_1'] = 'rimuovi gli accenti';
+$lang['deaccent_o_2'] = 'romanizza';
+$lang['gdlib_o_0'] = 'GD Lib non disponibile';
+$lang['gdlib_o_1'] = 'Versione 1.x';
+$lang['gdlib_o_2'] = 'Rileva automaticamente';
+$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';
+$lang['rss_content_o_abstract'] = 'Sunto';
+$lang['rss_content_o_diff'] = 'Diff unificata';
+$lang['rss_content_o_htmldiff'] = 'Tabella delle diff formattata HTML';
+$lang['rss_content_o_html'] = 'Tutto il contenuto della pagina in HTML';
+$lang['rss_linkto_o_diff'] = 'vista differenze';
+$lang['rss_linkto_o_page'] = 'pagina revisionata';
+$lang['rss_linkto_o_rev'] = 'elenco revisioni';
+$lang['rss_linkto_o_current'] = 'pagina attuale';
+$lang['compression_o_0'] = 'nessuna';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'non usare';
+$lang['xsendfile_o_1'] = 'Header proprietario lighttpd (prima della versione 1.5)';
+$lang['xsendfile_o_2'] = 'Header standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'Header proprietario Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Nome utente';
+$lang['showuseras_o_username'] = 'Nome completo dell\'utente';
+$lang['showuseras_o_email'] = 'Indirizzo email dell\'utente (offuscato in base alle impostazioni di sicurezza posta)';
+$lang['showuseras_o_email_link'] = 'Indirizzo email dell\'utente come collegamento mailto:';
+$lang['useheading_o_0'] = 'Mai';
+$lang['useheading_o_navigation'] = 'Solo navigazione';
+$lang['useheading_o_content'] = 'Solo contenuto wiki';
+$lang['useheading_o_1'] = 'Sempre';
+$lang['readdircache'] = 'Tempo massimo per le readdir cache (sec)';
diff --git a/lib/plugins/config/lang/ja/intro.txt b/lib/plugins/config/lang/ja/intro.txt
new file mode 100644
index 000000000..0c45471c6
--- /dev/null
+++ b/lib/plugins/config/lang/ja/intro.txt
@@ -0,0 +1,9 @@
+====== 設定管理 ======
+
+この画面で、Dokuwikiの設定を管理することが出来ます。 個々の設定に関しては [[doku>config]] を参照してください。 このプラグインに関する詳細な情報は [[doku>plugin:config]] を参照してください。
+
+背景が薄い赤になっている場合、その設定は変更することが出来ません。 背景が青の値はデフォルト、背景が白の値は現在の設定となっており、 どちらの値も変更が可能です。
+
+設定の変更後は必ず **保存** ボタンを押して変更を確定してください。 ボタンを押さなかった場合、変更は破棄されます。
+
+
diff --git a/lib/plugins/config/lang/ja/lang.php b/lib/plugins/config/lang/ja/lang.php
new file mode 100644
index 000000000..500d44539
--- /dev/null
+++ b/lib/plugins/config/lang/ja/lang.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * japanese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['menu'] = 'サイト設定';
+$lang['error'] = '不正な値が存在するため、設定は更新されませんでした。入力値を確認してから、再度更新してください。
+ <br />不正な値が入力されている項目は赤い線で囲まれています。';
+$lang['updated'] = '設定は正しく更新されました。';
+$lang['nochoice'] = '(他の選択肢はありません)';
+$lang['locked'] = '設定用ファイルを更新できません。もし意図して変更不可にしているのでなければ、<br />
+ ローカル設定ファイルの名前と権限を確認して下さい。';
+$lang['danger'] = '危険:この設定を変更するとウィキや設定管理画面にアクセスできなくなる恐れがあります。';
+$lang['warning'] = '注意:この設定を変更すると意図しない作動につながる可能性があります。';
+$lang['security'] = '警告:この設定を変更するとセキュリティに悪影響する恐れがあります。';
+$lang['_configuration_manager'] = '設定管理';
+$lang['_header_dokuwiki'] = 'DokuWiki';
+$lang['_header_plugin'] = 'プラグイン';
+$lang['_header_template'] = 'テンプレート';
+$lang['_header_undefined'] = 'その他';
+$lang['_basic'] = '基本';
+$lang['_display'] = '表示';
+$lang['_authentication'] = '認証';
+$lang['_anti_spam'] = 'スパム対策';
+$lang['_editing'] = '編集';
+$lang['_links'] = 'リンク';
+$lang['_media'] = 'メディア';
+$lang['_advanced'] = '高度な設定';
+$lang['_network'] = 'ネットワーク';
+$lang['_plugin_sufix'] = 'プラグイン設定';
+$lang['_template_sufix'] = 'テンプレート設定';
+$lang['_msg_setting_undefined'] = '設定のためのメタデータがありません。';
+$lang['_msg_setting_no_class'] = '設定クラスがありません。';
+$lang['_msg_setting_no_default'] = '初期値が設定されていません。';
+$lang['fmode'] = 'ファイル作成マスク';
+$lang['dmode'] = 'フォルダ作成マスク';
+$lang['lang'] = '使用言語';
+$lang['basedir'] = 'サーバのパス (例: <code>/dokuwiki/</code>)。空欄にすると自動的に検出します。';
+$lang['baseurl'] = 'サーバの URL (例: <code>http://www.yourserver.com</code>)。空欄にすると自動的に検出します。';
+$lang['savedir'] = '保存ディレクトリ';
+$lang['cookiedir'] = 'Cookie のパス。空欄にすると baseurl を使用します。';
+$lang['start'] = 'スタートページ名';
+$lang['title'] = 'WIKIタイトル';
+$lang['template'] = 'テンプレート';
+$lang['license'] = '作成した内容をどのライセンスでリリースしますか?';
+$lang['fullpath'] = 'ページのフッターに絶対パスを表示';
+$lang['recent'] = '最近の変更表示数';
+$lang['breadcrumbs'] = 'トレース(パンくず)表示数';
+$lang['youarehere'] = '現在位置を表示';
+$lang['typography'] = 'タイポグラフィー変換';
+$lang['htmlok'] = 'HTML埋め込み';
+$lang['phpok'] = 'PHP埋め込み';
+$lang['dformat'] = '日付フォーマット(PHPの<a href="http://www.php.net/strftime">strftime</a>関数を参照)';
+$lang['signature'] = '署名';
+$lang['toptoclevel'] = '目次 トップレベル見出し';
+$lang['tocminheads'] = '目次を生成するための最小見出し数';
+$lang['maxtoclevel'] = '目次 表示限度見出し';
+$lang['maxseclevel'] = '編集可能見出し';
+$lang['camelcase'] = 'キャメルケースリンク';
+$lang['deaccent'] = 'ページ名アクセント';
+$lang['useheading'] = '最初の見出しをページ名とする';
+$lang['refcheck'] = 'メディア参照元チェック';
+$lang['refshow'] = 'メディア参照元表示数';
+$lang['allowdebug'] = 'デバッグモード(<b>必要で無いときは無効にしてください</b>)';
+$lang['mediarevisions'] = 'メディアファイルの履歴を有効にしますか?';
+$lang['usewordblock'] = '単語リストに基づくスパムブロック';
+$lang['indexdelay'] = 'インデックスを許可(何秒後)';
+$lang['relnofollow'] = 'rel="nofollow"を付加';
+$lang['mailguard'] = 'メールアドレス保護';
+$lang['iexssprotect'] = 'アップロードファイルに悪意のあるJavaScriptやHTMLが含まれていないかチェックする';
+$lang['showuseras'] = '最終編集者の情報として表示する内容';
+$lang['useacl'] = 'アクセス管理を行う(ACL)';
+$lang['autopasswd'] = 'パスワードの自動生成(ACL)';
+$lang['authtype'] = '認証方法(ACL)';
+$lang['passcrypt'] = '暗号化方法(ACL)';
+$lang['defaultgroup'] = 'デフォルトグループ(ACL)';
+$lang['superuser'] = 'スーパーユーザー(ACL)';
+$lang['manager'] = 'マネージャー(特定の管理機能を使用可能なユーザーもしくはグループ)';
+$lang['profileconfirm'] = 'プロフィール変更時に現在のパスワードを要求(ACL)';
+$lang['disableactions'] = 'DokuWiki の動作を無効にする';
+$lang['disableactions_check'] = 'チェック';
+$lang['disableactions_subscription'] = '登録 / 解除';
+$lang['disableactions_wikicode'] = 'ソース閲覧 / 生データ出力';
+$lang['disableactions_other'] = 'その他の動作(カンマ区切り)';
+$lang['sneaky_index'] = 'デフォルトでは索引にすべての名前空間を表示しますが、この機能はユーザーに閲覧権限のない名前空間を非表示にします。ただし、閲覧が可能な副名前空間まで表示されなくなるため、ACLの設定が適正でない場合は索引機能が使えなくなる場合があります。';
+$lang['auth_security_timeout'] = '認証タイムアウト設定(秒)';
+$lang['securecookie'] = 'クッキーをHTTPSにてセットする場合は、ブラウザよりHTTPS経由で送信された場合にみに制限しますか?ログインのみをSSLで行う場合は、この機能を無効にしてください。';
+$lang['xmlrpc'] = 'XML-RPCインターフェースを有効/無効にする';
+$lang['xmlrpcuser'] = 'XML-RPCアクセスを指定グループとユーザーに制限します(半角コンマ区切り)。 すべての人にアクセスを許可する場合は空のままにしてください。';
+$lang['updatecheck'] = 'DokuWikiの更新とセキュリティに関する情報をチェックしますか? この機能は update.dokuwiki.org への接続が必要です。';
+$lang['userewrite'] = 'URLの書き換え';
+$lang['useslash'] = 'URL上の名前空間の区切りにスラッシュを使用';
+$lang['usedraft'] = '編集中の自動保存(ドラフト)機能を使用';
+$lang['sepchar'] = 'ページ名の単語区切り文字';
+$lang['canonical'] = 'canonical URL(正準URL)を使用';
+$lang['fnencode'] = '非アスキーファイル名のエンコーディング方法';
+$lang['autoplural'] = '自動複数形処理';
+$lang['compression'] = 'アーカイブファイルの圧縮方法';
+$lang['cachetime'] = 'キャッシュ保持時間(秒)';
+$lang['locktime'] = 'ファイルロック期限(秒)';
+$lang['fetchsize'] = '外部からのダウンロード最大サイズ';
+$lang['notify'] = '変更を通知するメールアドレス';
+$lang['registernotify'] = '新規ユーザー登録を通知するメールアドレス';
+$lang['mailfrom'] = 'メール送信時の送信元アドレス';
+$lang['mailprefix'] = '自動メールの題名に使用する接頭語';
+$lang['gzip_output'] = 'xhtmlに対するコンテンツ圧縮(gzip)を使用';
+$lang['gdlib'] = 'GDlibバージョン';
+$lang['im_convert'] = 'ImageMagick変換ツールへのパス';
+$lang['jpg_quality'] = 'JPG圧縮品質(0-100)';
+$lang['subscribers'] = '更新通知機能';
+$lang['subscribe_time'] = '購読リストと概要を送信する期間(秒)。「最近の変更とする期間」で指定した期間より小さくしてください。';
+$lang['compress'] = 'CSSとJavaScriptを圧縮';
+$lang['cssdatauri'] = 'HTTP リクエスト数によるオーバーヘッドを減らすため、CSS ファイルから参照される画像ファイルのサイズがここで指定するバイト数以内の場合は CSS ファイル内に Data URI として埋め込みます。このテクニックは IE7 以下では動作しません! <code>400</code> から <code>600</code> バイトがちょうどよい値です。<code>0</code> を指定すると埋め込み処理は行われません。';
+$lang['hidepages'] = '非公開ページ(Regex)';
+$lang['send404'] = '文書が存在しないページに"HTTP404/Page Not Found"を使用';
+$lang['sitemap'] = 'Googleサイトマップ作成頻度(日数)';
+$lang['broken_iua'] = 'ignore_user_abort関数が破損している恐れがあります。そのため、検索インデックスが動作しない可能性があります。IIS+PHP/CGIの組み合わせで破損することが判明しています。詳しくは<a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>を参照してください。';
+$lang['xsendfile'] = 'ウェブサーバーが静的ファイルを生成するために X-Sendfile ヘッダーを使用しますか?なお、この機能をウェブサーバーがサポートしている必要があります。';
+$lang['renderer_xhtml'] = 'Wikiの出力(xhtml)にレンダラーを使用する';
+$lang['renderer__core'] = '%s (Dokuwikiコア)';
+$lang['renderer__plugin'] = '%s (プラグイン)';
+$lang['rememberme'] = 'ログイン用クッキーを永久に保持することを許可(ログインを保持)';
+$lang['rss_type'] = 'RSSフィード形式';
+$lang['rss_linkto'] = 'RSS内リンク先';
+$lang['rss_content'] = 'XMLフィードに何を表示させますか?';
+$lang['rss_update'] = 'RSSフィードの更新間隔(秒)';
+$lang['recent_days'] = '最近の変更とする期間(日数)';
+$lang['rss_show_summary'] = 'フィードのタイトルにサマリーを表示';
+$lang['target____wiki'] = '内部リンクの表示先';
+$lang['target____interwiki'] = 'InterWikiリンクの表示先';
+$lang['target____extern'] = '外部リンクの表示先';
+$lang['target____media'] = 'メディアリンクの表示先';
+$lang['target____windows'] = 'Windowsリンクの表示先';
+$lang['proxy____host'] = 'プロキシ - サーバー名';
+$lang['proxy____port'] = 'プロキシ - ポート';
+$lang['proxy____user'] = 'プロキシ - ユーザー名';
+$lang['proxy____pass'] = 'プロキシ - パスワード';
+$lang['proxy____ssl'] = 'プロキシへの接続にsslを使用';
+$lang['proxy____except'] = 'スキップするプロキシのURL正規表現';
+$lang['safemodehack'] = 'セーフモード対策を行う';
+$lang['ftp____host'] = 'FTP サーバー名(セーフモード対策)';
+$lang['ftp____port'] = 'FTP ポート(セーフモード対策)';
+$lang['ftp____user'] = 'FTP ユーザー名(セーフモード対策)';
+$lang['ftp____pass'] = 'FTP パスワード(セーフモード対策)';
+$lang['ftp____root'] = 'FTP ルートディレクトリ(セーフモード対策)';
+$lang['license_o_'] = '選択されていません';
+$lang['typography_o_0'] = '無し';
+$lang['typography_o_1'] = '二重引用符(ダブルクオート)のみ';
+$lang['typography_o_2'] = 'すべての引用符(動作しない場合があります)';
+$lang['userewrite_o_0'] = '使用しない';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWikiによる設定';
+$lang['deaccent_o_0'] = '指定しない';
+$lang['deaccent_o_1'] = 'アクセントを除去';
+$lang['deaccent_o_2'] = 'ローマナイズ';
+$lang['gdlib_o_0'] = 'GDを利用できません';
+$lang['gdlib_o_1'] = 'バージョン 1.x';
+$lang['gdlib_o_2'] = '自動検出';
+$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';
+$lang['rss_content_o_abstract'] = '概要';
+$lang['rss_content_o_diff'] = '差分(Unified Diff)';
+$lang['rss_content_o_htmldiff'] = '差分(HTML形式)';
+$lang['rss_content_o_html'] = '完全なHTMLページ';
+$lang['rss_linkto_o_diff'] = '変更点のリスト';
+$lang['rss_linkto_o_page'] = '変更されたページ';
+$lang['rss_linkto_o_rev'] = 'リビジョンのリスト';
+$lang['rss_linkto_o_current'] = '現在のページ';
+$lang['compression_o_0'] = '圧縮しない';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = '使用しない';
+$lang['xsendfile_o_1'] = 'lighttpd ヘッダー(リリース1.5以前)';
+$lang['xsendfile_o_2'] = '標準 X-Sendfile ヘッダー';
+$lang['xsendfile_o_3'] = 'Nginx X-Accel-Redirect ヘッダー';
+$lang['showuseras_o_loginname'] = 'ログイン名';
+$lang['showuseras_o_username'] = 'ユーザーのフルネーム';
+$lang['showuseras_o_email'] = 'ユーザーのメールアドレス(メールガード設定による難読化)';
+$lang['showuseras_o_email_link'] = 'ユーザーのメールアドレスをリンクにする';
+$lang['useheading_o_0'] = '使用しない';
+$lang['useheading_o_navigation'] = 'ナビゲーションのみ';
+$lang['useheading_o_content'] = 'Wikiの内容のみ';
+$lang['useheading_o_1'] = '常に使用する';
+$lang['readdircache'] = 'readdir キャッシュの最大保持期間(秒)';
diff --git a/lib/plugins/config/lang/kk/lang.php b/lib/plugins/config/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/config/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/config/lang/ko/intro.txt b/lib/plugins/config/lang/ko/intro.txt
new file mode 100644
index 000000000..22dd96ef6
--- /dev/null
+++ b/lib/plugins/config/lang/ko/intro.txt
@@ -0,0 +1,9 @@
+====== 환경 설정 관리 ======
+
+DokuWiki 설치할 때 설정들을 변경하기 위해 사용하는 페이지입니다. 각 설정에 대한 자세한 도움말이 필요하다면 [[doku>ko:config|설정 문서(번역)]]와 [[doku>config|설정 문서(영문)]]를 참조합니다.
+
+플러그인에 대한 자세한 정보가 필요하다면 [[doku>plugin:config|플러그인 설정]]페이지를 참조합니다. 붉은 배경색으로 보이는 설정들은 이 플러인에서 변경하지 못하도록 되어있습니다. 파란 배경색으로 보이는 설정들은 기본 설정값을 가지고 있습니다. 흰색 배경색으로 보이는 설정들은 특별한 설치를 위해 설정되어 있습니다. 파란색과 흰색 배경 설정들이 수정 가능합니다.
+
+이페이지를 끝내기 전에 **저장**버튼을 누르지 않으면 설정값들은 적용되지 않습니다.
+
+
diff --git a/lib/plugins/config/lang/ko/lang.php b/lib/plugins/config/lang/ko/lang.php
new file mode 100644
index 000000000..20cfcdcfe
--- /dev/null
+++ b/lib/plugins/config/lang/ko/lang.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * korean language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author jk Lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['menu'] = '환경 설정';
+$lang['error'] = '잘못된 값때문에 설정들을 변경할 수 없습니다. 수정한 값들을 검사하고 확인을 누르기 바랍니다.
+ <br />잘못된 값(들)은 붉은 선으로 둘러싸여 있습니다.';
+$lang['updated'] = '설정이 성공적으로 변경되었습니다.';
+$lang['nochoice'] = '(다른 선택이 불가능합니다.)';
+$lang['locked'] = '환경 설정 파일을 수정할 수 없습니다. 의도된 행동이 아니라면,<br /> 파일이름과 권한이 맞는지 확인하기 바랍니다. ';
+$lang['danger'] = '위험 : 이 옵션을 잘못 수정하면 환경설정 메뉴를 사용할 수 없을 수도 있습니다.';
+$lang['warning'] = '경고 : 이 옵션을 잘못 수정하면 잘못 동작 할 수 있습니다.';
+$lang['security'] = '보안 경고 : 이 옵션은 보안에 위험이 있을 수 있습니다.';
+$lang['_configuration_manager'] = '환경 설정 관리자';
+$lang['_header_dokuwiki'] = 'DokuWiki 설정';
+$lang['_header_plugin'] = 'Plugin 설정';
+$lang['_header_template'] = 'Template 설정';
+$lang['_header_undefined'] = '정의되지 않은 설정';
+$lang['_basic'] = '기본 설정';
+$lang['_display'] = '화면 표시 설정';
+$lang['_authentication'] = '인증 설정';
+$lang['_anti_spam'] = '안티-스팸 설정';
+$lang['_editing'] = '편집 설정';
+$lang['_links'] = '링크 설정';
+$lang['_media'] = '미디어 설정';
+$lang['_advanced'] = '진보된 설정';
+$lang['_network'] = '네트워크 설정';
+$lang['_plugin_sufix'] = 'Plugin 설정';
+$lang['_template_sufix'] = 'Template 설정';
+$lang['_msg_setting_undefined'] = '설정되지 않은 메타데이타.';
+$lang['_msg_setting_no_class'] = '설정되지 않은 클래스.';
+$lang['_msg_setting_no_default'] = '기본값 없음.';
+$lang['fmode'] = '파일 생성 모드';
+$lang['dmode'] = '디렉토리 생성 모드';
+$lang['lang'] = '언어';
+$lang['basedir'] = '기본 디렉토리';
+$lang['baseurl'] = '기본 URL';
+$lang['savedir'] = '데이타 저장 디렉토리';
+$lang['start'] = '시작 페이지 이름';
+$lang['title'] = '위키 제목';
+$lang['template'] = '템플릿';
+$lang['license'] = '컨텐트에 어떤 라이센스 정책을 적용하시겠습니까?';
+$lang['fullpath'] = '페이지 하단에 전체 경로 보여주기';
+$lang['recent'] = '최근에 바뀐 것';
+$lang['breadcrumbs'] = '위치 추적 수';
+$lang['youarehere'] = '계층형 위치 추적';
+$lang['typography'] = '기호 대체';
+$lang['htmlok'] = 'HTML 내장 허용';
+$lang['phpok'] = 'PHP 내장 허용';
+$lang['dformat'] = '날짜 포맷 (PHP <a href="http://www.php.net/strftime">strftime</a> 기능) 참조';
+$lang['signature'] = '서명';
+$lang['toptoclevel'] = '목차 최상위 항목';
+$lang['tocminheads'] = '목차 표시 여부를 결정할 최소한의 표제 항목의 수';
+$lang['maxtoclevel'] = '목차 최대 단계';
+$lang['maxseclevel'] = '섹션 최대 편집 단계';
+$lang['camelcase'] = '링크에 CamelCase 사용';
+$lang['deaccent'] = '악센트 없는 페이지 이름';
+$lang['useheading'] = '페이지 이름으로 첫 헤드라인 사용';
+$lang['refcheck'] = '미디어 참조 검사';
+$lang['refshow'] = '보여줄 미디어 참조 수';
+$lang['allowdebug'] = '디버그 허용 <b>필요하지 않으면 금지!</b>';
+$lang['usewordblock'] = '금지단어를 사용해 스팸 막기';
+$lang['indexdelay'] = '색인 연기 시간(초)';
+$lang['relnofollow'] = '외부 링크에 rel="nofollow" 사용';
+$lang['mailguard'] = '이메일 주소를 알아볼 수 없게';
+$lang['iexssprotect'] = '업로드 파일의 악성 Javascript, HTML 코드 가능성 여부를 검사';
+$lang['showuseras'] = '마지막으로 페이지를 수정한 사용자를 보여줄지 여부';
+$lang['useacl'] = '접근 제어 목록(ACL) 사용';
+$lang['autopasswd'] = '자동으로 만들어진 패스워드';
+$lang['authtype'] = '인증 백-엔드';
+$lang['passcrypt'] = '패스워드 암호화 방법';
+$lang['defaultgroup'] = '기본 그룹';
+$lang['superuser'] = '슈퍼 유저';
+$lang['manager'] = '관리자 - 관리 기능들을 사용할 수 있는 그룹이나 사용자';
+$lang['profileconfirm'] = '개인정보 변경시 암호 재확인';
+$lang['disableactions'] = 'DokuWiki Action 금지';
+$lang['disableactions_check'] = '검사';
+$lang['disableactions_subscription'] = '구독 신청/해지';
+$lang['disableactions_wikicode'] = '문서 소스 보기';
+$lang['disableactions_other'] = '다른 Action(comma로 구분)';
+$lang['sneaky_index'] = '기본적으로, DokuWiki는 색인 목록에 모든 네임스페이스들을 보여줍니다.
+이 옵션을 설정하면 사용자가 읽기 권한을 가지고 있지 않은 네임스페이스들은 보여주지 않습니다. 접근 가능한 하위 네임스페이스들 보이지않게 설정하면 자동으로 설정됩니다.
+특정 ACL 설정은 색인 사용이 불가능하게 할 수도 있습니다.';
+$lang['auth_security_timeout'] = '인증 보안 초과 시간(초)';
+$lang['securecookie'] = 'HTTPS로 보내진 쿠키는 HTTPS에만 적용 할까요? 위키의 로그인 페이지만 SSL로 암호화 하고 위키 페이지는 그렇지 않은경우 꺼야 합니다.';
+$lang['xmlrpc'] = 'XML-RPC 인터페이스 지원/무시';
+$lang['xmlrpcuser'] = '주어진 그룹이나 유저들에게만 XML-RPC접근을 허락하려면 컴마로 구분하여 적으세요. 비어두면 모두에게 허용됩니다.';
+$lang['updatecheck'] = '업데이트와 보안 문제를 검사(DokuWiki를 update.dokuwiki.org에 연결해야 합니다.)';
+$lang['userewrite'] = 'URL rewriting기능 사용';
+$lang['useslash'] = 'URL에서 네임스페이스 구분자로 슬래쉬 문자 사용';
+$lang['usedraft'] = '편집하는 동안 자동으로 문서 초안 저장';
+$lang['sepchar'] = '페이지 이름 단어 구분자';
+$lang['canonical'] = '완전한 canonical URL 사용';
+$lang['fnencode'] = '아스키가 아닌 파일이름을 인코딩 하는 방법.';
+$lang['autoplural'] = '링크 연결시 plural폼 검사';
+$lang['compression'] = 'attic파일 압축 방법 선택';
+$lang['cachetime'] = '최대 캐쉬 생존 시간(초)';
+$lang['locktime'] = '쵀대 파일 잠금 시간(초)';
+$lang['fetchsize'] = 'fetch.php가 외부에서 다운로드할 수도 있는 최대 크기(바이트)';
+$lang['notify'] = '이메일 알람 기능';
+$lang['registernotify'] = '신규 등록자 알람 기능';
+$lang['mailfrom'] = '자동으로 보내지는 메일 발신자';
+$lang['mailprefix'] = '자동으로 보내지는 메일의 제목 말머리 내용';
+$lang['gzip_output'] = 'xhml 내용 gzip 압축 여부';
+$lang['gdlib'] = 'GD 라이브러리 버전';
+$lang['im_convert'] = 'ImageMagick 위치';
+$lang['jpg_quality'] = 'JPG 압축 품질 (0-100)';
+$lang['subscribers'] = '페이지 갱신 알람 기능';
+$lang['subscribe_time'] = ' 구독 목록과 요약이 보내질 경과 시간 (초); 이 것은 recent_days에서 설정된 시간보다 작아야 합니다.';
+$lang['compress'] = '최적화된 CSS, javascript 출력';
+$lang['hidepages'] = '매칭된 페이지 숨기기(정규표현식)';
+$lang['send404'] = '존재하지 않는 페이지에 대해 "HTTP 404/Page Not Found" 응답';
+$lang['sitemap'] = '구글 사이트맵 생성(날짜)';
+$lang['broken_iua'] = '설치된 시스템에서 ignore_user_abort 기능에 문제가 있으면 색인이 정상적으로 동작하지 않습니다. 이 기능이 IIS+PHP/CGI에서 문제가 있는 것으로 알려졌습니다. 자세한 정보는 <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>를 참고하기 바랍니다.';
+$lang['xsendfile'] = '웹 서버 static 파일 전송 지원을 위해 X-Sendfile 헤더를 사용한다면 이 옵션을 사용합니다.
+웹 서버가 이 기능을 지원해야 합니다.';
+$lang['renderer_xhtml'] = '주 (xhtml) 위키 출력 처리기';
+$lang['renderer__core'] = '%s (DokuWiki 내부 기능)';
+$lang['renderer__plugin'] = '%s (DokuWiki 플러그인)';
+$lang['rememberme'] = '로그인 정보 저장 허용';
+$lang['rss_type'] = 'XML feed 타잎';
+$lang['rss_linkto'] = 'XML feed 링크 정보';
+$lang['rss_content'] = 'XML feed 항목들에 표시되는 내용은?';
+$lang['rss_update'] = 'XML feed 갱신 주기(초)';
+$lang['recent_days'] = '최근 바뀐 페이지 기준 시간(날짜)';
+$lang['rss_show_summary'] = 'XML feed 제목에서 요약정보 보여주기';
+$lang['target____wiki'] = '내부 링크들에 대한 타겟 윈도우 ';
+$lang['target____interwiki'] = 'InterWiki 링크들에 대한 타겟 윈도우';
+$lang['target____extern'] = '외부 링크들에 대한 타겟 윈도우';
+$lang['target____media'] = '미디어 링크들에 대한 타겟 윈도우';
+$lang['target____windows'] = '윈도우 링크들에 대한 타겟 윈도우';
+$lang['proxy____host'] = '프록시 서버 이름';
+$lang['proxy____port'] = '프록시 서버 포트';
+$lang['proxy____user'] = '프록시 사용자 이름';
+$lang['proxy____pass'] = '프록시 패스워드';
+$lang['proxy____ssl'] = '프록시 연결시 ssl사용';
+$lang['proxy____except'] = '프록시설정이 무시될 URL주소들의 RegEx형식표현';
+$lang['safemodehack'] = 'safemode hack기능 사용';
+$lang['ftp____host'] = 'safemode hack의 FTP 서버';
+$lang['ftp____port'] = 'safemode hack의 FTP port';
+$lang['ftp____user'] = 'safemode hack의 FTP 사용자 이름';
+$lang['ftp____pass'] = 'safemode hack의 FTP 패스워드';
+$lang['ftp____root'] = 'safemode hack의 FTP 루트 디렉토리';
+$lang['license_o_'] = '선택하지 않음';
+$lang['typography_o_0'] = '사용 안함';
+$lang['typography_o_1'] = '이중 인용부호("")만 지원';
+$lang['typography_o_2'] = '모든 가능한 인용 부호 (동작 안될 수도 있음)';
+$lang['userewrite_o_0'] = '사용 안함';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki 내부 기능';
+$lang['deaccent_o_0'] = '사용 안함';
+$lang['deaccent_o_1'] = '악센트 제거';
+$lang['deaccent_o_2'] = '라틴문자화';
+$lang['gdlib_o_0'] = 'GD 라이브러리 사용 불가';
+$lang['gdlib_o_1'] = '버전 1.x';
+$lang['gdlib_o_2'] = '자동 인식';
+$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';
+$lang['rss_content_o_abstract'] = '개요';
+$lang['rss_content_o_diff'] = '통합 차이점 목록';
+$lang['rss_content_o_htmldiff'] = '차이점 목록 (HTML 테이블)';
+$lang['rss_content_o_html'] = '내용 (HTML 페이지)';
+$lang['rss_linkto_o_diff'] = '차이점 보기';
+$lang['rss_linkto_o_page'] = '변경 페이지 보기';
+$lang['rss_linkto_o_rev'] = '변경 목록 보기';
+$lang['rss_linkto_o_current'] = '최근 페이지 보기';
+$lang['compression_o_0'] = '없음';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = '사용 불가';
+$lang['xsendfile_o_1'] = '비공개 lighttpd 헤더 (1.5 이전 버전)';
+$lang['xsendfile_o_2'] = '표준 X-Sendfile 헤더';
+$lang['xsendfile_o_3'] = '비공개 Nginx X-Accel-Redirect 헤더';
+$lang['showuseras_o_loginname'] = '로그인 이름';
+$lang['showuseras_o_username'] = '사용자 이름';
+$lang['showuseras_o_email'] = '사용자 e-mail 주소(메일주소 보호 셋팅에 따라 안보일 수 있음)';
+$lang['showuseras_o_email_link'] = 'mailto: link로 표현될 사용자 e-mail 주소';
+$lang['useheading_o_0'] = '아니요';
+$lang['useheading_o_navigation'] = '네비게이션에만';
+$lang['useheading_o_content'] = '위키 내용에만';
+$lang['useheading_o_1'] = '항상';
+$lang['readdircache'] = 'readdir 캐쉬를 위한 최대 시간 (초)';
diff --git a/lib/plugins/config/lang/la/intro.txt b/lib/plugins/config/lang/la/intro.txt
new file mode 100644
index 000000000..573d34ac1
--- /dev/null
+++ b/lib/plugins/config/lang/la/intro.txt
@@ -0,0 +1,7 @@
+====== Optionum Administratio ======
+
+In hac pagina administratoris optiones mutare et inspicere potes. Auxilia in pagina [[doku>config|conformationis]] sunt, si singulas res uidere uis, i ad paginam [[doku>plugin:config|conformationis]].
+
+Optiones ostensae rubro colore tutae et non nunc mutabiles sunt. Optiones ostensae caeruleo colore praecipuae sunt et optiones ostensae in area alba singulares huic uici sunt. Et caerulae et albae optiones mutabiles sunt.
+
+Memento premere **SERVA** ante quam nouam paginam eas: si hoc non facias, mutata amissa sunt. \ No newline at end of file
diff --git a/lib/plugins/config/lang/la/lang.php b/lib/plugins/config/lang/la/lang.php
new file mode 100644
index 000000000..07d92ae36
--- /dev/null
+++ b/lib/plugins/config/lang/la/lang.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['menu'] = 'Optiones Administrationis';
+$lang['error'] = 'Optiones non nouatae ob errores: rursum temptat. Errores rubro colore signati sunt.';
+$lang['updated'] = 'Optiones feliciter nouatae.';
+$lang['nochoice'] = '(nulla optio est)';
+$lang['locked'] = 'Optio documenti non nouata est, <br/> optiones et facultates documenti inspicis.';
+$lang['danger'] = 'CAVE: si has optiones mutabis, in administrationis indicem non inire potes.';
+$lang['warning'] = 'CAVE: si hae optiones mutabis, graues errores erunt.';
+$lang['security'] = 'CAVE: si hae optiones mutabis, graues errores erunt.';
+$lang['_configuration_manager'] = 'Optionum administratio';
+$lang['_header_dokuwiki'] = 'Vicis Optiones';
+$lang['_header_plugin'] = 'Addendorum Optiones';
+$lang['_header_template'] = 'Vicis Formae Optiones';
+$lang['_header_undefined'] = 'Variae Optiones';
+$lang['_basic'] = 'Praecipuae Optiones';
+$lang['_display'] = 'Speciei Optiones';
+$lang['_authentication'] = 'Confirmationis Optiones';
+$lang['_anti_spam'] = 'In Mala Optiones';
+$lang['_editing'] = 'Recensendi Optiones';
+$lang['_links'] = 'Nexi Optiones';
+$lang['_media'] = 'Visiuorum Optiones';
+$lang['_advanced'] = 'Maiores Optiones';
+$lang['_network'] = 'Interretis Optiones';
+$lang['_plugin_sufix'] = 'Addendorum Optiones';
+$lang['_template_sufix'] = 'Vicis Formae Optiones';
+$lang['_msg_setting_undefined'] = 'Res codicum sine optionibus.';
+$lang['_msg_setting_no_class'] = 'Classes sine optionibus';
+$lang['_msg_setting_no_default'] = 'Nihil';
+$lang['fmode'] = 'Documentum creandum ratio';
+$lang['dmode'] = 'Scrinia creandam ratio';
+$lang['lang'] = 'Linguae optiones';
+$lang['basedir'] = 'Computatoris seruitoris domicilium (ex. <code>/dokuwiki/</code>). Nihil scribere si id machinatione agnoscere uis.';
+$lang['baseurl'] = 'Computatoris seruitoris VRL (ex. <code>http://www.yourserver.com</code>). Nihil scribere si id machinatione agnoscere uis.';
+$lang['savedir'] = 'Documentorum seruatorum domicilium';
+$lang['start'] = 'Nomen paginae dominicae';
+$lang['title'] = 'Vicis titulus';
+$lang['template'] = 'Vicis forma';
+$lang['license'] = 'Sub quibus legibus uicem creare uin?';
+$lang['fullpath'] = 'Totum domicilium paginae in pedibus scribis.';
+$lang['recent'] = 'Extremae mutationes';
+$lang['breadcrumbs'] = 'Numerus uestigiorum';
+$lang['youarehere'] = 'Ordo uestigiorum';
+$lang['typography'] = 'Signa supponentes';
+$lang['htmlok'] = 'HTML aptum facere';
+$lang['phpok'] = 'PHP aptum facere';
+$lang['dformat'] = 'Forma diei (uide paginam <a href="http://www.php.net/strftime">de diebus</a>)';
+$lang['signature'] = 'Subscriptio';
+$lang['toptoclevel'] = 'Gradus maior tabularum argumentorum';
+$lang['tocminheads'] = 'Minimus numerus capitum';
+$lang['maxtoclevel'] = 'Maximus numerus tabularum argumentorum';
+$lang['maxseclevel'] = 'Maxima pars gradus recensendi';
+$lang['camelcase'] = 'SignaContinua nexis apta facere';
+$lang['deaccent'] = 'Titulus paginarum abrogare';
+$lang['useheading'] = 'Capite primo ut titulo paginae uti';
+$lang['refcheck'] = 'Documenta uisiua inspicere';
+$lang['refshow'] = 'Numerus documentorum ostendorum';
+$lang['allowdebug'] = '<b>ineptum facias si non necessarium!</b> aptum facere';
+$lang['usewordblock'] = 'Malum interretiale ob uerba delere';
+$lang['indexdelay'] = 'Tempus transitum in ordinando (sec)';
+$lang['relnofollow'] = 'rel="nofollow" externis nexis uti';
+$lang['mailguard'] = 'Cursus interretiales abscondere';
+$lang['iexssprotect'] = 'Documenta nouata ob mala JavaScript uel HTML inspicere';
+$lang['showuseras'] = 'Quid, cum Sodalem, qui extremus paginam recensuit, ostendat, scribere';
+$lang['useacl'] = 'Aditus inspectionis indicibus uti';
+$lang['autopasswd'] = 'Tessera machinatione generata';
+$lang['authtype'] = 'Confirmationis finis';
+$lang['passcrypt'] = 'Ratio tesserae tuendae';
+$lang['defaultgroup'] = 'Grex communis';
+$lang['superuser'] = 'Magister\stra - grex, Sodalis uel index diuisus a uigulis sodalis1,@grex,sodalis2 cum plenis facultatibus sine ICA optionum termino';
+$lang['manager'] = 'Administrator - grex, Sodalis uel index diuisus a uigulis sodalis1,@grex,sodalis2 cum certis facultatibus';
+$lang['profileconfirm'] = 'Mutationes tessera confirmanda sunt';
+$lang['disableactions'] = 'Vicis actiones ineptas facere';
+$lang['disableactions_check'] = 'Inspicere';
+$lang['disableactions_subscription'] = 'Inscribe/Delere';
+$lang['disableactions_wikicode'] = 'Fontem uidere/Rudem transcribere';
+$lang['disableactions_other'] = 'Aliae actiones (uirgulis diuisae)';
+$lang['sneaky_index'] = 'Hic uicis omnia genera in indice inserit. Si ineptam hanc optionem facias, solum ea, quae Sodales uidere possunt, in indice erunt. Hoc suggreges et suggenera abscondere potest.';
+$lang['auth_security_timeout'] = 'Confirmationis Tempus (secundis)';
+$lang['securecookie'] = 'Formulae HTTPS mittine solum per HTTPS possunt? Ineptam hanc optio facias, si accessus uicis tutus est, sed interretis non.';
+$lang['xmlrpc'] = 'Aptam\Ineptam XML-RPC administrationem facere';
+$lang['xmlrpcuser'] = 'Accessus XML-RPC gregibus uel Sodalibus in hoc indice astringere. Nihil scribere ut omnes accessum habeant';
+$lang['updatecheck'] = 'Nouationes et fiducias inspicerene? Hic uicis connectere update.dokuwiki.org debes.';
+$lang['userewrite'] = 'VRL formosis uti';
+$lang['useslash'] = 'Repagula in URL, ut genera diuidas, uti';
+$lang['usedraft'] = 'Propositum in recensione machinatione seruatur';
+$lang['sepchar'] = 'Signum, quod paginas diuidit';
+$lang['canonical'] = 'VRL perfecto uti';
+$lang['fnencode'] = 'Ratio quae nomen documentorum non-ASCII codificit';
+$lang['autoplural'] = 'Pluralia in nexis inspicere';
+$lang['compression'] = 'Ratio compressionis documentis "attic"';
+$lang['cachetime'] = 'Maximum tempus formulis (sec)';
+$lang['locktime'] = 'Maximum tempus documentis inclusis (sec)';
+$lang['fetchsize'] = 'Maximum pondus (bytes), quod fetch.php ab externis onerare potest';
+$lang['notify'] = 'Adnotationis mutationes ad hunc cursum mittere';
+$lang['registernotify'] = 'De nouis Sodalibus ad hunc cursum notas mittere';
+$lang['mailfrom'] = 'Cursus interretialis, quo in cursibus uti';
+$lang['gzip_output'] = 'gzip Argumentum-Codificans xhtml uti';
+$lang['gdlib'] = 'GD Lib forma';
+$lang['im_convert'] = 'Domicilium machinae ImageMagick\'s';
+$lang['jpg_quality'] = 'JPG compressio colorum (0-100)';
+$lang['subscribers'] = 'Inscriptionis paginarum auxilium aptus facere';
+$lang['subscribe_time'] = 'Tempus post quod inscriptionum index et summa missa sunt (sec); Hic minor quam tempus declaratum fortasse est.';
+$lang['compress'] = 'CSS et javascript dimissio';
+$lang['hidepages'] = 'Paginas congruentes abscondere (uerba regularia)';
+$lang['send404'] = 'Mitte "HTTP 404/ Pagina non reperta" si paginae non sunt.';
+$lang['sitemap'] = 'Google formam situs gignere (dies)';
+$lang['broken_iua'] = 'ignore_user_abort functio inepta estne? Hoc indicem quaestionum, quae non aptae sunt, creare non potest. IIS+PHP/CGI ineptum est. Vide <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>';
+$lang['xsendfile'] = 'X-Sendfile utine ut seruitor interretialis documenta firma creet? Tuus seruitor interretialis hunc pati debes.';
+$lang['renderer_xhtml'] = 'Quid dimittere ut hoc in principio uicis (xhtml) utaris';
+$lang['renderer__core'] = '%s (uicis nucleus)';
+$lang['renderer__plugin'] = '%s (addenda)';
+$lang['rememberme'] = 'Formulas aditus aptas facere (memento me)';
+$lang['rss_type'] = 'XML summae genus';
+$lang['rss_linkto'] = 'XML summae connectio';
+$lang['rss_content'] = 'Quid in XML summis uidere?';
+$lang['rss_update'] = 'XML summae renouationis interuallum temporis';
+$lang['recent_days'] = 'Numerus mutationum recentium tenendorum (dies)';
+$lang['rss_show_summary'] = 'XML summa titulos ostendit';
+$lang['target____wiki'] = 'Fenestra nexis internis';
+$lang['target____interwiki'] = 'Fenestra nexis inter uicem';
+$lang['target____extern'] = 'Fenestra nexis externis';
+$lang['target____media'] = 'Fenestra nexis uisiuis';
+$lang['target____windows'] = 'Fenestra nexis fenestrarum';
+$lang['proxy____host'] = 'Proxis seruitoris nomen';
+$lang['proxy____port'] = 'Proxis portus';
+$lang['proxy____user'] = 'Proxis nomen sodalis';
+$lang['proxy____pass'] = 'Proxis tessera';
+$lang['proxy____ssl'] = 'SSL ut connectas uti';
+$lang['proxy____except'] = 'Verba, ut VRL inspicias, quibus Proxis non agnoscitur.';
+$lang['safemodehack'] = 'Ad tempus conseruatio apta facere';
+$lang['ftp____host'] = 'FTP computator seruitor ad tempus seruatis';
+$lang['ftp____port'] = 'FTP ianua ad tempus seruatis';
+$lang['ftp____user'] = 'FTP Sodalis ad tempus seruatis';
+$lang['ftp____pass'] = 'FTP tessera ad tempus seruatis';
+$lang['ftp____root'] = 'FTP domicilium ad tempus seruatis';
+$lang['license_o_'] = 'Nihil electum';
+$lang['typography_o_0'] = 'neuter';
+$lang['typography_o_1'] = 'sine singulis uirgulis';
+$lang['typography_o_2'] = 'cum singulis uirgulis';
+$lang['userewrite_o_0'] = 'neuter';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki domesticus';
+$lang['deaccent_o_0'] = 'ex';
+$lang['deaccent_o_1'] = 'accentum tollere';
+$lang['deaccent_o_2'] = 'Latinis litteris';
+$lang['gdlib_o_0'] = 'GD Lib inepta';
+$lang['gdlib_o_1'] = 'Forma 1.x';
+$lang['gdlib_o_2'] = 'Machinatione inspicere';
+$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';
+$lang['rss_content_o_abstract'] = 'Summa';
+$lang['rss_content_o_diff'] = 'Comparatio una';
+$lang['rss_content_o_htmldiff'] = 'Tabulae HTML formatae comparatae';
+$lang['rss_content_o_html'] = 'Pagina cum HTML';
+$lang['rss_linkto_o_diff'] = 'discrimina uidere';
+$lang['rss_linkto_o_page'] = 'pagina recensita';
+$lang['rss_linkto_o_rev'] = 'recensionum index';
+$lang['rss_linkto_o_current'] = 'hic pagina';
+$lang['compression_o_0'] = 'neuter';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'Noli uti';
+$lang['xsendfile_o_2'] = 'Praecipuus X-Sendfile';
+$lang['xsendfile_o_3'] = 'Proprietarius Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Sodalis nomen';
+$lang['showuseras_o_username'] = 'Sodalis nomen uerum';
+$lang['showuseras_o_email'] = 'Sodalis cursus interretialis (absconditus ut is tueratur)';
+$lang['showuseras_o_email_link'] = 'Sodalis cursus interretialis ut mailto: nexum';
+$lang['useheading_o_0'] = 'Numquam';
+$lang['useheading_o_navigation'] = 'Solum adspicere';
+$lang['useheading_o_content'] = 'Solum uicis argumentum';
+$lang['useheading_o_1'] = 'Semper';
+$lang['readdircache'] = 'Maximum tempus readdir (sec)';
diff --git a/lib/plugins/config/lang/lb/intro.txt b/lib/plugins/config/lang/lb/intro.txt
new file mode 100644
index 000000000..964ee851c
--- /dev/null
+++ b/lib/plugins/config/lang/lb/intro.txt
@@ -0,0 +1,7 @@
+====== Konfiguratioun ======
+
+Dëses Plugin hëlleft der bei der Konfiguratioun vun DokuWiki. Hëllef zu deenen eenzelnen Astellungen fënns de ënner [[doku>config]]. Méi Informatiounen zu dësem Plugin kriss de ënner [[doku>plugin:config]].
+
+Astellungen mat engem hellrouden Hannergrond si geséchert a kënnen net mat dësem Plugin verännert ginn. Astellungen mat hellbloem Hannergrond si Virastellungen, wäiss hannerluechte Felder weisen lokal verännert Werter un. Souwuel dié blo wéi och déi wäiss Felder kënne verännert ginn.
+
+Vergiess w.e.g. net **Späicheren** ze drécken iers de d'Säit verléiss, anescht ginn all deng Ännerungen verluer.
diff --git a/lib/plugins/config/lang/lb/lang.php b/lib/plugins/config/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/config/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/config/lang/lt/intro.txt b/lib/plugins/config/lang/lt/intro.txt
new file mode 100644
index 000000000..ac3c2f6e8
--- /dev/null
+++ b/lib/plugins/config/lang/lt/intro.txt
@@ -0,0 +1,7 @@
+====== Konfiguracijos Administravimas ======
+
+Naudokite šį puslapį Dokuwiki instaliacijos tvarkymui. Pagalba individualiems nustatymams [[doku>config]]. Daugiau informacijos apie šį priedą [[doku>plugin:config]].
+
+Nustatymai raudoname fone yra apsaugoti nuo pakeitimų ir negali būti pakeisti šio įrankio pagalba. Nustatymai mėlyname fone nustatyti pagal nutylėjimą, o baltame fone nustatyti lokaliai būtent šiai instaliacijai. Nustatymai mėlyname ir baltame fone gali būti keičiami.
+
+Prieš paliekant ši puslapį, nepamirškite išsaugoti pakeitimus, tai galite padaryti nuspaudę **SAVE** mygtuką, kitu atveju pakeitimai nebus išsaugoti.
diff --git a/lib/plugins/config/lang/lt/lang.php b/lib/plugins/config/lang/lt/lang.php
new file mode 100644
index 000000000..eff7f0e4a
--- /dev/null
+++ b/lib/plugins/config/lang/lt/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['lang'] = 'Kalba';
+$lang['template'] = 'Paruoštukas';
+$lang['recent'] = 'Paskutiniai taisymai';
+$lang['disableactions_check'] = 'Patikrinti';
+$lang['xsendfile_o_1'] = 'Firminė lighthttpd antraštė (prieš 1.5 išleidimą)';
+$lang['xsendfile_o_2'] = 'Standartinė X-Sendfile antraštė';
+$lang['xsendfile_o_3'] = 'Firminė Nginx X-Accel-Redirect antraštė';
+$lang['showuseras_o_loginname'] = 'Prisijungimo vardas';
+$lang['showuseras_o_username'] = 'Vartotojo pilnas vardas';
+$lang['showuseras_o_email'] = 'Vartotojo el. pašto adresas (pasak pašto apsaugos yra netinkamas)';
+$lang['showuseras_o_email_link'] = 'Vartotojo el. pašto adresas kaip mailto: nuoroda';
+$lang['useheading_o_0'] = 'Niekada';
+$lang['useheading_o_navigation'] = 'Tik Navigacija';
+$lang['useheading_o_content'] = 'Tik Wiki Turinys';
+$lang['useheading_o_1'] = 'Visada';
diff --git a/lib/plugins/config/lang/lv/intro.txt b/lib/plugins/config/lang/lv/intro.txt
new file mode 100644
index 000000000..e4d8d4526
--- /dev/null
+++ b/lib/plugins/config/lang/lv/intro.txt
@@ -0,0 +1,7 @@
+====== Konfigurācijas vednis ======
+
+Lapā var uzdot DokuWiki instalācijas iestatījumus. Palīdzību par atsevišķiem iestatījumiem meklēt [[doku>config]]. Sīkākas ziņas par šo moduli skatīt [[doku>plugin:config]].
+
+Ar sarkanu fonu parādītie iestatījumi ir aizsargāti un ar šo moduli nav labojami. Ar zilu fonu parādītie iestatījumi ir noklusētās vērtības, bet uz balta fona parādīti programmas lokālie iestatījumi . Gan zilos, gan baltos var labot.
+
+Pirms aizej no šīs lapas, atceries nopsiest pogu **SAGLABĀT**, lai nezustu veiktās izmaiņas.
diff --git a/lib/plugins/config/lang/lv/lang.php b/lib/plugins/config/lang/lv/lang.php
new file mode 100644
index 000000000..2f5883269
--- /dev/null
+++ b/lib/plugins/config/lang/lv/lang.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * Latvian, Lettish language file
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['menu'] = 'Konfigurācijas iestatījumi.';
+$lang['error'] = 'Iestatījumi nav saglabāti, jo uzdotas aplamas vērtības. Lūdzu pārskatīt izmaiņas un saglabāt atkārtoti.
+<br /> Aplamās vērtības izceltas sarkanā rāmī.';
+$lang['updated'] = 'Iestatījumi veiksmīgi saglabāti.';
+$lang['nochoice'] = '(citu iespēju nav)';
+$lang['locked'] = 'Iestatījumu fails nav grozāms, ja tā nevajag būt, <br />
+pārliecinies, ka ir pareizs lokālo iestatījuma faila vārds un tiesības.';
+$lang['danger'] = 'Bīstami: Šī parametra maiņa var padarīt wiki sistēmu un konfigurācijas izvēlni nepieejamu.';
+$lang['warning'] = 'Brīdinājums: Šī parametra maiņa var izraisīt negaidītu programmas uzvedību.';
+$lang['security'] = 'Drošības brīdinājums: Šī parametra maiņa var būt riskanta drošībai.';
+$lang['_configuration_manager'] = 'Konfigurācijas pārvaldnieks';
+$lang['_header_dokuwiki'] = 'Dokuwiki iestatījumi';
+$lang['_header_plugin'] = 'Moduļu iestatījumi';
+$lang['_header_template'] = 'Šablonu iestatījumi';
+$lang['_header_undefined'] = 'Citi iestatījumi';
+$lang['_basic'] = 'Pamatiestatījumi';
+$lang['_display'] = 'Izskata iestatījumi';
+$lang['_authentication'] = 'Autentifikācija';
+$lang['_anti_spam'] = 'Pretspama iestatījumi';
+$lang['_editing'] = 'Labošanas iestatījumi';
+$lang['_links'] = 'Saišu iestatījumi';
+$lang['_media'] = 'Mēdiju iestatījumi';
+$lang['_advanced'] = 'Smalkāka iestatīšana';
+$lang['_network'] = 'Tīkla iestatījumi';
+$lang['_plugin_sufix'] = 'moduļa iestatījumi';
+$lang['_template_sufix'] = 'šablona iestatījumi';
+$lang['_msg_setting_undefined'] = 'Nav atrodami iestatījumu metadati';
+$lang['_msg_setting_no_class'] = 'Nav iestatījumu klases';
+$lang['_msg_setting_no_default'] = 'Nav noklusētās vērtības';
+$lang['fmode'] = 'Tiesības izveidotajiem failiem';
+$lang['dmode'] = 'Tiesības izveidotajām direktorijām';
+$lang['lang'] = 'Valoda';
+$lang['basedir'] = 'Saknes direktorija';
+$lang['baseurl'] = 'Saknes adrese (URL)';
+$lang['savedir'] = 'Direktorija datu glabāšanai';
+$lang['start'] = 'Sākumlapas vārds';
+$lang['title'] = 'Wiki virsraksts';
+$lang['template'] = 'Šablons';
+$lang['license'] = 'Ar kādu licenci saturs tiks publicēts?';
+$lang['fullpath'] = 'Norādīt kājenē pilnu lapas ceļu';
+$lang['recent'] = 'Jaunākie grozījumi';
+$lang['breadcrumbs'] = 'Apmeklējumu vēstures garums';
+$lang['youarehere'] = 'Rādīt "tu atrodies šeit"';
+$lang['typography'] = 'Veikt tipogrāfijas aizvietošanu';
+$lang['htmlok'] = 'Atļaut iekļautu HTTP';
+$lang['phpok'] = 'Atļaut iekļautu PHP';
+$lang['dformat'] = 'Datuma formāts (sk. PHP <a href="http://www.php.net/strftime">strftime</a> funkciju)';
+$lang['signature'] = 'Paraksts';
+$lang['toptoclevel'] = 'Satura rādītāja pirmais līmenis';
+$lang['tocminheads'] = 'Mazākais virsrakstu skaits, no kuriem jāveido satura rādītājs.';
+$lang['maxtoclevel'] = 'Satura rādītāja dziļākais līmenis';
+$lang['maxseclevel'] = 'Dziļākais sekciju labošanas līmenis';
+$lang['camelcase'] = 'Lietot saitēm CamelCase';
+$lang['deaccent'] = 'Lapu nosaukumu transliterācija';
+$lang['useheading'] = 'Izmantot pirmo virsrakstu lapu nosaukumiem';
+$lang['refcheck'] = 'Pārbaudīt saites uz mēdiju failiem';
+$lang['refshow'] = 'Cik saites uz mēdiju failiem rādīt';
+$lang['allowdebug'] = 'Ieslēgt atkļūdošanu. <b>Izslēdz!</b>';
+$lang['usewordblock'] = 'Bloķēt spamu pēc slikto vārdu saraksta.';
+$lang['indexdelay'] = 'Laika aizture pirms indeksācijas (sekundēs)';
+$lang['relnofollow'] = 'rel="nofollow" ārējām saitēm';
+$lang['mailguard'] = 'Slēpt epasta adreses';
+$lang['iexssprotect'] = 'Pārbaudīt, vai augšupielādētajā failā nav nav potenciāli bīstamā JavaScript vai HTML koda.';
+$lang['showuseras'] = 'Kā rādīt pēdējo lietotāju, ka labojis lapu';
+$lang['useacl'] = 'Izmantot piekļuves tiesības';
+$lang['autopasswd'] = 'Automātiski ģenerēt paroles';
+$lang['authtype'] = 'Autentifikācijas mehānisms';
+$lang['passcrypt'] = 'Paroļu šifrēšanas metode';
+$lang['defaultgroup'] = 'Noklusētā grupa';
+$lang['superuser'] = 'Administrators - grupa, lietotājs vai to saraksts ( piem.: user1,@group1,user2), kam ir pilnas tiesības.';
+$lang['manager'] = 'Pārziņi - grupa, lietotājs vai to saraksts ( piem.: user1,@group1,user2), kam ir pieeja pie dažām administrēšanas funkcijām.';
+$lang['profileconfirm'] = 'Profila labošanai vajag paroli';
+$lang['disableactions'] = 'Bloķēt Dokuwiki darbības';
+$lang['disableactions_check'] = 'atzīmēt';
+$lang['disableactions_subscription'] = 'abonēt/atteikties';
+$lang['disableactions_wikicode'] = 'skatīt/eksportēt izejtekstu';
+$lang['disableactions_other'] = 'citas darbības (atdalīt ar komatiem)';
+$lang['sneaky_index'] = 'Pēc noklusētā DokuWiki lapu sarakstā parāda visu nodaļu lapas. Ieslēdzot šo parametru, noslēps tās nodaļas, kuras apmeklētājam nav tiesības lasīt. Bet tad tiks arī paslēptas dziļākas, bet atļautas nodaļas. Atsevišķos pieejas tiesību konfigurācijas gadījumos lapu saraksts var nedarboties.';
+$lang['auth_security_timeout'] = 'Autorizācijas drošības intervāls (sekundēs)';
+$lang['securecookie'] = 'Vai pa HTTPS sūtāmās sīkdatnes sūtīt tikai pa HTTPS? Atslēdz šo iespēju, kad tikai pieteikšanās wiki sistēmā notiek pa SSL šifrētu savienojumu, bet skatīšana - pa nešifrētu.';
+$lang['xmlrpc'] = 'Ieslēgt/izslēgt XML-RPC interfeisu.';
+$lang['xmlrpcuser'] = 'Ierobežot XML-RPC piekļuvi norādītām lietotāju grupām vai lietotājiem (atdalīt ar komatiem!). Atstāt tukšu, lai piekļuve būtu visiem.';
+$lang['updatecheck'] = 'Pārbaudīt, vai pieejami atjauninājumi un drošības brīdinājumi? Dokuwiki sazināsies ar update.dokuwiki.org';
+$lang['userewrite'] = 'Ērti lasāmas adreses (URL)';
+$lang['useslash'] = 'Lietot slīpiņu par URL atdalītāju';
+$lang['usedraft'] = 'Labojot automātiski saglabāt melnrakstu';
+$lang['sepchar'] = 'Lapas nosaukuma vārdu atdalītājs';
+$lang['canonical'] = 'Lietot kanoniskus URL';
+$lang['fnencode'] = 'Ne ASCII failvārdu kodēšanas metode:';
+$lang['autoplural'] = 'Automātisks daudzskaitlis';
+$lang['compression'] = 'Saspiešanas metode vecajiem failiem';
+$lang['cachetime'] = 'Bufera maksimālais vecums (sek)';
+$lang['locktime'] = 'Bloķēšanas failu maksimālais vecums';
+$lang['fetchsize'] = 'Maksimālais faila apjoms baitos, ko fetch.php var ielādēt no interneta.';
+$lang['notify'] = 'Nosūtīt izmaiņu paziņojumu uz epasta adresi';
+$lang['registernotify'] = 'Nosūtīt paziņojumu par jauniem lietotājiem uz epasta adresi';
+$lang['mailfrom'] = 'Epasta adrese automātiskajiem paziņojumiem';
+$lang['mailprefix'] = 'E-pasta temata prefikss automātiskajiem paziņojumiem';
+$lang['gzip_output'] = 'Lietot gzip Content-Encoding priekš xhtml';
+$lang['gdlib'] = 'GD Lib versija';
+$lang['im_convert'] = 'Ceļš uz ImageMagick convert rīku';
+$lang['jpg_quality'] = 'JPG saspiešanas kvalitāte';
+$lang['subscribers'] = 'Atļaut abonēt izmaiņas';
+$lang['subscribe_time'] = 'Pēc cik ilga laika izsūtīt abonētos sarakstus un kopsavilkumus (sekundes); jābūt mazākam par laiku, kas norādīts "recent_days".';
+$lang['compress'] = 'Saspiest CSS un javascript failus';
+$lang['hidepages'] = 'Slēpt lapas (regulāras izteiksmes)';
+$lang['send404'] = 'Par neesošām lapām atbildēt "HTTP 404/Page Not Found" ';
+$lang['sitemap'] = 'Lapas karte priekš Google (dienas)';
+$lang['broken_iua'] = 'Varbūt tavā serverī nedarbojas funkcija ignore_user_abort? Tā dēļ var nestādāt meklēšanas indeksācija. Šī problēma sastopama, piemēram, IIS ar PHP/CGI. Papildus informāciju skatīt <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Kļūdā Nr.852</a>.';
+$lang['xsendfile'] = 'Lietot X-Sendfile virsrakstu, augšupielādējot failu serverī? ';
+$lang['renderer_xhtml'] = 'Galveno (xhtml) wiki saturu renderēt ar ';
+$lang['renderer__core'] = '%s (dokuwiki kodols)';
+$lang['renderer__plugin'] = '%s (modulis)';
+$lang['rememberme'] = 'Atļaut pastāvīgas ielogošanās sīkdatnes ("atceries mani")';
+$lang['rss_type'] = 'XML barotnes veids';
+$lang['rss_linkto'] = 'XML barotnes uz ';
+$lang['rss_content'] = 'Ko attēlot XML barotnē?';
+$lang['rss_update'] = 'XML barotnes atjaunošanas intervāls (sec)';
+$lang['recent_days'] = 'Cik dienas glabāt jaunākās izmaiņas';
+$lang['rss_show_summary'] = 'Rādīt visrakstos XML barotnes kopsavilkumu ';
+$lang['target____wiki'] = 'Kur atvērt iekšējās saites';
+$lang['target____interwiki'] = 'Kur atvērt saites strap wiki';
+$lang['target____extern'] = 'Kur atvērt ārējās saites';
+$lang['target____media'] = 'Kur atvērt mēdiju saites';
+$lang['target____windows'] = 'Kur atvērt saites uz tīkla mapēm';
+$lang['proxy____host'] = 'Proxy servera vārds';
+$lang['proxy____port'] = 'Proxy ports';
+$lang['proxy____user'] = 'Proxy lietotāja vārds';
+$lang['proxy____pass'] = 'Proxy parole';
+$lang['proxy____ssl'] = 'Lietot SSL savienojumu ar proxy';
+$lang['proxy____except'] = 'Regulārā izteiksme tiem URL, kam nevar lietot proxy.';
+$lang['safemodehack'] = 'Lietot safemode apeju';
+$lang['ftp____host'] = 'FTP serveris safemode apejai';
+$lang['ftp____port'] = 'FTP ports safemode apejai';
+$lang['ftp____user'] = 'FTP lietotājvārds safemode apejai';
+$lang['ftp____pass'] = 'FTP parole safemode apejai';
+$lang['ftp____root'] = 'FTP saknes diektorija safemode apejai';
+$lang['license_o_'] = 'Ar nekādu';
+$lang['typography_o_0'] = 'neko';
+$lang['typography_o_1'] = 'tikai dubultpēdiņas';
+$lang['typography_o_2'] = 'visas pēdiņas (ne vienmēr strādā)';
+$lang['userewrite_o_0'] = 'nē';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki līdzekļi';
+$lang['deaccent_o_0'] = 'nē';
+$lang['deaccent_o_1'] = 'atmest diakritiku';
+$lang['deaccent_o_2'] = 'pārrakstīt latīņu burtiem';
+$lang['gdlib_o_0'] = 'GD Lib nav pieejama';
+$lang['gdlib_o_1'] = 'versija 1.x';
+$lang['gdlib_o_2'] = 'noteikt automātiksi';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstract';
+$lang['rss_content_o_diff'] = 'apvienotu diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatētu diff tabulu';
+$lang['rss_content_o_html'] = 'pilnu HTML lapas saturu';
+$lang['rss_linkto_o_diff'] = 'atšķirības';
+$lang['rss_linkto_o_page'] = 'grozītās lapas';
+$lang['rss_linkto_o_rev'] = 'grozījumu sarakstu';
+$lang['rss_linkto_o_current'] = 'patreizējo lapu';
+$lang['compression_o_0'] = 'nav';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nelietot';
+$lang['xsendfile_o_1'] = 'lighttpd (pirms laidiena 1.5) veida galvene';
+$lang['xsendfile_o_2'] = 'Standarta X-Sendfile galvene';
+$lang['xsendfile_o_3'] = 'Nginx X-Accel-Redirect veida galvene';
+$lang['showuseras_o_loginname'] = 'Login vārds';
+$lang['showuseras_o_username'] = 'Pilns lietotāja vārds';
+$lang['showuseras_o_email'] = 'Lietotāja epasta adrese (slēpta ar norādīto paņēmienu)';
+$lang['showuseras_o_email_link'] = 'Lietot epasta adreses kā mailto: saites';
+$lang['useheading_o_0'] = 'Nekad';
+$lang['useheading_o_navigation'] = 'Tikai navigācija';
+$lang['useheading_o_content'] = 'Tikai Wiki saturs';
+$lang['useheading_o_1'] = 'Vienmēr';
+$lang['readdircache'] = 'Maksimālais readdir kesš dzīves laiks (sek.)';
diff --git a/lib/plugins/config/lang/mk/lang.php b/lib/plugins/config/lang/mk/lang.php
new file mode 100644
index 000000000..6d4530f79
--- /dev/null
+++ b/lib/plugins/config/lang/mk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
diff --git a/lib/plugins/config/lang/mr/intro.txt b/lib/plugins/config/lang/mr/intro.txt
new file mode 100644
index 000000000..12ada73a1
--- /dev/null
+++ b/lib/plugins/config/lang/mr/intro.txt
@@ -0,0 +1,10 @@
+====== कॉन्फिगरेशन व्यवस्थापक ======
+
+तुमच्या डॉक्युविकीची सेटिंग बदलान्यासाथी हे पान वापरा.
+विशिष्ठ सेटिंग विषयी माहिती पाहिजे असल्यास [[doku>config]] पहा.
+प्लगिन विषयी अधिक माहितीसाठी [[doku>plugin:config]] पहा.
+हलक्या लाल पार्श्वभूमिमधे दाखवलेले सेटिंग सुरक्षित आहेत व या प्लगिन द्वारा बदलता येणार नाहीत.
+निळ्या पार्श्वभूमीमधे दाखवलेले सेटिंग आपोआप सेट होणार्या किमती आहेत आणि पांढर्या पार्श्वभूमीमधे
+दाखवलेले सेटिंग या इन्स्टॉलेशनसाठी ख़ास सेट केलेले आहेत. निळे आणि पांढरे दोन्ही सेटिंग बदलता येतील.
+
+ह्या पानावरून बाहर जाण्याआधी "Save" चे बटन क्लिक करायला विसरू नका नाहीतर सर्व बदल नाहीसे होतील. \ No newline at end of file
diff --git a/lib/plugins/config/lang/mr/lang.php b/lib/plugins/config/lang/mr/lang.php
new file mode 100644
index 000000000..321e05546
--- /dev/null
+++ b/lib/plugins/config/lang/mr/lang.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['menu'] = 'कॉन्फिगरेशन सेटिंग';
+$lang['error'] = 'चुकीचा शब्द टाकल्यामुळे सेटिंग अद्ययावत केलेली नाहीत. कृपया तुमचे बदल परत तपासा आणि परत सबमिट करा. <br /> चुकीच्या शब्दांभोवती लाल बॉर्डर दाखवली जाईल.';
+$lang['updated'] = 'सेटिंग अद्ययावत केली आहेत.';
+$lang['nochoice'] = '( इतर काही पर्याय नाहीत )';
+$lang['locked'] = 'सेटिंगची फाइल अद्ययावत करू शकलो नाही. जर हे सहेतुक नसेल तर, <br />
+सेटिंग च्या फाइल चे नाव व त्यावरील परवानग्या बरोबर असल्याची खात्री करा.';
+$lang['danger'] = 'सावधान : हा पर्याय बदलल्यास तुमची विकी आणि तिचे कॉनफिगरेशन निकामी होऊ शकते.';
+$lang['warning'] = 'सावघान: येथील पर्याय बदल्यास, अनपेक्षीत गोष्टी होऊ शकतात.';
+$lang['security'] = 'सुरक्षा संबंधी सूचना : हा पर्याय बदलल्यास तुमची साईट असुरक्षित होऊ शकते.';
+$lang['_configuration_manager'] = 'कॉन्फिगरेशन व्यवस्थापक';
+$lang['_header_dokuwiki'] = 'डॉक्युविकि सेटिंग';
+$lang['_header_plugin'] = 'प्लगिन सेटिंग';
+$lang['_header_template'] = 'टेम्पलेट (नमुना) सेटिंग';
+$lang['_header_undefined'] = 'अनिश्चित सेटिंग';
+$lang['_basic'] = 'पायाभूत सेटिंग';
+$lang['_display'] = 'डिसप्ले सेटिंग';
+$lang['_authentication'] = 'अधिकृत करण्याविषयी सेटिंग';
+$lang['_anti_spam'] = 'भंकस-विरोधी सेटिंग';
+$lang['_editing'] = 'संपादन सेटिंग';
+$lang['_links'] = 'लिंक सेटिंग';
+$lang['_media'] = 'दृक्श्राव्य माध्यम सेटिंग';
+$lang['_advanced'] = 'सविस्तर सेटिंग';
+$lang['_network'] = 'नेटवर्क सेटिंग';
+$lang['_plugin_sufix'] = 'प्लगिन सेटिंग';
+$lang['_template_sufix'] = 'टेम्पलेट ( नमुना ) सेटिंग';
+$lang['_msg_setting_undefined'] = 'सेटिंगविषयी उप-डेटा उपलब्ध नाही.';
+$lang['_msg_setting_no_class'] = 'सेटिंगचा क्लास उपलब्ध नाही';
+$lang['_msg_setting_no_default'] = 'आपोआप किम्मत नाही';
+$lang['fmode'] = 'फाइल निर्मिती मोड';
+$lang['dmode'] = 'डिरेक्टरी निर्मिती मोड';
+$lang['lang'] = 'भाषा';
+$lang['basedir'] = 'पायाभूत डिरेक्टरी';
+$lang['baseurl'] = 'पायाभूत URL';
+$lang['savedir'] = 'डेटा साठवण्यासाठीची डिरेक्टरी';
+$lang['start'] = 'सुरुवातीच्या पानाचे नाव';
+$lang['title'] = 'विकीचे शीर्षक';
+$lang['template'] = 'नमुना';
+$lang['license'] = 'कुठल्या लायसंसच्या अंतर्गत तुमचा मजकूर रिलीज़ केला गेला पाहिजे ?';
+$lang['fullpath'] = 'पानांचा पूर्ण पत्ता फूटर मधे दाखव';
+$lang['recent'] = 'अलीकडील बदल';
+$lang['breadcrumbs'] = 'ब्रेडक्रम्बची संख्या';
+$lang['youarehere'] = 'प्रतवार ब्रेडक्रम्ब';
+$lang['typography'] = 'अनवधानाने झालेल्या चुका बदला';
+$lang['htmlok'] = 'अंतर्गत HTML टाकायची परवानगी असू दे';
+$lang['phpok'] = 'अंतर्गत PHP टाकायची परवानगी असू दे';
+$lang['dformat'] = 'दिनांकाची पद्धत ( PHP चं <a href="http://www.php.net/strftime">strftime</a> हे फंक्शन पाहा )';
+$lang['signature'] = 'हस्ताक्षर';
+$lang['toptoclevel'] = 'अनुक्रमणिकेची सर्वोच्च पातळी';
+$lang['tocminheads'] = 'कमीत कमी किती शीर्षके असल्यास अनुक्रमणिका बनवावी';
+$lang['maxtoclevel'] = 'अनुक्रमणिकेची जास्तीत जास्त पातळी ';
+$lang['maxseclevel'] = 'विभागीय संपादनाची जास्तीतजास्त पातळी';
+$lang['camelcase'] = 'लिंकसाठी कॅमलकेस वापरा.';
+$lang['deaccent'] = 'सरळ्सोट पृष्ठ नाम';
+$lang['useheading'] = 'पहिलं शीर्षक पृष्ठ नाम म्हणुन वापरा';
+$lang['refcheck'] = 'दृक्श्राव्य माध्यमाचा संदर्भ तपासा';
+$lang['refshow'] = 'दृक्श्राव्य माध्यामाचे संदर्भ दाखवण्याची संख्या';
+$lang['allowdebug'] = 'डिबगची परवानगी <b> गरज नसल्यास बंद ठेवा !</b>';
+$lang['usewordblock'] = 'भंकस मजकूर थोपवण्यासाठी शब्दसमुह वापरा';
+$lang['indexdelay'] = 'सूचीकरणापूर्वीचा अवकाश ( सेकंदात )';
+$lang['relnofollow'] = 'बाह्य लिन्कसाठी rel=nofollow वापरा';
+$lang['mailguard'] = 'ईमेल दुर्बोध करा';
+$lang['iexssprotect'] = 'अपलोड केलेल्या फाइल हानिकारक जावास्क्रिप्ट किंवा HTML साठी तपासा';
+$lang['showuseras'] = 'पानाचं शेवटचं संपादन करणार्या सदस्याला काय दाखवायचं';
+$lang['useacl'] = 'ACL वापरा';
+$lang['autopasswd'] = 'पासवर्ड आपोआप बनवा';
+$lang['authtype'] = 'अधिकृत करण्याच्या व्यवस्थेचे बॅक-एंड';
+$lang['passcrypt'] = 'पासवर्ड गुप्त ठेवण्याची पद्धत';
+$lang['defaultgroup'] = 'डिफॉल्ट गट';
+$lang['superuser'] = 'सुपर सदस्य - गट, सदस्य किंवा स्वल्पविरामाने अलग केलेली यादी ( उदा. सदस्य१, गट१, सदस्य२ ) ज्यांना ACL च्या सेटिंग व्यतिरिक्त सर्व पानांवर पूर्ण हक्क असतो.';
+$lang['manager'] = 'व्यवस्थापक - गट, सदस्य किंवा स्वल्पविरामाने अलग केलेली यादी ( उदा. सदस्य१, गट१, सदस्य२ ) ज्यांना व्यवस्थापनाच्या निवडक सुविधा उपलब्ध असतात.';
+$lang['profileconfirm'] = 'प्रोफाइल मधील बदल पासवर्ड वापरून नक्की करा';
+$lang['disableactions'] = 'डॉक्युविकीच्या क्रिया बंद ठेवा';
+$lang['disableactions_check'] = 'तपासा';
+$lang['disableactions_subscription'] = 'सब्सक्राईब / अन्-सब्सक्राईब';
+$lang['disableactions_wikicode'] = 'स्त्रोत पहा / कच्च्या स्वरूपात एक्सपोर्ट करा';
+$lang['disableactions_other'] = 'इतर क्रिया ( स्वल्पविरामाने अलग केलेल्या )';
+$lang['sneaky_index'] = 'सूची दृश्यामधे डिफॉल्ट स्वरूपात डॉक्युविकी सगळे नेमस्पेस दाखवते. हा पर्याय चालू केल्यास सदस्याला वाचण्याची परवानगी नसलेले नेमस्पेस दिसणार नाहीत. यामुळे परवानगी असलेले उप - नेमस्पेस न दिसण्याची शक्यता आहे. यामुळे काही विशिष्ठ ACL सेटिंगसाठी सूची वापरता येण्यासारखी राहणार नाही.';
+$lang['auth_security_timeout'] = 'अधिकृत करण्याच्या प्रक्रियेची कालमर्यादा';
+$lang['securecookie'] = 'HTTPS वापरून सेट केलेले कूकीज ब्राउजरने HTTPS द्वाराच पाठवले पाहिजेत का? जर तुमच्या विकीचं फ़क्त लॉगिन पानच SSL वापरून सुरक्षित केलं असेल व पानांचं ब्राउजिंग असुरक्षित असेल तर हा पर्याय चालू करू नका.';
+$lang['xmlrpc'] = 'XML-RPC इंटरफेस चालू/बंद करा';
+$lang['xmlrpcuser'] = 'XML-RPC सुविधा फ़क्त इथे स्वल्पविरामाने अलग करून दिलेल्या गट किंवा वापरकर्त्याला उपलब्ध आहेत. सर्वाना ही सुविधा देण्यासाठी ही जागा रिकामी सोडा.';
+$lang['updatecheck'] = 'अपडेट आणि सुरक्षिततेविशयी सूचनान्वर पाळत ठेऊ का? या सुविधेसाठी डॉक्युविकीला update.dokuwiki.org शी संपर्क साधावा लागेल.';
+$lang['userewrite'] = 'छान छान URL वापर';
+$lang['useslash'] = 'URL मधे नेमस्पेस अलग करण्यासाठी \'/\' चिह्न वापरा';
+$lang['usedraft'] = 'संपादन करताना मसुदा आपोआप सुरक्षित करा';
+$lang['sepchar'] = 'पानाच्या नावातील शब्द अलग करण्याचे चिह्न';
+$lang['canonical'] = 'पूर्णपणे सुटसुटीत URL वापरा';
+$lang['autoplural'] = 'लिंकमधिल अनेकवचने तपासा';
+$lang['compression'] = 'अडगळीतल्या फाइल संकुचित करण्याची पद्धत';
+$lang['cachetime'] = 'कॅशचे जास्तीतजास्त वयोमान ( सेकंदात )';
+$lang['locktime'] = 'लॉक फाइलचे जास्तीतजास्त वयोमान ( सेकंदात )';
+$lang['fetchsize'] = 'बाह्य स्त्रोताकडून जास्तीतजास्त किती डाउनलोड fecth.php करू शकतो ( बाइट्स मधे )';
+$lang['notify'] = 'बदलाच्या सूचना ह्या ईमेल वर पाठवा';
+$lang['registernotify'] = 'नवीन नोंदणी केलेल्या सदस्यांची माहिती ह्या ईमेल वर पाठवा';
+$lang['mailfrom'] = 'आपोआप ईमेल पाठवण्यासाठी वापरायचा ईमेल';
+$lang['gzip_output'] = 'xhtml साठी gzip Content-encoding वापरा';
+$lang['gdlib'] = 'gzip लायब्ररीची आवृत्ती';
+$lang['im_convert'] = 'ImageMagik च्या परिवर्तन करणार्या टूलचा पाथ';
+$lang['jpg_quality'] = 'JPG संकुचित करण्याचा दर्जा ( १ - १०० )';
+$lang['subscribers'] = 'पानाची पुरवणी देण्याची सुविधा चालू करा';
+$lang['compress'] = 'CSS आणि जावास्क्रिप्टचे आउट्पुट संकुचित करा';
+$lang['hidepages'] = 'समान पाने लपवा';
+$lang['send404'] = 'अस्तित्वात नसलेल्या पानांसाठी "HTTP 404/Page not found" संदेश पाठवा';
+$lang['sitemap'] = 'गूगल साईट-मॅप बनवा';
+$lang['broken_iua'] = 'ignore_user_abort फंक्शन तुमच्या सिस्टम वर चालत नाही का? यामुळे शोध सूची निकामी होऊ शकते. IIS + PHP/CGI वर हे काम करत नाही हे नक्की झाले आहे. अधिक माहितीसाठी <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">बग ८५२</a> पहा.';
+$lang['xsendfile'] = 'सर्वर कडून स्थिर फाइल पाठवली जाण्यासाठी X-Sendfile शीर्षक ( header ) वापरू का ? तुमच्या वेब सर्वर मधे ही सुविधा असली पाहिजे.';
+$lang['renderer_xhtml'] = 'मुख्य ( xhtml ) विकी आउट्पुट साथी वापरायचा चित्रक ( renderer )';
+$lang['renderer__core'] = '%s (डॉक्युविकीचा मूलभूत)';
+$lang['renderer__plugin'] = '%s (प्लगिन)';
+$lang['rememberme'] = 'कायमच्या लॉगिन कुकीजला परवानगी दया ( लक्षात ठेवा )';
+$lang['rss_type'] = 'XML पुरवणीचा प्रकार';
+$lang['rss_linkto'] = 'XML पुरवणीची लिंक येथे जाते';
+$lang['rss_content'] = 'XML पुरवणीतल्या मुद्द्यामधे काय काय दाखवायचं?';
+$lang['rss_update'] = 'XML पुरवणी अद्ययावत करण्याचा कालखंड ( सेकंदात )';
+$lang['recent_days'] = 'किती अलीकडील बदल ठेवायचे? ( दिवसात )';
+$lang['rss_show_summary'] = 'XML पुरावानीच्या शीर्षकात सारांश दाखवा';
+$lang['target____wiki'] = 'अंतर्गत लिंकसाठीची विंडो';
+$lang['target____interwiki'] = 'आंतरविकि लिंकसाठीची विंडो';
+$lang['target____extern'] = 'बाह्य लिंकसाठीची विंडो';
+$lang['target____media'] = 'दृक्श्राव्य लिंकसाठीची विंडो';
+$lang['target____windows'] = 'विंडो लिंकसाठीची विंडो';
+$lang['proxy____host'] = 'छद्म ( proxy ) सर्वरचे नाव';
+$lang['proxy____port'] = 'छद्म ( proxy ) सर्वरचे पोर्ट';
+$lang['proxy____user'] = 'छद्म ( proxy ) सर्वरचे सदस्यनाम';
+$lang['proxy____pass'] = 'छद्म ( proxy ) सर्वरचा पासवर्ड';
+$lang['proxy____ssl'] = 'छद्म सर्वरला संपर्क साधण्यासाठी SSL वापरा';
+$lang['safemodehack'] = 'सेफमोड़ हॅक चालू करा';
+$lang['ftp____host'] = 'सेफमोड़ हॅक साठी FTP सर्वर';
+$lang['ftp____port'] = 'सेफमोड़ हॅक साठी FTP पोर्ट';
+$lang['ftp____user'] = 'सेफमोड़ हॅक साठी FTP सदस्यनाम';
+$lang['ftp____pass'] = 'सेफमोड़ हॅक साठी FTP पासवर्ड';
+$lang['ftp____root'] = 'सेफमोड़ हॅक साठी FTP मूळ डिरेक्टरी';
+$lang['license_o_'] = 'काही निवडले नाही';
+$lang['typography_o_0'] = 'काही नाही';
+$lang['typography_o_1'] = 'फक्त दुहेरी अवतरण चिह्न';
+$lang['typography_o_2'] = 'सर्व प्रकारची अवतरण चिन्हे ( नेहेमी चालेलच असं नाही )';
+$lang['userewrite_o_0'] = 'कुठेही नाही';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'डॉक्युविकी अंतर्गत';
+$lang['deaccent_o_0'] = 'बंद';
+$lang['deaccent_o_1'] = 'एक्सेंट काढून टाका';
+$lang['deaccent_o_2'] = 'रोमन लिपित बदला';
+$lang['gdlib_o_0'] = 'GD Lib उपलब्ध नाही';
+$lang['gdlib_o_1'] = 'आवृत्ती १.x';
+$lang['gdlib_o_2'] = 'आपोआप ओळखा';
+$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';
+$lang['rss_content_o_abstract'] = 'सारांश';
+$lang['rss_content_o_diff'] = 'एकत्रित फरक';
+$lang['rss_content_o_htmldiff'] = 'HTML पद्धतीचा फरकांचा तक्ता';
+$lang['rss_content_o_html'] = 'पानाचा पूर्ण HTML मजकूर';
+$lang['rss_linkto_o_diff'] = 'फरक दृश्य';
+$lang['rss_linkto_o_page'] = 'उजळणी केलेले पान';
+$lang['rss_linkto_o_rev'] = 'आवृत्त्यांची यादी';
+$lang['rss_linkto_o_current'] = 'सद्य पान';
+$lang['compression_o_0'] = 'काही नाही';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'वापरू नका';
+$lang['xsendfile_o_1'] = 'lighttpd चा प्रोप्रायटरी शीर्षक (हेडर)';
+$lang['xsendfile_o_2'] = 'स्टॅण्डर्ड X-sendfile शीर्षक';
+$lang['xsendfile_o_3'] = ' Nginx चा प्रोप्रायटरी Accel-Redirect शीर्षक';
+$lang['showuseras_o_loginname'] = 'लॉगिन नाम';
+$lang['showuseras_o_username'] = 'सदस्याचे पूर्ण नाव';
+$lang['showuseras_o_email'] = 'सदस्याचा ईमेल ( मेल सुरक्षिततेच्या सेटिंग अनुसार दुर्बोध केलेला ) ';
+$lang['showuseras_o_email_link'] = 'सदस्याचा ईमेल maito: लिंक स्वरूपात';
+$lang['useheading_o_0'] = 'कधीच नाही';
+$lang['useheading_o_navigation'] = 'फ़क्त मार्गदर्शन';
+$lang['useheading_o_content'] = 'फ़क्त विकी मजकूर';
+$lang['useheading_o_1'] = 'नेहमी';
diff --git a/lib/plugins/config/lang/ms/lang.php b/lib/plugins/config/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/config/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/config/lang/ne/lang.php b/lib/plugins/config/lang/ne/lang.php
new file mode 100644
index 000000000..a8b426b9c
--- /dev/null
+++ b/lib/plugins/config/lang/ne/lang.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['nochoice'] = '(अरु विकल्पहरु अनुपलव्ध)';
+$lang['_configuration_manager'] = 'नियन्त्रण व्यवस्थापक';
+$lang['_header_dokuwiki'] = 'DokuWiki सेटिंङ्ग';
+$lang['_header_plugin'] = 'प्लगइन सेटिंङ्ग';
+$lang['_header_template'] = 'टेम्प्लेट सेटिंङ्ग';
+$lang['_header_undefined'] = 'नखुलेको सेटिंङ्ग';
+$lang['_basic'] = 'आधारभूत सेटिंङ्ग';
+$lang['_display'] = 'प्रदर्शन सेटिंङ्ग';
+$lang['_authentication'] = 'आधिकारिकता सेटिंङ्ग';
+$lang['_anti_spam'] = 'स्प्याम विरुद्धको सेटिंङ्ग';
+$lang['_editing'] = 'सम्पादन सेटिंङ्ग';
+$lang['_links'] = 'लिङ्क सेटिंङ्ग';
+$lang['_media'] = 'मिडिया सेटिंङ्ग';
+$lang['_advanced'] = 'विशिष्ठ सेटिंङ्ग';
+$lang['_network'] = 'सञ्जाल सेटिंङ्ग';
+$lang['_plugin_sufix'] = 'प्लगइन सेटिंङ्ग';
+$lang['_template_sufix'] = 'टेम्प्लेट सेटिंङ्ग';
+$lang['_msg_setting_undefined'] = 'सेटिंङ्ग मेटाडाटा नभएको';
+$lang['_msg_setting_no_class'] = 'सेटिंङ्ग वर्ग नभएको';
+$lang['_msg_setting_no_default'] = 'कुनै पूर्व निर्धारित मान छैन ।';
+$lang['fmode'] = 'फाइल निर्माण स्थिति';
+$lang['dmode'] = 'डाइरेक्टरी निर्माण स्थिति';
+$lang['lang'] = 'भाषा';
+$lang['basedir'] = 'आधार डाइरेक्टरी';
+$lang['baseurl'] = 'आधार URL';
+$lang['savedir'] = 'सामग्री वचत गर्ने डाइरेक्टरी';
+$lang['start'] = 'पृष्ट नाम सुरुगर्नुहोस्';
+$lang['title'] = 'विकि शिर्षक';
+$lang['template'] = 'ढाँचा';
+$lang['license'] = 'कुन प्रमाण पत्रको आधारमा सामग्री प्रकाशन गरिनु पर्छ ?';
+$lang['fullpath'] = 'पष्ठको पूरा बाटो निम्नशिर्षकमा देखाउने';
+$lang['recent'] = 'हालैको परिवर्तन';
+$lang['htmlok'] = 'इम्बेडगरिएको HTML खुला गर्नुहोस ।';
+$lang['phpok'] = 'इम्बेडगरिएको PHP खुला गर्नुहोस ।';
+$lang['signature'] = 'दस्तखत';
+$lang['renderer__core'] = ' %s (dokuwiki core)';
+$lang['renderer__plugin'] = ' %s (plugin)';
+$lang['rss_type'] = 'XML फिड प्रकार';
+$lang['rss_linkto'] = 'को XML फिड';
+$lang['gdlib_o_1'] = 'संस्करण १.x';
+$lang['gdlib_o_2'] = 'आफै पत्तालगाउनु होस् ';
+$lang['rss_type_o_rss'] = 'आरसस ०॒.९१';
+$lang['rss_type_o_rss1'] = 'आरसस १.०';
+$lang['rss_type_o_rss2'] = 'आरसस २.०';
+$lang['rss_type_o_atom'] = 'एटम ०.३';
+$lang['rss_type_o_atom1'] = 'एटम १.०';
+$lang['rss_content_o_abstract'] = 'सारांस';
+$lang['rss_content_o_diff'] = 'एकिकृत फरक';
+$lang['rss_content_o_htmldiff'] = 'HTML ढाँचाको फरक सुची';
+$lang['rss_content_o_html'] = 'पूरा HTML पृष्टमा रहेको वस्तु';
+$lang['rss_linkto_o_diff'] = 'फरक अवलोकन';
+$lang['rss_linkto_o_rev'] = 'पुन:संस्करण सुची';
+$lang['rss_linkto_o_current'] = 'चालु पृष्ठ';
+$lang['compression_o_0'] = 'कुनै पनि होइन ';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'प्रयोग नगर्नुहोस्';
+$lang['showuseras_o_loginname'] = 'प्रवेश नाम';
+$lang['showuseras_o_username'] = 'प्रयोगकर्ताको पूरा नाम';
+$lang['useheading_o_0'] = 'कहिले पनि ';
+$lang['useheading_o_content'] = 'विकी विषयवस्तु मात्र';
+$lang['useheading_o_1'] = 'सधैँ';
diff --git a/lib/plugins/config/lang/nl/intro.txt b/lib/plugins/config/lang/nl/intro.txt
new file mode 100644
index 000000000..3814b70bd
--- /dev/null
+++ b/lib/plugins/config/lang/nl/intro.txt
@@ -0,0 +1,9 @@
+====== Configuratie Manager ======
+
+Gebruik deze pagina om de instellingen van je DokuWiki te bekijken en/of te wijzigen. Voor hulp over specifieke instellingen kun je kijken op [[doku>config]]. Voor meer informatie over deze plugin zie [[doku>plugin:config]].
+
+Instellingen met een rode achtergond kunnen niet worden gewijzigd met deze plugin. Instellingen met een blauwe achtergrond hebben de default waarde, en instellingen met een witte achtergrond zijn lokaal gewijzigd voor deze specifieke installatie. Zowel blauwe als witte instellingen kunnen worden gewijzigd.
+
+Vergeet niet op **Opslaan** te drukken alvorens de pagina te verlaten, anders gaan je wijzigingen verloren.
+
+
diff --git a/lib/plugins/config/lang/nl/lang.php b/lib/plugins/config/lang/nl/lang.php
new file mode 100644
index 000000000..c98d05adb
--- /dev/null
+++ b/lib/plugins/config/lang/nl/lang.php
@@ -0,0 +1,198 @@
+<?php
+/**
+ * dutch language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Pieter van der Meulen <pieter@vdmeulen.net>
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['menu'] = 'Configuratie-instellingen';
+$lang['error'] = 'De instellingen zijn niet gewijzigd wegens een incorrecte waarde, kijk je wijzigingen na en sla dan opnieuw op.<br />Je kunt de incorrecte waarde(s) herkennen aan de rode rand.';
+$lang['updated'] = 'Instellingen met succes opgeslagen.';
+$lang['nochoice'] = '(geen andere keuzemogelijkheden)';
+$lang['locked'] = 'Het bestand met instellingen kan niet worden gewijzigd. Als dit niet de bedoeling <br /> is, controleer dan de naam en de permissies voor het lokale installingenbestand.';
+$lang['danger'] = 'Gevaar: Het wijzigen van deze optie kan er voor zorgen dat uw wiki en het configuratiemenu niet langer toegankelijk zijn.';
+$lang['warning'] = 'Waarschuwing: Het wijzigen van deze optie kan onverwachte gedragingen veroorzaken.';
+$lang['security'] = 'Beveiligingswaarschuwing: Het wijzigen van deze optie kan een beveiligingsrisico inhouden.';
+$lang['_configuration_manager'] = 'Configuratiemanager';
+$lang['_header_dokuwiki'] = 'DokuWiki-instellingen';
+$lang['_header_plugin'] = 'Plugin-instellingen';
+$lang['_header_template'] = 'Sjabloon-instellingen';
+$lang['_header_undefined'] = 'Ongedefinieerde instellingen';
+$lang['_basic'] = 'Basisinstellingen';
+$lang['_display'] = 'Beeldinstellingen';
+$lang['_authentication'] = 'Authenticatie-instellingen';
+$lang['_anti_spam'] = 'Anti-spaminstellingen';
+$lang['_editing'] = 'Pagina-wijzigingsinstellingen';
+$lang['_links'] = 'Link-instellingen';
+$lang['_media'] = 'Media-instellingen';
+$lang['_advanced'] = 'Geavanceerde instellingen';
+$lang['_network'] = 'Netwerkinstellingen';
+$lang['_plugin_sufix'] = 'Plugin-instellingen';
+$lang['_template_sufix'] = 'Sjabloon-instellingen';
+$lang['_msg_setting_undefined'] = 'Geen metadata voor deze instelling.';
+$lang['_msg_setting_no_class'] = 'Geen class voor deze instelling.';
+$lang['_msg_setting_no_default'] = 'Geen standaard waarde.';
+$lang['fmode'] = 'Bestandaanmaak-modus (file creation mode)';
+$lang['dmode'] = 'Directory-aanmaak-modus (directory creation mode)';
+$lang['lang'] = 'Taal';
+$lang['basedir'] = 'Basisdirectory';
+$lang['baseurl'] = 'Basis-URL';
+$lang['savedir'] = 'Directory om data op te slaan';
+$lang['cookiedir'] = 'Cookie pad. Laat leeg om de basis URL te gebruiken.';
+$lang['start'] = 'Naam startpagina';
+$lang['title'] = 'Titel van de wiki';
+$lang['template'] = 'Sjabloon';
+$lang['license'] = 'Onder welke licentie zou je tekst moeten worden gepubliceerd?';
+$lang['fullpath'] = 'Volledig pad van pagina\'s in de footer weergeven';
+$lang['recent'] = 'Recente wijzigingen';
+$lang['breadcrumbs'] = 'Aantal broodkruimels';
+$lang['youarehere'] = 'Hierarchische broodkruimels';
+$lang['typography'] = 'Breng typografische wijzigingen aan';
+$lang['htmlok'] = 'Embedded HTML toestaan';
+$lang['phpok'] = 'Embedded PHP toestaan';
+$lang['dformat'] = 'Datum formaat (zie de PHP <a href="http://www.php.net/strftime">strftime</a> functie)';
+$lang['signature'] = 'Ondertekening';
+$lang['toptoclevel'] = 'Bovenste niveau voor inhoudsopgave';
+$lang['tocminheads'] = 'Minimum aantal koppen dat bepaald of een index gemaakt wordt';
+$lang['maxtoclevel'] = 'Laagste niveau voor inhoudsopgave';
+$lang['maxseclevel'] = 'Laagste sectiewijzigingsniveau';
+$lang['camelcase'] = 'CamelCase gebruiken voor links';
+$lang['deaccent'] = 'Paginanamen ontdoen van vreemde tekens';
+$lang['useheading'] = 'Eerste kopje voor paginanaam gebruiken';
+$lang['refcheck'] = 'Controleer verwijzingen naar media';
+$lang['refshow'] = 'Aantal te tonen mediaverwijzingen';
+$lang['allowdebug'] = 'Debug toestaan <b>uitzetten indien niet noodzakelijk!</b>';
+$lang['mediarevisions'] = 'Media revisies activeren?';
+$lang['usewordblock'] = 'Blokkeer spam op basis van woordenlijst';
+$lang['indexdelay'] = 'Uitstel voor indexeren (sec)';
+$lang['relnofollow'] = 'Gebruik rel="nofollow" voor externe links';
+$lang['mailguard'] = 'E-mailadressen onherkenbaar maken';
+$lang['iexssprotect'] = 'Controleer geüploade bestanden op mogelijk schadelijke JavaScript of HTML code';
+$lang['showuseras'] = 'Hoe de gebruiker die de pagina het laatst wijzigde weergeven';
+$lang['useacl'] = 'Gebruik access control lists';
+$lang['autopasswd'] = 'Zelf wachtwoorden genereren';
+$lang['authtype'] = 'Authenticatiemechanisme';
+$lang['passcrypt'] = 'Encryptie-methode voor wachtwoord ';
+$lang['defaultgroup'] = 'Standaardgroep';
+$lang['superuser'] = 'Superuser - een groep of gebruiker of kommalijst (gebruiker1,@groep1,gebruiker2) met volledige toegang tot alle pagina\'s en functies, ongeacht de ACL instellingen';
+$lang['manager'] = 'Beheerder - een groep of gebruiker of kommalijst (gebruiker1,@groep1,gebruiker2) met toegang tot bepaalde beheersfunctionaliteit';
+$lang['profileconfirm'] = 'Bevestig profielwijzigingen met wachtwoord';
+$lang['disableactions'] = 'Aangevinkte DokuWiki-akties uitschakelen';
+$lang['disableactions_check'] = 'Controleer';
+$lang['disableactions_subscription'] = 'Inschrijven/opzeggen';
+$lang['disableactions_wikicode'] = 'Bron bekijken/exporteer rauw';
+$lang['disableactions_other'] = 'Andere akties (gescheiden door komma\'s)';
+$lang['sneaky_index'] = 'Met de standaardinstellingen zal DokuWiki alle namespaces laten zien in de index. Het inschakelen van deze optie zorgt ervoor dat de namespaces waar de gebruiker geen leestoegang tot heeft, verborgen worden. Dit kan resulteren in het verbergen van subnamespaces waar de gebruiker wel toegang to heeft. Dit kan de index onbruikbaar maken met bepaalde ACL-instellingen.';
+$lang['auth_security_timeout'] = 'Authenticatiebeveiligings-timeout (seconden)';
+$lang['securecookie'] = 'Moeten cookies die via HTTPS gezet zijn alleen via HTTPS verzonden worden door de browser? Zet deze optie uit als alleen het inloggen op de wiki beveiligd is, maar het gebruik verder niet.';
+$lang['xmlrpc'] = 'Inschakelen/uitschakelen XML-RPC interface.';
+$lang['xmlrpcuser'] = 'Beperk XML-RPC toegang tot de lijst met kommagescheiden groepen of gebruikers die hier zijn opgegeven. Laat leeg om iedereen toegang te geven.';
+$lang['updatecheck'] = 'Controleer op nieuwe versies en beveiligingswaarschuwingen? DokuWiki moet hiervoor contact opnemen met update.dokuwiki.org.';
+$lang['userewrite'] = 'Gebruik nette URL\'s';
+$lang['useslash'] = 'Gebruik slash (/) als scheiding tussen namepaces in URL\'s';
+$lang['usedraft'] = 'Sla automatisch een concept op tijdens het wijzigen';
+$lang['sepchar'] = 'Woordscheider in paginanamen';
+$lang['canonical'] = 'Herleid URL\'s tot hun basisvorm';
+$lang['fnencode'] = 'Methode om niet-ASCII bestandsnamen te coderen.';
+$lang['autoplural'] = 'Controleer op meervoudsvormen in links';
+$lang['compression'] = 'Compressiemethode voor attic-bestanden';
+$lang['cachetime'] = 'Maximum leeftijd voor cache (sec)';
+$lang['locktime'] = 'Maximum leeftijd voor lockbestanden (sec)';
+$lang['fetchsize'] = 'Maximum grootte (bytes) die fetch.php mag downloaden van buiten';
+$lang['notify'] = 'Stuur e-mailnotificaties naar dit adres';
+$lang['registernotify'] = 'Stuur informatie over nieuw aangemelde gebruikers naar dit e-mailadres';
+$lang['mailfrom'] = 'E-mailadres voor automatische e-mail';
+$lang['mailprefix'] = 'Te gebruiken voorvoegsel voor onderwerp automatische email';
+$lang['gzip_output'] = 'Gebruik gzip Content-Encoding voor xhtml';
+$lang['gdlib'] = 'Versie GD Lib ';
+$lang['im_convert'] = 'Path naar ImageMagick\'s convert tool';
+$lang['jpg_quality'] = 'JPG compressiekwaliteit (0-100)';
+$lang['subscribers'] = 'Ondersteuning pagina-inschrijving aanzetten';
+$lang['subscribe_time'] = 'Inschrijvingsmeldingen en samenvattingen worden na deze tijdsduur (in seconden) verzonden. Deze waarde dient kleiner te zijn dan de tijd ingevuld bij "Hoeveel recente wijzigingen bewaren (dagen)"';
+$lang['compress'] = 'Compacte CSS en javascript output';
+$lang['cssdatauri'] = 'Maximale omvang in bytes van in CSS gelinkte afbeeldingen die bij de stylesheet moeten worden ingesloten ter reductie van de HTTP request header overhead. Deze techniek werkt niet in IE7 en ouder! <code>400</code> tot <code>600</code> is een geschikte omvang. Stel de omvang in op <code>0</code> om deze functionaliteit uit te schakelen.';
+$lang['hidepages'] = 'Verberg deze pagina\'s (regular expressions)';
+$lang['send404'] = 'Stuur "HTTP 404/Page Not Found" voor niet-bestaande pagina\'s';
+$lang['sitemap'] = 'Genereer Google sitemap (dagen)';
+$lang['broken_iua'] = 'Is de ignore_user_abort functie onbruikbaar op uw systeem? Dit kan een onbruikbare zoekindex tot gevolg hebben. IIS+PHP/CGI staat hier bekend om. Zie <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> voor meer informatie.';
+$lang['xsendfile'] = 'Gebruik de X-Sendfile header om de webserver statische content te laten versturen? De webserver moet dit wel ondersteunen.';
+$lang['renderer_xhtml'] = 'Weergavesysteem voor de standaard (xhtml) wiki-uitvoer';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permanente login cookie toestaan (onthoud mij)';
+$lang['rss_type'] = 'XML feed type';
+$lang['rss_linkto'] = 'XML feed linkt naar';
+$lang['rss_content'] = 'Wat moet er in de XML feed items weergegeven worden?';
+$lang['rss_update'] = 'XML feed verversingsinterval (sec)';
+$lang['recent_days'] = 'Hoeveel recente wijzigingen bewaren (dagen)';
+$lang['rss_show_summary'] = 'XML feed samenvatting in titel weergeven';
+$lang['target____wiki'] = 'Doelvenster voor interne links';
+$lang['target____interwiki'] = 'Doelvenster voor interwiki-links';
+$lang['target____extern'] = 'Doelvenster voor externe links';
+$lang['target____media'] = 'Doelvenster voor medialinks';
+$lang['target____windows'] = 'Doelvenster voor windows links';
+$lang['proxy____host'] = 'Proxy server';
+$lang['proxy____port'] = 'Proxy port';
+$lang['proxy____user'] = 'Proxy gebruikersnaam';
+$lang['proxy____pass'] = 'Proxy wachtwoord';
+$lang['proxy____ssl'] = 'Gebruik SSL om een connectie te maken met de proxy';
+$lang['proxy____except'] = 'Reguliere expressie om URL\'s te bepalen waarvoor de proxy overgeslaan moet worden.';
+$lang['safemodehack'] = 'Safemode hack aanzetten';
+$lang['ftp____host'] = 'FTP server voor safemode hack';
+$lang['ftp____port'] = 'FTP port voor safemode hack';
+$lang['ftp____user'] = 'FTP gebruikersnaam voor safemode hack';
+$lang['ftp____pass'] = 'FTP wachtwoord voor safemode hack';
+$lang['ftp____root'] = 'FTP root directory voor safemode hack';
+$lang['license_o_'] = 'Geen gekozen';
+$lang['typography_o_0'] = 'geen';
+$lang['typography_o_1'] = 'Alleen dubbele aanhalingstekens';
+$lang['typography_o_2'] = 'Alle aanhalingstekens (functioneert mogelijk niet altijd)';
+$lang['userewrite_o_0'] = 'geen';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki intern';
+$lang['deaccent_o_0'] = 'uit';
+$lang['deaccent_o_1'] = 'accenten verwijderen';
+$lang['deaccent_o_2'] = 'romaniseer';
+$lang['gdlib_o_0'] = 'GD Lib niet beschikbaar';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Autodetectie';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstract';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'Diff-tabel in HTML';
+$lang['rss_content_o_html'] = 'Volledige pagina-inhoud in HTML';
+$lang['rss_linkto_o_diff'] = 'verschillen';
+$lang['rss_linkto_o_page'] = 'de gewijzigde pagina';
+$lang['rss_linkto_o_rev'] = 'lijst van revisies';
+$lang['rss_linkto_o_current'] = 'de huidige pagina';
+$lang['compression_o_0'] = 'geen';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'niet gebruiken';
+$lang['xsendfile_o_1'] = 'Eigen lighttpd header (voor release 1.5)';
+$lang['xsendfile_o_2'] = 'Standaard X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Propritary Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'loginnaam';
+$lang['showuseras_o_username'] = 'Volledige naam';
+$lang['showuseras_o_email'] = 'E-mailadres (onherkenbaar gemaakt volgens mailguard-instelling)';
+$lang['showuseras_o_email_link'] = 'E-mailadres als mailto: link';
+$lang['useheading_o_0'] = 'Nooit';
+$lang['useheading_o_navigation'] = 'Alleen navigatie';
+$lang['useheading_o_content'] = 'Alleen wiki inhoud';
+$lang['useheading_o_1'] = 'Altijd';
+$lang['readdircache'] = 'Maximale leeftijd voor readdir cache (in seconden)';
diff --git a/lib/plugins/config/lang/no/intro.txt b/lib/plugins/config/lang/no/intro.txt
new file mode 100644
index 000000000..c1310cc6d
--- /dev/null
+++ b/lib/plugins/config/lang/no/intro.txt
@@ -0,0 +1,7 @@
+====== Konfigurasjonsinnstillinger ======
+
+Bruk denne siden for å kontrollere innstillingene for din DokuWiki. For hjelp om hver enkelt innstilling, se [[doku>config]]. For mer detaljer om denne innstillingssiden, se [[doku>plugin:config]].
+
+Innstillinger vist med lys rød bakgrunn er beskyttet og kan ikke endres på denne siden. Innstillinger vist med blå bakgrunn er standardverdier og innstillinger med hvit bakgrunn har blitt satt lokalt for denne installasjonen. Både blå og hvite innstillinger kan endres.
+
+Husk å trykke på **Lagre**-knappen før du forlater siden. Hvis ikke går endringene tapt.
diff --git a/lib/plugins/config/lang/no/lang.php b/lib/plugins/config/lang/no/lang.php
new file mode 100644
index 000000000..c41b5e566
--- /dev/null
+++ b/lib/plugins/config/lang/no/lang.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Norwegianlanguage file
+ *
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['menu'] = 'Konfigurasjonsinnstillinger';
+$lang['error'] = 'Innstillingene ble ikke oppdatert på grunn av en eller flere ugyldig verdier. Vennligst se gjennom endringene og prøv på nytt.
+<br />Ugyldige verdier er omgitt av en rød ramme.';
+$lang['updated'] = 'Innstillingene ble oppdatert.';
+$lang['nochoice'] = '(ingen andre mulige valg)';
+$lang['locked'] = 'Innstillingene kan ikke oppdateres. Hvis dette ikke er meningen,<br />
+forsikre deg om at fila med de lokale innstillingene har korrekt filnavn<br/>
+og tillatelser.';
+$lang['danger'] = 'Advarsel: Endrig av dette valget kan føre til at wiki og konfigurasjon menyen ikke blir tilgjengelig.';
+$lang['warning'] = 'Advarsel: Endring av dette valget kan føre til utilsiktet atferd.
+
+';
+$lang['security'] = 'Sikkerhetsadvarsel: Endring av dette valget kan innebære en sikkerhetsrisiko.';
+$lang['_configuration_manager'] = 'Konfigurasjonsinnstillinger';
+$lang['_header_dokuwiki'] = 'Innstillinger for DokuWiki';
+$lang['_header_plugin'] = 'Innstillinger for tillegg';
+$lang['_header_template'] = 'Innstillinger for maler';
+$lang['_header_undefined'] = 'Udefinerte innstillinger';
+$lang['_basic'] = 'Grunnleggende innstillinger';
+$lang['_display'] = 'Innstillinger for visning av sider';
+$lang['_authentication'] = 'Innstillinger for autentisering';
+$lang['_anti_spam'] = 'Anti-Spam innstillinger';
+$lang['_editing'] = 'Innstillinger for redigering';
+$lang['_links'] = 'Innstillinger for lenker';
+$lang['_media'] = 'Innstillinger for mediafiler';
+$lang['_advanced'] = 'Avanserte innstillinger';
+$lang['_network'] = 'Nettverksinnstillinger';
+$lang['_plugin_sufix'] = '&ndash; innstillinger for tillegg';
+$lang['_template_sufix'] = '&ndash; innstillinger for mal';
+$lang['_msg_setting_undefined'] = 'Ingen innstillingsmetadata';
+$lang['_msg_setting_no_class'] = 'Ingen innstillingsklasse';
+$lang['_msg_setting_no_default'] = 'Ingen standard verdi';
+$lang['fmode'] = 'Rettigheter for nye filer';
+$lang['dmode'] = 'Rettigheter for nye mapper';
+$lang['lang'] = 'Språk';
+$lang['basedir'] = 'Grunnkatalog';
+$lang['baseurl'] = 'Grunn-nettadresse';
+$lang['savedir'] = 'Mappe for lagring av data';
+$lang['cookiedir'] = 'Sti for informasjonskapsler. La stå blankt for å bruke grunn-nettadressa.';
+$lang['start'] = 'Sidenavn på forsiden';
+$lang['title'] = 'Navn på Wikien';
+$lang['template'] = 'Mal';
+$lang['license'] = 'Under hvilken lisens skal ditt innhold utgis?';
+$lang['fullpath'] = 'Vis full sti til sider i bunnteksten';
+$lang['recent'] = 'Siste endringer';
+$lang['breadcrumbs'] = 'Antall nylig besøkte sider som vises';
+$lang['youarehere'] = 'Vis hvor i hvilke(t) navnerom siden er';
+$lang['typography'] = 'Gjør typografiske erstatninger';
+$lang['htmlok'] = 'Tillat HTML';
+$lang['phpok'] = 'Tillat PHP';
+$lang['dformat'] = 'Datoformat (se <a href="http://www.php.net/strftime">PHPs datofunksjon</a>)';
+$lang['signature'] = 'Signatur';
+$lang['toptoclevel'] = 'Toppnivå for innholdsfortegnelse';
+$lang['tocminheads'] = 'Minimum antall overskrifter som bestemmer om innholdsbetegnelse skal bygges.';
+$lang['maxtoclevel'] = 'Maksimalt antall nivåer i innholdsfortegnelse';
+$lang['maxseclevel'] = 'Maksimalt nivå for redigering av seksjon';
+$lang['camelcase'] = 'Gjør KamelKasse til lenke automatisk';
+$lang['deaccent'] = 'Rensk sidenavn';
+$lang['useheading'] = 'Bruk første overskrift som tittel';
+$lang['refcheck'] = 'Sjekk referanser før mediafiler slettes';
+$lang['refshow'] = 'Antall viste referanser til mediafiler';
+$lang['allowdebug'] = 'Tillat feilsøking <b>skru av om det ikke behøves!</b>';
+$lang['mediarevisions'] = 'Slå på mediaversjonering?';
+$lang['usewordblock'] = 'Blokker søppel basert på ordliste';
+$lang['indexdelay'] = 'Forsinkelse før indeksering (sekunder)';
+$lang['relnofollow'] = 'Bruk rel="nofollow" på eksterne lenker';
+$lang['mailguard'] = 'Beskytt e-postadresser';
+$lang['iexssprotect'] = 'Sjekk om opplastede filer inneholder skadelig JavaScrips- eller HTML-kode';
+$lang['showuseras'] = 'Hva som skal med når man viser brukeren som sist redigerte en side.';
+$lang['useacl'] = 'Bruk lister for adgangskontroll (ACL)';
+$lang['autopasswd'] = 'Generer passord automatisk';
+$lang['authtype'] = 'Autentiseringsmetode';
+$lang['passcrypt'] = 'Metode for kryptering av passord';
+$lang['defaultgroup'] = 'Standardgruppe';
+$lang['superuser'] = 'Superbruker - en gruppe, bruker eller liste (kommaseparert) med full tilgang til alle sider og funksjoner uavhengig av ACL-innstillingene';
+$lang['manager'] = 'Administrator - en gruppe, bruker eller liste (kommaseparert) med tilgang til visse administratorfunksjoner';
+$lang['profileconfirm'] = 'Bekreft profilendringer med passord';
+$lang['disableactions'] = 'Skru av følgende DokuWiki-kommandoer';
+$lang['disableactions_check'] = 'Sjekk';
+$lang['disableactions_subscription'] = 'Meld på/av';
+$lang['disableactions_wikicode'] = 'Vis kildekode/eksporter rådata';
+$lang['disableactions_other'] = 'Andre kommandoer (kommaseparert)';
+$lang['sneaky_index'] = 'DokuWiki vil som standard vise alle navnerom i innholdsfortegnelsen. Hvis du skrur på dette alternativet vil brukere bare se de navnerommene der de har lesetilgang. Dette kan føre til at tilgjengelige undernavnerom skjules. Det kan gjøre innholdsfortegnelsen ubrukelig med enkelte ACL-oppsett.';
+$lang['auth_security_timeout'] = 'Autentisering utløper etter (sekunder)';
+$lang['securecookie'] = 'Skal informasjonskapsler satt via HTTPS kun sendes via HTTPS av nettleseren? Skal ikke velges dersom bare innloggingen til din wiki er sikret med SSL, og annen navigering på wikien er usikret.';
+$lang['xmlrpc'] = 'Slå på/slå av XML-RPC-grensesnitt';
+$lang['xmlrpcuser'] = 'Å tillate XML-RPC-adgang til bestemte grupper eller brukere, sette deres navne (kommaseparert) her. Slik får du tilgang til alle, la feltet tomt.
+';
+$lang['updatecheck'] = 'Se etter oppdateringer og sikkerhetsadvarsler? Denne funksjonen er avhengig av å kontakte update.dokuwiki.org.';
+$lang['userewrite'] = 'Bruk pene URLer';
+$lang['useslash'] = 'Bruk / som skilletegn mellom navnerom i URLer';
+$lang['usedraft'] = 'Lagre kladd automatisk under redigering';
+$lang['sepchar'] = 'Skilletegn mellom ord i sidenavn';
+$lang['canonical'] = 'Bruk fulle URLer (i stedet for relative)';
+$lang['fnencode'] = 'Metode for å kode ikke-ASCII-filnavn';
+$lang['autoplural'] = 'Se etter flertallsformer i lenker';
+$lang['compression'] = 'Metode for komprimering av gamle filer';
+$lang['cachetime'] = 'Maksimal alder på hurtiglager (sekunder)';
+$lang['locktime'] = 'Maksimal alder på låsefiler (sekunder)';
+$lang['fetchsize'] = 'Maksimal størrelse (byter) fetch.php kan laste eksternt';
+$lang['notify'] = 'Send meldinger om endringer denne e-postadressen';
+$lang['registernotify'] = 'Send info om nylig registrerte brukere til denne e-postadressen';
+$lang['mailfrom'] = 'Avsenderadresse for automatiske e-poster';
+$lang['mailprefix'] = 'Prefiks for emne i automatiske e-poster ';
+$lang['gzip_output'] = 'Bruk gzip Content-Encoding for XHTML';
+$lang['gdlib'] = 'Versjon av libGD';
+$lang['im_convert'] = 'Sti til ImageMagicks konverteringsverktøy';
+$lang['jpg_quality'] = 'JPEG-kvalitet (0-100)';
+$lang['subscribers'] = 'Åpne for abonnement på endringer av en side';
+$lang['subscribe_time'] = 'Hvor lenge det skal gå mellom utsending av e-poster med endringer (i sekunder). Denne verdien bør være mindre enn verdien i recent_days.';
+$lang['compress'] = 'Kompakt CSS og JavaScript';
+$lang['cssdatauri'] = 'Opp til denne størrelsen (i bytes) skal bilder som er vist til i CSS-filer kodes direkte inn i fila for å redusere antall HTTP-forespørsler. Denne teknikken fungerer ikke i IE < 8! Mellom <code>400</code> og <code>600</code> bytes er fornuftige verdier. Bruk <code>0</code> for å skru av funksjonen.';
+$lang['hidepages'] = 'Skjul sider fra automatiske lister (regulære uttrykk)';
+$lang['send404'] = 'Send "HTTP 404/Page Not Found" for ikke-eksisterende sider';
+$lang['sitemap'] = 'Lag Google-sidekart (dager)';
+$lang['broken_iua'] = 'Er funksjonen ignore_user_abort på ditt system ødelagt? Dette kan gjøre at indeksering av søk ikke fungerer. Dette er et kjent problem med IIS+PHP/CGI. Se <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> for mer informasjon.';
+$lang['xsendfile'] = 'Bruk X-Sendfile header for å la webserver levere statiske filer? Din webserver må støtte dette.';
+$lang['renderer_xhtml'] = 'Renderer til bruk for wiki-output (XHTML)';
+$lang['renderer__core'] = '%s (dokuwikikjerne)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Tillat permanente informasjonskapsler for innlogging (husk meg)';
+$lang['rss_type'] = 'Type XML-feed';
+$lang['rss_linkto'] = 'XML-feed lenker til';
+$lang['rss_content'] = 'Hva skal vises i XML-feed elementer?';
+$lang['rss_update'] = 'Intervall for oppdatering av XML-feed (sekunder)';
+$lang['recent_days'] = 'Hvor lenge skal nylige endringer beholdes (dager)';
+$lang['rss_show_summary'] = 'Vis redigeringskommentar i tittelen på elementer i XML-feed ';
+$lang['target____wiki'] = 'Mål for interne linker';
+$lang['target____interwiki'] = 'Mål for interwiki-lenker';
+$lang['target____extern'] = 'Mål for eksterne lenker';
+$lang['target____media'] = 'Mål for lenker til mediafiler';
+$lang['target____windows'] = 'Mål for lenker til nettverksstasjoner i Windows';
+$lang['proxy____host'] = 'Navn på proxyserver';
+$lang['proxy____port'] = 'Proxyport';
+$lang['proxy____user'] = 'Brukernavn på proxyserver';
+$lang['proxy____pass'] = 'Passord på proxyserver';
+$lang['proxy____ssl'] = 'Bruk SSL for å koble til proxyserver';
+$lang['proxy____except'] = 'Regulært uttrykk for URLer som ikke trenger en proxy.';
+$lang['safemodehack'] = 'Bruk safemode-hack';
+$lang['ftp____host'] = 'FTP-server for safemode-hack';
+$lang['ftp____port'] = 'FTP-port for safemode-hack';
+$lang['ftp____user'] = 'FTP-brukernavn for safemode-hack';
+$lang['ftp____pass'] = 'FTP-passord for safemode-hack';
+$lang['ftp____root'] = 'FTP-rotmappe for safemode-hack';
+$lang['license_o_'] = 'Ingen valgt';
+$lang['typography_o_0'] = 'ingen';
+$lang['typography_o_1'] = 'Kun doble anførselstegn';
+$lang['typography_o_2'] = 'Alle anførselstegn (virker ikke alltid)';
+$lang['userewrite_o_0'] = 'ingen';
+$lang['userewrite_o_1'] = 'Apache (.htaccess)';
+$lang['userewrite_o_2'] = 'DokuWiki internt';
+$lang['deaccent_o_0'] = 'av';
+$lang['deaccent_o_1'] = 'fjern aksenter';
+$lang['deaccent_o_2'] = 'bytt til kun latinske bokstaver';
+$lang['gdlib_o_0'] = 'GD lib ikke tilgjengelig';
+$lang['gdlib_o_1'] = 'Versjon 1.x';
+$lang['gdlib_o_2'] = 'Automatisk oppdaging';
+$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';
+$lang['rss_content_o_abstract'] = 'Ingress';
+$lang['rss_content_o_diff'] = 'Forent Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML-formatert diff-tabell';
+$lang['rss_content_o_html'] = 'Full HTML sideinnhold';
+$lang['rss_linkto_o_diff'] = 'endringsvisning';
+$lang['rss_linkto_o_page'] = 'den endrede siden';
+$lang['rss_linkto_o_rev'] = 'liste over endringer';
+$lang['rss_linkto_o_current'] = 'den nåværende siden';
+$lang['compression_o_0'] = 'ingen';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ikke bruk';
+$lang['xsendfile_o_1'] = 'Proprietær lighttpd header (før release 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Priprietær Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Brukernavn';
+$lang['showuseras_o_username'] = 'Brukerens fulle navn';
+$lang['showuseras_o_email'] = 'Brukerens e-postadresse (tilpasset i henhold til mailguar-instilling)';
+$lang['showuseras_o_email_link'] = 'Brukerens epost-addresse som "mailto:"-lenke';
+$lang['useheading_o_0'] = 'Aldri';
+$lang['useheading_o_navigation'] = 'Kun navigering';
+$lang['useheading_o_content'] = 'Kun wiki-innhold';
+$lang['useheading_o_1'] = 'Alltid';
+$lang['readdircache'] = 'Maksimal alder for mellomlagring av mappen med søkeindekser (sekunder)';
diff --git a/lib/plugins/config/lang/pl/intro.txt b/lib/plugins/config/lang/pl/intro.txt
new file mode 100644
index 000000000..72c0e1c13
--- /dev/null
+++ b/lib/plugins/config/lang/pl/intro.txt
@@ -0,0 +1,9 @@
+====== Menadżer konfiguracji ======
+
+Na tej stronie można zmienić ustawienia tej instalacji DokuWiki. W celu uzyskania pomocy na temat ustawień zajrzyj na stronę o [[doku>config|konfiguracji]]. W celu uzyskania informacji o tej wtyczce zajrzyj na stronę o [[doku>plugin:config|wtyczce]].
+
+Ustawienia w kolorze jasnoczerwonym są chronione i nie mogą być zmienioną z użyciem tej wtyczki. Ustawienia w kolorze niebieskim mają domyślne wartości. Ustawienia w kolorze białym są specyficzne dla tej instalacji. Ustawienia w kolorach niebieskim i białym mogą być zmienione.
+
+W celu zapisania nowej konfiguracji naciśnij **zapisz** przed opuszczeniem tej strony.
+
+
diff --git a/lib/plugins/config/lang/pl/lang.php b/lib/plugins/config/lang/pl/lang.php
new file mode 100644
index 000000000..a04f45c87
--- /dev/null
+++ b/lib/plugins/config/lang/pl/lang.php
@@ -0,0 +1,199 @@
+<?php
+/**
+ * polish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author Piotr JANKOWSKI <jankowski.piotr@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['menu'] = 'Ustawienia';
+$lang['error'] = 'Ustawienia nie zostały zapisane z powodu błędnych wartości, przejrzyj je i ponów próbę zapisu. <br/> Niepoprawne wartości są wyróżnione kolorem czerwonym.';
+$lang['updated'] = 'Ustawienia zostały zmienione.';
+$lang['nochoice'] = '(brak innych możliwości)';
+$lang['locked'] = 'Plik ustawień nie mógł zostać zmieniony, upewnij się, czy uprawnienia do pliku są odpowiednie.';
+$lang['danger'] = 'Uwaga: Zmiana tej opcji może uniemożliwić dostęp do twojej wiki oraz konfiguracji.';
+$lang['warning'] = 'Ostrzeżenie: Zmiana tej opcji może spowodować nieporządane skutki.';
+$lang['security'] = 'Alert bezpieczeństwa: Zmiana tej opcji może obniżyć bezpieczeństwo.';
+$lang['_configuration_manager'] = 'Menadżer konfiguracji';
+$lang['_header_dokuwiki'] = 'Ustawienia DokuWiki';
+$lang['_header_plugin'] = 'Ustawienia wtyczek';
+$lang['_header_template'] = 'Ustawienia motywu';
+$lang['_header_undefined'] = 'Inne ustawienia';
+$lang['_basic'] = 'Podstawowe';
+$lang['_display'] = 'Wygląd';
+$lang['_authentication'] = 'Autoryzacja';
+$lang['_anti_spam'] = 'Spam';
+$lang['_editing'] = 'Edycja';
+$lang['_links'] = 'Odnośniki';
+$lang['_media'] = 'Media';
+$lang['_advanced'] = 'Zaawansowane';
+$lang['_network'] = 'Sieć';
+$lang['_plugin_sufix'] = 'Wtyczki';
+$lang['_template_sufix'] = 'Motywy';
+$lang['_msg_setting_undefined'] = 'Brak danych o ustawieniu.';
+$lang['_msg_setting_no_class'] = 'Brak kategorii ustawień.';
+$lang['_msg_setting_no_default'] = 'Brak wartości domyślnej.';
+$lang['fmode'] = 'Tryb tworzenia pliku';
+$lang['dmode'] = 'Tryb tworzenia katalogu';
+$lang['lang'] = 'Język';
+$lang['basedir'] = 'Katalog główny';
+$lang['baseurl'] = 'Główny URL';
+$lang['savedir'] = 'Katalog z danymi';
+$lang['cookiedir'] = 'Ścieżka plików ciasteczek. Zostaw puste by użyć baseurl.';
+$lang['start'] = 'Tytuł strony początkowej';
+$lang['title'] = 'Tytuł wiki';
+$lang['template'] = 'Motyw';
+$lang['tagline'] = 'Motto (jeśli szablon daje taką możliwość)';
+$lang['sidebar'] = 'Nazwa strony paska bocznego (jeśli szablon je obsługuje), puste pole wyłącza pasek boczny';
+$lang['license'] = 'Pod jaką licencją publikować treści wiki?';
+$lang['fullpath'] = 'Wyświetlanie pełnych ścieżek';
+$lang['recent'] = 'Ilość ostatnich zmian';
+$lang['breadcrumbs'] = 'Długość śladu';
+$lang['youarehere'] = 'Ślad według struktury';
+$lang['typography'] = 'Konwersja cudzysłowu, myślników itp.';
+$lang['htmlok'] = 'Wstawki HTML';
+$lang['phpok'] = 'Wstawki PHP';
+$lang['dformat'] = 'Format daty';
+$lang['signature'] = 'Podpis';
+$lang['toptoclevel'] = 'Minimalny poziom spisu treści';
+$lang['tocminheads'] = 'Minimalna liczba nagłówków niezbędna do wytworzenia spisu treści.';
+$lang['maxtoclevel'] = 'Maksymalny poziom spisu treści';
+$lang['maxseclevel'] = 'Maksymalny poziom podziału na sekcje edycyjne';
+$lang['camelcase'] = 'Bikapitalizacja odnośników (CamelCase)';
+$lang['deaccent'] = 'Podmieniaj znaki spoza ASCII w nazwach';
+$lang['useheading'] = 'Pierwszy nagłówek jako tytuł';
+$lang['refcheck'] = 'Sprawdzanie odwołań przed usunięciem pliku';
+$lang['refshow'] = 'Ilość pokazywanych odwołań do pliku';
+$lang['allowdebug'] = 'Debugowanie (niebezpieczne!)';
+$lang['mediarevisions'] = 'Włączyć wersjonowanie multimediów?';
+$lang['usewordblock'] = 'Blokowanie spamu na podstawie słów';
+$lang['indexdelay'] = 'Okres indeksowania w sekundach';
+$lang['relnofollow'] = 'Nagłówek rel="nofollow" dla odnośników zewnętrznych';
+$lang['mailguard'] = 'Utrudnianie odczytu adresów e-mail';
+$lang['iexssprotect'] = 'Wykrywanie złośliwego kodu JavaScript i HTML w plikach';
+$lang['showuseras'] = 'Sposób wyświetlania nazwy użytkownika, który ostatnio edytował stronę';
+$lang['useacl'] = 'Kontrola uprawnień ACL';
+$lang['autopasswd'] = 'Automatyczne generowanie haseł';
+$lang['authtype'] = 'Typ autoryzacji';
+$lang['passcrypt'] = 'Kodowanie hasła';
+$lang['defaultgroup'] = 'Domyślna grupa';
+$lang['superuser'] = 'Administrator - grupa lub użytkownik z pełnymi uprawnieniami';
+$lang['manager'] = 'Menadżer - grupa lub użytkownik z uprawnieniami do zarządzania wiki';
+$lang['profileconfirm'] = 'Potwierdzanie zmiany profilu hasłem';
+$lang['disableactions'] = 'Wyłącz akcje DokuWiki';
+$lang['disableactions_check'] = 'Sprawdzanie';
+$lang['disableactions_subscription'] = 'Subskrypcje';
+$lang['disableactions_wikicode'] = 'Pokazywanie źródeł';
+$lang['disableactions_other'] = 'Inne akcje (oddzielone przecinkiem)';
+$lang['sneaky_index'] = 'Domyślnie, Dokuwiki pokazuje wszystkie katalogi w indeksie. Włączenie tej opcji ukryje katalogi, do których użytkownik nie ma praw. Może to spowodować ukrycie podkatalogów, do których użytkownik ma prawa. Ta opcja może spowodować błędne działanie indeksu w połączeniu z pewnymi konfiguracjami praw dostępu.';
+$lang['auth_security_timeout'] = 'Czas wygaśnięcia uwierzytelnienia (w sekundach)';
+$lang['securecookie'] = 'Czy ciasteczka wysłane do przeglądarki przez HTTPS powinny być przez nią odsyłane też tylko przez HTTPS? Odznacz tę opcję tylko wtedy, gdy logowanie użytkowników jest zabezpieczone SSL, ale przeglądanie stron odbywa się bez zabezpieczenia.';
+$lang['xmlrpc'] = 'Włącz/wyłącz interfejs XML-RPC';
+$lang['xmlrpcuser'] = 'Lista użytkowników i grup, którzy mogą korzystać z protokołu XML-RPC. Nazwy grup i użytkowników rozdziel przecinkami, puste pole oznacza dostęp dla wszystkich.';
+$lang['updatecheck'] = 'Sprawdzanie aktualizacji i bezpieczeństwa. DokuWiki będzie kontaktować się z serwerem update.dokuwiki.org.';
+$lang['userewrite'] = 'Proste adresy URL';
+$lang['useslash'] = 'Używanie ukośnika jako separatora w adresie URL';
+$lang['usedraft'] = 'Automatyczne zapisywanie szkicu podczas edycji';
+$lang['sepchar'] = 'Znak rozdzielający wyrazy nazw';
+$lang['canonical'] = 'Kanoniczne adresy URL';
+$lang['fnencode'] = 'Metoda kodowana nazw pików bez użycia ASCII.';
+$lang['autoplural'] = 'Automatyczne tworzenie liczby mnogiej';
+$lang['compression'] = 'Metoda kompresji dla usuniętych plików';
+$lang['cachetime'] = 'Maksymalny wiek cache w sekundach';
+$lang['locktime'] = 'Maksymalny wiek blokad w sekundach';
+$lang['fetchsize'] = 'Maksymalny rozmiar pliku (w bajtach) jaki można pobrać z zewnątrz';
+$lang['notify'] = 'Wysyłanie powiadomień na adres e-mail';
+$lang['registernotify'] = 'Prześlij informacje o nowych użytkownikach na adres e-mail';
+$lang['mailfrom'] = 'Adres e-mail tego wiki';
+$lang['mailprefix'] = 'Prefiks tematu e-mail do automatycznych wiadomości';
+$lang['gzip_output'] = 'Używaj kodowania GZIP dla zawartości XHTML';
+$lang['gdlib'] = 'Wersja biblioteki GDLib';
+$lang['im_convert'] = 'Ścieżka do programu imagemagick';
+$lang['jpg_quality'] = 'Jakość kompresji JPG (0-100)';
+$lang['subscribers'] = 'Subskrypcja';
+$lang['subscribe_time'] = 'Czas po którym są wysyłane listy subskrypcji i streszczenia (sek.); Powinna być to wartość większa niż podana w zmiennej recent_days.';
+$lang['compress'] = 'Kompresja arkuszy CSS i plików JavaScript';
+$lang['cssdatauri'] = 'Rozmiar w bajtach, poniżej którego odwołania do obrazów w plikach CSS powinny być osadzone bezpośrednio w arkuszu stylów by zmniejszyć ogólne żądania nagłówków HTTP. Technika ta nie działa w IE 7 i poniżej! <code>400</code> do <code>600</code> bajtów jest dobrą wartością. Ustaw <code>0</code> aby wyłączyć.';
+$lang['hidepages'] = 'Ukrywanie stron pasujących do wzorca (wyrażenie regularne)';
+$lang['send404'] = 'Nagłówek "HTTP 404/Page Not Found" dla nieistniejących stron';
+$lang['sitemap'] = 'Okres generowania Google Sitemap (w dniach)';
+$lang['broken_iua'] = 'Czy funkcja "ignore_user_abort" działa? Jeśli nie, może to powodować problemy z indeksem przeszukiwania. Funkcja nie działa przy konfiguracji oprogramowania IIS+PHP/CGI. Szczegółowe informacje: <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>.';
+$lang['xsendfile'] = 'Użyj nagłówka HTTP X-Sendfile w celu przesyłania statycznych plików. Serwer HTTP musi obsługiwać ten nagłówek.';
+$lang['renderer_xhtml'] = 'Mechanizm renderowania głównej treści strony (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki)';
+$lang['renderer__plugin'] = '%s (wtyczka)';
+$lang['rememberme'] = 'Pozwól na ciasteczka automatycznie logujące (pamiętaj mnie)';
+$lang['rss_type'] = 'Typ RSS';
+$lang['rss_linkto'] = 'Odnośniki w RSS';
+$lang['rss_content'] = 'Rodzaj informacji wyświetlanych w RSS ';
+$lang['rss_update'] = 'Okres aktualizacji RSS (w sekundach)';
+$lang['recent_days'] = 'Ilość ostatnich zmian (w dniach)';
+$lang['rss_show_summary'] = 'Podsumowanie w tytule';
+$lang['target____wiki'] = 'Okno docelowe odnośników wewnętrznych';
+$lang['target____interwiki'] = 'Okno docelowe odnośników do innych wiki';
+$lang['target____extern'] = 'Okno docelowe odnośników zewnętrznych';
+$lang['target____media'] = 'Okno docelowe odnośników do plików';
+$lang['target____windows'] = 'Okno docelowe odnośników zasobów Windows';
+$lang['proxy____host'] = 'Proxy - serwer';
+$lang['proxy____port'] = 'Proxy - port';
+$lang['proxy____user'] = 'Proxy - nazwa użytkownika';
+$lang['proxy____pass'] = 'Proxy - hasło';
+$lang['proxy____ssl'] = 'Proxy - SSL';
+$lang['proxy____except'] = 'Wyrażenie regularne określające adresy URL, do których nie należy używać proxy.';
+$lang['safemodehack'] = 'Bezpieczny tryb (przez FTP)';
+$lang['ftp____host'] = 'FTP - serwer';
+$lang['ftp____port'] = 'FTP - port';
+$lang['ftp____user'] = 'FTP - nazwa użytkownika';
+$lang['ftp____pass'] = 'FTP - hasło';
+$lang['ftp____root'] = 'FTP - katalog główny';
+$lang['license_o_'] = 'Nie wybrano żadnej';
+$lang['typography_o_0'] = 'brak';
+$lang['typography_o_1'] = 'tylko podwójne cudzysłowy';
+$lang['typography_o_2'] = 'wszystkie cudzysłowy (nie działa we wszystkich przypadkach)';
+$lang['userewrite_o_0'] = 'brak';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'dokuwiki';
+$lang['deaccent_o_0'] = 'zostaw oryginalną pisownię';
+$lang['deaccent_o_1'] = 'usuń litery';
+$lang['deaccent_o_2'] = 'zamień na ASCII';
+$lang['gdlib_o_0'] = 'biblioteka GDLib niedostępna';
+$lang['gdlib_o_1'] = 'wersja 1.x';
+$lang['gdlib_o_2'] = 'automatyczne wykrywanie';
+$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';
+$lang['rss_content_o_abstract'] = 'Streszczenie';
+$lang['rss_content_o_diff'] = 'Różnice';
+$lang['rss_content_o_htmldiff'] = 'Różnice w postaci HTML';
+$lang['rss_content_o_html'] = 'Pełna strona w postaci HTML';
+$lang['rss_linkto_o_diff'] = 'różnice';
+$lang['rss_linkto_o_page'] = 'zmodyfikowana strona';
+$lang['rss_linkto_o_rev'] = 'lista zmian';
+$lang['rss_linkto_o_current'] = 'aktualna strona';
+$lang['compression_o_0'] = 'brak';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nie używaj';
+$lang['xsendfile_o_1'] = 'Specyficzny nagłówek lightttpd (poniżej wersji 1.5)';
+$lang['xsendfile_o_2'] = 'Standardowy nagłówek HTTP X-Sendfile';
+$lang['xsendfile_o_3'] = 'Specyficzny nagłówek Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Login użytkownika';
+$lang['showuseras_o_username'] = 'Pełne nazwisko użytkownika';
+$lang['showuseras_o_email'] = 'E-mail użytkownika (ukrywanie według ustawień mailguard)';
+$lang['showuseras_o_email_link'] = 'Adresy e-mail użytkowników w formie linku mailto:';
+$lang['useheading_o_0'] = 'Nigdy';
+$lang['useheading_o_navigation'] = 'W nawigacji';
+$lang['useheading_o_content'] = 'W treści';
+$lang['useheading_o_1'] = 'Zawsze';
+$lang['readdircache'] = 'Maksymalny czas dla bufora readdir (w sek).';
diff --git a/lib/plugins/config/lang/pt-br/intro.txt b/lib/plugins/config/lang/pt-br/intro.txt
new file mode 100644
index 000000000..850ba25cb
--- /dev/null
+++ b/lib/plugins/config/lang/pt-br/intro.txt
@@ -0,0 +1,7 @@
+====== Gerenciador de Configurações ======
+
+Use essa página para controlar as configurações da instalação do seu DokuWiki. Para ajuda acerca dos itens, consulte [[doku>config]]. Para mais detalhes sobre esse plug-in, veja [[doku>plugin:config]].
+
+Definições que apresentem um fundo vermelho claro são protegidas e não podem ser alteradas com esse plug-in. As definições com um fundo azul são o padrão e as com um fundo branco foram configuradas localmente para essa instalação em particular. Tanto as definições em azul quanto as em branco podem ser alteradas.
+
+Lembre-se de pressionar o botão **Salvar** antes de sair dessa página, caso contrário, suas configurações serão perdidas. \ No newline at end of file
diff --git a/lib/plugins/config/lang/pt-br/lang.php b/lib/plugins/config/lang/pt-br/lang.php
new file mode 100644
index 000000000..093e60ff8
--- /dev/null
+++ b/lib/plugins/config/lang/pt-br/lang.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['menu'] = 'Configurações do DokuWiki';
+$lang['error'] = 'As configurações não foram atualizadas devido a um valor inválido. Por favor, reveja suas alterações e reenvie-as.<br />O(s) valor(es) incorreto(s) serão exibidos contornados por uma borda vermelha.';
+$lang['updated'] = 'As configurações foram atualizadas com sucesso.';
+$lang['nochoice'] = '(nenhuma outra opção disponível)';
+$lang['locked'] = 'Não foi possível atualizar o arquivo de configurações. Se isso <br />
+não for intencional, certifique-se de que o nome do arquivo e as <br />
+e as suas permissões estejam corretos.';
+$lang['danger'] = 'Perigo: Alterar esta opção poderá tornar o seu wiki e menu de configuração inacessíveis.';
+$lang['warning'] = 'Aviso: A alteração desta opção pode causar um comportamento indesejável.';
+$lang['security'] = 'Aviso de segurança: A alteração desta opção pode representar um risco de segurança.';
+$lang['_configuration_manager'] = 'Gerenciador de configurações';
+$lang['_header_dokuwiki'] = 'Configurações do DokuWiki';
+$lang['_header_plugin'] = 'Configurações de plug-ins';
+$lang['_header_template'] = 'Configurações de modelos';
+$lang['_header_undefined'] = 'Configurações indefinidas';
+$lang['_basic'] = 'Configurações básicas';
+$lang['_display'] = 'Configurações de exibição';
+$lang['_authentication'] = 'Configurações de autenticação';
+$lang['_anti_spam'] = 'Configurações do anti-spam';
+$lang['_editing'] = 'Configurações de edição';
+$lang['_links'] = 'Configurações de link';
+$lang['_media'] = 'Configurações de mídia';
+$lang['_advanced'] = 'Configurações avançadas';
+$lang['_network'] = 'Configurações de rede';
+$lang['_plugin_sufix'] = 'Configurações de plug-ins';
+$lang['_template_sufix'] = 'Configurações de modelos';
+$lang['_msg_setting_undefined'] = 'Nenhum metadado configurado.';
+$lang['_msg_setting_no_class'] = 'Nenhuma classe definida.';
+$lang['_msg_setting_no_default'] = 'Nenhum valor padrão.';
+$lang['fmode'] = 'Modo de criação do arquivo';
+$lang['dmode'] = 'Modo de criação do diretório';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Diretório base';
+$lang['baseurl'] = 'URL base';
+$lang['savedir'] = 'Diretório para salvar os dados';
+$lang['cookiedir'] = 'Caminhos dos cookies. Deixe em branco para usar a url base.';
+$lang['start'] = 'Nome da página inicial';
+$lang['title'] = 'Título do wiki';
+$lang['template'] = 'Modelo';
+$lang['license'] = 'Sob qual licença o seu conteúdo deve ser disponibilizado?';
+$lang['fullpath'] = 'Indica o caminho completo das páginas no rodapé';
+$lang['recent'] = 'Modificações recentes';
+$lang['breadcrumbs'] = 'Número de elementos na trilha de páginas visitadas';
+$lang['youarehere'] = 'Trilha hierárquica';
+$lang['typography'] = 'Efetuar modificações tipográficas';
+$lang['htmlok'] = 'Permitir incorporação de HTML';
+$lang['phpok'] = 'Permitir incorporação de PHP';
+$lang['dformat'] = 'Formato da data (veja a função <a href="http://www.php.net/strftime">strftime</a> do PHP)';
+$lang['signature'] = 'Assinatura';
+$lang['toptoclevel'] = 'Nível mais alto para a tabela de conteúdos';
+$lang['tocminheads'] = 'Quantidade mínima de cabeçalhos para a construção da tabela de conteúdos.';
+$lang['maxtoclevel'] = 'Nível máximo para entrar na tabela de conteúdos';
+$lang['maxseclevel'] = 'Nível máximo para gerar uma seção de edição';
+$lang['camelcase'] = 'Usar CamelCase para links';
+$lang['deaccent'] = '"Limpar" os nomes das páginas';
+$lang['useheading'] = 'Usar o primeiro cabeçalho como nome da página';
+$lang['refcheck'] = 'Verificação de referência da mídia';
+$lang['refshow'] = 'Número de referências de mídia a exibir';
+$lang['allowdebug'] = 'Habilitar a depuração <b>(desabilite se não for necessário!)</b>';
+$lang['usewordblock'] = 'Bloquear spam baseado em lista de palavras';
+$lang['indexdelay'] = 'Tempo de espera antes da indexação (seg)';
+$lang['relnofollow'] = 'Usar rel="nofollow" em links externos';
+$lang['mailguard'] = 'Obscurecer endereços de e-mail';
+$lang['iexssprotect'] = 'Verificar a existência de possíveis códigos maliciosos em HTML ou JavaScript nos arquivos enviados';
+$lang['showuseras'] = 'O que exibir quando mostrar o usuário que editou a página pela última vez';
+$lang['useacl'] = 'Usar listas de controle de acesso';
+$lang['autopasswd'] = 'Gerar senhas automaticamente';
+$lang['authtype'] = 'Método de autenticação';
+$lang['passcrypt'] = 'Método de criptografia da senha';
+$lang['defaultgroup'] = 'Grupo padrão';
+$lang['superuser'] = 'Superusuário - um grupo, usuário ou uma lista separada por vírgulas (usuário1,@grupo1,usuário2) que tenha acesso completo a todas as páginas e funções, independente das definições da ACL';
+$lang['manager'] = 'Gerente - um grupo, usuário ou uma lista separada por vírgulas (usuário1,@grupo1,usuário2) que tenha acesso a certas funções de gerenciamento';
+$lang['profileconfirm'] = 'Confirmar mudanças no perfil com a senha';
+$lang['disableactions'] = 'Desabilitar as ações do DokuWiki';
+$lang['disableactions_check'] = 'Verificação';
+$lang['disableactions_subscription'] = 'Monitoramento';
+$lang['disableactions_wikicode'] = 'Ver a fonte/Exportar sem processamento';
+$lang['disableactions_other'] = 'Outras ações (separadas por vírgula)';
+$lang['sneaky_index'] = 'Por padrão, o DokuWiki irá exibir todos os espaços de nomes na visualização do índice. Ao habilitar essa opção, serão escondidos aqueles que o usuário não tiver permissão de leitura. Isso pode resultar na omissão de subespaços de nomes, tornando o índice inútil para certas configurações de ACL.';
+$lang['auth_security_timeout'] = 'Tempo limite de segurança para autenticações (seg)';
+$lang['securecookie'] = 'Os cookies definidos via HTTPS devem ser enviados para o navegador somente via HTTPS? Desabilite essa opção quando somente a autenticação do seu wiki for realizada de maneira segura via SSL e a navegação, de maneira insegura.';
+$lang['xmlrpc'] = 'Habilitar/desabilitar interface XML-RPC.';
+$lang['xmlrpcuser'] = 'Acesso Restrito ao XML-RPC para grupos separados por virgula ou usuários aqui. Deixe em branco para conveder acesso a todos.';
+$lang['updatecheck'] = 'Verificar atualizações e avisos de segurança? O DokuWiki precisa contactar o "splitbrain.org" para efetuar esse recurso.';
+$lang['userewrite'] = 'Usar URLs "limpas"';
+$lang['useslash'] = 'Usar a barra como separador de espaços de nomes nas URLs';
+$lang['usedraft'] = 'Salvar o rascunho automaticamente durante a edição';
+$lang['sepchar'] = 'Separador de palavras no nome da página';
+$lang['canonical'] = 'Usar URLs absolutas (http://servidor/caminho)';
+$lang['fnencode'] = 'Método de codificação não-ASCII de nome de arquivos.';
+$lang['autoplural'] = 'Verificar formas plurais nos links';
+$lang['compression'] = 'Método de compressão para arquivos antigos';
+$lang['cachetime'] = 'Tempo máximo para o cache (seg)';
+$lang['locktime'] = 'Tempo máximo para o bloqueio de arquivos (seg)';
+$lang['fetchsize'] = 'Tamanho máximo (em bytes) que o "fetch.php" pode transferir do exterior';
+$lang['notify'] = 'Enviar notificações de mudança para esse endereço de e-mail';
+$lang['registernotify'] = 'Enviar informações de usuários registrados para esse endereço de e-mail';
+$lang['mailfrom'] = 'Endereço de e-mail a ser utilizado para mensagens automáticas';
+$lang['mailprefix'] = 'Prefixo do assunto dos e-mails de envio automático';
+$lang['gzip_output'] = 'Usar "Content-Encoding" do gzip para o código xhtml';
+$lang['gdlib'] = 'Versão da biblioteca "GD Lib"';
+$lang['im_convert'] = 'Caminho para a ferramenta de conversão ImageMagick';
+$lang['jpg_quality'] = 'Qualidade de compressão do JPG (0-100)';
+$lang['subscribers'] = 'Habilitar o suporte ao monitoramento de páginas';
+$lang['subscribe_time'] = 'Tempo de espera antes do envio das listas e mensagens de monitoramento (segundos); este tempo deve ser menor que o especificado no parâmetro recent_days';
+$lang['compress'] = 'Compactar as saídas de CSS e JavaScript';
+$lang['cssdatauri'] = 'Tamanho máximo em bytes para o qual as imagens referenciadas em arquivos CSS devam ser incorporadas na folha de estilos (o arquivo CSS) para reduzir o custo dos pedidos HTTP. Essa técnica não funcionará na versões do IE < 8! Valores de <code>400</code> a <code>600</code> são bons. Defina o valor <code>0</code> para desativar.';
+$lang['hidepages'] = 'Esconder páginas correspondentes (expressão regular)';
+$lang['send404'] = 'Enviar "HTTP 404/Página não encontrada" para páginas não existentes';
+$lang['sitemap'] = 'Gerar Google Sitemap (dias)';
+$lang['broken_iua'] = 'A função "ignore_user_abort" está com defeito no seu sistema? Isso pode causar um índice de busca defeituoso. IIS+PHP/CGI reconhecidamente possui esse erro. Veja o <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">bug 852</a> para mais informações.';
+$lang['xsendfile'] = 'Usar o cabeçalho "X-Sendfile" para permitir que o servidor web encaminhe arquivos estáticos? Seu servidor web precisa ter suporte a isso.';
+$lang['renderer_xhtml'] = 'Renderizador a ser utilizado para a saída principal (xhtml) do wiki';
+$lang['renderer__core'] = '%s (núcleo do DokuWiki)';
+$lang['renderer__plugin'] = '%s ("plug-in")';
+$lang['rememberme'] = 'Permitir cookies de autenticação permanentes ("Lembre-se de mim")';
+$lang['rss_type'] = 'Tipo de fonte XML';
+$lang['rss_linkto'] = 'Os links da fonte XML apontam para';
+$lang['rss_content'] = 'O que deve ser exibido nos itens da fonte XML?';
+$lang['rss_update'] = 'Intervalo de atualização da fonte XML (seg)';
+$lang['recent_days'] = 'Quantas mudanças recentes devem ser mantidas (dias)?';
+$lang['rss_show_summary'] = 'Resumo de exibição da fonte XML no título';
+$lang['target____wiki'] = 'Parâmetro "target" para links internos';
+$lang['target____interwiki'] = 'Parâmetro "target" para links interwiki';
+$lang['target____extern'] = 'Parâmetro "target" para links externos';
+$lang['target____media'] = 'Parâmetro "target" para links de mídia';
+$lang['target____windows'] = 'Parâmetro "target" para links do Windows';
+$lang['proxy____host'] = 'Nome do servidor proxy';
+$lang['proxy____port'] = 'Porta do proxy';
+$lang['proxy____user'] = 'Nome de usuário do proxy';
+$lang['proxy____pass'] = 'Senha do proxy';
+$lang['proxy____ssl'] = 'Usar SSL para conectar ao proxy';
+$lang['proxy____except'] = 'Expressões regulares de URL para excessão de proxy.';
+$lang['safemodehack'] = 'Habilitar o contorno de segurança';
+$lang['ftp____host'] = 'Servidor FTP para o contorno de segurança';
+$lang['ftp____port'] = 'Porta do FTP para o contorno de segurança';
+$lang['ftp____user'] = 'Nome do usuário FTP para o contorno de segurança';
+$lang['ftp____pass'] = 'Senha do usuário FTP para o contorno de segurança';
+$lang['ftp____root'] = 'Diretório raiz do FTP para o contorno de segurança';
+$lang['license_o_'] = 'Nenhuma escolha';
+$lang['typography_o_0'] = 'nenhuma';
+$lang['typography_o_1'] = 'excluir aspas simples';
+$lang['typography_o_2'] = 'incluir aspas simples (nem sempre funciona)';
+$lang['userewrite_o_0'] = 'não';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'interno do DokuWiki';
+$lang['deaccent_o_0'] = 'não';
+$lang['deaccent_o_1'] = 'remover acentos';
+$lang['deaccent_o_2'] = 'romanizar';
+$lang['gdlib_o_0'] = 'a "GD Lib" não está disponível';
+$lang['gdlib_o_1'] = 'versão 1.x';
+$lang['gdlib_o_2'] = 'detecção automática';
+$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';
+$lang['rss_content_o_abstract'] = 'resumo';
+$lang['rss_content_o_diff'] = 'diff unificado';
+$lang['rss_content_o_htmldiff'] = 'tabela de diff formatada em HTML';
+$lang['rss_content_o_html'] = 'conteúdo completo da página em HTML';
+$lang['rss_linkto_o_diff'] = 'visualização das diferenças';
+$lang['rss_linkto_o_page'] = 'página revisada';
+$lang['rss_linkto_o_rev'] = 'lista de revisões';
+$lang['rss_linkto_o_current'] = 'página atual';
+$lang['compression_o_0'] = 'nenhum';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'não usar';
+$lang['xsendfile_o_1'] = 'cabeçalho proprietário lighttpd (anterior à versão 1.5)';
+$lang['xsendfile_o_2'] = 'cabeçalho "X-Sendfile" padrão';
+$lang['xsendfile_o_3'] = 'cabeçalho proprietário "Nginx X-Accel-Redirect"';
+$lang['showuseras_o_loginname'] = 'nome de usuário';
+$lang['showuseras_o_username'] = 'nome completo do usuário';
+$lang['showuseras_o_email'] = 'endereço de e-mail do usuário (obscurecido segundo a definição anterior)';
+$lang['showuseras_o_email_link'] = 'endereço de e-mail de usuário como um link "mailto:"';
+$lang['useheading_o_0'] = 'nunca';
+$lang['useheading_o_navigation'] = 'somente a navegação';
+$lang['useheading_o_content'] = 'somente o conteúdo do wiki';
+$lang['useheading_o_1'] = 'sempre';
+$lang['readdircache'] = 'Tempo máximo para cache readdir (segundos)';
diff --git a/lib/plugins/config/lang/pt/intro.txt b/lib/plugins/config/lang/pt/intro.txt
new file mode 100644
index 000000000..2010dadaf
--- /dev/null
+++ b/lib/plugins/config/lang/pt/intro.txt
@@ -0,0 +1,7 @@
+====== Gerenciador de Configurações ======
+
+Use esta página para controlar as definições da instalação do seu DokuWiki. Para ajuda acerca dos itens, consulte [[doku>config]]. Para mais detalhes sobre este plugin, veja [[doku>plugin:config]].
+
+Definições que apresentem um fundo vermelho claro são protegidas e não podem ser alteradas com este plugin. Definições com um fundo azul são padrão e definições com um fundo branco foram configuradas localmente para essa instalação em particular. Tanto as definições em azul como em branco podem ser alteradas.
+
+Lembre-se de pressionar o botão **Guardar** antes de sair desta página, caso contrário, as suas definições serão perdidas. \ No newline at end of file
diff --git a/lib/plugins/config/lang/pt/lang.php b/lib/plugins/config/lang/pt/lang.php
new file mode 100644
index 000000000..fe05bd281
--- /dev/null
+++ b/lib/plugins/config/lang/pt/lang.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Portugueselanguage file
+ *
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['menu'] = 'Configuração';
+$lang['error'] = 'Parâmetros de Configuração não actualizados devido a valores inválidos. Por favor, reveja as modificações que pretende efectuar antes de re-submetê-las.<br /> Os valores incorrectos serão mostrados dentro de uma "moldura" vermelha.';
+$lang['updated'] = 'Parâmetros de Configuração actualizados com sucesso.';
+$lang['nochoice'] = '(não existem outras escolhas disponíveis)';
+$lang['locked'] = 'O ficheiro de configuração não pôde ser actualizado, se isso foi não intencional, <br />certifique-se que o nome e as permissões do ficheiro de configuração estejam correctas.
+';
+$lang['danger'] = 'Perigo: Alterar esta opção poderá tornar o seu wiki e o menu de configuração inacessíveis.';
+$lang['warning'] = 'Aviso: A alteração desta opção poderá causar comportamento involuntário.';
+$lang['security'] = 'Aviso de segurança: Alterar esta opção pode apresentar um risco de segurança.';
+$lang['_configuration_manager'] = 'Gestor de Parâmetros de Configuração';
+$lang['_header_dokuwiki'] = 'Parâmetros DokuWiki';
+$lang['_header_plugin'] = 'Parâmetros dos Plugins';
+$lang['_header_template'] = 'Parâmetros das Templates';
+$lang['_header_undefined'] = 'Parâmetros não definidos';
+$lang['_basic'] = 'Configurações Básicas';
+$lang['_display'] = 'Configuração de Apresentação';
+$lang['_authentication'] = 'Configuração de Autenticação';
+$lang['_anti_spam'] = 'Configuração Anti-Spam';
+$lang['_editing'] = 'Configuração de Edição';
+$lang['_links'] = 'Configuração de Ligações';
+$lang['_media'] = 'Configuração de Media';
+$lang['_advanced'] = 'Configurações Avançadas';
+$lang['_network'] = 'Configuração de Rede';
+$lang['_plugin_sufix'] = 'Configuração dos Plugins';
+$lang['_template_sufix'] = 'Configuração das Templates';
+$lang['_msg_setting_undefined'] = 'Nenhum metadado configurado.';
+$lang['_msg_setting_no_class'] = 'Nenhuma classe definida.';
+$lang['_msg_setting_no_default'] = 'Sem valor por omissão.';
+$lang['fmode'] = 'Modo de criação de ficheiros.';
+$lang['dmode'] = 'Modo de criação de pastas.';
+$lang['lang'] = 'Idioma';
+$lang['basedir'] = 'Pasta Base';
+$lang['baseurl'] = 'URL Base';
+$lang['savedir'] = 'Pasta para guardar dados';
+$lang['start'] = 'Nome da Página Inicial';
+$lang['title'] = 'Título deste Wiki';
+$lang['template'] = 'Template';
+$lang['license'] = 'Sob que licença o seu conteúdo deverá ser disponibilizado?';
+$lang['fullpath'] = 'Revelar caminho completo no rodapé';
+$lang['recent'] = 'Alterações recentes';
+$lang['breadcrumbs'] = 'Número máximo de breadcrumbs';
+$lang['youarehere'] = 'Breadcrumbs hierárquicas';
+$lang['typography'] = 'Executar substituições tipográficas';
+$lang['htmlok'] = 'Permitir embeber HTML';
+$lang['phpok'] = 'Permitir embeber PHP';
+$lang['dformat'] = 'Formato de Data (ver função PHP\'s <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Assinatura';
+$lang['toptoclevel'] = 'Nível de topo para a tabela de conteúdo';
+$lang['tocminheads'] = 'Quantidade mínima de cabeçalhos para a construção da tabela de conteúdos.';
+$lang['maxtoclevel'] = 'Máximo nível para a tabela de conteúdo';
+$lang['maxseclevel'] = 'Máximo nível para editar secção';
+$lang['camelcase'] = 'Usar CamelCase';
+$lang['deaccent'] = 'Nomes das páginas sem acentos';
+$lang['useheading'] = 'Usar o primeiro cabeçalho para o nome da página';
+$lang['refcheck'] = 'Verificação de referência da media';
+$lang['refshow'] = 'Número de referências de media a exibir';
+$lang['allowdebug'] = 'Permitir depuração <b>desabilite se não for necessário!</b>';
+$lang['usewordblock'] = 'Bloquear spam baseado em lista de palavras (wordlist)';
+$lang['indexdelay'] = 'Tempo de espera antes da indexação (seg)';
+$lang['relnofollow'] = 'Usar rel="nofollow" em links externos';
+$lang['mailguard'] = 'Obscurecer endereços de email';
+$lang['iexssprotect'] = 'Verificar os arquivos enviados contra possíveis códigos maliciosos em HTML ou JavaScript';
+$lang['showuseras'] = 'O que exibir quando mostrar o utilizador que editou a página pela última vez';
+$lang['useacl'] = 'Usar ACL - Listas de Controlo de Acessos';
+$lang['autopasswd'] = 'Auto-gerar senhas';
+$lang['authtype'] = 'Método de autenticação';
+$lang['passcrypt'] = 'Método de cifragem da senha';
+$lang['defaultgroup'] = 'Grupo por omissão';
+$lang['superuser'] = 'Superutilizador - um grupo, utilizador ou uma lista separada por vírgulas usuário1,@grupo1,usuário2 que tem acesso completo a todas as páginas e funções, independente das definições da ACL';
+$lang['manager'] = 'Gestor - um grupo, utilizador ou uma lista separada por vírgulas usuário1,@grupo1,usuário2 que tem acesso a certas funções de gestão';
+$lang['profileconfirm'] = 'Confirmar mudanças no perfil com a senha';
+$lang['disableactions'] = 'Desactivar acções DokuWiki';
+$lang['disableactions_check'] = 'Checar';
+$lang['disableactions_subscription'] = 'Subscrever/Não Subscrver';
+$lang['disableactions_wikicode'] = 'Ver fonte/Exportar em bruto';
+$lang['disableactions_other'] = 'Outras acções (separadas por vírgula)';
+$lang['sneaky_index'] = 'Por norma, o DokuWiki irá exibir todos os espaços de nomes na visualização do índice. Ao habilitar essa opção, serão escondidos aqueles em que o utilizador não tenha permissão de leitura. Isto pode resultar na omissão de sub-ramos acessíveis, que poderá tornar o índice inútil para certas configurações de ACL.';
+$lang['auth_security_timeout'] = 'Tempo limite de segurança para autenticações (seg)';
+$lang['securecookie'] = 'Os cookies definidos via HTTPS deverão ser enviados para o navegador somente via HTTPS? Desabilite essa opção quando somente a autenticação do seu wiki for realizada de maneira segura via SSL e a navegação de maneira insegura.';
+$lang['xmlrpc'] = 'Habilitar/desabilitar interface XML-RPC.';
+$lang['xmlrpcuser'] = 'Restringir acesso XML-RPC para os grupos separados por vírgula ou utilizadores inseridos aqui. Deixar vazio para dar acesso a todos.';
+$lang['updatecheck'] = 'Verificar por actualizações e avisos de segurança? O DokuWiki precisa contactar o "splitbrain.org" para efectuar esta verificação.';
+$lang['userewrite'] = 'Usar URLs SEO';
+$lang['useslash'] = 'Usar a barra como separador de espaços de nomes nas URLs';
+$lang['usedraft'] = 'Guardar o rascunho automaticamente durante a edição';
+$lang['sepchar'] = 'Separador de palavras no nome da página';
+$lang['canonical'] = 'Usar URLs absolutas (http://servidor/caminho)';
+$lang['fnencode'] = 'Método de codificar nomes de ficheiro não-ASCII.';
+$lang['autoplural'] = 'Verificar formas plurais nos links';
+$lang['compression'] = 'Método de compressão para histórico';
+$lang['cachetime'] = 'Idade máxima para cache (seg.)';
+$lang['locktime'] = 'Idade máxima para locks (seg.)';
+$lang['fetchsize'] = 'Tamanho máximo (bytes) que o fetch.php pode transferir do exterior';
+$lang['notify'] = 'Enviar notificações de mudanças para este endereço de email';
+$lang['registernotify'] = 'Enviar informações de utilizadores registados para este endereço de email';
+$lang['mailfrom'] = 'Endereço de email a ser utilizado para mensagens automáticas';
+$lang['mailprefix'] = 'Prefixo de email a ser utilizado para mensagens automáticas';
+$lang['gzip_output'] = 'Usar "Content-Encoding" do gzip para o código xhtml';
+$lang['gdlib'] = 'Versão GD Lib';
+$lang['im_convert'] = 'Caminho para a ferramenta "convert" do ImageMagick';
+$lang['jpg_quality'] = 'Compressão/Qualidade JPG (0-100)';
+$lang['subscribers'] = 'Habilitar o suporte a subscrição de páginas ';
+$lang['subscribe_time'] = 'Tempo após o qual as listas de subscrição e "digests" são enviados (seg.); Isto deve ser inferior ao tempo especificado em recent_days.';
+$lang['compress'] = 'Compactar as saídas de CSS e JavaScript';
+$lang['cssdatauri'] = 'Tamanho em bytes até ao qual as imagens referenciadas em ficheiros CSS devem ser embutidas diretamente no CSS para reduzir a carga de pedidos HTTP extra. Esta técnica não funciona em IE 7 e abaixo! <code>400</code> a <code>600</code> bytes é um bom valor. Escolher <code>0</code> para desativar.';
+$lang['hidepages'] = 'Esconder páginas correspondentes (expressões regulares)';
+$lang['send404'] = 'Enviar "HTTP 404/Página não encontrada" para páginas não existentes';
+$lang['sitemap'] = 'Gerar Sitemap Google (dias)';
+$lang['broken_iua'] = 'A função "ignore_user_abort" não está a funcionar no seu sistema? Isso pode causar um índice de busca defeituoso. Sistemas com IIS+PHP/CGI são conhecidos por possuírem este problema. Veja o <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">bug 852</a> para mais informações.';
+$lang['xsendfile'] = 'Usar o cabeçalho "X-Sendfile" para permitir o servidor de internet encaminhar ficheiros estáticos? O seu servidor de internet precisa ter suporte a isso.';
+$lang['renderer_xhtml'] = 'Renderizador a ser utilizado para a saída principal do wiki (xhtml)';
+$lang['renderer__core'] = '%s (núcleo dokuwiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permitir cookies de autenticação permanentes (Memorizar?)';
+$lang['rss_type'] = 'Tipo de feed XML';
+$lang['rss_linkto'] = 'Links de feed XML ara';
+$lang['rss_content'] = 'O que deve ser exibido nos itens do alimentador XML?';
+$lang['rss_update'] = 'Intervalo de actualização do alimentador XML (seg)';
+$lang['recent_days'] = 'Quantas mudanças recentes devem ser mantidas? (dias)';
+$lang['rss_show_summary'] = 'Resumo de exibição do alimentador XML no título';
+$lang['target____wiki'] = 'Parâmetro "target" para links internos';
+$lang['target____interwiki'] = 'Parâmetro "target" para links entre wikis';
+$lang['target____extern'] = 'Parâmetro "target" para links externos';
+$lang['target____media'] = 'Parâmetro "target" para links de media';
+$lang['target____windows'] = 'Parâmetro "target" para links do Windows';
+$lang['proxy____host'] = 'Nome do servidor proxy';
+$lang['proxy____port'] = 'Porta de Proxy';
+$lang['proxy____user'] = 'Nome de utilizador Proxy';
+$lang['proxy____pass'] = 'Password de Proxy ';
+$lang['proxy____ssl'] = 'Usar SSL para conectar ao proxy';
+$lang['proxy____except'] = 'Expressão regular para condizer URLs para os quais o proxy deve ser saltado.';
+$lang['safemodehack'] = 'Habilitar modo de segurança';
+$lang['ftp____host'] = 'Servidor FTP para o modo de segurança';
+$lang['ftp____port'] = 'Porta de FTP para o modo de segurança';
+$lang['ftp____user'] = 'Nome do utilizador FTP para o modo de segurança';
+$lang['ftp____pass'] = 'Senha do utilizador FTP para o modo de segurança';
+$lang['ftp____root'] = 'Directoria raiz do FTP para o modo de segurança';
+$lang['license_o_'] = 'Nenhuma escolha';
+$lang['typography_o_0'] = 'nenhum';
+$lang['typography_o_1'] = 'Apenas entre aspas';
+$lang['typography_o_2'] = 'Entre aspas e apóstrofes';
+$lang['userewrite_o_0'] = 'nenhum';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'interno (DokuWiki)';
+$lang['deaccent_o_0'] = 'desligado';
+$lang['deaccent_o_1'] = 'remover acentos';
+$lang['deaccent_o_2'] = 'romanizar';
+$lang['gdlib_o_0'] = 'A GD Lib não está disponível';
+$lang['gdlib_o_1'] = 'Versão 1.x';
+$lang['gdlib_o_2'] = 'Auto-detecção';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstracto';
+$lang['rss_content_o_diff'] = 'Diferenças Unificadas';
+$lang['rss_content_o_htmldiff'] = 'Tabela de diff formatada em HTML';
+$lang['rss_content_o_html'] = 'Conteúdo completo da página em HTML';
+$lang['rss_linkto_o_diff'] = 'vista de diferenças';
+$lang['rss_linkto_o_page'] = 'página revista';
+$lang['rss_linkto_o_rev'] = 'lista de revisões';
+$lang['rss_linkto_o_current'] = 'página actual';
+$lang['compression_o_0'] = 'Sem Compressão';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'não usar';
+$lang['xsendfile_o_1'] = 'Cabeçalho proprietário lighttpd (anterior à versão 1.5)';
+$lang['xsendfile_o_2'] = 'Cabeçalho "X-Sendfile" padrão';
+$lang['xsendfile_o_3'] = 'Cabeçalho proprietário "Nginx X-Accel-Redirect"';
+$lang['showuseras_o_loginname'] = 'Nome de utilizador';
+$lang['showuseras_o_username'] = 'Nome completo do utilizador';
+$lang['showuseras_o_email'] = 'Endereço email do utilizador (ofuscado de acordo com a configuração mailguard)';
+$lang['showuseras_o_email_link'] = 'Endereço de e-mail de usuário como um link "mailto:"';
+$lang['useheading_o_0'] = 'Nunca';
+$lang['useheading_o_navigation'] = 'Apenas Navegação';
+$lang['useheading_o_content'] = 'Apenas Conteúdo Wiki';
+$lang['useheading_o_1'] = 'Sempre';
+$lang['readdircache'] = 'Idade máxima para a cache de "readdir" (seg)';
diff --git a/lib/plugins/config/lang/ro/intro.txt b/lib/plugins/config/lang/ro/intro.txt
new file mode 100644
index 000000000..f5cbbe81e
--- /dev/null
+++ b/lib/plugins/config/lang/ro/intro.txt
@@ -0,0 +1,7 @@
+====== Manager Configurare ======
+
+Folosiţi această pagină pentru a controla setările instalării DokuWiki. Pentru ajutor la probleme punctuale, consultaţi [[doku>config]]. Pentru mai multe detalii privind acest plugin, consultaţi [[doku>plugin:config]].
+
+Setările pe un fond roşu-deschis sunt protejate şi nu pot fi modificate cu acest plugin. Setările pe un fond albastru sunt valori implicite iar cele pe fond alb au fost setate local pentru această instalare individualizată. Setările pe fond albastru şi alb pot fi modificate.
+
+Nu uitaţi să apăsaţi butonul **SALVEAZĂ** înainte de a părăsi această pagină; altfel, modificările aduse se vor pierde.
diff --git a/lib/plugins/config/lang/ro/lang.php b/lib/plugins/config/lang/ro/lang.php
new file mode 100644
index 000000000..5845e3c35
--- /dev/null
+++ b/lib/plugins/config/lang/ro/lang.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['menu'] = 'Setări de Configurare';
+$lang['error'] = 'Setări nu au fost actualizate datorită unei valori incorecte; verificaţi modificările şi încercaţi din nou. <br /> Valorile incorecte vor apărea într-un chenar roşu.';
+$lang['updated'] = 'Setările au fost actualizate cu succes.';
+$lang['nochoice'] = '(nici o altă opţiune nu este disponibilă)';
+$lang['locked'] = 'Fişierul de setări nu poate fi actualizat. Dacă nu s-a dorit aceasta, asiguraţi-vă că numele şi drepturile de acces ale fişierului de setări localizate sunt corecte.';
+$lang['danger'] = 'Pericol: Modificarea aceastei opțiuni poate conduce la imposibilitatea accesării wiki-ului și a meniului de configurare!';
+$lang['warning'] = 'Atenție: Modificarea aceastei opțiuni poate duce la evenimente nedorite!';
+$lang['security'] = 'Alertă de securitate: Modificarea acestei opțiuni poate prezenta un risc de securitate!';
+$lang['_configuration_manager'] = 'Manager Configurare';
+$lang['_header_dokuwiki'] = 'Setări DokuWiki';
+$lang['_header_plugin'] = 'Setări Plugin-uri';
+$lang['_header_template'] = 'Setări Şabloane';
+$lang['_header_undefined'] = 'Setări Nedefinite';
+$lang['_basic'] = 'Setări de Bază';
+$lang['_display'] = 'Setări Afişare';
+$lang['_authentication'] = 'Setări Autentificare';
+$lang['_anti_spam'] = 'Setări Anti-Spam';
+$lang['_editing'] = 'Setări Editare';
+$lang['_links'] = 'Setări Legături';
+$lang['_media'] = 'Setări Media';
+$lang['_advanced'] = 'Setări Avansate';
+$lang['_network'] = 'Setări Reţea';
+$lang['_plugin_sufix'] = 'Setări Plugin-uri';
+$lang['_template_sufix'] = 'Setări Şabloane';
+$lang['_msg_setting_undefined'] = 'Nesetat metadata';
+$lang['_msg_setting_no_class'] = 'Nesetat class';
+$lang['_msg_setting_no_default'] = 'Nici o valoare implicită';
+$lang['fmode'] = 'Mod creare fişier';
+$lang['dmode'] = 'Mod creare director';
+$lang['lang'] = 'Limbă';
+$lang['basedir'] = 'Director bază';
+$lang['baseurl'] = 'URL bază ';
+$lang['savedir'] = 'Director pentru salvarea datelor';
+$lang['cookiedir'] = 'Cale Cookie. Lăsați gol pentru a utiliza baseurl.';
+$lang['start'] = 'Numele paginii de start';
+$lang['title'] = 'Titlul wiki';
+$lang['template'] = 'Şablon';
+$lang['license'] = 'Sub ce licenţă va fi publicat conţinutul?';
+$lang['fullpath'] = 'Arată calea completă a paginii în subsol';
+$lang['recent'] = 'Modificări recente';
+$lang['breadcrumbs'] = 'Numărul de "urme" lăsate';
+$lang['youarehere'] = 'Structura ierarhică a "urmelor" lăsate';
+$lang['typography'] = 'Fă înlocuiri topografice';
+$lang['htmlok'] = 'Permite intercalare cod HTML';
+$lang['phpok'] = 'Permite intercalare cod PHP';
+$lang['dformat'] = 'Format dată (vezi funcţia PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Semnătura';
+$lang['toptoclevel'] = 'Primul nivel pentru cuprins';
+$lang['tocminheads'] = 'Numărul minim de titluri ce determină dacă se alcătuieşte Tabelul de Cuprins (TOC)';
+$lang['maxtoclevel'] = 'Nivelul maxim pentru cuprins';
+$lang['maxseclevel'] = 'Nivelul maxim de editare al secţiunii';
+$lang['camelcase'] = 'Foloseşte CamelCase pentru legături';
+$lang['deaccent'] = 'numedepagină curate';
+$lang['useheading'] = 'Foloseşte primul titlu pentru numele paginii';
+$lang['refcheck'] = 'Verificare referinţă media';
+$lang['refshow'] = 'Numărul de referinţe media de arătat';
+$lang['allowdebug'] = 'Permite depanarea <b>dezactivaţi dacă cu e necesar!</b>';
+$lang['mediarevisions'] = 'Activează revizii media?';
+$lang['usewordblock'] = 'Blochează spam-ul pe baza listei de cuvinte';
+$lang['indexdelay'] = 'Timpul de întârziere înainte de indexare (sec)';
+$lang['relnofollow'] = 'Folosiţi rel="nofollow" pentru legăturile externe';
+$lang['mailguard'] = 'Adrese de email acoperite';
+$lang['iexssprotect'] = 'Verifică fişierele încărcate pentru posibil cod periculos JavaScript sau HTML';
+$lang['showuseras'] = 'Ce se afişează la indicarea utilizatorului care a editat ultimul o pagină';
+$lang['useacl'] = 'Utilizează liste de control al accesului';
+$lang['autopasswd'] = 'Parole autogenerate';
+$lang['authtype'] = 'Autentificare backend';
+$lang['passcrypt'] = 'Metoda de criptare a parolei';
+$lang['defaultgroup'] = 'Grup implicit';
+$lang['superuser'] = 'Superuser - un grup sau un utilizator cu acces complet la toate paginile şi funcţiile indiferent de setările ACL';
+$lang['manager'] = 'Manager - un grup sau un utilizator cu acces la anumite funcţii de management';
+$lang['profileconfirm'] = 'Confirmă schimbarea profilului cu parola';
+$lang['disableactions'] = 'Dezactivează acţiunile DokuWiki';
+$lang['disableactions_check'] = 'Verifică';
+$lang['disableactions_subscription'] = 'Subscrie/Anulează subscrierea';
+$lang['disableactions_wikicode'] = 'Vizualizează sursa/Export Raw';
+$lang['disableactions_other'] = 'Alte acţiuni (separate prin virgulă)';
+$lang['sneaky_index'] = 'Implicit, DokuWiki va arăta toate numele de spaţii la vizualizarea indexului. Activând această opţiune vor fi ascunse acelea la care utilizatorul nu are drepturi de citire. Aceasta poate determina ascunderea sub-numelor de spaţii accesibile. Aceasta poate face index-ul inutilizabil cu anumite setări ale ACL';
+$lang['auth_security_timeout'] = 'Timpul de expirare al Autentificării Securizate (secunde)';
+$lang['securecookie'] = 'Cookies-urile setate via HTTPS să fie trimise doar via HTTPS de către browser? Dezactivaţi această opţiune numai când login-ul wiki-ului este securizat cu SSL dar navigarea wiki-ului se realizează nesecurizat.';
+$lang['xmlrpc'] = 'Activează/dezactivează interfaţa XML-RPC';
+$lang['xmlrpcuser'] = 'Restricţionaţi accesul XML-RPC la grupurile sau utilizatorii separaţi prin virgulă daţi aici. Lasaţi gol pentru a da acces tuturor.';
+$lang['updatecheck'] = 'Verificare actualizări şi avertismente privind securitatea? DokuWiki trebuie să contacteze update.dokuwiki.org pentru această facilitate.';
+$lang['userewrite'] = 'Folosire URL-uri "nice"';
+$lang['useslash'] = 'Foloseşte slash-ul ca separator de spaţii de nume în URL-uri';
+$lang['usedraft'] = 'Salvează automat o schiţă în timpul editării';
+$lang['sepchar'] = 'Separator cuvinte în numele paginii';
+$lang['canonical'] = 'Foloseşte URL-uri canonice';
+$lang['fnencode'] = 'Metoda de encodare a numelor fişierelor non-ASCII.';
+$lang['autoplural'] = 'Verifică formele de plural în legături';
+$lang['compression'] = 'Metoda de criptare a fişierelor pod';
+$lang['cachetime'] = 'Durata maximă pentru cache (secunde)';
+$lang['locktime'] = 'Durata maximă pentru blocarea fişierelor (secunde)';
+$lang['fetchsize'] = 'Dimensiunea maximă (byte) pe care fetch.php poate să descarce din exterior';
+$lang['notify'] = 'Trimite notificări privind modificările pe această adresă de email';
+$lang['registernotify'] = 'Trimite informare noilor utilizatori înregistraţi pe această adresă de email';
+$lang['mailfrom'] = 'Adresa de email utilizată pentru mailuri automate';
+$lang['mailprefix'] = 'Prefix subiect e-mail de folosit pentru mail-uri automate';
+$lang['gzip_output'] = 'Foloseşte gzip pentru codarea conţinutului xhtml';
+$lang['gdlib'] = 'Versiunea GD Lib';
+$lang['im_convert'] = 'Calea către instrumentul de conversie ImageMagick';
+$lang['jpg_quality'] = 'Calitatea compresiei JPG (0-100)';
+$lang['subscribers'] = 'Activează suportul pentru subscrierea paginii';
+$lang['subscribe_time'] = 'Timpul după care lista de abonare şi digestie sunt trimise (sec); Aceasta ar trebui să fie mai mic decât timpul specificat în recent_days.';
+$lang['compress'] = 'Compactează codul CSS şi javascript produs';
+$lang['cssdatauri'] = 'Dimensiunea în octeți până la care imaginile regasite în fișierele CSS ar trebui să fie incluse direct în stylesheet pentru a reduce supraîncărcarea antetului cererii HTTP. Această tehnică nu va funcționa în IE < 8! <code>400</code> până la <code>600</code> octeți sunt suficienți. Introduceți <code>0</code> pentru a dezactiva această opțiune.';
+$lang['hidepages'] = 'Ascunde paginile pereche (expresii regulate)';
+$lang['send404'] = 'Trimite mesajul "HTTP 404/Page Not Found" pentru paginile inexistente';
+$lang['sitemap'] = 'Generează Google sitemap (zile)';
+$lang['broken_iua'] = 'Funcţia ignore_user_abort nu funcţionează pe sistemul dumneavoastră? Aceasta poate determina nefuncţionarea indexului de căutare. IIS+PHP/CGI sunt cunoscute ca fiind nefuncţionale. Mai multe detalii găsiţi la <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a>';
+$lang['xsendfile'] = 'Folosiţi header-ul X-Send pentru a-i permite serverului web să trimită fişiere statice? Serverul web trebuie să permită aceasta.';
+$lang['renderer_xhtml'] = 'Motorul de randare principal folosit pentru afişarea wiki în format xhtml';
+$lang['renderer__core'] = '%s (nucleu dokuwiki)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Permiteţi cookies permanente la login (ţine-mă minte)';
+$lang['rss_type'] = 'Tip flux XML';
+$lang['rss_linkto'] = 'Fluxul XML se leagă la';
+$lang['rss_content'] = 'Ce să afişez în obiectele fluxurilor XML';
+$lang['rss_update'] = 'Intervalul de actualizare a fluxului XML (sec)';
+$lang['recent_days'] = 'Câte modificări recente să se păstreze?';
+$lang['rss_show_summary'] = 'Fluxul XML arată rezumat în titlu';
+$lang['target____wiki'] = 'Fereastra ţintă pentru legăturile interne';
+$lang['target____interwiki'] = 'Fereastra ţintă pentru legăturile interwiki';
+$lang['target____extern'] = 'Fereastra ţintă pentru legăturile externe';
+$lang['target____media'] = 'Fereastra ţintă pentru legăturile media';
+$lang['target____windows'] = 'Fereastra ţintă pentru legăturile windows';
+$lang['proxy____host'] = 'Nume server Proxy';
+$lang['proxy____port'] = 'Port Proxy';
+$lang['proxy____user'] = 'Nume utilizator Proxy';
+$lang['proxy____pass'] = 'Parolă Proxy';
+$lang['proxy____ssl'] = 'Foloseşte SSL pentru conectare la Proxy';
+$lang['proxy____except'] = 'Expresie regulară de potrivit cu URL-uri pentru care proxy-ul trebuie păsuit.';
+$lang['safemodehack'] = 'Activează safemode hack';
+$lang['ftp____host'] = 'Server FTP pentru safemode hack';
+$lang['ftp____port'] = 'Port FTP pentru safemode hack';
+$lang['ftp____user'] = 'Nume utilizator pentru safemode hack';
+$lang['ftp____pass'] = 'Parolă FTP pentru safemode hack';
+$lang['ftp____root'] = 'Director rădăcină FTP pentru safemode hack';
+$lang['license_o_'] = 'Nici una aleasă';
+$lang['typography_o_0'] = 'nimic';
+$lang['typography_o_1'] = 'Numai ghilimele duble';
+$lang['typography_o_2'] = 'Toate ghilimelele (s-ar putea să nu fucţioneze întotdeauna)';
+$lang['userewrite_o_0'] = 'nimic';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki intern';
+$lang['deaccent_o_0'] = 'închis';
+$lang['deaccent_o_1'] = 'înlătură accentele';
+$lang['deaccent_o_2'] = 'romanizează';
+$lang['gdlib_o_0'] = 'biblioteca GD Lib nu este disponibilă';
+$lang['gdlib_o_1'] = 'Versiunea 1.x';
+$lang['gdlib_o_2'] = 'Detectare automată';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstract';
+$lang['rss_content_o_diff'] = 'Diferenţe unificate';
+$lang['rss_content_o_htmldiff'] = 'Tabel diferenţe în format HTML';
+$lang['rss_content_o_html'] = 'Conţinut pagină complet HTML';
+$lang['rss_linkto_o_diff'] = 'vizualizare diferenţe';
+$lang['rss_linkto_o_page'] = 'pagina revizuită';
+$lang['rss_linkto_o_rev'] = 'lista revizuirilor';
+$lang['rss_linkto_o_current'] = 'pagina curentă';
+$lang['compression_o_0'] = 'nici una';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nu se foloseşte';
+$lang['xsendfile_o_1'] = 'Header proprietar lighttpd (înaintea versiunii 1.5)';
+$lang['xsendfile_o_2'] = 'Header standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'Header proprietar Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Numele de login';
+$lang['showuseras_o_username'] = 'Numele complet al utilizatorului';
+$lang['showuseras_o_email'] = 'Adresa de e-mail a utilizatorului (mascată conform setărilor de protecţie)';
+$lang['showuseras_o_email_link'] = 'Adresa de e-mail a utilizatorului ca mailto: link';
+$lang['useheading_o_0'] = 'Niciodată';
+$lang['useheading_o_navigation'] = 'Doar navigare';
+$lang['useheading_o_content'] = 'Doar conţinutul Wiki';
+$lang['useheading_o_1'] = 'Întotdeauna';
+$lang['readdircache'] = 'Vârsta maximă depozitare readdir (sec)';
diff --git a/lib/plugins/config/lang/ru/intro.txt b/lib/plugins/config/lang/ru/intro.txt
new file mode 100644
index 000000000..a629d9332
--- /dev/null
+++ b/lib/plugins/config/lang/ru/intro.txt
@@ -0,0 +1,9 @@
+====== Настройки вики ======
+
+Здесь вы можете изменить настройки своей «ДокуВики». Для справки по поводу конкретных опций смотрите [[doku>config]]. Дополнительные детали об этом плагине доступны здесь: [[doku>plugin:config]].
+
+Настройки, отображаемые на светло-красном фоне, защищены от изменений и не могут быть отредактированы с помощью этого плагина. Голубым фоном отмечены настройки со значениями по умолчанию, а белым фоном — настройки, которые были локально изменены для этой конкретной «ДокуВики». Как голубые, так и белые настройки доступны для изменения.
+
+Не забудьте нажать кнопку «**Сохранить**» перед тем, как покинуть эту страницу, иначе все ваши изменения будут потеряны.
+
+
diff --git a/lib/plugins/config/lang/ru/lang.php b/lib/plugins/config/lang/ru/lang.php
new file mode 100644
index 000000000..f29257a28
--- /dev/null
+++ b/lib/plugins/config/lang/ru/lang.php
@@ -0,0 +1,196 @@
+<?php
+/**
+ * Russian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Andrew Pleshakov <beotiger@mail.ru>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['menu'] = 'Настройки вики';
+$lang['error'] = 'Настройки не были сохранены из-за ошибки в одном из значений. Пожалуйста, проверьте свои изменения и попробуйте ещё раз.<br />Неправильные значения будут обведены красной рамкой.';
+$lang['updated'] = 'Настройки успешно сохранены.';
+$lang['nochoice'] = '(нет других вариантов)';
+$lang['locked'] = 'Файл настройки недоступен для изменения. Если это не специально, <br />убедитесь, что файл локальной настройки имеет правильное имя и права доступа.';
+$lang['danger'] = 'Внимание: изменение этой опции может сделать вашу вики и меню конфигурации недоступными.';
+$lang['warning'] = 'Предостережение: изменение этой опции может вызвать непредсказуемое поведение.';
+$lang['security'] = 'Предостережение по безопасности: изменение этой опции может вызвать риск, связанный с безопасностью.';
+$lang['_configuration_manager'] = 'Настройки вики';
+$lang['_header_dokuwiki'] = 'Параметры «ДокуВики»';
+$lang['_header_plugin'] = 'Параметры плагинов';
+$lang['_header_template'] = 'Параметры шаблонов';
+$lang['_header_undefined'] = 'Прочие параметры';
+$lang['_basic'] = 'Основные параметры';
+$lang['_display'] = 'Параметры отображения';
+$lang['_authentication'] = 'Параметры аутентификации';
+$lang['_anti_spam'] = 'Параметры блокировки спама';
+$lang['_editing'] = 'Параметры правки';
+$lang['_links'] = 'Параметры ссылок';
+$lang['_media'] = 'Параметры медиафайлов';
+$lang['_advanced'] = 'Тонкая настройка';
+$lang['_network'] = 'Параметры сети';
+$lang['_plugin_sufix'] = 'Параметры плагина';
+$lang['_template_sufix'] = 'Параметры шаблона';
+$lang['_msg_setting_undefined'] = 'Не найдены метаданные настроек.';
+$lang['_msg_setting_no_class'] = 'Не найден класс настроек.';
+$lang['_msg_setting_no_default'] = 'Не задано значение по умолчанию.';
+$lang['fmode'] = 'Права для создаваемых файлов';
+$lang['dmode'] = 'Права для создаваемых директорий';
+$lang['lang'] = 'Язык';
+$lang['basedir'] = 'Корневая директория (например, <code>/dokuwiki/</code>). Оставьте пустым для автоопределения.';
+$lang['baseurl'] = 'Корневой адрес (URL) (например, <code>http://www.yourserver.ru</code>). Оставьте пустым для автоопределения.';
+$lang['savedir'] = 'Директория для данных';
+$lang['start'] = 'Имя стартовой страницы';
+$lang['title'] = 'Название вики';
+$lang['template'] = 'Шаблон';
+$lang['license'] = 'На условиях какой лицензии будет предоставляться содержимое вики?';
+$lang['fullpath'] = 'Полный путь к документу';
+$lang['recent'] = 'Недавние изменения (кол-во)';
+$lang['breadcrumbs'] = 'Вы посетили (кол-во)';
+$lang['youarehere'] = 'Показывать «Вы находитесь здесь»';
+$lang['typography'] = 'Типографские символы';
+$lang['htmlok'] = 'Разрешить HTML';
+$lang['phpok'] = 'Разрешить PHP';
+$lang['dformat'] = 'Формат даты и времени';
+$lang['signature'] = 'Шаблон подписи';
+$lang['toptoclevel'] = 'Мин. уровень в содержании';
+$lang['tocminheads'] = 'Мин. количество заголовков, при котором будет составлено содержание';
+$lang['maxtoclevel'] = 'Макс. уровень в содержании';
+$lang['maxseclevel'] = 'Макс. уровень для правки';
+$lang['camelcase'] = 'Использовать ВикиРегистр для ссылок';
+$lang['deaccent'] = 'Транслитерация в именах страниц';
+$lang['useheading'] = 'Первый заголовок вместо имени';
+$lang['refcheck'] = 'Проверять ссылки на медиафайлы';
+$lang['refshow'] = 'Показывать ссылок на медиафайлы';
+$lang['allowdebug'] = 'Включить отладку (отключите!)';
+$lang['usewordblock'] = 'Блокировать спам по ключевым словам';
+$lang['indexdelay'] = 'Задержка перед индексированием';
+$lang['relnofollow'] = 'rel="nofollow" для внешних ссылок';
+$lang['mailguard'] = 'Кодировать адреса электронной почты';
+$lang['iexssprotect'] = 'Проверять закачанные файлы на наличие потенциально опасного кода JavaScript или HTML';
+$lang['showuseras'] = 'Что отображать при показе пользователя, редактировавшего страницу последним';
+$lang['useacl'] = 'Использовать списки прав доступа';
+$lang['autopasswd'] = 'Автогенерация паролей';
+$lang['authtype'] = 'Механизм аутентификации';
+$lang['passcrypt'] = 'Метод шифрования пароля';
+$lang['defaultgroup'] = 'Группа по умолчанию';
+$lang['superuser'] = 'Суперпользователь — группа или пользователь с полным доступом ко всем страницам и функциям администрирования, независимо от установок ACL. Перечень разделяйте запятыми: user1,@group1,user2';
+$lang['manager'] = 'Менеджер — группа или пользователь с доступом к определённым функциям управления. Перечень разделяйте запятыми: user1,@group1,user2';
+$lang['profileconfirm'] = 'Пароль для изменения профиля';
+$lang['disableactions'] = 'Заблокировать операции «ДокуВики»';
+$lang['disableactions_check'] = 'Проверка';
+$lang['disableactions_subscription'] = 'Подписка/Отмена подписки';
+$lang['disableactions_wikicode'] = 'Показ/экспорт исходного текста';
+$lang['disableactions_other'] = 'Другие операции (через запятую)';
+$lang['sneaky_index'] = 'По умолчанию, «ДокуВики» показывает в индексе страниц все пространства имён. Включение этой опции скроет пространства имён, для которых пользователь не имеет прав чтения. Это может привести к скрытию доступных вложенных пространств имён и потере функциональности индекса страниц при некоторых конфигурациях прав доступа.';
+$lang['auth_security_timeout'] = 'Интервал для безопасности авторизации (сек.)';
+$lang['securecookie'] = 'Должны ли куки (cookies), выставленные через HTTPS, отправляться браузером только через HTTPS. Отключите эту опцию в случае, когда только логин вашей вики передаётся через SSL, а обычный просмотр осуществляется в небезопасном режиме.';
+$lang['xmlrpc'] = 'Включить/выключить XML-RPC интерфейс.';
+$lang['xmlrpcuser'] = 'Запретить XML-RPC-доступ для списка групп и пользователей, перечисленных через запятую. Оставьте пустым, если хотите оставить доступ всем.';
+$lang['updatecheck'] = 'Проверять наличие обновлений и предупреждений о безопасности? Для этого «ДокуВики» потребуется связываться с сайтом <a href="http://www.splitbrain.org/">splitbrain.org</a>.';
+$lang['userewrite'] = 'Удобочитаемые адреса (URL)';
+$lang['useslash'] = 'Использовать слэш';
+$lang['usedraft'] = 'Автоматически сохранять черновик во время правки';
+$lang['sepchar'] = 'Разделитель слов в имени страницы';
+$lang['canonical'] = 'Полные канонические адреса (URL)';
+$lang['fnencode'] = 'Метод кодирования имён файлов, записанных не ASCII-символами.';
+$lang['autoplural'] = 'Автоматическое мн. число';
+$lang['compression'] = 'Метод сжатия для архивных файлов';
+$lang['cachetime'] = 'Время жизни кэш-файла (сек.)';
+$lang['locktime'] = 'Время блокировки страницы (сек.)';
+$lang['fetchsize'] = 'Максимальный размер файла (в байтах), который fetch.php может скачивать с внешнего источника';
+$lang['notify'] = 'Электронный адрес для извещений';
+$lang['registernotify'] = 'Посылать информацию о новых зарегистрированных пользователях на этот электронный адрес';
+$lang['mailfrom'] = 'Электронный адрес вики (От:)';
+$lang['mailprefix'] = 'Префикс используемый для автоматического письма станет темой сообщений';
+$lang['gzip_output'] = 'Использовать gzip-сжатие для xhtml';
+$lang['gdlib'] = 'Версия LibGD';
+$lang['im_convert'] = 'Путь к ImageMagick';
+$lang['jpg_quality'] = 'Качество сжатия JPG (0–100). Значение по умолчанию — 70.';
+$lang['subscribers'] = 'Разрешить подписку на изменения';
+$lang['subscribe_time'] = 'Интервал рассылки подписок и сводок (сек.). Должен быть меньше, чем значение, указанное в recent_days.';
+$lang['compress'] = 'Сжимать файлы CSS и javascript';
+$lang['hidepages'] = 'Скрыть страницы (рег. выражение)';
+$lang['send404'] = 'Посылать «HTTP404/Page Not Found»';
+$lang['sitemap'] = 'Число дней, через которое нужно создавать (обновлять) карту сайта для поисковиков (Гугл, Яндекс и др.)';
+$lang['broken_iua'] = 'Возможно, функция ignore_user_abort не работает в вашей системе? Это может привести к потере функциональности индексирования поиска. Эта проблема присутствует, например, в IIS+PHP/CGI. Для дополнительной информации смотрите <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">баг 852</a>.';
+$lang['xsendfile'] = 'Используете заголовок X-Sendfile для загрузки файлов на веб-сервер? Ваш веб-сервер должен поддерживать это.';
+$lang['renderer_xhtml'] = 'Обработчик основного (xhtml) вывода вики';
+$lang['renderer__core'] = '%s (ядро dokuwiki)';
+$lang['renderer__plugin'] = '%s (плагин)';
+$lang['rememberme'] = 'Разрешить перманентные куки (cookies) для входа («запомнить меня»)';
+$lang['rss_type'] = 'Тип RSS';
+$lang['rss_linkto'] = 'Ссылки в RSS';
+$lang['rss_content'] = 'Что отображать в строках XML-ленты?';
+$lang['rss_update'] = 'Интервал обновления XML-ленты (сек.)';
+$lang['recent_days'] = 'На сколько дней назад сохранять недавние изменения';
+$lang['rss_show_summary'] = 'Показывать краткую выдержку в заголовках XML-ленты';
+$lang['target____wiki'] = 'target для внутренних ссылок';
+$lang['target____interwiki'] = 'target для ссылок между вики';
+$lang['target____extern'] = 'target для внешних ссылок';
+$lang['target____media'] = 'target для ссылок на медиафайлы';
+$lang['target____windows'] = 'target для ссылок на сетевые каталоги';
+$lang['proxy____host'] = 'proxy-адрес';
+$lang['proxy____port'] = 'proxy-порт';
+$lang['proxy____user'] = 'proxy-имя пользователя';
+$lang['proxy____pass'] = 'proxy-пароль';
+$lang['proxy____ssl'] = 'proxy-ssl';
+$lang['proxy____except'] = 'Регулярное выражение для адресов (URL), для которых прокси должен быть пропущен.';
+$lang['safemodehack'] = 'Включить обход safemode (хак)';
+$lang['ftp____host'] = 'ftp-адрес';
+$lang['ftp____port'] = 'ftp-порт';
+$lang['ftp____user'] = 'ftp-имя пользователя';
+$lang['ftp____pass'] = 'ftp-пароль';
+$lang['ftp____root'] = 'ftp-корневая директория';
+$lang['license_o_'] = 'Не выбрано';
+$lang['typography_o_0'] = 'нет';
+$lang['typography_o_1'] = 'Только двойные кавычки';
+$lang['typography_o_2'] = 'Все кавычки (может не всегда работать)';
+$lang['userewrite_o_0'] = '(нет)';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'средствами «ДокуВики»';
+$lang['deaccent_o_0'] = 'отключить';
+$lang['deaccent_o_1'] = 'убирать только диакр. знаки';
+$lang['deaccent_o_2'] = 'полная транслитерация';
+$lang['gdlib_o_0'] = 'LibGD недоступна';
+$lang['gdlib_o_1'] = 'версия 1.x';
+$lang['gdlib_o_2'] = 'автоопределение';
+$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';
+$lang['rss_content_o_abstract'] = 'Абстрактный';
+$lang['rss_content_o_diff'] = 'Объединённый diff';
+$lang['rss_content_o_htmldiff'] = 'HTML-форматированная таблица diff';
+$lang['rss_content_o_html'] = 'Полное содержимое HTML-страницы';
+$lang['rss_linkto_o_diff'] = 'отличия от текущей';
+$lang['rss_linkto_o_page'] = 'текст страницы';
+$lang['rss_linkto_o_rev'] = 'история правок';
+$lang['rss_linkto_o_current'] = 'текущая версия';
+$lang['compression_o_0'] = 'без сжатия';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'не используется';
+$lang['xsendfile_o_1'] = 'Проприетарный lighttpd-заголовок (перед релизом 1.5)';
+$lang['xsendfile_o_2'] = 'Стандартный заголовок X-Sendfile';
+$lang['xsendfile_o_3'] = 'Проприетарный заголовок Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Логин';
+$lang['showuseras_o_username'] = 'Полное имя пользователя';
+$lang['showuseras_o_email'] = 'Адрес электропочты в шифрованном виде (см. mailguard)';
+$lang['showuseras_o_email_link'] = 'Адрес электропочты в виде ссылки mailto:';
+$lang['useheading_o_0'] = 'Никогда';
+$lang['useheading_o_navigation'] = 'Только навигация';
+$lang['useheading_o_content'] = 'Только содержимое вики';
+$lang['useheading_o_1'] = 'Всегда';
+$lang['readdircache'] = 'Максимальное время жизни кэша readdir (сек.)';
diff --git a/lib/plugins/config/lang/sk/intro.txt b/lib/plugins/config/lang/sk/intro.txt
new file mode 100644
index 000000000..5de62a315
--- /dev/null
+++ b/lib/plugins/config/lang/sk/intro.txt
@@ -0,0 +1,7 @@
+====== Správa konfigurácie ======
+
+Túto stránku môžete používať na zmenu nastavení Vašej DokuWiki inštalácie. Popis jednotlivých nastavení je uvedený v [[doku>config]]. Viac detailov o tomto plugine nájdete v [[doku>plugin:config]].
+
+Nastavenia zobrazené na červenom pozadí sú neprístupné a nemôžu byť týmto pluginom zmenené. Nastavenia s modrým pozadím obsahujú prednastavené hodnoty a nastavenia s bielym pozadím boli nastavené lokálne pre túto konkrétnu inštaláciu. Nastavenia s modrým a bielym pozadím môžu byť zmenené.
+
+Nezabudnite stlačiť tlačidlo **Uložiť** pred opustením stránky, inak budú vaše zmeny stratené. \ No newline at end of file
diff --git a/lib/plugins/config/lang/sk/lang.php b/lib/plugins/config/lang/sk/lang.php
new file mode 100644
index 000000000..9f55248a3
--- /dev/null
+++ b/lib/plugins/config/lang/sk/lang.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Slovaklanguage file
+ *
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['menu'] = 'Nastavenia konfigurácie';
+$lang['error'] = 'Nastavenia neboli aktualizované kvôli neplatnej hodnote, prosím skontrolujte vaše zmeny a znovu ich pošlite. <br />Nesprávna hodnota(y) bude ohraničená červeným okrajom.';
+$lang['updated'] = 'Nastavenia úspešne aktualizované.';
+$lang['nochoice'] = '(žiadne ďalšie dostupné voľby)';
+$lang['locked'] = 'Súbor s nastaveniami nemôže byť aktualizovaný, ak toto nie je zámerom, <br />
+uistite sa, že názov a práva lokálneho súboru sú správne.';
+$lang['danger'] = 'Nebezpečie: Zmeny tohto nastavenia môžu spôsobiť nedostupnosť wiki a nastavovacieho menu.';
+$lang['warning'] = 'Varovanie: Zmena tohto nastavenia môže viesť neželanému správaniu.';
+$lang['security'] = 'Bezpečnostné riziko: Zmenou tohto nastavenie môže vzniknúť bezpečnostné riziko.';
+$lang['_configuration_manager'] = 'Správa konfigurácie';
+$lang['_header_dokuwiki'] = 'Nastavenia DokuWiki';
+$lang['_header_plugin'] = 'Nastavenia plug-inov';
+$lang['_header_template'] = 'Nastavenia šablóny';
+$lang['_header_undefined'] = 'Nešpecifikované nastavenia';
+$lang['_basic'] = 'Základné nastavenia';
+$lang['_display'] = 'Nastavenia zobrazovania';
+$lang['_authentication'] = 'Nastavenia zabezpečenia';
+$lang['_anti_spam'] = 'Nastavenia anti-spamu';
+$lang['_editing'] = 'Nastavenia úprav';
+$lang['_links'] = 'Nastavenia odkazov';
+$lang['_media'] = 'Nastavenia médií';
+$lang['_advanced'] = 'Rozšírené nastavenia';
+$lang['_network'] = 'Nastavenia siete';
+$lang['_plugin_sufix'] = 'Nastavenia plug-inu';
+$lang['_template_sufix'] = 'Nastavenia šablóny';
+$lang['_msg_setting_undefined'] = 'Nenastavené metadata.';
+$lang['_msg_setting_no_class'] = 'Nenastavená trieda.';
+$lang['_msg_setting_no_default'] = 'Žiadna predvolená hodnota.';
+$lang['fmode'] = 'Spôsob vytvárania súborov';
+$lang['dmode'] = 'Spôsob vytvárania adresárov';
+$lang['lang'] = 'Jazyk';
+$lang['basedir'] = 'Hlavný adresár (napr. <code>/dokuwiki/</code>). Prázdna hodnota znamená použitie autodetekcie.';
+$lang['baseurl'] = 'Adresa servera (napr. <code>http://www.yourserver.com</code>). Prázdna hodnota znamená použitie autodetekcie.';
+$lang['savedir'] = 'Adresár pre ukladanie dát';
+$lang['cookiedir'] = 'Cesta k cookies. Prázdna hodnota znamená použitie adresy servera.';
+$lang['start'] = 'Názov štartovacej stránky';
+$lang['title'] = 'Názov wiki';
+$lang['template'] = 'Šablóna';
+$lang['license'] = 'Pod ktorou licenciou bude publikovaný obsah stránky?';
+$lang['fullpath'] = 'Zobrazovať plnú cestu k stránkam v pätičke';
+$lang['recent'] = 'Posledné zmeny';
+$lang['breadcrumbs'] = 'Počet záznamov histórie';
+$lang['youarehere'] = 'Nachádzate sa';
+$lang['typography'] = 'Vykonať typografické zmeny';
+$lang['htmlok'] = 'Umožniť vkladanie HTML';
+$lang['phpok'] = 'Umožniť vkladanie PHP';
+$lang['dformat'] = 'Formát dátumu (pozri funkciu PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Podpis';
+$lang['toptoclevel'] = 'Najvyššia úroveň pre generovanie obsahu.';
+$lang['tocminheads'] = 'Minimálny počet nadpisov pre generovanie obsahu';
+$lang['maxtoclevel'] = 'Maximálna úroveň pre generovanie obsahu.';
+$lang['maxseclevel'] = 'Maximálna úroveň sekcie pre editáciu';
+$lang['camelcase'] = 'Použiť CamelCase pre odkazy';
+$lang['deaccent'] = 'Upraviť názvy stránok';
+$lang['useheading'] = 'Použiť nadpis pre názov stránky';
+$lang['refcheck'] = 'Kontrolovať odkazy na médiá (pred vymazaním)';
+$lang['refshow'] = 'Počet zobrazených odkazov na médiá';
+$lang['allowdebug'] = 'Povoliť ladenie chýb <b>deaktivujte, ak nie je potrebné!</b>';
+$lang['mediarevisions'] = 'Povoliť verzie súborov?';
+$lang['usewordblock'] = 'Blokovať spam na základe zoznamu známych slov';
+$lang['indexdelay'] = 'Časové oneskorenie pred indexovaním (sek)';
+$lang['relnofollow'] = 'Používať rel="nofollow" pre externé odkazy';
+$lang['mailguard'] = 'Zamaskovať e-mailovú adresu';
+$lang['iexssprotect'] = 'Kontrolovať nahraté súbory na prítomnosť nebezpečného JavaScript alebo HTML kódu';
+$lang['showuseras'] = 'Čo použiť pri zobrazení používateľa, ktorý posledný upravoval stránku';
+$lang['useacl'] = 'Použiť kontrolu prístupu (ACL)';
+$lang['autopasswd'] = 'Autogenerovanie hesla';
+$lang['authtype'] = 'Systém autentifikácie (back-end)';
+$lang['passcrypt'] = 'Spôsob šifrovania hesiel';
+$lang['defaultgroup'] = 'Predvolená skupina';
+$lang['superuser'] = 'Správca - skupina, používateľ alebo čiarkou oddelený zoznam "pouzivatel1,@skupina1,pouzivatel2" s plným prístupom ku všetkým stránkam a funkciám nezávisle od ACL nastavení';
+$lang['manager'] = 'Manažér - skupina, používateľ alebo čiarkou oddelený zoznam "pouzivatel1,@skupina1,pouzivatel2" s prístupom k vybraným správcovským funkciám';
+$lang['profileconfirm'] = 'Potvrdzovať zmeny profilu heslom';
+$lang['disableactions'] = 'Zakázať DokuWiki akcie';
+$lang['disableactions_check'] = 'Skontrolovať';
+$lang['disableactions_subscription'] = 'Povoliť/Zrušiť informovanie o zmenách stránky';
+$lang['disableactions_wikicode'] = 'Pozrieť zdroj/Exportovať zdroj';
+$lang['disableactions_other'] = 'Iné akcie (oddelené čiarkou)';
+$lang['sneaky_index'] = 'DokuWiki implicitne ukazuje v indexe všetky menné priestory. Povolením tejto voľby sa nezobrazia menné priestory, ku ktorým nemá používateľ právo na čítanie. Dôsledkom môže byť nezobrazenie vnorených prístupných menných priestorov. Táto voľba môže mať za následok nepoužiteľnosť indexu s určitými ACL nastaveniami.';
+$lang['auth_security_timeout'] = 'Časový limit pri prihlasovaní (v sekundách)';
+$lang['securecookie'] = 'Mal by prehliadač posielať cookies nastavené cez HTTPS posielať iba cez HTTPS (bezpečné) pripojenie? Vypnite túto voľbu iba v prípade, ak je prihlasovanie do Vašej wiki zabezpečené SSL, ale prezeranie wiki je nezabezpečené.';
+$lang['xmlrpc'] = 'Povoliť/zakázať XML-RPC rozhranie.';
+$lang['xmlrpcuser'] = 'Obmedziť XML-RPC prístup iba pre uvedené skupiny alebo používateľov (oddelených čiarkami).';
+$lang['updatecheck'] = 'Kontrolovať aktualizácie a bezpečnostné upozornenia? DokuWiki potrebuje pre túto funkciu prístup k update.dokuwiki.org.';
+$lang['userewrite'] = 'Používať nice URLs';
+$lang['useslash'] = 'Používať lomku (/) ako oddeľovač v URL';
+$lang['usedraft'] = 'Automaticky ukladať koncept počas úpravy stránky';
+$lang['sepchar'] = 'Oddeľovač slov v názvoch stránok';
+$lang['canonical'] = 'Používať plne kanonické URL názvy';
+$lang['fnencode'] = 'Spôsob kódovania non-ASCII mien súborov.';
+$lang['autoplural'] = 'Kontrolovať množné číslo v odkazoch';
+$lang['compression'] = 'Metóda kompresie pre staré verzie stránok';
+$lang['cachetime'] = 'Maximálne trvanie cache (sek)';
+$lang['locktime'] = 'Maximálne trvanie blokovacích súborov (sek)';
+$lang['fetchsize'] = 'Maximálna veľkosť (v bajtoch) pri sťahovaní z externých zdrojov';
+$lang['notify'] = 'Posielať upozornenia na zmeny na túto e-mailovú adresu';
+$lang['registernotify'] = 'Posielať informáciu o nových užívateľoch na túto e-mailovú adresu';
+$lang['mailfrom'] = 'E-mailová adresa na automatické e-maily';
+$lang['mailprefix'] = 'Prefix predmetu emailovej spravy zasielanej automaticky';
+$lang['gzip_output'] = 'Používať gzip Content-Encoding pre xhtml';
+$lang['gdlib'] = 'Verzia GD Lib';
+$lang['im_convert'] = 'Cesta k ImageMagick convert tool';
+$lang['jpg_quality'] = 'Kvalita JPG kompresie (0-100)';
+$lang['subscribers'] = 'Povoliť podporu informovania o zmenách stránky';
+$lang['subscribe_time'] = 'Časový inteval, po uplynutí ktorého sú zasielané informácie o zmenách stránky alebo menného priestoru (sek); hodnota by mala byť menšia ako čas zadaný pri položke recent_days.';
+$lang['compress'] = 'Komprimovať CSS a javascript výstup';
+$lang['cssdatauri'] = 'Veľkosť v bytoch, do ktorej by mali byť obrázky s odkazom v CSS vložené priamo do štýlu z dôvodu obmedzenia HTTP požiadaviek. Tento postup nefunguje v IE verzie 7 a nižšie! Vhodná hodnota je od <code>400</code> do <code>600</code> bytov. Hodnota <code>0</code> deaktivuje túto metódu.';
+$lang['hidepages'] = 'Skryť zodpovedajúce stránky (regulárne výrazy)';
+$lang['send404'] = 'Poslať "HTTP 404/Page Not Found" pre neexistujúce stránky';
+$lang['sitemap'] = 'Generovať Google sitemap (dni)';
+$lang['broken_iua'] = 'Je vo Vašom systéme funkcia ignore_user_abort poškodená? Môže to mať za následok nefunkčnosť vyhľadávania v indexe. IIS+PHP/CGI je známy tým, že nefunguje správne. Pozrite <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> pre dalšie informácie.';
+$lang['xsendfile'] = 'Používať X-Sendfile hlavičku pre doručenie statických súborov webserverom? Webserver musí túto funkcionalitu podporovať.';
+$lang['renderer_xhtml'] = 'Používané vykresľovacie jadro pre hlavný (xhtml) wiki výstup';
+$lang['renderer__core'] = '%s (dokuwiki jadro)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Povoliť trvalé prihlasovacie cookies (zapamätaj si ma)';
+$lang['rss_type'] = 'Typ XML feedu';
+$lang['rss_linkto'] = 'XML zdroj odkazuje na';
+$lang['rss_content'] = 'Čo zobrazovať v XML feede?';
+$lang['rss_update'] = 'Časový interval obnovy XML feedu (sek.)';
+$lang['recent_days'] = 'Koľko posledných zmien uchovávať (dni)';
+$lang['rss_show_summary'] = 'XML zdroj ukáže prehľad v názve';
+$lang['target____wiki'] = 'Cieľové okno (target) pre interné odkazy';
+$lang['target____interwiki'] = 'Cieľové okno (target) pre interwiki odkazy';
+$lang['target____extern'] = 'Cieľové okno (target) pre externé odkazy';
+$lang['target____media'] = 'Cieľové okno (target) pre media odkazy';
+$lang['target____windows'] = 'Cieľové okno (target) pre windows odkazy';
+$lang['proxy____host'] = 'Proxy server - názov';
+$lang['proxy____port'] = 'Proxy server - port';
+$lang['proxy____user'] = 'Proxy server - užívateľské meno';
+$lang['proxy____pass'] = 'Proxy server - heslo';
+$lang['proxy____ssl'] = 'Proxy server - použiť SSL';
+$lang['proxy____except'] = 'Regulárny výraz popisujúci URL odkazy, pre ktoré by proxy nemala byť použitá.';
+$lang['safemodehack'] = 'Povoliť "safemode hack"';
+$lang['ftp____host'] = 'FTP server pre "safemode hack"';
+$lang['ftp____port'] = 'FTP port pre "safemode hack"';
+$lang['ftp____user'] = 'FTP používateľ pre "safemode hack"';
+$lang['ftp____pass'] = 'FTP heslo pre "safemode hack"';
+$lang['ftp____root'] = 'FTP hlavný adresár pre "safemode hack"';
+$lang['license_o_'] = 'žiadna';
+$lang['typography_o_0'] = 'žiadne';
+$lang['typography_o_1'] = 'okrem jednoduchých úvodzoviek';
+$lang['typography_o_2'] = 'vrátane jednoduchých úvodzoviek (nemusí to vždy fungovať)';
+$lang['userewrite_o_0'] = 'žiadne';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki interné';
+$lang['deaccent_o_0'] = 'vypnuté';
+$lang['deaccent_o_1'] = 'odstrániť diakritiku';
+$lang['deaccent_o_2'] = 'romanizovať (do latinky)';
+$lang['gdlib_o_0'] = 'GD Lib nie je dostupná';
+$lang['gdlib_o_1'] = 'Verzia 1.x';
+$lang['gdlib_o_2'] = 'Autodetekcia';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstrakt';
+$lang['rss_content_o_diff'] = 'Normalizovaný Diff';
+$lang['rss_content_o_htmldiff'] = 'Tabuľka zmien v HTML formáte';
+$lang['rss_content_o_html'] = 'Obsah stránky v HTML formáte';
+$lang['rss_linkto_o_diff'] = 'prehľad zmien';
+$lang['rss_linkto_o_page'] = 'upravená stránka';
+$lang['rss_linkto_o_rev'] = 'zoznam zmien';
+$lang['rss_linkto_o_current'] = 'aktuálna stránka';
+$lang['compression_o_0'] = 'žiadna';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'nepoužívať';
+$lang['xsendfile_o_1'] = 'Proprietárna lighttpd hlavička (pre vydaním 1.5)';
+$lang['xsendfile_o_2'] = 'Štandardná X-Sendfile hlavička';
+$lang['xsendfile_o_3'] = 'Proprietárna Nginx X-Accel-Redirect hlavička';
+$lang['showuseras_o_loginname'] = 'Prihlasovacie meno';
+$lang['showuseras_o_username'] = 'Celé meno používateľa';
+$lang['showuseras_o_email'] = 'E-mailová adresa používateľa (zamaskovaná podľa nastavenia)';
+$lang['showuseras_o_email_link'] = 'E-mailová adresa používateľa vo forme odkazu mailto:';
+$lang['useheading_o_0'] = 'Nikdy';
+$lang['useheading_o_navigation'] = 'Iba navigácia';
+$lang['useheading_o_content'] = 'Iba Wiki obsah';
+$lang['useheading_o_1'] = 'Vždy';
+$lang['readdircache'] = 'Maximálne trvanie readdir cache (sek)';
diff --git a/lib/plugins/config/lang/sl/intro.txt b/lib/plugins/config/lang/sl/intro.txt
new file mode 100644
index 000000000..506cd34bd
--- /dev/null
+++ b/lib/plugins/config/lang/sl/intro.txt
@@ -0,0 +1,7 @@
+====== Splošne nastavitve ======
+
+Na tej strani je mogoče spreminjati nastavitve sistema DokuWiki. Pomoč o posameznih nastavitvah je na voljo med [[doku>config|nastavitvami]]. Več podrobnosti o vstavku je na voljo na [[doku>plugin:config|nastavitvami vstavka]].
+
+Nastavitve označene s svetlo rdečim ozadjem so zaščitene in jih s tem vstavkom ni mogoče spreminjati. Nastavitve označene s svetlo modrim ozadjem so privzete vrednosti in nastavitve z belim ozadjem so tiste, ki so bile določene krajevno posebej za to nastavitev. Spreminjati je mogoče vrednosti označene z modrimi in belim ozadjem.
+
+Spremembe je treba **shraniti**, da se uveljavijo, sicer se spremembe prezrejo.
diff --git a/lib/plugins/config/lang/sl/lang.php b/lib/plugins/config/lang/sl/lang.php
new file mode 100644
index 000000000..ba4836823
--- /dev/null
+++ b/lib/plugins/config/lang/sl/lang.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Dejan Levec <webphp@gmail.com>
+ * @author Boštjan Seničar <senicar@gmail.com>
+ * @author Gregor Skumavc (grega.skumavc@gmail.com)
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['menu'] = 'Splošne nastavitve';
+$lang['error'] = 'Nastavitve niso shranjene zaradi neveljavne vrednosti.<br />Neveljavna vrednost je označena z rdečim robom vnosnega polja.';
+$lang['updated'] = 'Nastavitve so uspešno posodobljene.';
+$lang['nochoice'] = '(ni drugih možnosti na voljo)';
+$lang['locked'] = 'Nastavitvene datoteke ni mogoče posodobiti.<br />Preverite dovoljenja za spreminjanje in ime nastavitvene datoteke.';
+$lang['danger'] = 'Opozorilo: spreminjanje te možnosti lahko povzroči težave v delovanju sistema wiki.';
+$lang['warning'] = 'Opozorilo: spreminjanje te možnosti lahko vpliva na pravilno delovanje sistema wiki.';
+$lang['security'] = 'Varnostno opozorilo: spreminjanje te možnosti lahko vpliva na varnost sistema.';
+$lang['_configuration_manager'] = 'Upravljalnik nastavitev';
+$lang['_header_dokuwiki'] = 'Nastavitve DokuWiki';
+$lang['_header_plugin'] = 'Nastavitve vstavkov';
+$lang['_header_template'] = 'Nastavitve predlog';
+$lang['_header_undefined'] = 'Neopredeljene nastavitve';
+$lang['_basic'] = 'Osnovne nastavitve';
+$lang['_display'] = 'Nastavitve prikazovanja';
+$lang['_authentication'] = 'Nastavitve overjanja';
+$lang['_anti_spam'] = 'Nastavitve neželenih sporočil (Anti-Spam)';
+$lang['_editing'] = 'Nastavitve urejanja';
+$lang['_links'] = 'Nastavitve povezav';
+$lang['_media'] = 'Predstavne nastavitve';
+$lang['_advanced'] = 'Napredne nastavitve';
+$lang['_network'] = 'Omrežne nastavitve';
+$lang['_plugin_sufix'] = 'nastavitve';
+$lang['_template_sufix'] = 'nastavitve';
+$lang['_msg_setting_undefined'] = 'Ni nastavitvenih metapodatkov.';
+$lang['_msg_setting_no_class'] = 'Ni nastavitvenega razreda.';
+$lang['_msg_setting_no_default'] = 'Ni privzete vrednosti.';
+$lang['fmode'] = 'Način ustvarjanja datotek';
+$lang['dmode'] = 'Način ustvarjanja map';
+$lang['lang'] = 'Jezik vmesnika';
+$lang['basedir'] = 'Pot do strežnika (npr. /dokuwiki/). Prazno polje določa samodejno zaznavanje';
+$lang['baseurl'] = 'Naslov URL strežnika (npr. http://www.streznik.si). Prazno polje določa samodejno zaznavanje';
+$lang['savedir'] = 'Mapa za shranjevanje podatkov';
+$lang['cookiedir'] = 'Pot do piškotka. Prazno polje določa uporabo osnovnega naslova (baseurl)';
+$lang['start'] = 'Ime začetne strani wiki';
+$lang['title'] = 'Naslov Wiki spletišča';
+$lang['template'] = 'Predloga';
+$lang['tagline'] = 'Označna vrstica (ob podpori predloge)';
+$lang['sidebar'] = 'Ime strani stranske vrstice (ob podpori predloge); prazno polje onemogoči stransko vrstico.';
+$lang['license'] = 'Pod pogoji katerega dovoljenja je objavljena vsebina?';
+$lang['fullpath'] = 'Pokaži polno pot strani v nogi strani';
+$lang['recent'] = 'Nedavne spremembe';
+$lang['breadcrumbs'] = 'Število drobtinic poti';
+$lang['youarehere'] = 'Hierarhične drobtinice poti';
+$lang['typography'] = 'Omogoči tipografske zamenjave';
+$lang['htmlok'] = 'Dovoli vstavljeno kodo HTML';
+$lang['phpok'] = 'Dovoli vstavljeno kodo PHP';
+$lang['dformat'] = 'Oblika zapisa časa (funkcija PHP <a href="http://www.php.net/strftime">strftime</a>)';
+$lang['signature'] = 'Podpis';
+$lang['toptoclevel'] = 'Vrhnja raven kazala';
+$lang['tocminheads'] = 'Najmanjše število naslovov za izgradnjo kazala';
+$lang['maxtoclevel'] = 'Najvišja raven kazala';
+$lang['maxseclevel'] = 'Največja raven urejanja odseka';
+$lang['camelcase'] = 'Uporabi EnoBesedni zapisa za povezave';
+$lang['deaccent'] = 'Počisti imena strani';
+$lang['useheading'] = 'Uporabi prvi naslov za ime strani';
+$lang['refcheck'] = 'Preverjanje sklica predstavnih datotek';
+$lang['refshow'] = 'Število predstavih sklicev za prikaz';
+$lang['allowdebug'] = 'Dovoli razhroščevanje (po potrebi!)';
+$lang['mediarevisions'] = 'Ali naj se omogočijo objave predstavnih vsebin?';
+$lang['usewordblock'] = 'Zaustavi neželeno besedilo glede na seznam besed';
+$lang['indexdelay'] = 'Časovni zamik pred ustvarjanjem kazala (v sekundah)';
+$lang['relnofollow'] = 'Uporabni možnost rel="nofollow" pri zunanjih povezavah';
+$lang['mailguard'] = 'Šifriraj elektronske naslove';
+$lang['iexssprotect'] = 'Preveri poslane datoteke za zlonamerno kodo JavaScript ali HTML';
+$lang['showuseras'] = 'Kaj prikazati za prikaz uporabnika, ki je zadnji urejal stran';
+$lang['useacl'] = 'Uporabi seznam nadzora dostopa (ACL)';
+$lang['autopasswd'] = 'Samodejno ustvari gesla';
+$lang['authtype'] = 'Ozadnji način overitve';
+$lang['passcrypt'] = 'Način šifriranja gesel';
+$lang['defaultgroup'] = 'Privzeta skupina';
+$lang['superuser'] = 'Skrbnik - skupina, uporabnik ali z vejico ločen seznam uporabnik1,@skupina1,uporabnik2 s polnim dostopom do vseh strani in možnosti, neodvisno od nastavitev nadzora dostopa ACL';
+$lang['manager'] = 'Upravljavec - skupina, uporabnik ali z vejico ločen seznam uporabnik1,@skupina1,uporabnik2 z dovoljenji za dostop do nekaterih možnosti upravljanja';
+$lang['profileconfirm'] = 'Potrdi spremembe profila z geslom';
+$lang['disableactions'] = 'Onemogoči dejanja DokuWiki';
+$lang['disableactions_check'] = 'Preveri';
+$lang['disableactions_subscription'] = 'Naročanje/Preklic naročnine';
+$lang['disableactions_wikicode'] = 'Pogled izvorne kode/Surovi izvoz';
+$lang['disableactions_other'] = 'Druga dejanja (z vejico ločen seznam)';
+$lang['sneaky_index'] = 'Privzeto pokaže sistem DokuWiki vse imenske prostore v pogledu kazala. Z omogočanjem te možnosti bodo skriti vsi imenski prostori, v katere prijavljen uporabnik nima dovoljenj dostopa. S tem je mogoče preprečiti dostop do podrejenih strani. Možnost lahko vpliva na uporabnost nastavitev nadzora dostopa ACL.';
+$lang['auth_security_timeout'] = 'Varnostna časovna omejitev overitve (v sekundah)';
+$lang['securecookie'] = 'Ali naj se piškotki poslani preko varne povezave HTTPS v brskalniku pošiljajo le preko HTTPS? Onemogočanje možnosti je priporočljivo le takrat, ko je prijava varovana s protokolom SSL, brskanje po strani pa ni posebej zavarovano.';
+$lang['xmlrpc'] = 'Omogoči/Onemogoči vmesnik XML-RPC.';
+$lang['xmlrpcuser'] = 'Omejitev dostopa do vmesnika XML-RPC z vejico ločenim seznamom skupin in uporabnikov. Prazno polje pomeni, prost dostop za vse uporabnike.';
+$lang['updatecheck'] = 'Ali naj sistem preveri za posodobitve in varnostna opozorila.';
+$lang['userewrite'] = 'Uporabi olepšan zapis naslovov URL';
+$lang['useslash'] = 'Uporabi poševnico kot ločilnik imenskih prostorov v naslovih URL';
+$lang['usedraft'] = 'Samodejno shrani osnutek med urejanjem strani';
+$lang['sepchar'] = 'Ločilnik besed imen strani';
+$lang['canonical'] = 'Uporabi polni kanonični zapis naslova URL';
+$lang['fnencode'] = 'Način kodiranja ne-ASCII imen datotek.';
+$lang['autoplural'] = 'Preveri množinske oblike povezav';
+$lang['compression'] = 'Način stiskanja za arhivirane datoteke';
+$lang['cachetime'] = 'Največja dovoljena starost predpomnilnika (v sekundah)';
+$lang['locktime'] = 'Največja dovoljena starost datotek zaklepa (v sekundah)';
+$lang['fetchsize'] = 'največja dovoljena velikost zunanjega prejemanja z datoteko fetch.php (v bajtih)';
+$lang['notify'] = 'Pošlji obvestila o spremembah na določen elektronski naslov';
+$lang['registernotify'] = 'Pošlji obvestila o novih vpisanih uporabnikih na določen elektronski naslov';
+$lang['mailfrom'] = 'Elektronski naslov za samodejno poslana sporočila';
+$lang['mailprefix'] = 'Predpona zadeve elektronskega sporočila za samodejna sporočila.';
+$lang['gzip_output'] = 'Uporabi stiskanje gzip vsebine za xhtml';
+$lang['gdlib'] = 'Različica GD Lib';
+$lang['im_convert'] = 'Pot do orodja za pretvarjanje slik ImageMagick';
+$lang['jpg_quality'] = 'Kakovost stiskanja datotek JPG (0-100)';
+$lang['subscribers'] = 'Omogoči podporo naročanju na strani';
+$lang['subscribe_time'] = 'Čas po katerem so poslani povzetki sprememb (v sekundah); Vrednost mora biti krajša od časa, ki je določen z nedavno_dni.';
+$lang['compress'] = 'Združi odvod CSS in JavaScript v brskalniku';
+$lang['cssdatauri'] = 'Velikost sklicanih slik v bajtih, ki so navedene v datotekah CSS za zmanjšanje zahtev osveževanja strežnika HTTP. Ta možnost ni podprta v brskalniku MS IE 7 in nižjih različicah! Ustrezne vrednosti so <code>400</code> do <code>600</code> bajtov. Vrednost <code>0</code> onemogoči možnost.';
+$lang['hidepages'] = 'Skrij skladne strani (logični izraz)';
+$lang['send404'] = 'Pošlji "HTTP 404/Strani ni mogoče najti" pri dostopu do neobstoječih strani';
+$lang['sitemap'] = 'Ustvari Google kazalo strani (v dnevih)';
+$lang['broken_iua'] = 'Ali je možnost ignore_user_abort okvarjena na sistemu? Napaka lahko vpliva na delovanje iskalnika. Napake so pogoste ob uporabi IIS+PHP/CGI. Več o tem si je mogoče prebrati v <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">poročilu o hrošču 852</a>.';
+$lang['xsendfile'] = 'Uporabi glavo X-Sendfile za prejemanje statičnih datotek. Spletni strežnik mora možnost podpirati.';
+$lang['renderer_xhtml'] = 'Izrisovalnik za odvod Wiki strani (xhtml)';
+$lang['renderer__core'] = '%s (jedro dokuwiki)';
+$lang['renderer__plugin'] = '%s (vstavek)';
+$lang['rememberme'] = 'Dovoli trajne prijavne piškotke (trajno pomnenje prijave)';
+$lang['rss_type'] = 'Vrsta virov XML';
+$lang['rss_linkto'] = 'XML viri so povezani z';
+$lang['rss_content'] = 'Kaj prikazati med predmeti virov XML?';
+$lang['rss_update'] = 'Časovni razmik posodobitve virov XML (v sekundah)';
+$lang['recent_days'] = 'Koliko nedavnih sprememb naj se ohrani (v dnevih)';
+$lang['rss_show_summary'] = 'Viri XML so povzeti v naslovu';
+$lang['target____wiki'] = 'Ciljno okno za notranje povezave';
+$lang['target____interwiki'] = 'Ciljno okno za notranje wiki povezave';
+$lang['target____extern'] = 'Ciljno okno za zunanje povezave';
+$lang['target____media'] = 'Ciljno okno za predstavne povezave';
+$lang['target____windows'] = 'Ciljno okno za povezave oken';
+$lang['proxy____host'] = 'Ime posredniškega strežnika';
+$lang['proxy____port'] = 'Vrata posredniškega strežnika';
+$lang['proxy____user'] = 'Uporabniško ime posredniškega strežnika';
+$lang['proxy____pass'] = 'Geslo posredniškega strežnika';
+$lang['proxy____ssl'] = 'Uporabi varno povezavo SSL za povezavo z posredniškim strežnikom';
+$lang['proxy____except'] = 'Logični izrazi morajo biti skladni z naslovi URL, ki gredo mimo posredniškega strežnika.';
+$lang['safemodehack'] = 'Omogoči obhod načina SafeMode PHP';
+$lang['ftp____host'] = 'Strežnik FTP za obhod načina SafeMode';
+$lang['ftp____port'] = 'Vrata strežnika FTP za obhod načina SafeMode';
+$lang['ftp____user'] = 'Uporabniško ime za FTP za obhod načina SafeMode';
+$lang['ftp____pass'] = 'Geslo za strežnik FTP za obhod načina SafeMode';
+$lang['ftp____root'] = 'Korenska mapa FTP za obhod načina SafeMode';
+$lang['license_o_'] = 'Ni izbranega dovoljenja';
+$lang['typography_o_0'] = 'brez';
+$lang['typography_o_1'] = 'izloči enojne narekovaje';
+$lang['typography_o_2'] = 'z enojnimi narekovaji (lahko včasih ne deluje)';
+$lang['userewrite_o_0'] = 'brez';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'notranji DokuWiki';
+$lang['deaccent_o_0'] = 'onemogočeno';
+$lang['deaccent_o_1'] = 'odstrani naglasne oznake';
+$lang['deaccent_o_2'] = 'pretvori v romanski zapis';
+$lang['gdlib_o_0'] = 'Knjižnica GD Lib ni na voljo';
+$lang['gdlib_o_1'] = 'Različica 1.x';
+$lang['gdlib_o_2'] = 'Samodejno zaznavanje';
+$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';
+$lang['rss_content_o_abstract'] = 'Povzetek';
+$lang['rss_content_o_diff'] = 'Poenotena primerjava';
+$lang['rss_content_o_htmldiff'] = 'HTML oblikovana preglednica primerjave';
+$lang['rss_content_o_html'] = 'Polna HTML vsebina strani';
+$lang['rss_linkto_o_diff'] = 'primerjalni pogled';
+$lang['rss_linkto_o_page'] = 'pregledana stran';
+$lang['rss_linkto_o_rev'] = 'seznam pregledovanj';
+$lang['rss_linkto_o_current'] = 'trenutna stran';
+$lang['compression_o_0'] = 'brez';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ne uporabi';
+$lang['xsendfile_o_1'] = 'lastniška glava lighttpd (pred različico 1.5)';
+$lang['xsendfile_o_2'] = 'običajna glava X-Sendfile';
+$lang['xsendfile_o_3'] = 'lastniška glava Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Prijavno ime';
+$lang['showuseras_o_username'] = 'Polno ime uporabnika';
+$lang['showuseras_o_email'] = 'Elektronski naslov uporabnika (šifriran po določilih varovanja)';
+$lang['showuseras_o_email_link'] = 'Elektronski naslov uporabnika kot povezava mailto:';
+$lang['useheading_o_0'] = 'nikoli';
+$lang['useheading_o_navigation'] = 'le za krmarjenje';
+$lang['useheading_o_content'] = 'le za vsebino Wiki';
+$lang['useheading_o_1'] = 'vedno';
+$lang['readdircache'] = 'Največja dovoljena starost predpomnilnika prebranih map (v sekundah)';
diff --git a/lib/plugins/config/lang/sq/intro.txt b/lib/plugins/config/lang/sq/intro.txt
new file mode 100644
index 000000000..687b497c9
--- /dev/null
+++ b/lib/plugins/config/lang/sq/intro.txt
@@ -0,0 +1,7 @@
+====== Menaxheri Konfigurimit ======
+
+Përdoreni këtë faqe për të kontrolluar kuadrot e instalimit të DokuWiki-t tuaj. Për ndihmë mbi kuadro individuale referojuni [[doku>config]]. Për më tepër detaje rreth këtij plugin-i shih [[doku>plugin:config]].
+
+Kuadrot e treguara me një backgroudn me një ngjyrë të kuqe të lehtë janë të mbrojtura dhe nuk mund të ndryshohen me këtë plugin. Kuadrot e treguara me një background blu janë vlerat default dhe kuadrot e treguara me një background të bardhë janë vendosur lokalisht për këtë instalim të caktuar. Si kuadrot blu, ashtu edhe ato të bardhë mund të ndryshohen.
+
+Kujtohuni të shtypni butonin **Ruaj** para se të dilni nga kjo faqe ose ndryshimet tuaja do të humbasin. \ No newline at end of file
diff --git a/lib/plugins/config/lang/sq/lang.php b/lib/plugins/config/lang/sq/lang.php
new file mode 100644
index 000000000..adeb2a47d
--- /dev/null
+++ b/lib/plugins/config/lang/sq/lang.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['menu'] = 'Konfigurimi i Kuadrove';
+$lang['error'] = 'Kuadrot nuk u përditësuan për shkak të një vlere të palejuar, ju lutem rishikoni ndryshimet tuaja dhe ridorëzojeni.
+<br />Vlerat e pasakta tregohen të rrethuara nga një kornizë e kuqe.';
+$lang['updated'] = 'Kuadrot u përditësuan me sukses.';
+$lang['nochoice'] = '(asnjë zgjedhje tjetër e disponueshme)';
+$lang['locked'] = 'Skedari i kuadrove nuk mund të përditësohet, nëse kjo është e paqëllimshme, <br /> sigurohuni që emri i skedarit të kuadrove lokale dhe të drejtat të jenë të sakta.';
+$lang['danger'] = 'Rrezik: Ndrishimi i kësaj alternative mund ta bëjë wiki-n dhe menunë tuaj të konfigurimit të pa aksesueshme.';
+$lang['warning'] = 'Paralajmërim: Ndryshimi i kësaj alternative mund të shkaktojë sjellje të padëshiruara.';
+$lang['security'] = 'Paralajmërim Sigurie: Ndryshimi i kësaj alternative mund të paraqesë një rrezik në siguri.';
+$lang['_configuration_manager'] = 'Menaxhuesi i Kuadrove';
+$lang['_header_dokuwiki'] = 'Kuadrot e DokuWiki-t';
+$lang['_header_plugin'] = 'Kuadrot e Plugin-eve';
+$lang['_header_template'] = 'Kuadrot e Template-eve';
+$lang['_header_undefined'] = 'Kuadro të Papërcaktuara';
+$lang['_basic'] = 'Kuadro Elementare';
+$lang['_display'] = 'Kuadrot e Shfaqjes';
+$lang['_authentication'] = 'Kuadrot e Autentikimit';
+$lang['_anti_spam'] = 'Kuadrot Anti-Spam';
+$lang['_editing'] = 'Kuadrot e Redaktimit';
+$lang['_links'] = 'Kuadrot e Link-eve';
+$lang['_media'] = 'Kuadrot e Medias';
+$lang['_advanced'] = 'Kuadro të Avancuara';
+$lang['_network'] = 'Kuadrot e Rrjetit';
+$lang['_plugin_sufix'] = 'Kuadrot e Plugin-eve';
+$lang['_template_sufix'] = 'Kuadrot e Template-eve';
+$lang['_msg_setting_undefined'] = 'Metadata pa kuadro.';
+$lang['_msg_setting_no_class'] = 'Klasë pa kuadro.';
+$lang['_msg_setting_no_default'] = 'Asnjë vlerë default.';
+$lang['fmode'] = 'Mënyra krijim skedari';
+$lang['dmode'] = 'Mënyra krijim dosjeje.';
+$lang['lang'] = 'Gjuha e ndërfaqes';
+$lang['basedir'] = 'Path-i i Serverit (psh <code>/dokuwiki/</code>). Lëre bosh për ta gjetur automatikisht.';
+$lang['baseurl'] = 'URL-ja serverit (psh <code>http://www.serveriyt.com</code>). Lëre bosh për ta gjetur automatikisht.';
+$lang['savedir'] = 'Direktoria për të ruajtur të dhënat';
+$lang['start'] = 'Emri i faqes së fillimit';
+$lang['title'] = 'Titulli i Wiki-t';
+$lang['template'] = 'Template';
+$lang['license'] = 'Nën cilën liçensë duhet të vihet përmbajtja juar?';
+$lang['fullpath'] = 'Trego adresën e plotë të faqeve në footer.';
+$lang['recent'] = 'Ndryshimet më të fundit';
+$lang['breadcrumbs'] = 'Numri i gjurmëve';
+$lang['youarehere'] = 'Gjurmë hierarkike';
+$lang['typography'] = 'Bëj zëvendësime tipografike';
+$lang['htmlok'] = 'Lejo HTML të ngulitura';
+$lang['phpok'] = 'Lejo PHP të ngulitura';
+$lang['dformat'] = 'Formati i Datës (shiko funksionin <a href="http://www.php.net/strftime">strftime</a> e PHP-së)';
+$lang['signature'] = 'Firma';
+$lang['toptoclevel'] = 'Niveli i Kreut për tabelën e përmbajtjes';
+$lang['tocminheads'] = 'Sasia minimum e titrave që përcaktojnë nëse TOC ndërtohet ose jo';
+$lang['maxtoclevel'] = 'Niveli maksimum për tabelën e përmbajtjes';
+$lang['maxseclevel'] = 'Niveli maksimum për redaktim të seksionit';
+$lang['camelcase'] = 'Përdor CamelCase (shkronja e parë e çdo fjale është kapitale) për linke-t';
+$lang['deaccent'] = 'Emra faqesh të pastër';
+$lang['useheading'] = 'Përdor titra të nivelit të parë për faqet e emrave';
+$lang['refcheck'] = 'Kontroll për referim mediash';
+$lang['refshow'] = 'Numri i referimeve të medias që duhet të tregohet';
+$lang['allowdebug'] = 'Lejo debug <b>çaktivizoje nëse nuk nevojitet!</b>';
+$lang['usewordblock'] = 'Blloko spam-in duke u bazuar mbi listë fjalësh';
+$lang['indexdelay'] = 'Vonesa në kohë para index-imit (sekonda)';
+$lang['relnofollow'] = 'Përdor rel="nofollow" në linke të jashtëm';
+$lang['mailguard'] = 'Errëso adresat e email-it';
+$lang['iexssprotect'] = 'Kontrollo skedarët e ngarkuar për kod të mundshëm dashakeqës JavaScript ose HTML';
+$lang['showuseras'] = 'Cfarë të shfaqësh kur t\'i tregosh përdoruesit faqen e fundit të redaktuar';
+$lang['useacl'] = 'Përdor lista kontrolli të aksesit';
+$lang['autopasswd'] = 'Autogjenero fjalëkalime';
+$lang['authtype'] = 'Backend autentikimi';
+$lang['passcrypt'] = 'Metoda e enkriptimit të fjalëkalimit';
+$lang['defaultgroup'] = 'Grupi default';
+$lang['superuser'] = 'Superpërdorues - grup, përdorues ose listë e ndarë me presje user1, @group1,user2 me akses të plotë në të gjitha faqet dhe funksionet pavarësisht kuadrove të ACL';
+$lang['manager'] = 'Menaxher - grup, përdorues ose listë e ndarë me presje user1,@group1,user2 me akses në disa funksione të caktuara menaxhimi';
+$lang['profileconfirm'] = 'Konfirmo ndryshimet ne profil me fjalëkalim';
+$lang['disableactions'] = 'Caktivizo veprimet e DokuWiki-it';
+$lang['disableactions_check'] = 'Kontrollo';
+$lang['disableactions_subscription'] = 'Abonohu/Fshi Abonim';
+$lang['disableactions_wikicode'] = 'Shiku kodin burim/ Eksportoje të Papërpunuar';
+$lang['disableactions_other'] = 'Veprime të tjera (të ndarë me presje)';
+$lang['sneaky_index'] = 'Vetiu DokuWiki tregon të gjithë hapësirat e emrit në shikimin e index-it. Aktivizimi i kësaj alternative do të fshehë ato ku përdoruesi nuk ka të drejta leximi. Kjo mund të përfundojë në fshehje të nënhapësirave të emrit të aksesueshme. Kjo mund ta bëjë index-in të papërdorshëm me disa konfigurime të caktuara të ACL-së.';
+$lang['auth_security_timeout'] = 'Koha e Përfundimit për Autentikim (sekonda)';
+$lang['securecookie'] = 'A duhet që cookies të vendosura nëpërmjet HTTPS të dërgohen vetëm nëpërmjet HTTPS nga shfletuesit? Caktivizojeni këtë alternativë kur vetëm hyrja në wiki-n tuaj sigurohet me SSL por shfletimi i wiki-t bëhet në mënyrë të pasigurtë.';
+$lang['xmlrpc'] = 'Aktivizo/Caktivizo ndërfaqen XML-RPC';
+$lang['xmlrpcuser'] = 'Kufizo aksesin XML-RPC vetëm tek grupet ose përdoruesit e ndarë me presje të dhënë këtu. Lëre bosh për t\'i dhënë akses të gjithëve.';
+$lang['updatecheck'] = 'Kontrollo për përditësime dhe paralajmërime sigurie? DokuWiki duhet të kontaktojë me update.dokuwiki.org për këtë veti.';
+$lang['userewrite'] = 'Përdor URL të këndshme.';
+$lang['useslash'] = 'Përdor / si ndarës të hapësirave të emrit në URL';
+$lang['usedraft'] = 'Ruaj automatikisht një skicë gjatë redaktimit';
+$lang['sepchar'] = 'Fjala ndarëse për emrin e faqes';
+$lang['canonical'] = 'Përdor URL kanonike të plota';
+$lang['autoplural'] = 'Kontrollo për forma shumës në link-e';
+$lang['compression'] = 'Metoda kompresimit për skedarët atikë';
+$lang['cachetime'] = 'Mosha maksimale për cache (sekonda)';
+$lang['locktime'] = 'Mosha maksimale për kyçjen e skedarëve (sekonda)';
+$lang['fetchsize'] = 'Madhësia maksimale (bytes) që fetch.php mund të shkarkojë nga jashtë';
+$lang['notify'] = 'Dërgo lajmërim për ndryshime te kjo adresë email-i';
+$lang['registernotify'] = 'Dërgo info për përdoruesit e sapo regjistruar te kjo adresë email-i';
+$lang['mailfrom'] = 'Adresa e email-it që do të përdoret për dërgimin e email-eve automatikë';
+$lang['gzip_output'] = 'Përdor gzip Content-Encoding për xhtml';
+$lang['gdlib'] = 'Versioni i GD Lib';
+$lang['im_convert'] = 'Path-i për tek mjeti i konvertimit ImageMagick';
+$lang['jpg_quality'] = 'Cilësia e kompresimit JPG (0-100)';
+$lang['subscribers'] = 'Aktivizo suportin për abonim faqesh';
+$lang['subscribe_time'] = 'Koha pas së cilës listat e abonimeve dhe konsumimet dërgohen (sekonda); Kjo duhet të jetë më e vogël se koha e specifikuar në ditët më të fundit';
+$lang['compress'] = 'Kompaktëso daljet CSS dhe JavaScript ';
+$lang['hidepages'] = 'Fshi faqet që përkojnë (shprehjet e rregullta)';
+$lang['send404'] = 'Dërgo "HTTP 404/Page Not Found" për faqe që nuk ekzistojnë';
+$lang['sitemap'] = 'Gjenero Google sitemap (ditë)';
+$lang['broken_iua'] = 'Funksioni ignore_user_abort është i prishur në sistemin tuaj? Kjo mund të shkaktojë një indeks kërkimi jo funksional. IIS+PHP/CGI njihen si të prishura. Shiko <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> për më shumë info.';
+$lang['xsendfile'] = 'Përdor kokën X-Sendfile për të lejuar webserver-in të dërgojë skedarë statikë? Kjo duhet të suportohet nga webserver-i juaj.';
+$lang['renderer_xhtml'] = 'Riprodhuesi i përdorur për daljen wiki kryesore (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Lejo cookies hyrjeje të përhershme (më kujto mua)';
+$lang['rss_type'] = 'Tipi feed XML';
+$lang['rss_linkto'] = 'XML feed lidhet me';
+$lang['rss_content'] = 'Cfarë të shfaqësh në objektet XML feed?';
+$lang['rss_update'] = 'Intervali i përditësimit XML feed (sekonda)';
+$lang['recent_days'] = 'Sa ndryshime të fundit duhen mbajtur (ditë)';
+$lang['rss_show_summary'] = 'XML feed trego përmbledhjen në titull';
+$lang['target____wiki'] = 'Dritarja target për link-e të brendshëm';
+$lang['target____interwiki'] = 'Dritarja target për link-e interwiki';
+$lang['target____extern'] = 'Dritarja target për link-e të jashtme';
+$lang['target____media'] = 'Dritarja target për link-e mediash';
+$lang['target____windows'] = 'Dritarja target për link-e windows-i';
+$lang['proxy____host'] = 'Emri i serverit të proxy-t';
+$lang['proxy____port'] = 'Porta e proxy-t';
+$lang['proxy____user'] = 'Emri i përdoruesit për proxy-n';
+$lang['proxy____pass'] = 'Fjalëkalimi proxy-t';
+$lang['proxy____ssl'] = 'Përdor SSL për tu lidhur me proxy-n';
+$lang['safemodehack'] = 'Aktivizo hack në safemode';
+$lang['ftp____host'] = 'Server FTP për safemode hack';
+$lang['ftp____port'] = 'Porta FTP për safemode hack';
+$lang['ftp____user'] = 'Emri përdoruesit për safemode hack';
+$lang['ftp____pass'] = 'Fjalëkalimi FTP për safemode hack';
+$lang['ftp____root'] = 'Direktoria rrënjë për safemode hack';
+$lang['license_o_'] = 'Nuk u zgjodh asgjë';
+$lang['typography_o_0'] = 'Asgjë';
+$lang['typography_o_1'] = 'përjashtim i thonjëzave teke';
+$lang['typography_o_2'] = 'përfshirje e thonjëzave teke (nuk punon gjithmonë) ';
+$lang['userewrite_o_0'] = 'asgjë';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Brendësia DokuWiki';
+$lang['deaccent_o_0'] = 'fikur';
+$lang['deaccent_o_1'] = 'hiq theksin';
+$lang['deaccent_o_2'] = 'romanizo';
+$lang['gdlib_o_0'] = 'GD Lib nuk është e disponueshme';
+$lang['gdlib_o_1'] = 'Versioni 1.x';
+$lang['gdlib_o_2'] = 'Dallim automatik';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstrakte';
+$lang['rss_content_o_diff'] = 'Ndryshime të njësuara';
+$lang['rss_content_o_htmldiff'] = 'Tabelë ndryshimesh e formatuar në HTML';
+$lang['rss_content_o_html'] = 'Përmbajtje e plotë faqeje HTML';
+$lang['rss_linkto_o_diff'] = 'shikimi ndryshimit';
+$lang['rss_linkto_o_page'] = 'faqja e rishikuar';
+$lang['rss_linkto_o_rev'] = 'lista e rishikimeve';
+$lang['rss_linkto_o_current'] = 'faqja aktuale';
+$lang['compression_o_0'] = 'asgjë';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'mos e përdor';
+$lang['xsendfile_o_1'] = 'Proprietary lighttpd header (para lëshimit 1.5)';
+$lang['xsendfile_o_2'] = 'X-Sendfile header standard';
+$lang['xsendfile_o_3'] = 'Proprietary Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Emri hyrjes';
+$lang['showuseras_o_username'] = 'Emri i plotë i përdoruesit';
+$lang['showuseras_o_email'] = 'Adresa e email-it e përdoruesit (errësuar sipas kuadros mailguard)';
+$lang['showuseras_o_email_link'] = 'Adresa email e përdoruesit si një mailto: link';
+$lang['useheading_o_0'] = 'Kurrë';
+$lang['useheading_o_navigation'] = 'Vetëm për Navigim';
+$lang['useheading_o_content'] = 'Vetëm për Përmbajtje Wiki';
+$lang['useheading_o_1'] = 'Gjithmonë';
diff --git a/lib/plugins/config/lang/sr/intro.txt b/lib/plugins/config/lang/sr/intro.txt
new file mode 100644
index 000000000..0ee76edcd
--- /dev/null
+++ b/lib/plugins/config/lang/sr/intro.txt
@@ -0,0 +1,7 @@
+====== Управљач подешавањима ======
+
+Ову страну користите за контролу подешавања вашег DokuWiki-ја. За помоћ о индивидуалним поставкама погледајте [[doku>config]]. За више информација о додацима погледајте [[doku>plugin:config]].
+
+Подешавања која имају светло црвену позадину су заштићена и не могу се мењати овим додатком. Подешавања која имају светло плаву позадину су подразумеване вредности и подешавања са белом позадином су локална за ову вики инсталацију. И плава и бела подешавања се могу мењати.
+
+Не заборавите да притиснете дугме **Сачувај** када завршите са изменама, у супротном ће ваше измене бити изгубљене.
diff --git a/lib/plugins/config/lang/sr/lang.php b/lib/plugins/config/lang/sr/lang.php
new file mode 100644
index 000000000..5906dcd7e
--- /dev/null
+++ b/lib/plugins/config/lang/sr/lang.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['menu'] = 'Подешавања';
+$lang['error'] = 'Подешавања нису прихваћена јер постоји вредност са грешком, проверите измене које сте извршили и поновите слање.<br />Вредност(и) са грешком су приказане са црвеним оквиром.';
+$lang['updated'] = 'Измене су сачуване.';
+$lang['nochoice'] = '(не постоји други избор)';
+$lang['locked'] = 'Датотека са подешавањима не може да се ажурира, ако вам то није намера проверите да ли су дозволе исправно постављене.';
+$lang['danger'] = 'Опасно: Променом ове опције може се десити да ваш вики и мени за подешавања буде недоступан.';
+$lang['warning'] = 'Упозорење: Промена ове опције може проузроковати нежељене ефекте.';
+$lang['security'] = 'Сигурносно упозорење: Промена ове опције може да проузрокује сигурносни ризик.';
+$lang['_configuration_manager'] = 'Управљач подешавањима';
+$lang['_header_dokuwiki'] = 'Подешавања Dokuwiki-ја';
+$lang['_header_plugin'] = 'Подешавања за додатке';
+$lang['_header_template'] = 'Подешавања за шаблоне';
+$lang['_header_undefined'] = 'Неразврстана подешавања';
+$lang['_basic'] = 'Основна подешавања';
+$lang['_display'] = 'Подешавања приказа';
+$lang['_authentication'] = 'Подешавања провере';
+$lang['_anti_spam'] = 'Подешавања за борбу против спама';
+$lang['_editing'] = 'Подешавања измена';
+$lang['_links'] = 'Подешавања линковања';
+$lang['_media'] = 'Подешавања медија';
+$lang['_advanced'] = 'Напредна подешавања';
+$lang['_network'] = 'Подешавања мреже';
+$lang['_plugin_sufix'] = 'Подешавања за додатке';
+$lang['_template_sufix'] = 'Подешавања за шаблоне';
+$lang['_msg_setting_undefined'] = 'Нема метаподатака подешавања';
+$lang['_msg_setting_no_class'] = 'Нема класе подешавања';
+$lang['_msg_setting_no_default'] = 'Нема подразумеване вредности';
+$lang['fmode'] = 'Начин прављења датотека';
+$lang['dmode'] = 'Начин прављења фасцикла';
+$lang['lang'] = 'Језик';
+$lang['basedir'] = 'Основна фасцикла';
+$lang['baseurl'] = 'Основни УРЛ';
+$lang['savedir'] = 'Фасцикла у којој ће се чувати подаци';
+$lang['start'] = 'Назив почетне странице';
+$lang['title'] = 'Назив викија';
+$lang['template'] = 'Шаблон';
+$lang['license'] = 'Под којом лиценцом желите да ваш материјал буде објављен?';
+$lang['fullpath'] = 'Објави целу путању странице у заглављу на дну стране';
+$lang['recent'] = 'Последње промене';
+$lang['breadcrumbs'] = 'Број пређених корака (страница)';
+$lang['youarehere'] = 'Хиерархијске кораке (странице)';
+$lang['typography'] = 'Уради типографске замене';
+$lang['htmlok'] = 'Дозволи угњежђени ХТМЛ';
+$lang['phpok'] = 'Дозволи угњежђени ПХП';
+$lang['dformat'] = 'Облик датума (погледајте ПХПову <a href="http://www.php.net/strftime">strftime</a> функцију)';
+$lang['signature'] = 'Потпис';
+$lang['toptoclevel'] = 'Највиши ниво за садржај';
+$lang['tocminheads'] = 'Минималан број наслова који одређују да ли ће Садржај бити направљен';
+$lang['maxtoclevel'] = 'Максимални ниво за садржај';
+$lang['maxseclevel'] = 'Максималан број секција које се мењају';
+$lang['camelcase'] = 'Користи CamelCase за линкове';
+$lang['deaccent'] = 'Чисти имена страница';
+$lang['useheading'] = 'Преузми наслов првог нивоа за назив странице';
+$lang['refcheck'] = 'Провери референце медијских датотека';
+$lang['refshow'] = 'Број референци које се приказују за медијске датотеке';
+$lang['allowdebug'] = 'Укључи дебаговање <b>искључи ако није потребно!</b>';
+$lang['usewordblock'] = 'Блокирај спам на основу листе речи';
+$lang['indexdelay'] = 'Одлагање индексирања (секунде)';
+$lang['relnofollow'] = 'Користи rel="nofollow" за спољне линкове';
+$lang['mailguard'] = 'Замутити Е-адресе';
+$lang['iexssprotect'] = 'Провера потенцијално малициозног кода у Јаваскрипт или ХТМЛ коду';
+$lang['showuseras'] = 'Шта приказати за исписивање корисника који је последњи вршио измене';
+$lang['useacl'] = 'Користи листу права приступа';
+$lang['autopasswd'] = 'Аутогенерисане лозинки';
+$lang['authtype'] = 'Позадински систем аутентификације';
+$lang['passcrypt'] = 'Метода енкрипције лозинки';
+$lang['defaultgroup'] = 'Подразумевана група';
+$lang['superuser'] = 'Суперкорисник - група, корисник или зарезом одвојена листа корисника корисник1,@група1,корисник2 са отвореним проступом свим страницама и функцијама без обзира на поставке Контроле приступа';
+$lang['manager'] = 'Управник - група, корисник или зарезом одвојена листа корисника корисник1,@група1,корисник2 са отвореним проступом неким функцијама за управљање';
+$lang['profileconfirm'] = 'Потврди промене у профилу куцањем лозинке';
+$lang['disableactions'] = 'Искључи DokuWiki наредбе';
+$lang['disableactions_check'] = 'Провера';
+$lang['disableactions_subscription'] = 'Претплата';
+$lang['disableactions_wikicode'] = 'Прикажи извор/Извези сирово';
+$lang['disableactions_other'] = 'Остале наредбе (раздвојене зарезом)';
+$lang['sneaky_index'] = 'По инсталацији DokuWiki ће у индексу приказати све именске просторе. Укључивањем ове опције именски простори у којима корисник нема право читања ће бити сакривени. Консеквенца је да ће и доступни подпростори бити сакривени. Ово доводи до неупотребљивости Права приступа у неким поставкама.';
+$lang['auth_security_timeout'] = 'Временска пауза у аутентификацији (секунде)';
+$lang['securecookie'] = 'Да ли колачићи који су постављени преко ХТТПС треба слати веб читачу само преко ХТТПС? Искључите ову опцију само ако је пријављивање на вики заштићено ССЛом а остали део викија незаштићен.';
+$lang['xmlrpc'] = 'Укључи/искључи ИксМЛ-РПЦ интерфејс';
+$lang['xmlrpcuser'] = 'Ограничи ИксМЛ-РПЦ приступ на наведене групе корисника раздвојене зарезом. Остави празно да би свима дао приступ.';
+$lang['updatecheck'] = 'Провера надоградњи и сигурносних упозорења? Dokuwiki мора да контактира update.dokuwiki.org ради добијања информација.';
+$lang['userewrite'] = 'Направи леп УРЛ';
+$lang['useslash'] = 'Користи косу црту у УРЛу за раздвајање именских простора ';
+$lang['usedraft'] = 'Аутоматски сачувај скицу у току писања измена';
+$lang['sepchar'] = 'Раздвајање речи у називу странице';
+$lang['canonical'] = 'Користи правилне УРЛове';
+$lang['fnencode'] = 'Метод кодирања не-ASCII имена фајлова:';
+$lang['autoplural'] = 'Провери облик множине у линковима';
+$lang['compression'] = 'Метод компресије за attic датотеке';
+$lang['cachetime'] = 'Максимално трајање оставе (сек)';
+$lang['locktime'] = 'МАксимално трајање закључавања датотека (сек)';
+$lang['fetchsize'] = 'Максимална величина (у бајтима) коју може да преузме fetch.php од споља';
+$lang['notify'] = 'Пошаљи обавештења о променама на ову е-адресу';
+$lang['registernotify'] = 'Пошаљи обавештење о новорегистрованим корисницима на ову е-адресу';
+$lang['mailfrom'] = 'Е-адреса која се користи као пошиљаоц за аутоматске е-поруке';
+$lang['gzip_output'] = 'Користи гзип шифрирање за иксХТМЛ';
+$lang['gdlib'] = 'ГД Либ верзија';
+$lang['im_convert'] = 'Путања до алатке за коверзију ИмиџМеџик ';
+$lang['jpg_quality'] = 'ЈПГ квалитет компресије (0-100)';
+$lang['subscribers'] = 'Укључи могућност претплате за странице';
+$lang['subscribe_time'] = 'Време након ког се спискови претплатника и сижеи шаљу (у секундама); Ова цифра би требало да буде мања од цифре наведене под recent_days';
+$lang['compress'] = 'Сажимај ЦСС и јаваскрипт';
+$lang['hidepages'] = 'Сакриј подударне странице (на основу регуларних израза)';
+$lang['send404'] = 'Пошаљи поруку "ХТТП 404/Страница не постоји" за непостојеће странице';
+$lang['sitemap'] = 'Генериши Гугл мапу сајта (дан)';
+$lang['broken_iua'] = 'Да ли је функција ignore_user_abort function не ради на вашем систему? Ово може проузроковати неиндексирање података за претрагу. ИИС+ПХП/ЦГИ је често ван функције. Погледајте <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">баг 852</a> за више информација.';
+$lang['xsendfile'] = 'Користи заглавље X-Sendfile да би веб сервер могао да испоручује статичке датотеке? Веб сервер треба да подржава ову функцију.';
+$lang['renderer_xhtml'] = 'Исцртавање користи главни (xhtml) вики испис';
+$lang['renderer__core'] = '%s (dokuwiki језгро)';
+$lang['renderer__plugin'] = '%s (додатак)';
+$lang['rememberme'] = 'Дозволи стални колачић за пријављивање (запамти ме)';
+$lang['rss_type'] = 'Врста ИксМЛ довода';
+$lang['rss_linkto'] = 'ИксМЛ довод линкује на';
+$lang['rss_content'] = 'Шта треба приказати у ИксМЛ доводу?';
+$lang['rss_update'] = 'ИксМЛ';
+$lang['recent_days'] = 'Колико последњих промена чувати (дани)';
+$lang['rss_show_summary'] = 'ИксМЛ довод приказује збир у наслову';
+$lang['target____wiki'] = 'Циљни прозор за интерне линкове';
+$lang['target____interwiki'] = 'Циљни прозор за међувики линкове';
+$lang['target____extern'] = 'Циљни прозор за спољне линкове';
+$lang['target____media'] = 'Циљни прозор за медијске линкове';
+$lang['target____windows'] = 'Циљни прозор за Виндоуз линкове';
+$lang['proxy____host'] = 'Назив посредника (проксија)';
+$lang['proxy____port'] = 'Порт посредника (проксија)';
+$lang['proxy____user'] = 'Корисничко име на посреднику (проксију)';
+$lang['proxy____pass'] = 'Лозинка на посреднику (проксију)';
+$lang['proxy____ssl'] = 'Користи ССЛ за повезивање са посредником (проксијем)';
+$lang['proxy____except'] = 'Редован израз који би требало да се подудара са веб адресом странице за коју треба прескочити посредника (прокси).';
+$lang['safemodehack'] = 'Укључи преправку за безбедни режим';
+$lang['ftp____host'] = 'ФТП сервер за безбедни режим';
+$lang['ftp____port'] = 'ФТП порт за безбедни режим';
+$lang['ftp____user'] = 'ФТП корисничко име за безбедни режим';
+$lang['ftp____pass'] = 'ФТП лозинка за безбедни режим';
+$lang['ftp____root'] = 'ФТП основна фасцикла за безбедни режим';
+$lang['license_o_'] = 'Није одабрано';
+$lang['typography_o_0'] = 'не';
+$lang['typography_o_1'] = 'Само дупли наводници';
+$lang['typography_o_2'] = 'Сви наводници (неће увек радити)';
+$lang['userewrite_o_0'] = 'не';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki интерно';
+$lang['deaccent_o_0'] = 'искључено';
+$lang['deaccent_o_1'] = 'уклони акценте';
+$lang['deaccent_o_2'] = 'романизуј';
+$lang['gdlib_o_0'] = 'ГД Либ није доступан';
+$lang['gdlib_o_1'] = 'Верзија 1.*';
+$lang['gdlib_o_2'] = 'Аутопроналажење';
+$lang['rss_type_o_rss'] = 'РСС 0.91';
+$lang['rss_type_o_rss1'] = 'РСС 1.0';
+$lang['rss_type_o_rss2'] = 'РСС 2.0';
+$lang['rss_type_o_atom'] = 'Атом 0.3';
+$lang['rss_type_o_atom1'] = 'Атом 1.0';
+$lang['rss_content_o_abstract'] = 'Издвојити';
+$lang['rss_content_o_diff'] = 'Једностране разлике';
+$lang['rss_content_o_htmldiff'] = 'ХТМЛ форматирана табела разлика';
+$lang['rss_content_o_html'] = 'ХТМЛ садржај странице';
+$lang['rss_linkto_o_diff'] = 'приказ разлика';
+$lang['rss_linkto_o_page'] = 'исправљена страница';
+$lang['rss_linkto_o_rev'] = 'листа исправки';
+$lang['rss_linkto_o_current'] = 'тренутна страница';
+$lang['compression_o_0'] = 'не';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'не';
+$lang['xsendfile_o_1'] = 'Власничко lighttpd заглавље (пре верзије 1.5)';
+$lang['xsendfile_o_2'] = 'Стандардно заглавље X-Sendfile';
+$lang['xsendfile_o_3'] = 'Власничко заглавље Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Корисничко име';
+$lang['showuseras_o_username'] = 'Име и презиме корисника';
+$lang['showuseras_o_email'] = 'Е-адреса (замућено по подешавањима mailguard-а)';
+$lang['showuseras_o_email_link'] = 'Корисничка Е-адреса као mailto: веза';
+$lang['useheading_o_0'] = 'Никада';
+$lang['useheading_o_navigation'] = 'Сами навигација';
+$lang['useheading_o_content'] = 'Само за садржај викија';
+$lang['useheading_o_1'] = 'Увек';
+$lang['readdircache'] = 'Максимално време трајања за readdir cache (у секундама)';
diff --git a/lib/plugins/config/lang/sv/intro.txt b/lib/plugins/config/lang/sv/intro.txt
new file mode 100644
index 000000000..8887d4a7b
--- /dev/null
+++ b/lib/plugins/config/lang/sv/intro.txt
@@ -0,0 +1,9 @@
+====== Hantera inställningar ======
+
+Använd den här sidan för att göra inställningar i din Dokuwiki. För hjälp angående specifika inställningar, se [[doku>config]]. För mer detaljer om den här insticksmodulen, se [[doku>plugin:config]].
+
+Inställningar med en rosa bakgrund är skyddade och kan inte ändras med den här insticksmodulen. Inställningar med en blå bakgrund är standardvärden, och inställningar som visas med en vit bakgrund har ändrats i den här installationen. Både blåa och vita inställningar kan ändras.
+
+Kom i håg att trycka på knappen **Spara** innan du lämnar den här sidan, annars kommer ändringarna att gå förlorade.
+
+
diff --git a/lib/plugins/config/lang/sv/lang.php b/lib/plugins/config/lang/sv/lang.php
new file mode 100644
index 000000000..dfd93d37d
--- /dev/null
+++ b/lib/plugins/config/lang/sv/lang.php
@@ -0,0 +1,194 @@
+<?php
+/**
+ * swedish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['menu'] = 'Hantera inställningar';
+$lang['error'] = 'Inställningarna uppdaterades inte på grund av ett felaktigt värde. Titta igenom dina ändringar och försök sedan spara igen.
+ <br />Felaktiga värden är omgivna av en röd ram.';
+$lang['updated'] = 'Inställningarna uppdaterade.';
+$lang['nochoice'] = '(inga andra val tillgängliga)';
+$lang['locked'] = 'Filen med inställningar kan inte uppdateras. Om det inte är meningen att det ska vara så, <br />
+ kontrollera att filen med lokala inställningar har rätt namn och filskydd.';
+$lang['danger'] = 'Risk: Denna förändring kan göra wikin och inställningarna otillgängliga.';
+$lang['warning'] = 'Varning: Denna förändring kan orsaka icke åsyftade resultat.';
+$lang['security'] = 'Säkerhetsvarning: Denna förändring kan innebära en säkerhetsrisk.';
+$lang['_configuration_manager'] = 'Hantera inställningar';
+$lang['_header_dokuwiki'] = 'Inställningar för DokuWiki';
+$lang['_header_plugin'] = 'Inställningar för insticksmoduler';
+$lang['_header_template'] = 'Inställningar för mallar';
+$lang['_header_undefined'] = 'Odefinierade inställningar';
+$lang['_basic'] = 'Grundläggande inställningar';
+$lang['_display'] = 'Inställningar för presentation';
+$lang['_authentication'] = 'Inställningar för autentisering';
+$lang['_anti_spam'] = 'Inställningar för anti-spam';
+$lang['_editing'] = 'Inställningar för redigering';
+$lang['_links'] = 'Inställningar för länkar';
+$lang['_media'] = 'Inställningar för medier';
+$lang['_advanced'] = 'Avancerade inställningar';
+$lang['_network'] = 'Nätverksinställningar';
+$lang['_plugin_sufix'] = '(inställningar för insticksmodul)';
+$lang['_template_sufix'] = '(inställningar för mall)';
+$lang['_msg_setting_undefined'] = 'Ingen inställningsmetadata.';
+$lang['_msg_setting_no_class'] = 'Ingen inställningsklass.';
+$lang['_msg_setting_no_default'] = 'Inget standardvärde.';
+$lang['fmode'] = 'Filskydd för nya filer';
+$lang['dmode'] = 'Filskydd för nya kataloger';
+$lang['lang'] = 'Språk';
+$lang['basedir'] = 'Grundkatalog';
+$lang['baseurl'] = 'Grund-webbadress';
+$lang['savedir'] = 'Katalog för att spara data';
+$lang['start'] = 'Startsidans namn';
+$lang['title'] = 'Wikins namn';
+$lang['template'] = 'Mall';
+$lang['license'] = 'Under vilken licens skall ditt innehåll publiceras?';
+$lang['fullpath'] = 'Visa fullständig sökväg i sidfoten';
+$lang['recent'] = 'Antal poster under "Nyligen ändrat"';
+$lang['breadcrumbs'] = 'Antal spår';
+$lang['youarehere'] = 'Hierarkiska spår';
+$lang['typography'] = 'Aktivera typografiska ersättningar';
+$lang['htmlok'] = 'Tillåt inbäddad HTML';
+$lang['phpok'] = 'Tillåt inbäddad PHP';
+$lang['dformat'] = 'Datumformat (se PHP:s <a href="http://www.php.net/strftime">strftime</a>-funktion)';
+$lang['signature'] = 'Signatur';
+$lang['toptoclevel'] = 'Toppnivå för innehållsförteckning';
+$lang['tocminheads'] = 'Minimalt antal rubriker för att avgöra om innehållsförteckning byggs';
+$lang['maxtoclevel'] = 'Maximal nivå för innehållsförteckning';
+$lang['maxseclevel'] = 'Maximal nivå för redigering av rubriker';
+$lang['camelcase'] = 'Använd CamelCase för länkar';
+$lang['deaccent'] = 'Rena sidnamn';
+$lang['useheading'] = 'Använda första rubriken som sidnamn';
+$lang['refcheck'] = 'Kontrollera referenser till mediafiler';
+$lang['refshow'] = 'Antal mediareferenser som ska visas';
+$lang['allowdebug'] = 'Tillåt felsökning <b>stäng av om det inte behövs!</b>';
+$lang['usewordblock'] = 'Blockera spam baserat på ordlista';
+$lang['indexdelay'] = 'Tidsfördröjning före indexering (sek)';
+$lang['relnofollow'] = 'Använd rel="nofollow" för externa länkar';
+$lang['mailguard'] = 'Koda e-postadresser';
+$lang['iexssprotect'] = 'Kontrollera om uppladdade filer innehåller eventuellt skadlig JavaScript eller HTML-kod';
+$lang['showuseras'] = 'Vad som skall visas när man visar den användare som senast redigerade en sida';
+$lang['useacl'] = 'Använd behörighetslista (ACL)';
+$lang['autopasswd'] = 'Autogenerera lösenord';
+$lang['authtype'] = 'System för autentisering';
+$lang['passcrypt'] = 'Metod för kryptering av lösenord';
+$lang['defaultgroup'] = 'Förvald grupp';
+$lang['superuser'] = 'Huvudadministratör - en grupp eller en användare med full tillgång till alla sidor och funktioner, oavsett behörighetsinställningars';
+$lang['manager'] = 'Administratör -- en grupp eller användare med tillgång till vissa administrativa funktioner.';
+$lang['profileconfirm'] = 'Bekräfta ändringarna i profilen med lösenordet';
+$lang['disableactions'] = 'Stäng av funktioner i DokuWiki';
+$lang['disableactions_check'] = 'Kontroll';
+$lang['disableactions_subscription'] = 'Prenumerera/Säg upp prenumeration';
+$lang['disableactions_wikicode'] = 'Visa källkod/Exportera råtext';
+$lang['disableactions_other'] = 'Andra funktioner (kommaseparerade)';
+$lang['sneaky_index'] = 'Som standard visar DokuWiki alla namnrymder på indexsidan. Genom att aktivera det här valet döljer man namnrymder som användaren inte har behörighet att läsa. Det kan leda till att man döljer åtkomliga undernamnrymder, och gör indexet oanvändbart med vissa ACL-inställningar.';
+$lang['auth_security_timeout'] = 'Autentisieringssäkerhets timeout (sekunder)';
+$lang['securecookie'] = 'Skall cookies som sätts via HTTPS endast skickas via HTTPS från webbläsaren? Avaktivera detta alternativ endast om inloggningen till din wiki är säkrad med SSL men läsning av wikin är osäkrad.';
+$lang['xmlrpc'] = 'Aktivera/avaktivera XML-RPC-gränssnitt';
+$lang['xmlrpcuser'] = 'Begränsa XML-RPC tillträde till komma separerade grupper eller användare som ges här. Lämna tomt för att ge tillgång till alla.';
+$lang['updatecheck'] = 'Kontrollera uppdateringar och säkerhetsvarningar? DokuWiki behöver kontakta update.dokuwiki.org för den här funktionen.';
+$lang['userewrite'] = 'Använd rena webbadresser';
+$lang['useslash'] = 'Använd snedstreck för att separera namnrymder i webbadresser';
+$lang['usedraft'] = 'Spara utkast automatiskt under redigering';
+$lang['sepchar'] = 'Ersätt blanktecken i webbadresser med';
+$lang['canonical'] = 'Använd fullständiga webbadresser';
+$lang['autoplural'] = 'Leta efter pluralformer av länkar';
+$lang['compression'] = 'Metod för komprimering av gamla versioner';
+$lang['cachetime'] = 'Maximal livslängd för cache (sek)';
+$lang['locktime'] = 'Maximal livslängd för fillåsning (sek)';
+$lang['fetchsize'] = 'Maximal storlek (bytes) som fetch.php får ladda ned externt';
+$lang['notify'] = 'Skicka meddelande om ändrade sidor till den här e-postadressen';
+$lang['registernotify'] = 'Skicka meddelande om nyregistrerade användare till en här e-postadressen';
+$lang['mailfrom'] = 'Avsändaradress i automatiska e-postmeddelanden';
+$lang['mailprefix'] = 'Prefix i början på ämnesraden vid automatiska e-postmeddelanden';
+$lang['gzip_output'] = 'Använd gzip Content-Encoding för xhtml';
+$lang['gdlib'] = 'Version av GD-biblioteket';
+$lang['im_convert'] = 'Sökväg till ImageMagicks konverteringsverktyg';
+$lang['jpg_quality'] = 'Kvalitet för JPG-komprimering (0-100)';
+$lang['subscribers'] = 'Aktivera stöd för prenumeration på ändringar';
+$lang['compress'] = 'Komprimera CSS och javascript';
+$lang['hidepages'] = 'Dölj matchande sidor (reguljära uttryck)';
+$lang['send404'] = 'Skicka "HTTP 404/Page Not Found" för sidor som inte finns';
+$lang['sitemap'] = 'Skapa Google sitemap (dagar)';
+$lang['broken_iua'] = 'Är funktionen ignore_user_abort trasig på ditt system? Det kan i så fall leda till att indexering av sökningar inte fungerar. Detta är ett känt problem med IIS+PHP/CGI. Se <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> för mer info.';
+$lang['xsendfile'] = 'Använd X-Sendfile huvudet för att låta webservern leverera statiska filer? Din webserver behöver stöd för detta.';
+$lang['renderer_xhtml'] = 'Generera för användning i huvudwikipresentation (xhtml)';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['rememberme'] = 'Tillåt permanenta inloggningscookies (kom ihåg mig)';
+$lang['rss_type'] = 'Typ av XML-flöde';
+$lang['rss_linkto'] = 'XML-flöde pekar på';
+$lang['rss_content'] = 'Vad ska visas för saker i XML-flödet?';
+$lang['rss_update'] = 'Uppdateringsintervall för XML-flöde (sek)';
+$lang['recent_days'] = 'Hur många ändringar som ska sparas (dagar)';
+$lang['rss_show_summary'] = 'XML-flöde visar sammanfattning i rubriken';
+$lang['target____wiki'] = 'Målfönster för interna länkar';
+$lang['target____interwiki'] = 'Målfönster för interwiki-länkar';
+$lang['target____extern'] = 'Målfönster för externa länkar';
+$lang['target____media'] = 'Målfönster för medialänkar';
+$lang['target____windows'] = 'Målfönster för windowslänkar';
+$lang['proxy____host'] = 'Proxyserver';
+$lang['proxy____port'] = 'Proxyport';
+$lang['proxy____user'] = 'Användarnamn för proxy';
+$lang['proxy____pass'] = 'Lösenord för proxy';
+$lang['proxy____ssl'] = 'Använd ssl för anslutning till proxy';
+$lang['safemodehack'] = 'Aktivera safemode hack';
+$lang['ftp____host'] = 'FTP-server för safemode hack';
+$lang['ftp____port'] = 'FTP-port för safemode hack';
+$lang['ftp____user'] = 'FTP-användarnamn för safemode hack';
+$lang['ftp____pass'] = 'FTP-lösenord för safemode hack';
+$lang['ftp____root'] = 'FTP-rotkatalog för safemode hack';
+$lang['license_o_'] = 'Ingen vald';
+$lang['typography_o_0'] = 'Inga';
+$lang['typography_o_1'] = 'enbart dubbla citattecken';
+$lang['typography_o_2'] = 'både dubbla och enkla citattecken (fungerar inte alltid)';
+$lang['userewrite_o_0'] = 'av';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki internt';
+$lang['deaccent_o_0'] = 'av';
+$lang['deaccent_o_1'] = 'ta bort accenter';
+$lang['deaccent_o_2'] = 'romanisera';
+$lang['gdlib_o_0'] = 'GD-bibliotek inte tillgängligt';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Automatisk detektering';
+$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';
+$lang['rss_content_o_abstract'] = 'Abstrakt';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formaterad diff tabell';
+$lang['rss_content_o_html'] = 'Sidans innehåll i full HTML';
+$lang['rss_linkto_o_diff'] = 'lista på skillnader';
+$lang['rss_linkto_o_page'] = 'den reviderade sidan';
+$lang['rss_linkto_o_rev'] = 'lista över ändringar';
+$lang['rss_linkto_o_current'] = 'den aktuella sidan';
+$lang['compression_o_0'] = 'ingen';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'använd ej';
+$lang['xsendfile_o_1'] = 'Proprietär lighttpd-header (före version 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile-huvud';
+$lang['xsendfile_o_3'] = 'Proprietär Nginx X-Accel-Redirect header';
+$lang['showuseras_o_loginname'] = 'Användarnamn';
+$lang['showuseras_o_username'] = 'Namn';
+$lang['showuseras_o_email'] = 'Användarens e-postadress (obfuskerad enligt inställningarna i mailguard)';
+$lang['showuseras_o_email_link'] = 'Användarens e-postadress som mailto: länk';
+$lang['useheading_o_0'] = 'Aldrig';
+$lang['useheading_o_navigation'] = 'Endst navigering';
+$lang['useheading_o_content'] = 'Endast innehåll i wiki';
+$lang['useheading_o_1'] = 'Alltid';
diff --git a/lib/plugins/config/lang/th/lang.php b/lib/plugins/config/lang/th/lang.php
new file mode 100644
index 000000000..ce7c55e91
--- /dev/null
+++ b/lib/plugins/config/lang/th/lang.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Arthit Suriyawongkul <arthit@gmail.com>
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['menu'] = 'ตั้งค่าการปรับแต่ง';
+$lang['updated'] = 'การปรับแต่งค่าถูกบันทึกเรียบร้อย';
+$lang['_configuration_manager'] = 'จัดการการปรับตั้งค่า';
+$lang['_header_dokuwiki'] = 'การตั้งค่า DokuWiki';
+$lang['_header_plugin'] = 'การตั้งค่า Plugin';
+$lang['_header_template'] = 'การตั้งค่าเทมเพลต';
+$lang['_basic'] = 'การตั้งค่าพื้นฐาน';
+$lang['_display'] = 'การตั้งค่าการแสดงผล';
+$lang['_authentication'] = 'การตั้งค่าสิทธิ์การเข้าถึง';
+$lang['_anti_spam'] = 'การตั้งค่าป้องกันสแปม';
+$lang['_editing'] = 'การตั้งค่าการแก้ไขปรับปรุง';
+$lang['_links'] = 'การตั้งค่าลิงก์';
+$lang['_media'] = 'การตั้งค่าภาพ-เสียง';
+$lang['_advanced'] = 'การตั้งค่าขั้นสูง';
+$lang['_network'] = 'การตั้งค่าเครือข่าย';
+$lang['_plugin_sufix'] = 'การตั้งค่าโปรแกรมเสริม (plugin)';
+$lang['lang'] = 'ภาษา';
+$lang['basedir'] = 'ไดเรคทอรีพื้นฐาน';
+$lang['baseurl'] = 'URL พื้นฐาน';
+$lang['savedir'] = 'ไดเรคทอรีที่บันทึกข้อมูล';
+$lang['start'] = 'ชื่อหน้าเริ่มต้น';
+$lang['recent'] = 'การเปลี่ยนแปลงล่าสุด';
+$lang['htmlok'] = 'อนุญาตให้ใช้ HTML';
+$lang['phpok'] = 'อนุญาตให้ใช้ PHP';
+$lang['signature'] = 'ลายเซนต์';
+$lang['usewordblock'] = 'คำที่จะถือว่าเป็นสแปม';
+$lang['relnofollow'] = 'ใช้ rel="nofollow" สำหรับลิงก์ภายนอก';
+$lang['autopasswd'] = 'สร้างรหัสผ่านให้อัตโนมัติ';
+$lang['passcrypt'] = 'กระบวนการเข้ารหัส สำหรับเก็บบันทึกรหัสผ่าน';
+$lang['defaultgroup'] = 'กลุ่มมาตรฐาน';
+$lang['profileconfirm'] = 'ใส่รหัสผ่านเพื่อยืนยันการเปลี่ยนแปลงข้อมูล';
+$lang['disableactions_check'] = 'ตรวจสอบ';
+$lang['auth_security_timeout'] = 'ระยะเวลาที่จะตัดการเชื่อมต่อแบบการใช้งานด้วยสิทธิ์ผู้ใช้ (วินาที)';
+$lang['xmlrpc'] = 'ใช้งาน/ยกเลิก การเชื่อมต่อแบบ XML-RPC';
+$lang['userewrite'] = 'แสดงที่อยู่เว็บ (URL) แบบอ่านเข้าใจง่าย';
+$lang['cachetime'] = 'ระยะเวลาสำหรับการเก็บแคช (วินาที)';
+$lang['locktime'] = 'ระยะเวลานานสุด ที่จะล็อคไม่ให้แก้ไขไฟล์ (วินาที)';
+$lang['fetchsize'] = 'ขนาดไฟล์ใหญ่สุด (bytes) fetch.php ที่จะดาวน์โหลดจากภายนอก';
+$lang['notify'] = 'ส่งการแจ้งเตือนไปยังที่อยู่อีเมลนี้';
+$lang['gzip_output'] = 'ใช้ gzip Content-Encoding สำหรับ xhtml';
+$lang['gdlib'] = 'เลขรุ่นของ GD Library';
+$lang['compress'] = 'บีบย่อ CSS และ javascript (เพื่อให้แสดงหน้าเว็บเร็วขึ้น)';
+$lang['hidepages'] = 'ซ่อนหน้าที่เข้ากันได้ (regular expressions)';
+$lang['send404'] = 'ให้แสดง "HTTP 404/Page Not Found" เมื่อไม่พบข้อมูลหน้านั้น';
+$lang['sitemap'] = 'สร้าง กูเกิ้ล ไซต์แมพ (จำนวนวัน)';
+$lang['renderer__core'] = '%s (แกนหลักของ dokuwiki)';
+$lang['renderer__plugin'] = '%s (โปรแกรมเสริม - plugin)';
+$lang['rememberme'] = 'อนุญาตให้จดจำการ login แบบถาวร';
+$lang['rss_type'] = 'ชนิดของ XML feed';
+$lang['rss_linkto'] = 'ลิงก์เชื่อมโยงไปยัง XML feed';
+$lang['rss_content'] = 'ต้องการให้มีอะไรแสดงอยู่ใน XML feed บ้าง?';
+$lang['rss_update'] = 'ความถี่ในการอัพเดท XML feed (เป็นวินาที)';
+$lang['recent_days'] = 'จำนวนวันที่เก็บรายการที่ถูกแก้ไขล่าสุด';
+$lang['rss_show_summary'] = 'ไตเติ้ลของบทสรุปย่อของ XML feed';
+$lang['target____wiki'] = 'เปิดแสดงลิงก์ภายใน ในหน้าเว็บแบบใด';
+$lang['target____interwiki'] = 'เปิดแสดงลิงก์ interwiki ในหน้าเว็บแบบใด';
+$lang['target____extern'] = 'เปิดแสดงลิงก์ภายนอก ในหน้าเว็บแบบใด';
+$lang['target____media'] = 'เปิดแสดงลิงก์ของมีเดีย ในหน้าเว็บแบบใด';
+$lang['target____windows'] = 'เปิดแสดงลิงก์ของวินโดวส์ ในหน้าเว็บแบบใด';
+$lang['proxy____host'] = 'ชื่อ server ของ proxy';
+$lang['proxy____port'] = 'port ของ proxy';
+$lang['proxy____user'] = 'user name ของ proxy';
+$lang['proxy____pass'] = 'รหัสผ่านของ proxy';
+$lang['proxy____ssl'] = 'ใช้ ssl ในการเชื่อมต่อกับ proxy';
+$lang['license_o_'] = 'ไม่ถูกเลือก';
+$lang['typography_o_0'] = 'ไม่มี';
+$lang['typography_o_1'] = 'ไม่รวมเครื่องหมายอัญประกาศเดี่ยว';
+$lang['typography_o_2'] = 'รวมเครื่องหมายอัญประกาศเดี่ยว (อาจใช้ไม่ได้ในบางครั้ง)';
+$lang['userewrite_o_0'] = 'ไม่มี';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['deaccent_o_0'] = 'ปิด';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'ตรวจสอบอัตโนมัติ';
+$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';
+$lang['rss_content_o_abstract'] = 'บทคัดย่อ';
+$lang['rss_content_o_html'] = 'หน้าเนื้อหาแบบแสดง HTML เต็มรูปแบบ';
+$lang['rss_linkto_o_diff'] = 'มุมมองที่แตกต่าง';
+$lang['rss_linkto_o_rev'] = 'รายการของการปรับแก้ไข';
+$lang['rss_linkto_o_current'] = 'หน้าปัจจุบัน';
+$lang['compression_o_0'] = 'ไม่มีการบีบอัด';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'ไม่ใช้';
+$lang['xsendfile_o_2'] = 'หัวเอกสารแบบ Standard X-Sendfile';
+$lang['xsendfile_o_3'] = 'หัวเอกสารแบบ Proprietary Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'ชื่อผู้ใช้';
+$lang['showuseras_o_username'] = 'ชื่อ-นามสกุล';
+$lang['showuseras_o_email_link'] = 'อีเมลของผู้ใช้ ที่จะปรากฏ ณ mailto: link';
+$lang['useheading_o_0'] = 'ไม่เลย';
+$lang['useheading_o_navigation'] = 'เฉพาะตัวนำทาง';
+$lang['useheading_o_content'] = 'เฉพาะเนื้อหาวิกิ';
+$lang['useheading_o_1'] = 'เสมอ';
diff --git a/lib/plugins/config/lang/tr/intro.txt b/lib/plugins/config/lang/tr/intro.txt
new file mode 100644
index 000000000..4a9654222
--- /dev/null
+++ b/lib/plugins/config/lang/tr/intro.txt
@@ -0,0 +1,7 @@
+====== Site Ayarları Yönetimi ======
+
+Bu sayfayı DokuWiki kurulumunun ayarlarını değiştirmek için kullanabilirsiniz. Ayarların ayrıntıları için [[doku>config]] sayfasını kullanınız. Bu eklenti ile ilgili daha ayrıntılı bilgi için [[doku>plugin:config]] sayfasına bakınız.
+
+Açık kırmızı renkle gösterilenler bu eklenti ile değiştirilemez. Mavi ile gösterilenler varsayılan değerlerdir. Beyaz altyazı ile gösterilenler is bu kuruluma özel değiştirilmiş ayarlardır. Mavi ve beyaz ayarlar değiştirilebilir.
+
+Değişiklik yapmanız durumunda **Kaydet** tuşuna basmayı unutmayınız. Aksi takdirde sayfayı kapattığınızda tüm ayarlar silinecektir. \ No newline at end of file
diff --git a/lib/plugins/config/lang/tr/lang.php b/lib/plugins/config/lang/tr/lang.php
new file mode 100644
index 000000000..6d7d7cc2e
--- /dev/null
+++ b/lib/plugins/config/lang/tr/lang.php
@@ -0,0 +1,135 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['menu'] = 'Site Ayarları';
+$lang['error'] = 'Ayarlar yanlış bir değer girildiği için güncellenemedi. Lütfen değişikliklerinizi gözden geçirin ve tekrar gönderin.
+<br />Yanlış değer(ler) kırmızı çerçeve içinde gösterilecektir.';
+$lang['updated'] = 'Ayarlar başarıyla güncellendi.';
+$lang['nochoice'] = '(başka seçim bulunmamaktadır)';
+$lang['locked'] = 'Ayar dosyası güncellenemedi. <br />
+dosya adı ve yetkilerininin doğru olduğuna emin olun.';
+$lang['danger'] = 'Tehlike: Bu özelliği değiştirirseniz, wiki\'nize ve konfigürasyon menunüze ulaşamayabilirsiniz.';
+$lang['warning'] = 'Uyarı: Bu özelliği değiştirmek istenmeyen davranışa sebep olabilir.';
+$lang['security'] = 'Güvenlik Uyarısı: Bu özelliği değiştirmek güvenlik riski çıkartabilir.';
+$lang['_configuration_manager'] = 'Site Ayarları Yönetimi';
+$lang['_header_dokuwiki'] = 'DokuWiki Ayarları';
+$lang['_header_plugin'] = 'Eklenti Ayarları';
+$lang['_header_template'] = 'Şablon (Template) Ayarları';
+$lang['_header_undefined'] = 'Tanımsız Ayarlar';
+$lang['_basic'] = 'Ana Ayarlar';
+$lang['_display'] = 'Gösterim Ayarları';
+$lang['_authentication'] = 'Onaylama Ayarları';
+$lang['_anti_spam'] = 'Spam Engelleme Ayarları';
+$lang['_editing'] = 'Sayfa Yazımı Ayarları';
+$lang['_links'] = 'Bağlantı Ayarları';
+$lang['_media'] = 'Medya Ayarları';
+$lang['_advanced'] = 'Gelişmiş Ayarlar';
+$lang['_network'] = 'Ağ Ayarları';
+$lang['_plugin_sufix'] = 'Eklenti Ayarları';
+$lang['_template_sufix'] = 'Şablon (Template) Ayarları';
+$lang['_msg_setting_undefined'] = 'Ayar üstverisi yok.';
+$lang['_msg_setting_no_class'] = 'Ayar sınıfı yok.';
+$lang['_msg_setting_no_default'] = 'Varsayılan değer yok.';
+$lang['fmode'] = 'Dosya oluşturma yetkisi';
+$lang['dmode'] = 'Klasör oluşturma yetkisi';
+$lang['lang'] = 'Dil';
+$lang['basedir'] = 'Kök dizin';
+$lang['baseurl'] = 'Kök URL';
+$lang['savedir'] = 'Verileri kaydetmek için kullanılacak klasör';
+$lang['start'] = 'Ana sayfa adı';
+$lang['title'] = 'Wiki başlığı';
+$lang['template'] = 'Şablon (Template)';
+$lang['license'] = 'İçeriğinizi hangi lisans altında yayınlansın?';
+$lang['fullpath'] = 'sayfaların tüm patikasını (full path) göster';
+$lang['recent'] = 'En son değiştirilenler';
+$lang['breadcrumbs'] = 'Ekmek kırıntıların sayısı';
+$lang['youarehere'] = 'hiyerarşik ekmek kırıntıları';
+$lang['typography'] = 'Tipografik değiştirmeleri yap';
+$lang['htmlok'] = 'Gömülü HTML koduna izin ver';
+$lang['phpok'] = 'Gömülü PHP koduna izin ver';
+$lang['dformat'] = 'Tarih biçimi (PHP\'nin <a href="http://www.php.net/strftime">strftime</a> fonksiyonuna bakın)';
+$lang['signature'] = 'İmza';
+$lang['toptoclevel'] = 'İçindekiler için en üst seviye';
+$lang['tocminheads'] = 'İçindekilerin oluşturulması için gereken (en az) başlık sayısı';
+$lang['maxtoclevel'] = 'İçindekiler için en fazla seviye';
+$lang['maxseclevel'] = 'Bölümün azami düzenleme düzeyi';
+$lang['camelcase'] = 'Linkler için CamelCase kullan';
+$lang['deaccent'] = 'Sayfa adlarınız temizle';
+$lang['useheading'] = 'Sayfa isimleri için ilk başlığı kullan';
+$lang['refcheck'] = 'Araç kaynak denetimi';
+$lang['refshow'] = 'Gösterilecek araç kaynağı sayısı';
+$lang['allowdebug'] = 'Yanlış ayıklamasına izin ver <b>lazım değilse etkisiz kıl!</b>';
+$lang['usewordblock'] = 'Wordlistesine göre spam engelle';
+$lang['indexdelay'] = 'Indekslemeden evvel zaman gecikmesi (saniye)';
+$lang['relnofollow'] = 'Dışsal linkler rel="nofollow" kullan';
+$lang['mailguard'] = 'Email adreslerini karart';
+$lang['iexssprotect'] = 'Yüklenmiş dosyaları muhtemel kötu niyetli JavaScript veya HTML koduna kontrol et';
+$lang['showuseras'] = 'Bir sayfayı en son düzenleyen kullanıcıya ne gösterilsin';
+$lang['useacl'] = 'Erişim kontrol listesini kullan';
+$lang['autopasswd'] = 'Parolaları otamatikmen üret';
+$lang['authtype'] = 'Kimlik denetleme arka uç';
+$lang['passcrypt'] = 'Parola şifreleme metodu';
+$lang['defaultgroup'] = 'Varsayılan grup';
+$lang['disableactions'] = 'DokuWiki eylemlerini etkisiz kıl';
+$lang['disableactions_check'] = 'Kontrol et';
+$lang['disableactions_subscription'] = 'Abone ol/Abonelikten vazgeç';
+$lang['canonical'] = 'Tamolarak kurallara uygun URL\'leri kullan';
+$lang['mailfrom'] = 'Otomatik e-postalar için kullanılacak e-posta adresi';
+$lang['gdlib'] = 'GD Lib sürümü';
+$lang['jpg_quality'] = 'JPG sıkıştırma kalitesi [0-100]';
+$lang['sitemap'] = 'Google site haritası oluştur (gün)';
+$lang['renderer__core'] = '%s (dokuwiki çekirdeği)';
+$lang['renderer__plugin'] = '%s (eklenti)';
+$lang['rss_content'] = 'XML beslemesinde ne gösterilsin?';
+$lang['rss_update'] = 'XML beslemesini güncelleme aralığı';
+$lang['rss_show_summary'] = 'XML beslemesinde özeti başlıkta göster';
+$lang['proxy____host'] = 'Proxy sunucu adı';
+$lang['proxy____user'] = 'Proxy kullanıcı adı';
+$lang['proxy____pass'] = 'Proxy şifresi';
+$lang['proxy____ssl'] = 'Proxy ile bağlanırken ssl kullan';
+$lang['safemodehack'] = 'Safemod hackını etkili kıl';
+$lang['ftp____host'] = 'Safemod hackı için kullanılacak FTP suncusu';
+$lang['ftp____user'] = 'Safemod hackı için kullanılacak FTP kullanıcı adı';
+$lang['ftp____pass'] = 'Safemod hackı için kullanılacak FTP parolası';
+$lang['license_o_'] = 'Seçilmedi';
+$lang['typography_o_0'] = 'Yok';
+$lang['userewrite_o_0'] = 'hiçbiri';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki dahili';
+$lang['deaccent_o_0'] = 'Kapalı';
+$lang['deaccent_o_1'] = 'aksan işaretlerini kaldır';
+$lang['deaccent_o_2'] = 'roman harfleri kullan';
+$lang['gdlib_o_0'] = 'GD Lib mevcut değil';
+$lang['gdlib_o_1'] = 'Versiyon 1.x';
+$lang['gdlib_o_2'] = 'Otomatik tesbit';
+$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';
+$lang['rss_content_o_abstract'] = 'Soyut';
+$lang['rss_content_o_diff'] = 'Birleştirilmiş Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML biçimlendirilmiş diff tablosu';
+$lang['rss_content_o_html'] = 'Tüm HTML sayfa içeriği';
+$lang['rss_linkto_o_diff'] = 'görünümü değiştir';
+$lang['rss_linkto_o_page'] = 'gözden geçirilmiş sayfa';
+$lang['rss_linkto_o_rev'] = 'sürümlerin listesi';
+$lang['rss_linkto_o_current'] = 'Șu anki sayfa';
+$lang['compression_o_0'] = 'hiçbiri';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'kullanma';
+$lang['showuseras_o_loginname'] = 'Kullanıcı adı';
+$lang['showuseras_o_username'] = 'Kullanıcının tam adı';
+$lang['showuseras_o_email'] = 'Kullanıcının mail adresi (mailguard ayarlarına göre karartılıyor)';
+$lang['showuseras_o_email_link'] = 'Kullanıcının mail adresi mailto: linki şeklinde';
+$lang['useheading_o_0'] = 'Hiçbir zaman';
+$lang['useheading_o_navigation'] = 'Sadece Navigasyon';
+$lang['useheading_o_content'] = 'Sadece Wiki içeriği';
+$lang['useheading_o_1'] = 'Her zaman';
diff --git a/lib/plugins/config/lang/uk/intro.txt b/lib/plugins/config/lang/uk/intro.txt
new file mode 100644
index 000000000..7255c30f9
--- /dev/null
+++ b/lib/plugins/config/lang/uk/intro.txt
@@ -0,0 +1,7 @@
+====== Настройка конфігурації ======
+
+Використовуйте цю сторінку для настройки ДокуВікі. Для довідок щодо конкретних параметрів дивіться [[doku>config]]. Для більш детальної інформації про цей доданок дивіться [[doku>plugin:config]].
+
+Параметри, що виділені червоним кольором тла захищені та не можуть бути змінені за допомогою цього доданка. Параметри, з синім кольором тла мають значення по замовчуванню, а параметри з білим тлом були встановлені для цієї локальної інсталяції. Сині та білі параметри можуть бути змінені.
+
+Не забувайте натискати кнопку **ЗБЕРЕГТИ** до того, як покинути цю сторінку, інакше всі зміни буде втрачено.
diff --git a/lib/plugins/config/lang/uk/lang.php b/lib/plugins/config/lang/uk/lang.php
new file mode 100644
index 000000000..72d7e12f5
--- /dev/null
+++ b/lib/plugins/config/lang/uk/lang.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * ukrainian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oleksiy Voronin <ovoronin@gmail.com>
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ * @author Kate Arzamastseva pshns@ukr.net
+ */
+$lang['menu'] = 'Настройка конфігурації';
+$lang['error'] = 'Параметри не збережено через помилкові значення. Будь ласка, перегляньте ваші зміни та спробуйте ще раз
+<br />Помилкові значення будуть виділені червоною рамкою.';
+$lang['updated'] = 'Параметри успішно збережено.';
+$lang['nochoice'] = '(інших варіантів не існує)';
+$lang['locked'] = 'Неможливо записати файл настройки. Переконайтеся, <br />
+що ім\'я та права доступу для локального файлу вказано правильно.';
+$lang['danger'] = 'УВАГА! Зміна цього параметру може призвести до недоступності вашої Вікі та меню конфігурації.';
+$lang['warning'] = 'УВАГА! Зміна цього параметру може призвести до непередбачуваних наслідків.';
+$lang['security'] = 'УВАГА! Зміна цього параметру може призвести до послаблення безпеки вашої Вікі.';
+$lang['_configuration_manager'] = 'Управління конфігурацією';
+$lang['_header_dokuwiki'] = 'Настройки ДокуВікі';
+$lang['_header_plugin'] = 'Настройки Доданків';
+$lang['_header_template'] = 'Настройки шаблонів';
+$lang['_header_undefined'] = 'Невизначені настройки';
+$lang['_basic'] = 'Базові настройки';
+$lang['_display'] = 'Настройки дисплея';
+$lang['_authentication'] = 'Настройки автентифікації';
+$lang['_anti_spam'] = 'Настройки Анти-спаму';
+$lang['_editing'] = 'Настройки редагування';
+$lang['_links'] = 'Настройки посилань';
+$lang['_media'] = 'Настройки медіа';
+$lang['_advanced'] = 'Розширені настройки';
+$lang['_network'] = 'Настройки мережі';
+$lang['_plugin_sufix'] = 'Настройки (доданок)';
+$lang['_template_sufix'] = 'Настройки (шаблон)';
+$lang['_msg_setting_undefined'] = 'Немає метаданих параметру.';
+$lang['_msg_setting_no_class'] = 'Немає класу параметру.';
+$lang['_msg_setting_no_default'] = 'Немає значення за замовчуванням.';
+$lang['fmode'] = 'Права для створених файлів';
+$lang['dmode'] = 'Права для створених папок';
+$lang['lang'] = 'Мова';
+$lang['basedir'] = 'Коренева папка';
+$lang['baseurl'] = 'Кореневий URL';
+$lang['savedir'] = 'Папка для збереження даних';
+$lang['start'] = 'Назва стартової сторінки';
+$lang['title'] = 'Назва Вікі';
+$lang['template'] = 'Шаблон';
+$lang['license'] = 'Під якою ліцензією слід публікувати вміст?';
+$lang['fullpath'] = 'Повний шлях до документу';
+$lang['recent'] = 'Останні зміни';
+$lang['breadcrumbs'] = 'Ви відвідали (кількість сторінок, що показується)';
+$lang['youarehere'] = 'Показувати "Ви тут"';
+$lang['typography'] = 'Замінювати типографські символи';
+$lang['htmlok'] = 'Дозволити HTML';
+$lang['phpok'] = 'Дозволити PHP';
+$lang['dformat'] = 'Формат дати (дивіться функцію <a href="http://www.php.net/strftime">strftime</a> PHP)';
+$lang['signature'] = 'Підпис';
+$lang['toptoclevel'] = 'Мінімальний рівень для змісту';
+$lang['tocminheads'] = 'Мінімальна кількість заголовків, необхідна для створення таблиці змісту';
+$lang['maxtoclevel'] = 'Максимальний рівень для таблиці змісту';
+$lang['maxseclevel'] = 'Максимальний рівень секції для редагування';
+$lang['camelcase'] = 'Використовувати CamelCase';
+$lang['deaccent'] = 'Транслітерація в іменах сторінок';
+$lang['useheading'] = 'Першій заголовок замість імені';
+$lang['refcheck'] = 'Перевіряти посилання на медіа-файлі';
+$lang['refshow'] = 'Показувати кількість медіа-посилань';
+$lang['allowdebug'] = 'Дозволити відлагодження <b>вимкніть, якщо не потрібно!</b>';
+$lang['usewordblock'] = 'Блокувати спам по списку слів';
+$lang['indexdelay'] = 'Затримка перед індексацією';
+$lang['relnofollow'] = 'Використовувати rel="nofollow"';
+$lang['mailguard'] = 'Кодувати адреси e-mail';
+$lang['iexssprotect'] = 'Перевірте оновлені файли на можливі заборонені Javascript чи HTML коди';
+$lang['showuseras'] = 'Що вказувати при відображенні користувача, який востаннє редагував сторінку';
+$lang['useacl'] = 'Використовувати ACL';
+$lang['autopasswd'] = 'Автоматичне створення паролів';
+$lang['authtype'] = 'Аутентифікація';
+$lang['passcrypt'] = 'Метод шифрування паролів';
+$lang['defaultgroup'] = 'Група за замовчуванням';
+$lang['superuser'] = 'Суперкористувач';
+$lang['manager'] = 'Менеджер - група, користувач чи розділений комами список user1,@group1,user2 з правами до певних функцій керування';
+$lang['profileconfirm'] = 'Підтверджувати зміни профілю паролем';
+$lang['disableactions'] = 'Заборонити дії ДокуВікі';
+$lang['disableactions_check'] = 'Перевірити';
+$lang['disableactions_subscription'] = 'Підписатись/Відписатись';
+$lang['disableactions_wikicode'] = 'Переглянути код/Експорт';
+$lang['disableactions_other'] = 'Інші дії (розділені комами)';
+$lang['sneaky_index'] = 'За замовчуванням, ДокуВікі показує всі простори імен в змісті. Активація цієї опції сховає ті простори, де користувач не має прав на читання. Результатом може бути неможливість доступу до певних відкритих просторів імен. Це зробить неможливим використання змісту при певних конфігураціях.';
+$lang['auth_security_timeout'] = 'Таймаут аутентифікації (в секундах)';
+$lang['securecookie'] = 'Чи повинен браузер надсилати файли cookies тільки через HTTPS? Вимкніть цей параметр, лише тоді, якщо вхід до Вікі захищено SSL, але перегляд сторінок відбувається у незахищеному режимі.';
+$lang['xmlrpc'] = 'Дозволити/заборонити XML-RPC інтерфейс';
+$lang['xmlrpcuser'] = 'Заборонити XML-RPC доступ до користувачів або груп поданих тут та розділених комою. Залишіть поле незаповненим, щоб дозволити доступ усім.';
+$lang['updatecheck'] = 'Перевірити наявність оновлень чи попереджень безпеки? Для цього ДокуВікі необхідно зв\'язатися зі update.dokuwiki.org.';
+$lang['userewrite'] = 'Красиві URL';
+$lang['useslash'] = 'Слеш, як розділювач просторів імен в URL';
+$lang['usedraft'] = 'Автоматично зберігати чернетку при редагуванні';
+$lang['sepchar'] = 'Розділювач слів у імені сторінки';
+$lang['canonical'] = 'Канонічні URL';
+$lang['fnencode'] = 'Метод для кодування імен файлів, що містять не ASCII символи.';
+$lang['autoplural'] = 'Перевіряти множину у посиланнях';
+$lang['compression'] = 'Метод стиснення attic файлів';
+$lang['cachetime'] = 'Максимальний вік кешу (сек)';
+$lang['locktime'] = 'Час блокування (сек)';
+$lang['fetchsize'] = 'Максимальний розмір (в байтах), що fetch.php може завантажувати з зовні';
+$lang['notify'] = 'E-mail для сповіщень';
+$lang['registernotify'] = 'Надсилати інформацію про нових користувачів на цю адресу';
+$lang['mailfrom'] = 'E-mail для автоматичних повідомлень';
+$lang['mailprefix'] = 'Префікс теми повідомлення, що використовується в автоматичній розсилці електронних листів';
+$lang['gzip_output'] = 'Використовувати gzip, як Content-Encoding для xhtml';
+$lang['gdlib'] = 'Версія GD Lib';
+$lang['im_convert'] = 'Шлях до ImageMagick';
+$lang['jpg_quality'] = 'Якість компресії JPG (0-100)';
+$lang['subscribers'] = 'Підписка на зміни';
+$lang['subscribe_time'] = 'Час, після якого список підписки та дайджести будуть надіслані (сек.); Має бути меншим за час, вказаний у перемінній recent_days';
+$lang['compress'] = 'Стискати файли CSS та javascript';
+$lang['hidepages'] = 'Ховати сторінки (regular expressions)';
+$lang['send404'] = 'Надсилати "HTTP 404/Сторінка не знайдена " для неіснуючих сторінок';
+$lang['sitemap'] = 'Створювати мапу сайту для Google (дні)';
+$lang['broken_iua'] = 'У вашій системі зіпсована функція ignore_user_abort? Це може зіпсувати пошукову систему. IIS+PHP/CGI не працює. Дивіться <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> для отримання додаткової інформації';
+$lang['xsendfile'] = 'Використовувати заголовок X-Sendfile для доставки статичних файлів веб сервером? Ваш веб сервер повинен підтримувати цю функцію.';
+$lang['renderer_xhtml'] = 'Транслятор (Renderer) для основного виводу wiki (xhtml)';
+$lang['renderer__core'] = '%s (ядро докуВікі)';
+$lang['renderer__plugin'] = '%s (доданок)';
+$lang['rememberme'] = 'Дозволити постійні файли cookies для входу (Запам\'ятати мене)';
+$lang['rss_type'] = 'тип RSS';
+$lang['rss_linkto'] = 'посилання в RSS';
+$lang['rss_content'] = 'Що відображати в пунктах XML-feed';
+$lang['rss_update'] = 'Інтервал оновлення RSS (сек)';
+$lang['recent_days'] = 'Скільки останніх змін пам\'ятати (дні)';
+$lang['rss_show_summary'] = 'Показувати підсумки змін в заголовку XML-feed';
+$lang['target____wiki'] = 'Target для внутрішніх посилань';
+$lang['target____interwiki'] = 'Target для інтерВікі-посилань';
+$lang['target____extern'] = 'Target для зовнішніх посилань';
+$lang['target____media'] = 'Target для медіа-посилань';
+$lang['target____windows'] = 'Target для посилань на мережеві папки';
+$lang['proxy____host'] = 'Адреса Proxy';
+$lang['proxy____port'] = 'Порт Proxy';
+$lang['proxy____user'] = 'Користувач Proxy';
+$lang['proxy____pass'] = 'Пароль Proxy';
+$lang['proxy____ssl'] = 'Використовувати ssl для з\'єднання з Proxy';
+$lang['proxy____except'] = 'Регулярний вираз для веб-адреси, яку проксі-сервер пропустить.';
+$lang['safemodehack'] = 'Увімкнути хак safemode';
+$lang['ftp____host'] = 'FTP-сервер для хаку safemode';
+$lang['ftp____port'] = 'FTP-порт для хаку safemode';
+$lang['ftp____user'] = 'Користувач FTP для хаку safemode';
+$lang['ftp____pass'] = 'Пароль FTP для хаку safemode';
+$lang['ftp____root'] = 'Коренева папка FTP для хаку safemode';
+$lang['license_o_'] = 'не вибрано';
+$lang['typography_o_0'] = 'жодного';
+$lang['typography_o_1'] = 'Лише подвійні лапки';
+$lang['typography_o_2'] = 'Всі лапки (може не завжди працювати)';
+$lang['userewrite_o_0'] = 'немає';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'Засобами ДокуВікі';
+$lang['deaccent_o_0'] = 'вимкнено';
+$lang['deaccent_o_1'] = 'вилучати діакритичні знаки';
+$lang['deaccent_o_2'] = 'транслітерація';
+$lang['gdlib_o_0'] = 'GD Lib не доступна';
+$lang['gdlib_o_1'] = 'Версія 1.x';
+$lang['gdlib_o_2'] = 'Автовизначення';
+$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';
+$lang['rss_content_o_abstract'] = 'Короткий зміст';
+$lang['rss_content_o_diff'] = 'Уніфіковані зміни (diff)';
+$lang['rss_content_o_htmldiff'] = 'Таблиця змін у форматі HTML';
+$lang['rss_content_o_html'] = 'Повний зміст сторінки HTML';
+$lang['rss_linkto_o_diff'] = 'перегляд відмінностей';
+$lang['rss_linkto_o_page'] = 'текст сторінки';
+$lang['rss_linkto_o_rev'] = 'перелік ревізій';
+$lang['rss_linkto_o_current'] = 'поточна сторінка';
+$lang['compression_o_0'] = 'немає';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = 'не використовувати';
+$lang['xsendfile_o_1'] = 'Фірмовий заголовок lighthttpd (до версії 1.5)';
+$lang['xsendfile_o_2'] = 'Стандартний X-Sendfile заголовок';
+$lang['xsendfile_o_3'] = 'Фірмовий заголовок Nginx X-Accel-Redirect';
+$lang['showuseras_o_loginname'] = 'Логін';
+$lang['showuseras_o_username'] = 'Повне ім’я користувача';
+$lang['showuseras_o_email'] = 'E-mail користувача (прихована відповідно до настройок)';
+$lang['showuseras_o_email_link'] = 'E-mail користувача як посилання mailto:';
+$lang['useheading_o_0'] = 'Ніколи';
+$lang['useheading_o_navigation'] = 'Лише для навігації';
+$lang['useheading_o_content'] = 'Лише у змісті';
+$lang['useheading_o_1'] = 'Завжди';
+$lang['readdircache'] = 'Максимальний вік для файлів кешу (сек.)';
diff --git a/lib/plugins/config/lang/zh-tw/intro.txt b/lib/plugins/config/lang/zh-tw/intro.txt
new file mode 100644
index 000000000..c257947d9
--- /dev/null
+++ b/lib/plugins/config/lang/zh-tw/intro.txt
@@ -0,0 +1,7 @@
+====== 配置管理器 ======
+
+使用本頁控制您的 Dokuwiki 設定。每個獨立設定的相關訊息可參閱 [[doku>config]]。配置管理器的更多訊息請參閱 [[doku>plugin:config]]。
+
+淡紅色背景的項目是被保護的,不能通過這個管理器更改。藍色背景的項目是系統的預設值,白色背景的項目是您更改過的。藍色和白色的設定項目都可以更改。
+
+離開本頁之前不要忘記點擊最下面的 **儲存** 按鈕,否則您的修改將不會生效。
diff --git a/lib/plugins/config/lang/zh-tw/lang.php b/lib/plugins/config/lang/zh-tw/lang.php
new file mode 100644
index 000000000..4f44eb60d
--- /dev/null
+++ b/lib/plugins/config/lang/zh-tw/lang.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Chinese Traditional language file
+ *
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '系統配置設定';
+$lang['error'] = '設定因為不合法的值而未更新,請檢查您的更改並重新送出。
+<br />不正確的值會被紅色方框包住。';
+$lang['updated'] = '成功地更新設定。';
+$lang['nochoice'] = '(無其他可用選項)';
+$lang['locked'] = '設定檔無法更新,若非故意,請確認本地檔名及權限正確。';
+$lang['danger'] = '危險:改變此選項可能使您無法存取維基及配置選單。';
+$lang['warning'] = '警告:改變此選項可能導致不可預期的行為。';
+$lang['security'] = '安全性警告:改變此選項可能造成安全風險。';
+$lang['_configuration_manager'] = '配置管理';
+$lang['_header_dokuwiki'] = 'DokuWiki 設定';
+$lang['_header_plugin'] = '插件設定';
+$lang['_header_template'] = '樣板設定';
+$lang['_header_undefined'] = '未定義設定';
+$lang['_basic'] = '基本設定';
+$lang['_display'] = '顯示設定';
+$lang['_authentication'] = '認證設定';
+$lang['_anti_spam'] = '反垃圾設定';
+$lang['_editing'] = '編輯設定';
+$lang['_links'] = '連結設定';
+$lang['_media'] = '媒體設定';
+$lang['_advanced'] = '進階設定';
+$lang['_network'] = '網路設定';
+$lang['_plugin_sufix'] = '插件設定';
+$lang['_template_sufix'] = '樣板設定';
+$lang['_msg_setting_undefined'] = '設定的後設數據不存在。';
+$lang['_msg_setting_no_class'] = '設定的分類不存在。';
+$lang['_msg_setting_no_default'] = '無預設值';
+$lang['fmode'] = '檔案建立模式';
+$lang['dmode'] = '目錄建立模式';
+$lang['lang'] = '語系';
+$lang['basedir'] = '根目錄';
+$lang['baseurl'] = '根路徑 (URL)';
+$lang['savedir'] = '儲存資料的目錄';
+$lang['cookiedir'] = 'Cookie 路徑。設定空白則使用 baseurl。';
+$lang['start'] = '開始頁面的名稱';
+$lang['title'] = '維基標題';
+$lang['template'] = '樣板';
+$lang['license'] = '您希望您的內容為何種授權方式?';
+$lang['fullpath'] = '顯示完整的路徑於頁面底部';
+$lang['recent'] = '最近更新';
+$lang['breadcrumbs'] = '導覽鏈數量';
+$lang['youarehere'] = '顯示階層式導覽鏈';
+$lang['typography'] = '進行字元替換';
+$lang['htmlok'] = '允許嵌入式 HTML';
+$lang['phpok'] = '允許嵌入式 PHP';
+$lang['dformat'] = '日期格式 (參見 PHP 的 <a href="http://www.php.net/strftime">strftime</a> 函數)';
+$lang['signature'] = '簽名';
+$lang['toptoclevel'] = '目錄表的最上層級';
+$lang['tocminheads'] = '決定是否建立目錄表的最少標題數量';
+$lang['maxtoclevel'] = '目錄表顯示的最大層級';
+$lang['maxseclevel'] = '可編輯段落的最大層級';
+$lang['camelcase'] = '對連結使用 CamelCase';
+$lang['deaccent'] = '清理頁面名稱';
+$lang['useheading'] = '使用第一個標題作為頁面名稱';
+$lang['refcheck'] = '媒體連結檢查';
+$lang['refshow'] = '媒體連結的顯示數量';
+$lang['allowdebug'] = '允許除錯 <b>(不需要請停用!)</b>';
+$lang['usewordblock'] = '根據字詞表阻擋垃圾訊息';
+$lang['indexdelay'] = '建立索引前的延遲時間 (秒)';
+$lang['relnofollow'] = '外部連結使用 rel="nofollow"';
+$lang['mailguard'] = '混淆 E-mail 位址';
+$lang['iexssprotect'] = '檢查上傳的檔案中是否隱含惡意的 JavaScript 或 HTML 碼';
+$lang['showuseras'] = '將最後編輯頁面的使用者顯示為:';
+$lang['useacl'] = '使用存取控制名單';
+$lang['autopasswd'] = '自動產生密碼';
+$lang['authtype'] = '認證後台管理方式';
+$lang['passcrypt'] = '密碼加密方式';
+$lang['defaultgroup'] = '預設群組';
+$lang['superuser'] = '超級用戶 - 不論 ACL 如何設定,都能訪問所有頁面與功能的用戶組/用戶';
+$lang['manager'] = '管理員 - 能訪問相應管理功能的用戶组/用戶';
+$lang['profileconfirm'] = '修改個人資料時需要確認密碼';
+$lang['disableactions'] = '停用的 DokuWiki 動作';
+$lang['disableactions_check'] = '檢查';
+$lang['disableactions_subscription'] = '訂閱/取消訂閱';
+$lang['disableactions_wikicode'] = '檢視原始碼/匯出原始檔';
+$lang['disableactions_other'] = '其他功能 (逗號分隔)';
+$lang['sneaky_index'] = '預設情況下,DokuWiki 會在索引頁會顯示所有命名空間。啟用此選項會隱藏用戶沒有閱讀權限的頁面,但也可能將能閱讀的子頁面一併隱藏。在特定 ACL 設定下,這可能導致索引無法使用。';
+$lang['auth_security_timeout'] = '安全認證的計時 (秒)';
+$lang['securecookie'] = 'HTTPS 頁面設定的 cookie 是否只能由瀏覽器經 HTTPS 傳送?取消此選項後,只有登入維基會被 SSL 保護而瀏覽時不會。';
+$lang['xmlrpc'] = '啟用/停用 XML-RPC 介面';
+$lang['xmlrpcuser'] = 'XML-RPC 存取權限將局限於在此提供的群組或使用者 (逗號分隔)。若要開放權限給所有人請留白。';
+$lang['updatecheck'] = '檢查更新與安全性警告?DokuWiki 需要聯繫 update.dokuwiki.org 才能使用此功能。';
+$lang['userewrite'] = '使用好看的 URL';
+$lang['useslash'] = '在 URL 中使用斜線作為命名空間的分隔字元';
+$lang['usedraft'] = '編輯時自動儲存草稿';
+$lang['sepchar'] = '頁面名稱中單字的分隔字元';
+$lang['canonical'] = '使用最典型的 URL';
+$lang['fnencode'] = '非 ASCII 文件名稱的編輯方法。';
+$lang['autoplural'] = '檢查複數形式的連結 (英文)';
+$lang['compression'] = 'attic 文件的壓縮方式';
+$lang['cachetime'] = '緩存的最大存在時間 (秒)';
+$lang['locktime'] = '檔案的最大鎖定時間 (秒)';
+$lang['fetchsize'] = 'fetch.php 可以從外部下載的最大檔案尺寸 (bytes)';
+$lang['notify'] = '寄送變更通知信到這個 E-mail 位址';
+$lang['registernotify'] = '寄送新使用者註冊資訊到這個 E-mail 位址';
+$lang['mailfrom'] = '自動發送郵件時使用的郵件地址';
+$lang['mailprefix'] = '自動發送郵件時使用的標題前綴';
+$lang['gzip_output'] = '對 xhtml 使用 gzip 內容編碼';
+$lang['gdlib'] = 'GD Lib 版本';
+$lang['im_convert'] = 'ImageMagick 的轉換工具路徑';
+$lang['jpg_quality'] = 'JPG 壓縮品質(0-100)';
+$lang['subscribers'] = '啟用頁面訂閱';
+$lang['subscribe_time'] = '訂閱列表和摘要發送的時間間隔 (秒);這個值應該小於指定的最近更改保留時間 (recent_days)。';
+$lang['compress'] = '壓縮 CSS 與 JavaScript 的輸出';
+$lang['cssdatauri'] = 'CSS 中所引用的圖片假如小於該數字大小(bytes),將會被直接嵌入 CSS 中來減少 HTTP Request 的發送。此功能在 IE 7 及之下版本不支援。推薦使用 <code>400</code> 到 <code>600</code> 之間。設定為<code>0</code> 則停用。';
+$lang['hidepages'] = '隱藏匹配的界面 (正規式)';
+$lang['send404'] = '存取不存在的頁面時送出 "HTTP 404/Page Not Found"';
+$lang['sitemap'] = '產生 Google 站台地圖 (天)';
+$lang['broken_iua'] = 'ignore_user_abort 功能失效了?這有可能導致搜索索引不可用。IIS+PHP/CGI 已損壞。請參閱 <a href=\"http://bugs.splitbrain.org/?do=details&task_id=852\">Bug 852</a> 獲取更多信息。';
+$lang['xsendfile'] = '使用 X-Sendfile 頭讓服務器發送狀態文件?您的服務器需要支持該功能。';
+$lang['renderer_xhtml'] = '主要維基輸出 (xhtml) 的的渲染器';
+$lang['renderer__core'] = '%s (dokuwiki 核心)';
+$lang['renderer__plugin'] = '%s (插件)';
+$lang['rememberme'] = '允許自動登入 (記住我)';
+$lang['rss_type'] = 'XML feed 類型';
+$lang['rss_linkto'] = 'XML feed 連結到';
+$lang['rss_content'] = 'XML feed 項目中顯示什麼呢?';
+$lang['rss_update'] = 'XML feed 更新間隔時間 (秒)';
+$lang['recent_days'] = '儲存多少天內的變更';
+$lang['rss_show_summary'] = '於標題中顯示簡要的 XML feed';
+$lang['target____wiki'] = '內部連結的目標視窗';
+$lang['target____interwiki'] = '跨維基連結的目標視窗';
+$lang['target____extern'] = '外部連結的目標視窗';
+$lang['target____media'] = '媒體連結的目標視窗';
+$lang['target____windows'] = 'Windows 連結的目標視窗';
+$lang['proxy____host'] = 'Proxy 伺服器名稱';
+$lang['proxy____port'] = 'Proxy 連接埠';
+$lang['proxy____user'] = 'Proxy 使用者名稱';
+$lang['proxy____pass'] = 'Proxy 密碼';
+$lang['proxy____ssl'] = '使用 SSL 連接到 Proxy';
+$lang['proxy____except'] = '比對 proxy 代理時應跳過的地址的正規式。';
+$lang['safemodehack'] = '啟用 Safemode Hack';
+$lang['ftp____host'] = 'Safemode Hack 的 FTP 伺服器';
+$lang['ftp____port'] = 'Safemode Hack 的 FTP 端口';
+$lang['ftp____user'] = 'Safemode Hack 的 FTP 帳戶';
+$lang['ftp____pass'] = 'Safemode Hack 的 FTP 密碼';
+$lang['ftp____root'] = 'Safemode Hack 的 FTP 根路徑';
+$lang['license_o_'] = '未選擇';
+$lang['typography_o_0'] = '無';
+$lang['typography_o_1'] = '只限雙引號';
+$lang['typography_o_2'] = '包括單引號 (未必能運作)';
+$lang['userewrite_o_0'] = '無';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki 內部控制';
+$lang['deaccent_o_0'] = '關閉';
+$lang['deaccent_o_1'] = '移除重音符號';
+$lang['deaccent_o_2'] = '羅馬字母轉寫';
+$lang['gdlib_o_0'] = 'GD Lib 無法使用';
+$lang['gdlib_o_1'] = '版本 1.x';
+$lang['gdlib_o_2'] = '自動偵測';
+$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';
+$lang['rss_content_o_abstract'] = '摘要';
+$lang['rss_content_o_diff'] = '統一的差異';
+$lang['rss_content_o_htmldiff'] = 'HTML 格式的差異對照表';
+$lang['rss_content_o_html'] = '完整的 HTML 頁面內容';
+$lang['rss_linkto_o_diff'] = '差異檢視';
+$lang['rss_linkto_o_page'] = '已修訂的頁面';
+$lang['rss_linkto_o_rev'] = '版本清單';
+$lang['rss_linkto_o_current'] = '目前頁面';
+$lang['compression_o_0'] = '無';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = '不使用';
+$lang['xsendfile_o_1'] = '專有 lighttpd 標頭 (1.5 發布前)';
+$lang['xsendfile_o_2'] = '標準 X-Sendfile 標頭';
+$lang['xsendfile_o_3'] = '專有 Nginx X-Accel-Redirect 標頭';
+$lang['showuseras_o_loginname'] = '登入名稱';
+$lang['showuseras_o_username'] = '完整姓名';
+$lang['showuseras_o_email'] = '使用者的 email 位址 (根據郵件監控設定混淆化)';
+$lang['showuseras_o_email_link'] = '使用者的 email 位址標示成 mailto: link';
+$lang['useheading_o_0'] = '永不';
+$lang['useheading_o_navigation'] = '僅導覽';
+$lang['useheading_o_content'] = '僅維基內容';
+$lang['useheading_o_1'] = '總是';
+$lang['readdircache'] = 'readdir 緩存的最大存在時間 (秒)';
diff --git a/lib/plugins/config/lang/zh/intro.txt b/lib/plugins/config/lang/zh/intro.txt
new file mode 100644
index 000000000..a7db4eda0
--- /dev/null
+++ b/lib/plugins/config/lang/zh/intro.txt
@@ -0,0 +1,9 @@
+====== 配置管理器 ======
+
+使用本页中的内容来控制您的 Dokuwiki 设置。 每个单独设置的相关信息请参阅 [[doku>config]]。 配置管理器的更多信息请参阅 [[doku>plugin:config]]。
+
+淡红色背景的项目被保护,不能通过这个管理器更改。 蓝色背景的项目是系统的默认值,白色背景的项目是您作出更改的项目。蓝色和白色的设置项目都可以更改。
+
+离开本页之前不要忘记点击最后的 **保存** 按钮,否则您做的修改不会生效。
+
+
diff --git a/lib/plugins/config/lang/zh/lang.php b/lib/plugins/config/lang/zh/lang.php
new file mode 100644
index 000000000..2f6444ffa
--- /dev/null
+++ b/lib/plugins/config/lang/zh/lang.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Chinese(Simplified) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '配置设置';
+$lang['error'] = '由于非法参数,设置没有更新。请检查您做的改动并重新提交。
+ <br />非法参数会用红框包围显示。';
+$lang['updated'] = '设置更新成功。';
+$lang['nochoice'] = '(没有其他可用选项)';
+$lang['locked'] = '设置文件无法更新。如果这是您没有意料到的,<br />
+ 请确保本地设置文件的名称和权限设置正确。';
+$lang['danger'] = '危险:更改这个选项可能会使用你的Wiki页面和配置菜单无法进入。';
+$lang['warning'] = '注意:更改这个选项可能会造成未知结果。';
+$lang['security'] = '安全提示:更改这个选项可能会有安全隐患。';
+$lang['_configuration_manager'] = '配置管理器';
+$lang['_header_dokuwiki'] = 'DokuWiki 设置';
+$lang['_header_plugin'] = '插件设置';
+$lang['_header_template'] = '模板设置';
+$lang['_header_undefined'] = '其他设置';
+$lang['_basic'] = '基本设置';
+$lang['_display'] = '显示设置';
+$lang['_authentication'] = '认证设置';
+$lang['_anti_spam'] = '反垃圾邮件/评论设置';
+$lang['_editing'] = '编辑设置';
+$lang['_links'] = '链接设置';
+$lang['_media'] = '媒体设置';
+$lang['_advanced'] = '高级设置';
+$lang['_network'] = '网络设置';
+$lang['_plugin_sufix'] = '插件设置';
+$lang['_template_sufix'] = '模板设置';
+$lang['_msg_setting_undefined'] = '设置的元数据不存在。';
+$lang['_msg_setting_no_class'] = '设置的分类不存在。';
+$lang['_msg_setting_no_default'] = '设置的默认值不存在。';
+$lang['fmode'] = '文件的创建模式';
+$lang['dmode'] = '文件夹的创建模式';
+$lang['lang'] = '语言';
+$lang['basedir'] = '根目录';
+$lang['baseurl'] = '根路径(URL)';
+$lang['savedir'] = '保存数据的目录';
+$lang['cookiedir'] = 'Cookie 路径。留空以使用 baseurl。';
+$lang['start'] = '开始页面的名称';
+$lang['title'] = '维基站点的标题';
+$lang['template'] = '模版';
+$lang['license'] = '您愿意让你贡献的内容在何种许可方式下发布?';
+$lang['fullpath'] = '在页面底部显示完整路径';
+$lang['recent'] = '最近更新';
+$lang['breadcrumbs'] = '显示“足迹”的数量';
+$lang['youarehere'] = '显示“您在这里”';
+$lang['typography'] = '进行字符替换';
+$lang['htmlok'] = '允许嵌入式 HTML';
+$lang['phpok'] = '允许嵌入式 PHP';
+$lang['dformat'] = '日期格式(参见 PHP 的 <a href="http://www.php.net/strftime">strftime</a> 功能)';
+$lang['signature'] = '签名样式';
+$lang['toptoclevel'] = '目录的最顶层';
+$lang['tocminheads'] = '头条数目的最小数目,这将用于决定是否创建目录列表(TOC)';
+$lang['maxtoclevel'] = '目录的最多层次';
+$lang['maxseclevel'] = '段落编辑的最多层次';
+$lang['camelcase'] = '对链接使用 CamelCase';
+$lang['deaccent'] = '清理页面名称';
+$lang['useheading'] = '使用“标题 H1”作为页面名称';
+$lang['refcheck'] = '检查媒体与页面的挂钩情况';
+$lang['refshow'] = '显示媒体与页面挂钩情况的数量';
+$lang['allowdebug'] = '允许调试 <b>如果您不需要调试,请勿勾选!</b>';
+$lang['usewordblock'] = '根据 wordlist 阻止垃圾评论';
+$lang['indexdelay'] = '构建索引前的时间延滞(秒)';
+$lang['relnofollow'] = '对外部链接使用 rel="nofollow" 标签';
+$lang['mailguard'] = '弄乱邮件地址(保护用户的邮件地址)';
+$lang['iexssprotect'] = '检验上传的文件以避免可能存在的恶意 JavaScript 或 HTML 代码';
+$lang['showuseras'] = '显示用户为';
+$lang['useacl'] = '使用访问控制列表(ACL)';
+$lang['autopasswd'] = '自动生成密码';
+$lang['authtype'] = '认证后台管理方式';
+$lang['passcrypt'] = '密码加密方法';
+$lang['defaultgroup'] = '默认组';
+$lang['superuser'] = '超级用户 - 不论 ACL 如何设置,都能访问所有页面与功能的用户组/用户';
+$lang['manager'] = '管理员 - 能访问相应管理功能的用户组/用户';
+$lang['profileconfirm'] = '更新个人信息时需要输入当前密码';
+$lang['disableactions'] = '停用 DokuWiki 功能';
+$lang['disableactions_check'] = '检查';
+$lang['disableactions_subscription'] = '订阅/退订';
+$lang['disableactions_wikicode'] = '查看源文件/导出源文件';
+$lang['disableactions_other'] = '其他功能(用英文逗号分隔)';
+$lang['sneaky_index'] = '默认情况下,DokuWiki 在索引页会显示所有 namespace。启用该选项能隐藏那些用户没有权限阅读的页面。但也可能将用户能够阅读的子页面一并隐藏。这有可能导致在特定 ACL 设置下,索引功能不可用。';
+$lang['auth_security_timeout'] = '认证安全超时(秒)';
+$lang['securecookie'] = '要让浏览器须以HTTPS方式传送在HTTPS会话中设置的cookies吗?请只在登录过程为SSL加密而浏览维基为明文的情况下打开此选项。';
+$lang['xmlrpc'] = '启用/禁用 XML-RPC 交互界面。';
+$lang['xmlrpcuser'] = '将 XML-RPC 连接限制在用逗号分隔的组或用户中。留空对所有人开启连接权限。';
+$lang['updatecheck'] = '自动检查更新并接收安全警告吗?开启该功能后 DokuWiki 将自动访问 splitbrain.org。';
+$lang['userewrite'] = '使用更整洁的 URL';
+$lang['useslash'] = '在 URL 中使用斜杠作为命名空间的分隔符';
+$lang['usedraft'] = '编辑时自动保存一份草稿';
+$lang['sepchar'] = '页面名称中的单词分隔符';
+$lang['canonical'] = '使用完全标准的 URL';
+$lang['fnencode'] = '非 ASCII 文件名的编码方法。';
+$lang['autoplural'] = '在链接中检查多种格式';
+$lang['compression'] = 'attic 文件的压缩方式';
+$lang['cachetime'] = '缓存的最长时间(秒)';
+$lang['locktime'] = '独有编辑权/文件锁定的最长时间(秒)';
+$lang['fetchsize'] = 'fetch.php 能从外部下载的最大文件大小(字节)';
+$lang['notify'] = '发送更改通知给这个邮件地址';
+$lang['registernotify'] = '发送新注册用户的信息给这个邮件地址';
+$lang['mailfrom'] = '自动发送邮件时使用的邮件地址';
+$lang['mailprefix'] = '自动发送邮件时使用的邮件地址前缀';
+$lang['gzip_output'] = '对 xhtml 使用 gzip 内容编码';
+$lang['gdlib'] = 'GD 库版本';
+$lang['im_convert'] = 'ImageMagick 转换工具的路径';
+$lang['jpg_quality'] = 'JPG 压缩质量(0-100)';
+$lang['subscribers'] = '启用页面订阅支持';
+$lang['subscribe_time'] = '订阅列表和摘要发送的时间间隔(秒);这应当小于指定的最近更改保留时间(recent_days)。
+';
+$lang['compress'] = '使 CSS 和 javascript 的输出更紧密';
+$lang['cssdatauri'] = '字节数。CSS 文件引用的图片若小于该字节,则被直接嵌入样式表中来减少 HTTP 请求头的开销。这个技术在 IE 中不起作用。<code>400</code> 到 <code>600</code> 字节是不错的值。设置为 <code>0</code> 则禁用。';
+$lang['hidepages'] = '隐藏匹配的界面(正则表达式)';
+$lang['send404'] = '发送 "HTTP 404/页面没有找到" 错误信息给不存在的页面';
+$lang['sitemap'] = '生成 Google sitemap(天)';
+$lang['broken_iua'] = 'ignore_user_abort 功能失效了?这有可能导致搜索索引不可用。IIS+PHP/CGI 已损坏。请参阅 <a href="http://bugs.splitbrain.org/?do=details&amp;task_id=852">Bug 852</a> 获取更多信息。';
+$lang['xsendfile'] = '使用 X-Sendfile 头让服务器发送状态文件?您的服务器需要支持该功能。';
+$lang['renderer_xhtml'] = '主维基页面 (xhtml) 输出使用的渲染';
+$lang['renderer__core'] = '%s(DokuWiki 内核)';
+$lang['renderer__plugin'] = '%s(插件)';
+$lang['rememberme'] = '允许在本地机长期保留登录cookies信息(记住我)';
+$lang['rss_type'] = 'XML feed 类型';
+$lang['rss_linkto'] = 'XML feed 链接到';
+$lang['rss_content'] = 'XML feed 项目中显示什么呢?';
+$lang['rss_update'] = 'XML feed 升级间隔(秒)';
+$lang['recent_days'] = '保留多少天的最近更改(天)';
+$lang['rss_show_summary'] = 'XML feed 在标题中显示摘要';
+$lang['target____wiki'] = '内部链接的目标窗口';
+$lang['target____interwiki'] = 'Interwiki 链接的目标窗口';
+$lang['target____extern'] = '外部链接的目标窗口';
+$lang['target____media'] = '媒体文件链接的目标窗口';
+$lang['target____windows'] = 'Windows 链接的目标窗口';
+$lang['proxy____host'] = '代理服务器的名称';
+$lang['proxy____port'] = '代理服务器的端口';
+$lang['proxy____user'] = '代理服务器的用户名';
+$lang['proxy____pass'] = '代理服务器的密码';
+$lang['proxy____ssl'] = '使用 SSL 连接到代理服务器';
+$lang['proxy____except'] = '用来匹配代理应跳过的地址的正则表达式。';
+$lang['safemodehack'] = '启用 Safemode Hack';
+$lang['ftp____host'] = 'Safemode Hack 的 FTP 服务器';
+$lang['ftp____port'] = 'Safemode Hack 的 FTP 端口';
+$lang['ftp____user'] = 'Safemode Hack 的 FTP 用户名';
+$lang['ftp____pass'] = 'Safemode Hack 的 FTP 密码';
+$lang['ftp____root'] = 'Safemode Hack 的 FTP 根路径';
+$lang['license_o_'] = '什么都没有选';
+$lang['typography_o_0'] = '无';
+$lang['typography_o_1'] = '仅限双引号';
+$lang['typography_o_2'] = '所有引号(不一定能正常运行)';
+$lang['userewrite_o_0'] = '无';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki 内部控制';
+$lang['deaccent_o_0'] = '关闭';
+$lang['deaccent_o_1'] = '移除重音符号';
+$lang['deaccent_o_2'] = '用罗马字拼写';
+$lang['gdlib_o_0'] = 'GD 库不可用';
+$lang['gdlib_o_1'] = '1.x 版';
+$lang['gdlib_o_2'] = '自动检测';
+$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';
+$lang['rss_content_o_abstract'] = '摘要';
+$lang['rss_content_o_diff'] = '统一差异';
+$lang['rss_content_o_htmldiff'] = 'HTML 格式化的差异表';
+$lang['rss_content_o_html'] = '完整的 hTML 页面内容';
+$lang['rss_linkto_o_diff'] = '差别查看';
+$lang['rss_linkto_o_page'] = '已修订的页面';
+$lang['rss_linkto_o_rev'] = '修订列表';
+$lang['rss_linkto_o_current'] = '当前页面';
+$lang['compression_o_0'] = '无';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+$lang['xsendfile_o_0'] = '不要使用';
+$lang['xsendfile_o_1'] = '专有 lighttpd 头(1.5 发布前)';
+$lang['xsendfile_o_2'] = '标准 X-Sendfile 头';
+$lang['xsendfile_o_3'] = '专有 Nginx X-Accel-Redirect 头';
+$lang['showuseras_o_loginname'] = '登录名';
+$lang['showuseras_o_username'] = '用户全名';
+$lang['showuseras_o_email'] = '用户的电子邮箱(按邮箱保护设置加扰)';
+$lang['showuseras_o_email_link'] = '以mailto:形式显示用户的电子邮箱';
+$lang['useheading_o_0'] = '从不';
+$lang['useheading_o_navigation'] = '仅限导航';
+$lang['useheading_o_content'] = '仅限维基内容内';
+$lang['useheading_o_1'] = '一直';
+$lang['readdircache'] = 'readdir缓存的最长寿命(秒)';
diff --git a/lib/plugins/config/plugin.info.txt b/lib/plugins/config/plugin.info.txt
new file mode 100644
index 000000000..ace4889b6
--- /dev/null
+++ b/lib/plugins/config/plugin.info.txt
@@ -0,0 +1,6 @@
+author Christopher Smith
+email chris@jalakai.co.uk
+date 2007-08-05
+name Configuration Manager
+desc Manage Dokuwiki's Configuration Settings
+url http://dokuwiki.org/plugin:config
diff --git a/lib/plugins/config/rtl.css b/lib/plugins/config/rtl.css
new file mode 100644
index 000000000..b8b9660e2
--- /dev/null
+++ b/lib/plugins/config/rtl.css
@@ -0,0 +1,45 @@
+#config__manager fieldset {
+ clear: both;
+}
+
+#config__manager fieldset td {
+ text-align: right;
+}
+
+#config__manager label {
+ text-align: right;
+}
+
+#config__manager td.value input.checkbox {
+ float: right;
+ padding-left: 0;
+ padding-right: 0.7em;
+}
+
+#config__manager td.value label {
+ float: left;
+}
+
+#config__manager td.label {
+ padding: 0.8em 1em 0.6em 0;
+}
+
+#config__manager td.label span.outkey {
+ float: right;
+ margin-right: 1em;
+}
+
+#config__manager td.label label {
+ clear: right;
+}
+
+#config__manager td.label img {
+ float: left;
+}
+
+#config__manager .selection {
+ width: 14.8em;
+ float: right;
+ margin: 0 0 2px 0.3em;
+}
+
diff --git a/lib/plugins/config/settings/config.class.php b/lib/plugins/config/settings/config.class.php
new file mode 100644
index 000000000..1cdab607f
--- /dev/null
+++ b/lib/plugins/config/settings/config.class.php
@@ -0,0 +1,1057 @@
+<?php
+/**
+ * Configuration Class and generic setting classes
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+
+if (!class_exists('configuration')) {
+
+ class configuration {
+
+ var $_name = 'conf'; // name of the config variable found in the files (overridden by $config['varname'])
+ var $_format = 'php'; // format of the config file, supported formats - php (overridden by $config['format'])
+ var $_heading = ''; // heading string written at top of config file - don't include comment indicators
+ var $_loaded = false; // set to true after configuration files are loaded
+ var $_metadata = array(); // holds metadata describing the settings
+ var $setting = array(); // array of setting objects
+ var $locked = false; // configuration is considered locked if it can't be updated
+
+ // configuration filenames
+ var $_default_files = array();
+ var $_local_files = array(); // updated configuration is written to the first file
+ var $_protected_files = array();
+
+ var $_plugin_list = null;
+
+ /**
+ * constructor
+ */
+ function configuration($datafile) {
+ global $conf, $config_cascade;
+
+ if (!@file_exists($datafile)) {
+ msg('No configuration metadata found at - '.htmlspecialchars($datafile),-1);
+ return;
+ }
+ include($datafile);
+
+ if (isset($config['varname'])) $this->_name = $config['varname'];
+ if (isset($config['format'])) $this->_format = $config['format'];
+ if (isset($config['heading'])) $this->_heading = $config['heading'];
+
+ $this->_default_files = $config_cascade['main']['default'];
+ $this->_local_files = $config_cascade['main']['local'];
+ $this->_protected_files = $config_cascade['main']['protected'];
+
+# if (isset($file['default'])) $this->_default_file = $file['default'];
+# if (isset($file['local'])) $this->_local_file = $file['local'];
+# if (isset($file['protected'])) $this->_protected_file = $file['protected'];
+
+ $this->locked = $this->_is_locked();
+
+ $this->_metadata = array_merge($meta, $this->get_plugintpl_metadata($conf['template']));
+
+ $this->retrieve_settings();
+ }
+
+ function retrieve_settings() {
+ global $conf;
+ $no_default_check = array('setting_fieldset', 'setting_undefined', 'setting_no_class');
+
+ if (!$this->_loaded) {
+ $default = array_merge($this->get_plugintpl_default($conf['template']), $this->_read_config_group($this->_default_files));
+ $local = $this->_read_config_group($this->_local_files);
+ $protected = $this->_read_config_group($this->_protected_files);
+
+ $keys = array_merge(array_keys($this->_metadata),array_keys($default), array_keys($local), array_keys($protected));
+ $keys = array_unique($keys);
+
+ foreach ($keys as $key) {
+ if (isset($this->_metadata[$key])) {
+ $class = $this->_metadata[$key][0];
+ $class = ($class && class_exists('setting_'.$class)) ? 'setting_'.$class : 'setting';
+ if ($class=='setting') {
+ $this->setting[] = new setting_no_class($key,$param);
+ }
+
+ $param = $this->_metadata[$key];
+ array_shift($param);
+ } else {
+ $class = 'setting_undefined';
+ $param = NULL;
+ }
+
+ if (!in_array($class, $no_default_check) && !isset($default[$key])) {
+ $this->setting[] = new setting_no_default($key,$param);
+ }
+
+ $this->setting[$key] = new $class($key,$param);
+ $this->setting[$key]->initialize($default[$key],$local[$key],$protected[$key]);
+ }
+
+ $this->_loaded = true;
+ }
+ }
+
+ function save_settings($id, $header='', $backup=true) {
+ global $conf;
+
+ if ($this->locked) return false;
+
+ // write back to the last file in the local config cascade
+ $file = end($this->_local_files);
+
+ // backup current file (remove any existing backup)
+ if (@file_exists($file) && $backup) {
+ if (@file_exists($file.'.bak')) @unlink($file.'.bak');
+ if (!io_rename($file, $file.'.bak')) return false;
+ }
+
+ if (!$fh = @fopen($file, 'wb')) {
+ io_rename($file.'.bak', $file); // problem opening, restore the backup
+ return false;
+ }
+
+ if (empty($header)) $header = $this->_heading;
+
+ $out = $this->_out_header($id,$header);
+
+ foreach ($this->setting as $setting) {
+ $out .= $setting->out($this->_name, $this->_format);
+ }
+
+ $out .= $this->_out_footer();
+
+ @fwrite($fh, $out);
+ fclose($fh);
+ if($conf['fperm']) chmod($file, $conf['fperm']);
+ return true;
+ }
+
+ function _read_config_group($files) {
+ $config = array();
+ foreach ($files as $file) {
+ $config = array_merge($config, $this->_read_config($file));
+ }
+
+ return $config;
+ }
+
+ /**
+ * return an array of config settings
+ */
+ function _read_config($file) {
+
+ if (!$file) return array();
+
+ $config = array();
+# $file = eval('return '.$file.';');
+
+ if ($this->_format == 'php') {
+
+ if(@file_exists($file)){
+ $contents = @php_strip_whitespace($file);
+ }else{
+ $contents = '';
+ }
+ $pattern = '/\$'.$this->_name.'\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$'.$this->_name.'|@include|$))/s';
+ $matches=array();
+ preg_match_all($pattern,$contents,$matches,PREG_SET_ORDER);
+
+ for ($i=0; $i<count($matches); $i++) {
+
+ // correct issues with the incoming data
+ // FIXME ... for now merge multi-dimensional array indices using ____
+ $key = preg_replace('/.\]\[./',CM_KEYMARKER,$matches[$i][1]);
+
+ // remove quotes from quoted strings & unescape escaped data
+ $value = preg_replace('/^(\'|")(.*)(?<!\\\\)\1$/s','$2',$matches[$i][2]);
+ $value = strtr($value, array('\\\\'=>'\\','\\\''=>'\'','\\"'=>'"'));
+
+ $config[$key] = $value;
+ }
+ }
+
+ return $config;
+ }
+
+ function _out_header($id, $header) {
+ $out = '';
+ if ($this->_format == 'php') {
+ $out .= '<'.'?php'."\n".
+ "/*\n".
+ " * ".$header."\n".
+ " * Auto-generated by ".$id." plugin\n".
+ " * Run for user: ".$_SERVER['REMOTE_USER']."\n".
+ " * Date: ".date('r')."\n".
+ " */\n\n";
+ }
+
+ return $out;
+ }
+
+ function _out_footer() {
+ $out = '';
+ if ($this->_format == 'php') {
+ # if ($this->_protected_file) {
+ # $out .= "\n@include(".$this->_protected_file.");\n";
+ # }
+ $out .= "\n// end auto-generated content\n";
+ }
+
+ return $out;
+ }
+
+ // 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
+ function _is_locked() {
+ if (!$this->_local_files) return true;
+
+# $local = eval('return '.$this->_local_file.';');
+ $local = $this->_local_files[0];
+
+ if (!is_writable(dirname($local))) return true;
+ if (@file_exists($local) && !is_writable($local)) return true;
+
+ return false;
+ }
+
+ /**
+ * not used ... conf's contents are an array!
+ * reduce any multidimensional settings to one dimension using CM_KEYMARKER
+ */
+ function _flatten($conf,$prefix='') {
+
+ $out = array();
+
+ foreach($conf as $key => $value) {
+ if (!is_array($value)) {
+ $out[$prefix.$key] = $value;
+ continue;
+ }
+
+ $tmp = $this->_flatten($value,$prefix.$key.CM_KEYMARKER);
+ $out = array_merge($out,$tmp);
+ }
+
+ return $out;
+ }
+
+ function get_plugin_list() {
+ if (is_null($this->_plugin_list)) {
+ $list = plugin_list('',true); // all plugins, including disabled ones
+
+ // remove this plugin from the list
+ $idx = array_search('config',$list);
+ unset($list[$idx]);
+
+ trigger_event('PLUGIN_CONFIG_PLUGINLIST',$list);
+ $this->_plugin_list = $list;
+ }
+
+ return $this->_plugin_list;
+ }
+
+ /**
+ * load metadata for plugin and template settings
+ */
+ function get_plugintpl_metadata($tpl){
+ $file = '/conf/metadata.php';
+ $class = '/conf/settings.class.php';
+ $metadata = array();
+
+ foreach ($this->get_plugin_list() as $plugin) {
+ $plugin_dir = plugin_directory($plugin);
+ if (@file_exists(DOKU_PLUGIN.$plugin_dir.$file)){
+ $meta = array();
+ @include(DOKU_PLUGIN.$plugin_dir.$file);
+ @include(DOKU_PLUGIN.$plugin_dir.$class);
+ if (!empty($meta)) {
+ $metadata['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.'plugin_settings_name'] = array('fieldset');
+ }
+ foreach ($meta as $key => $value){
+ if ($value[0]=='fieldset') { continue; } //plugins only get one fieldset
+ $metadata['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
+ }
+ }
+ }
+
+ // the same for the active template
+ if (@file_exists(tpl_incdir().$file)){
+ $meta = array();
+ @include(tpl_incdir().$file);
+ @include(tpl_incdir().$class);
+ if (!empty($meta)) {
+ $metadata['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.'template_settings_name'] = array('fieldset');
+ }
+ foreach ($meta as $key => $value){
+ if ($value[0]=='fieldset') { continue; } //template only gets one fieldset
+ $metadata['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
+ }
+ }
+
+ return $metadata;
+ }
+
+ /**
+ * load default settings for plugins and templates
+ */
+ function get_plugintpl_default($tpl){
+ $file = '/conf/default.php';
+ $default = array();
+
+ foreach ($this->get_plugin_list() as $plugin) {
+ $plugin_dir = plugin_directory($plugin);
+ if (@file_exists(DOKU_PLUGIN.$plugin_dir.$file)){
+ $conf = array();
+ @include(DOKU_PLUGIN.$plugin_dir.$file);
+ foreach ($conf as $key => $value){
+ $default['plugin'.CM_KEYMARKER.$plugin.CM_KEYMARKER.$key] = $value;
+ }
+ }
+ }
+
+ // the same for the active template
+ if (@file_exists(tpl_incdir().$file)){
+ $conf = array();
+ @include(tpl_incdir().$file);
+ foreach ($conf as $key => $value){
+ $default['tpl'.CM_KEYMARKER.$tpl.CM_KEYMARKER.$key] = $value;
+ }
+ }
+
+ return $default;
+ }
+
+ }
+}
+
+if (!class_exists('setting')) {
+ class setting {
+
+ var $_key = '';
+ var $_default = NULL;
+ var $_local = NULL;
+ var $_protected = NULL;
+
+ var $_pattern = '';
+ var $_error = false; // only used by those classes which error check
+ var $_input = NULL; // only used by those classes which error check
+
+ var $_cautionList = array(
+ 'basedir' => 'danger', 'baseurl' => 'danger', 'savedir' => 'danger', 'cookiedir' => 'danger', 'useacl' => 'danger', 'authtype' => 'danger', 'superuser' => 'danger', 'userewrite' => 'danger',
+ 'start' => 'warning', 'camelcase' => 'warning', 'deaccent' => 'warning', 'sepchar' => 'warning', 'compression' => 'warning', 'xsendfile' => 'warning', 'renderer_xhtml' => 'warning', 'fnencode' => 'warning',
+ 'allowdebug' => 'security', 'htmlok' => 'security', 'phpok' => 'security', 'iexssprotect' => 'security', 'xmlrpc' => 'security', 'fullpath' => 'security'
+ );
+
+ function setting($key, $params=NULL) {
+ $this->_key = $key;
+
+ if (is_array($params)) {
+ foreach($params as $property => $value) {
+ $this->$property = $value;
+ }
+ }
+ }
+
+ /**
+ * receives current values for the setting $key
+ */
+ function initialize($default, $local, $protected) {
+ if (isset($default)) $this->_default = $default;
+ if (isset($local)) $this->_local = $local;
+ if (isset($protected)) $this->_protected = $protected;
+ }
+
+ /**
+ * update setting with user provided value $input
+ * if value fails error check, save it
+ *
+ * @return true if changed, false otherwise (incl. on error)
+ */
+ function update($input) {
+ if (is_null($input)) return false;
+ if ($this->is_protected()) return false;
+
+ $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;
+ }
+
+ /**
+ * @return array(string $label_html, string $input_html)
+ */
+ function html(&$plugin, $echo=false) {
+ $value = '';
+ $disable = '';
+
+ if ($this->is_protected()) {
+ $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 = '<textarea rows="3" cols="40" id="config___'.$key.'" name="config['.$key.']" class="edit" '.$disable.'>'.$value.'</textarea>';
+ return array($label,$input);
+ }
+
+ /**
+ * generate string to save setting value to file according to $fmt
+ */
+ function out($var, $fmt='php') {
+
+ if ($this->is_protected()) return '';
+ if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
+
+ $out = '';
+
+ if ($fmt=='php') {
+ // translation string needs to be improved FIXME
+ $tr = array("\n"=>'\n', "\r"=>'\r', "\t"=>'\t', "\\" => '\\\\', "'" => '\\\'');
+ $tr = array("\\" => '\\\\', "'" => '\\\'');
+
+ $out = '$'.$var."['".$this->_out_key()."'] = '".strtr($this->_local, $tr)."';\n";
+ }
+
+ return $out;
+ }
+
+ function prompt(&$plugin) {
+ $prompt = $plugin->getLang($this->_key);
+ if (!$prompt) $prompt = htmlspecialchars(str_replace(array('____','_'),' ',$this->_key));
+ return $prompt;
+ }
+
+ function is_protected() { return !is_null($this->_protected); }
+ function is_default() { return !$this->is_protected() && is_null($this->_local); }
+ function error() { return $this->_error; }
+
+ function caution() {
+ if (!array_key_exists($this->_key, $this->_cautionList)) return false;
+ return $this->_cautionList[$this->_key];
+ }
+
+ function _out_key($pretty=false,$url=false) {
+ if($pretty){
+ $out = str_replace(CM_KEYMARKER,"&raquo;",$this->_key);
+ if ($url && !strstr($out,'&raquo;')) {//provide no urls for plugins, etc.
+ if ($out == 'start') //one exception
+ 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;
+ }else{
+ return str_replace(CM_KEYMARKER,"']['",$this->_key);
+ }
+ }
+ }
+}
+
+if (!class_exists('setting_string')) {
+ class setting_string extends setting {
+ function html(&$plugin, $echo=false) {
+ $value = '';
+ $disable = '';
+
+ if ($this->is_protected()) {
+ $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);
+ }
+ }
+}
+
+if (!class_exists('setting_password')) {
+ class setting_password extends setting_string {
+
+ var $_code = 'plain'; // mechanism to be used to obscure passwords
+
+ function update($input) {
+ if ($this->is_protected()) 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;
+ }
+
+ function html(&$plugin, $echo=false) {
+
+ $value = '';
+ $disable = $this->is_protected() ? '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);
+ }
+ }
+}
+
+if (!class_exists('setting_email')) {
+ if (!defined('SETTING_EMAIL_PATTERN')) define('SETTING_EMAIL_PATTERN','<^'.PREG_PATTERN_VALID_EMAIL.'$>');
+
+ class setting_email extends setting_string {
+ var $_pattern = SETTING_EMAIL_PATTERN; // no longer required, retained for backward compatibility - FIXME, may not be necessary
+ var $_multiple = false;
+
+ /**
+ * update setting with user provided value $input
+ * if value fails error check, save it
+ *
+ * @return true if changed, false otherwise (incl. on error)
+ */
+ function update($input) {
+ if (is_null($input)) return false;
+ if ($this->is_protected()) return false;
+
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ if ($this->_multiple) {
+ $mails = array_filter(array_map('trim', split(',', $input)));
+ } else {
+ $mails = array($input);
+ }
+
+ foreach ($mails as $mail) {
+ if (!mail_isvalid($mail)) {
+ $this->_error = true;
+ $this->_input = $input;
+ return false;
+ }
+ }
+
+ $this->_local = $input;
+ return true;
+ }
+ }
+}
+
+if (!class_exists('setting_richemail')) {
+ class setting_richemail extends setting_email {
+
+ /**
+ * update setting with user provided value $input
+ * if value fails error check, save it
+ *
+ * @return true if changed, false otherwise (incl. on error)
+ */
+ function update($input) {
+ if (is_null($input)) return false;
+ if ($this->is_protected()) return false;
+
+ $value = is_null($this->_local) ? $this->_default : $this->_local;
+ if ($value == $input) return false;
+
+ // replace variables with pseudo values
+ $test = $input;
+ $test = str_replace('@USER@','joe',$test);
+ $test = str_replace('@NAME@','Joe Schmoe',$test);
+ $test = str_replace('@MAIL@','joe@example.com',$test);
+
+ // now only check the address part
+ if(preg_match('#(.*?)<(.*?)>#',$test,$matches)){
+ $text = trim($matches[1]);
+ $addr = $matches[2];
+ }else{
+ $addr = $test;
+ }
+
+ if ($test !== '' && !mail_isvalid($addr)) {
+ $this->_error = true;
+ $this->_input = $input;
+ return false;
+ }
+
+ $this->_local = $input;
+ return true;
+ }
+
+ }
+}
+
+
+if (!class_exists('setting_numeric')) {
+ class setting_numeric extends setting_string {
+ // This allows for many PHP syntax errors...
+ // var $_pattern = '/^[-+\/*0-9 ]*$/';
+ // much more restrictive, but should eliminate syntax errors.
+ var $_pattern = '/^[-+]? *[0-9]+ *(?:[-+*] *[0-9]+ *)*$/';
+ var $_min = null;
+ var $_max = null;
+
+ 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;
+ }
+
+ function out($var, $fmt='php') {
+
+ if ($this->is_protected()) return '';
+ if (is_null($this->_local) || ($this->_default == $this->_local)) return '';
+
+ $out = '';
+
+ if ($fmt=='php') {
+ $local = $this->_local === '' ? "''" : $this->_local;
+ $out .= '$'.$var."['".$this->_out_key()."'] = ".$local.";\n";
+ }
+
+ return $out;
+ }
+ }
+}
+
+if (!class_exists('setting_numericopt')) {
+ class setting_numericopt extends setting_numeric {
+ // just allow an empty config
+ var $_pattern = '/^(|[-]?[0-9]+(?:[-+*][0-9]+)*)$/';
+ }
+}
+
+if (!class_exists('setting_onoff')) {
+ class setting_onoff extends setting_numeric {
+
+ function html(&$plugin) {
+ $value = '';
+ $disable = '';
+
+ if ($this->is_protected()) {
+ $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);
+ }
+
+ function update($input) {
+ if ($this->is_protected()) 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;
+ }
+ }
+}
+
+if (!class_exists('setting_multichoice')) {
+ class setting_multichoice extends setting_string {
+ var $_choices = array();
+
+ function html(&$plugin) {
+ $value = '';
+ $disable = '';
+ $nochoice = '';
+
+ if ($this->is_protected()) {
+ $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->is_protected() && 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);
+ }
+
+ function update($input) {
+ if (is_null($input)) return false;
+ if ($this->is_protected()) 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;
+ }
+ }
+}
+
+
+if (!class_exists('setting_dirchoice')) {
+ class setting_dirchoice extends setting_multichoice {
+
+ var $_dir = '';
+
+ function initialize($default,$local,$protected) {
+
+ // 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);
+ }
+ }
+}
+
+
+if (!class_exists('setting_hidden')) {
+ class setting_hidden extends setting {
+ // Used to explicitly ignore a setting in the configuration manager.
+ }
+}
+
+if (!class_exists('setting_fieldset')) {
+ class setting_fieldset extends setting {
+ // A do-nothing class used to detect the 'fieldset' type.
+ // Used to start a new settings "display-group".
+ }
+}
+
+if (!class_exists('setting_undefined')) {
+ class setting_undefined extends setting_hidden {
+ // A do-nothing class used to detect settings with no metadata entry.
+ // Used internaly to hide undefined settings, and generate the undefined settings list.
+ }
+}
+
+if (!class_exists('setting_no_class')) {
+ class setting_no_class extends setting_undefined {
+ // 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.
+ }
+}
+
+if (!class_exists('setting_no_default')) {
+ class setting_no_default extends setting_undefined {
+ // A do-nothing class used to detect settings with no default value.
+ // Used internaly to hide undefined settings, and generate the undefined settings list.
+ }
+}
+
+if (!class_exists('setting_multicheckbox')) {
+ class setting_multicheckbox extends setting_string {
+
+ var $_choices = array();
+ var $_combine = array();
+
+ function update($input) {
+ if ($this->is_protected()) 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;
+ }
+
+ function html(&$plugin, $echo=false) {
+
+ $value = '';
+ $disable = '';
+
+ if ($this->is_protected()) {
+ $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"' : '';
+
+ // ideally this would be handled using a second class of "default", however IE6 does not
+ // correctly support CSS selectors referencing multiple class names on the same element
+ // (e.g. .default.selection).
+ $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
+ $other = join(',',$value);
+
+ $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
+ */
+ 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
+ */
+ 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));
+ }
+ }
+}
+
+/**
+ * Provide php_strip_whitespace (php5 function) functionality
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+if (!function_exists('php_strip_whitespace')) {
+
+ if (function_exists('token_get_all')) {
+
+ if (!defined('T_ML_COMMENT')) {
+ define('T_ML_COMMENT', T_COMMENT);
+ } else {
+ define('T_DOC_COMMENT', T_ML_COMMENT);
+ }
+
+ /**
+ * modified from original
+ * source Google Groups, php.general, by David Otton
+ */
+ function php_strip_whitespace($file) {
+ if (!@is_readable($file)) return '';
+
+ $in = join('',@file($file));
+ $out = '';
+
+ $tokens = token_get_all($in);
+
+ foreach ($tokens as $token) {
+ if (is_string ($token)) {
+ $out .= $token;
+ } else {
+ list ($id, $text) = $token;
+ switch ($id) {
+ case T_COMMENT : // fall thru
+ case T_ML_COMMENT : // fall thru
+ case T_DOC_COMMENT : // fall thru
+ case T_WHITESPACE :
+ break;
+ default : $out .= $text; break;
+ }
+ }
+ }
+ return ($out);
+ }
+
+ } else {
+
+ function is_whitespace($c) { return (strpos("\t\n\r ",$c) !== false); }
+ function is_quote($c) { return (strpos("\"'",$c) !== false); }
+ function is_escaped($s,$i) {
+ $idx = $i-1;
+ while(($idx>=0) && ($s{$idx} == '\\')) $idx--;
+ return (($i - $idx + 1) % 2);
+ }
+
+ function is_commentopen($str, $i) {
+ if ($str{$i} == '#') return "\n";
+ if ($str{$i} == '/') {
+ if ($str{$i+1} == '/') return "\n";
+ if ($str{$i+1} == '*') return "*/";
+ }
+
+ return false;
+ }
+
+ function php_strip_whitespace($file) {
+
+ if (!@is_readable($file)) return '';
+
+ $contents = join('',@file($file));
+ $out = '';
+
+ $state = 0;
+ for ($i=0; $i<strlen($contents); $i++) {
+ if (!$state && is_whitespace($contents{$i})) continue;
+
+ if (!$state && ($c_close = is_commentopen($contents, $i))) {
+ $c_open_len = ($contents{$i} == '/') ? 2 : 1;
+ $i = strpos($contents, $c_close, $i+$c_open_len)+strlen($c_close)-1;
+ continue;
+ }
+
+ $out .= $contents{$i};
+ if (is_quote($contents{$i})) {
+ if (($state == $contents{$i}) && !is_escaped($contents, $i)) { $state = 0; continue; }
+ if (!$state) {$state = $contents{$i}; continue; }
+ }
+ }
+
+ return $out;
+ }
+ }
+}
diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php
new file mode 100644
index 000000000..af815e8dc
--- /dev/null
+++ b/lib/plugins/config/settings/config.metadata.php
@@ -0,0 +1,216 @@
+<?php
+/**
+ * Metadata for configuration manager plugin
+ *
+ * Note: This file should be included within a function to ensure it
+ * doesn't clash with the settings it is describing.
+ *
+ * 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:
+ * Generic (source: settings/config.class.php)
+ * -------------------------------------------
+ * '' - 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, setting output in quotes
+ * 'richemail' - text input, input must conform to email address format but accepts variables and
+ * emails with a real name prepended (when email address is given in <>)
+ * '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 '_'.
+ *
+ * Single Setting (source: settings/extra.class.php)
+ * -------------------------------------------------
+ * '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
+ *
+ * Any setting commented or missing will use 'setting' class - text input, minimal validation, quoted output
+ *
+ * Defined parameters:
+ * '_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
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+// ---------------[ settings for settings ]------------------------------
+$config['format'] = 'php'; // format of setting files, supported formats: php
+$config['varname'] = 'conf'; // name of the config variable, sans $
+
+// this string is written at the top of the rewritten settings file,
+// !! do not include any comment indicators !!
+// this value can be overriden when calling save_settings() method
+$config['heading'] = 'Dokuwiki\'s Main Configuration File - Local Settings';
+
+/* DEPRECATED
+// ---------------[ setting files ]--------------------------------------
+// these values can be string expressions, they will be eval'd before use
+$file['local'] = "DOKU_CONF.'local.php'"; // mandatory (file doesn't have to exist)
+$file['default'] = "DOKU_CONF.'dokuwiki.php'"; // optional
+$file['protected'] = "DOKU_CONF.'local.protected.php'"; // optional
+ */
+
+// test value (FIXME, remove before publishing)
+//$meta['test'] = array('multichoice','_choices' => array(''));
+
+// --------------[ setting metadata ]------------------------------------
+// - for description of format and fields see top of file
+// - order the settings in the order you wish them to appear
+// - any settings not mentioned will come after the last setting listed and
+// will use the default class with no parameters
+
+$meta['_basic'] = array('fieldset');
+$meta['title'] = array('string');
+$meta['start'] = array('string','_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');
+$meta['basedir'] = array('string');
+$meta['baseurl'] = array('string');
+$meta['cookiedir'] = array('string');
+$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');
+
+$meta['_display'] = array('fieldset');
+$meta['recent'] = array('numeric');
+$meta['breadcrumbs'] = array('numeric','_min' => 0);
+$meta['youarehere'] = array('onoff');
+$meta['fullpath'] = array('onoff');
+$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','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');
+$meta['deaccent'] = array('multichoice','_choices' => array(0,1,2));
+$meta['useheading'] = array('multichoice','_choices' => array(0,'navigation','content',1));
+$meta['refcheck'] = array('onoff');
+$meta['refshow'] = array('numeric');
+
+$meta['_authentication'] = array('fieldset');
+$meta['useacl'] = array('onoff');
+$meta['autopasswd'] = array('onoff');
+$meta['authtype'] = array('authtype');
+$meta['passcrypt'] = array('multichoice','_choices' => array('smd5','md5','apr1','sha1','ssha','lsmd5','crypt','mysql','my411','kmd5','pmd5','hmd5','bcrypt'));
+$meta['defaultgroup']= array('string');
+$meta['superuser'] = array('string');
+$meta['manager'] = array('string');
+$meta['profileconfirm'] = array('onoff');
+$meta['rememberme'] = array('onoff');
+$meta['registernotify'] = array('email');
+$meta['disableactions'] = array('disableactions',
+ '_choices' => array('backlink','index','recent','revisions','search','subscription','register','resendpwd','profile','edit','wikicode','check'),
+ '_combine' => array('subscription' => array('subscribe','unsubscribe'), 'wikicode' => array('source','export_raw')));
+$meta['sneaky_index'] = array('onoff');
+$meta['auth_security_timeout'] = array('numeric');
+$meta['securecookie'] = array('onoff');
+$meta['xmlrpc'] = array('onoff');
+$meta['xmlrpcuser'] = 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');
+
+$meta['_editing'] = array('fieldset');
+$meta['usedraft'] = array('onoff');
+$meta['htmlok'] = array('onoff');
+$meta['phpok'] = array('onoff');
+$meta['notify'] = array('email', '_multiple' => true);
+$meta['subscribers'] = array('onoff');
+$meta['subscribe_time'] = array('numeric');
+$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['_advanced'] = array('fieldset');
+$meta['updatecheck'] = array('onoff');
+$meta['userewrite'] = array('multichoice','_choices' => array(0,1,2));
+$meta['useslash'] = array('onoff');
+$meta['sepchar'] = array('sepchar');
+$meta['canonical'] = array('onoff');
+$meta['fnencode'] = array('multichoice','_choices' => array('url','safe','utf-8'));
+$meta['autoplural'] = array('onoff');
+$meta['mailfrom'] = array('richemail');
+$meta['mailprefix'] = array('string');
+$meta['compress'] = array('onoff');
+$meta['cssdatauri'] = array('numeric','_pattern' => '/^\d+$/');
+$meta['gzip_output'] = array('onoff');
+$meta['hidepages'] = array('string');
+$meta['send404'] = array('onoff');
+$meta['compression'] = array('compression');
+$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_update'] = array('numeric');
+$meta['recent_days'] = array('numeric');
+$meta['rss_show_summary'] = array('onoff');
+$meta['broken_iua'] = array('onoff');
+$meta['xsendfile'] = array('multichoice','_choices' => array(0,1,2,3));
+$meta['renderer_xhtml'] = array('renderer','_format' => 'xhtml','_choices' => array('xhtml'));
+$meta['readdircache'] = array('numeric');
+
+$meta['_network'] = array('fieldset');
+$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');
+$meta['safemodehack'] = array('onoff');
+$meta['ftp____host'] = array('string','_pattern' => '#^(|[a-z0-9\-\.+]+)$#i');
+$meta['ftp____port'] = array('numericopt');
+$meta['ftp____user'] = array('string');
+$meta['ftp____pass'] = array('password','_code' => 'base64');
+$meta['ftp____root'] = array('string');
+
diff --git a/lib/plugins/config/settings/extra.class.php b/lib/plugins/config/settings/extra.class.php
new file mode 100644
index 000000000..b4e35b1cc
--- /dev/null
+++ b/lib/plugins/config/settings/extra.class.php
@@ -0,0 +1,175 @@
+<?php
+/**
+ * additional setting classes specific to these settings
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+if (!class_exists('setting_sepchar')) {
+ class setting_sepchar extends setting_multichoice {
+
+ function setting_sepchar($key,$param=NULL) {
+ $str = '_-.';
+ for ($i=0;$i<strlen($str);$i++) $this->_choices[] = $str{$i};
+
+ // call foundation class constructor
+ $this->setting($key,$param);
+ }
+ }
+}
+
+if (!class_exists('setting_savedir')) {
+ class setting_savedir extends setting_string {
+
+ function update($input) {
+ if ($this->is_protected()) 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;
+ }
+ }
+}
+
+if (!class_exists('setting_authtype')) {
+ class setting_authtype extends setting_multichoice {
+
+ function initialize($default,$local,$protected) {
+
+ // populate $this->_choices with a list of available auth mechanisms
+ $authtypes = glob(DOKU_INC.'inc/auth/*.class.php');
+ $authtypes = preg_replace('#^.*/([^/]*)\.class\.php$#i','$1', $authtypes);
+ $authtypes = array_diff($authtypes, array('basic'));
+ sort($authtypes);
+
+ $this->_choices = $authtypes;
+
+ parent::initialize($default,$local,$protected);
+ }
+ }
+}
+
+if (!class_exists('setting_im_convert')) {
+ class setting_im_convert extends setting_string {
+
+ function update($input) {
+ if ($this->is_protected()) 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;
+ }
+ }
+}
+
+if (!class_exists('setting_disableactions')) {
+ class setting_disableactions extends setting_multicheckbox {
+
+ function html(&$plugin, $echo=false) {
+ global $lang;
+
+ // make some language adjustments (there must be a better way)
+ // transfer some DokuWiki language strings to the plugin
+ if (!$plugin->localised) $this->setupLocale();
+ $plugin->lang[$this->_key.'_revisions'] = $lang['btn_revs'];
+
+ foreach ($this->_choices as $choice)
+ if (isset($lang['btn_'.$choice])) $plugin->lang[$this->_key.'_'.$choice] = $lang['btn_'.$choice];
+
+ return parent::html($plugin, $echo);
+ }
+ }
+}
+
+if (!class_exists('setting_compression')) {
+ class setting_compression extends setting_multichoice {
+
+ var $_choices = array('0'); // 0 = no compression, always supported
+
+ function initialize($default,$local,$protected) {
+
+ // 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);
+ }
+ }
+}
+
+if (!class_exists('setting_license')) {
+ class setting_license extends setting_multichoice {
+
+ var $_choices = array(''); // none choosen
+
+ function initialize($default,$local,$protected) {
+ global $license;
+
+ foreach($license as $key => $data){
+ $this->_choices[] = $key;
+ $this->lang[$this->_key.'_o_'.$key] = $data['name'];
+ }
+
+ parent::initialize($default,$local,$protected);
+ }
+ }
+}
+
+
+if (!class_exists('setting_renderer')) {
+ class setting_renderer extends setting_multichoice {
+ var $_prompts = array();
+
+ function initialize($default,$local,$protected) {
+ $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);
+ }
+
+ function html(&$plugin, $echo=false) {
+
+ // make some language adjustments (there must be a better way)
+ // transfer some plugin names to the config plugin
+ if (!$plugin->localised) $this->setupLocale();
+
+ foreach ($this->_choices as $choice) {
+ if (!isset($plugin->lang[$this->_key.'_o_'.$choice])) {
+ if (!isset($this->_prompts[$choice])) {
+ $plugin->lang[$this->_key.'_o_'.$choice] = sprintf($plugin->lang['renderer__core'],$choice);
+ } else {
+ $plugin->lang[$this->_key.'_o_'.$choice] = sprintf($plugin->lang['renderer__plugin'],$this->_prompts[$choice]);
+ }
+ }
+ }
+ return parent::html($plugin, $echo);
+ }
+ }
+}
diff --git a/lib/plugins/config/style.css b/lib/plugins/config/style.css
new file mode 100644
index 000000000..65c44a758
--- /dev/null
+++ b/lib/plugins/config/style.css
@@ -0,0 +1,136 @@
+/* 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;
+}
+#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;
+}
+#config__manager fieldset td.value {
+ /* fixed data column width */
+ width: 31em;
+}
+
+#config__manager td.label {
+ padding: 0.8em 0 0.6em 1em;
+ vertical-align: top;
+}
+
+#config__manager td.label label {
+ clear: left;
+ display: block;
+}
+#config__manager td.label img {
+ padding: 0 10px;
+ vertical-align: middle;
+ float: right;
+}
+
+#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;
+}
+
+#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 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;
+}
+
+#config__manager .selection label {
+ float: right;
+ width: 14em;
+ font-size: 90%;
+}
+
+
+/* IE6 correction */
+* html #config__manager .selection label {
+ padding-top: 2px;
+}
+
+#config__manager .selection input.checkbox {
+ padding-left: 0.7em;
+}
+
+#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/lib/plugins/index.html b/lib/plugins/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/plugins/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<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/lib/plugins/info/lang/sl/lang.php b/lib/plugins/info/lang/sl/lang.php
new file mode 100644
index 000000000..62936947c
--- /dev/null
+++ b/lib/plugins/info/lang/sl/lang.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * English language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ */
+
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['onHidden'] = 'Click to display ⇲';
+$lang['onVisible'] = 'Click to hide ⇱';
diff --git a/lib/plugins/info/plugin.info.txt b/lib/plugins/info/plugin.info.txt
new file mode 100644
index 000000000..2432225f1
--- /dev/null
+++ b/lib/plugins/info/plugin.info.txt
@@ -0,0 +1,6 @@
+author Andreas Gohr
+email andi@splitbrain.org
+date 2008-09-12
+name Info Plugin
+desc Displays information about various DokuWiki internals
+url http://dokuwiki.org/plugin:info
diff --git a/lib/plugins/info/syntax.php b/lib/plugins/info/syntax.php
new file mode 100644
index 000000000..9aedbf0aa
--- /dev/null
+++ b/lib/plugins/info/syntax.php
@@ -0,0 +1,256 @@
+<?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>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ */
+class syntax_plugin_info extends DokuWiki_Syntax_Plugin {
+
+ /**
+ * return some info
+ */
+ function getInfo(){
+ return array(
+ 'author' => 'Andreas Gohr',
+ 'email' => 'andi@splitbrain.org',
+ 'date' => '2008-09-12',
+ 'name' => 'Info Plugin',
+ 'desc' => 'Displays information about various DokuWiki internals',
+ 'url' => 'http://dokuwiki.org/plugin:info',
+ );
+ }
+
+ /**
+ * What kind of syntax are we?
+ */
+ function getType(){
+ return 'substition';
+ }
+
+ /**
+ * What about paragraphs?
+ */
+ function getPType(){
+ return 'block';
+ }
+
+ /**
+ * Where to sort in?
+ */
+ function getSort(){
+ return 155;
+ }
+
+
+ /**
+ * Connect pattern to lexer
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('~~INFO:\w+~~',$mode,'plugin_info');
+ }
+
+
+ /**
+ * Handle the match
+ */
+ function handle($match, $state, $pos, &$handler){
+ $match = substr($match,7,-2); //strip ~~INFO: from start and ~~ from end
+ return array(strtolower($match));
+ }
+
+ /**
+ * Create output
+ */
+ function render($format, &$renderer, $data) {
+ if($format == 'xhtml'){
+ //handle various info stuff
+ switch ($data[0]){
+ case 'version':
+ $renderer->doc .= getVersion();
+ break;
+ case 'syntaxmodes':
+ $renderer->doc .= $this->_syntaxmodes_xhtml();
+ break;
+ case 'syntaxtypes':
+ $renderer->doc .= $this->_syntaxtypes_xhtml();
+ break;
+ case 'syntaxplugins':
+ $this->_plugins_xhtml('syntax', $renderer);
+ break;
+ case 'adminplugins':
+ $this->_plugins_xhtml('admin', $renderer);
+ break;
+ case 'actionplugins':
+ $this->_plugins_xhtml('action', $renderer);
+ break;
+ case 'rendererplugins':
+ $this->_plugins_xhtml('renderer', $renderer);
+ break;
+ case 'helperplugins':
+ $this->_plugins_xhtml('helper', $renderer);
+ break;
+ case 'helpermethods':
+ $this->_helpermethods_xhtml($renderer);
+ 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
+ */
+ function _plugins_xhtml($type, &$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
+ */
+ function _helpermethods_xhtml(&$renderer){
+ global $lang;
+
+ $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($params, '</td></tr><tr><td>').'</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
+ */
+ function _syntaxtypes_xhtml(){
+ 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
+ */
+ function _syntaxmodes_xhtml(){
+ $modes = p_get_parsermodes();
+ $doc = '';
+
+ foreach ($modes as $mode){
+ $doc .= $mode['mode'].' ('.$mode['sort'].'), ';
+ }
+ return $doc;
+ }
+
+ /**
+ * Adds a TOC item
+ */
+ function _addToTOC($text, $level, &$renderer){
+ global $conf;
+
+ 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/lib/plugins/plugin/admin.php b/lib/plugins/plugin/admin.php
new file mode 100644
index 000000000..b2108f185
--- /dev/null
+++ b/lib/plugins/plugin/admin.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Plugin management functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+// todo
+// - maintain a history of file modified
+// - allow a plugin to contain extras to be copied to the current template (extra/tpl/)
+// - to images (lib/images/) [ not needed, should go in lib/plugin/images/ ]
+
+require_once(DOKU_PLUGIN."/plugin/classes/ap_manage.class.php");
+
+//--------------------------[ GLOBALS ]------------------------------------------------
+// note: probably should be dokuwiki wide globals, where they can be accessed by pluginutils.php
+// global $plugin_types;
+// $plugin_types = array('syntax', 'admin');
+
+// plugins that are an integral part of dokuwiki, they shouldn't be disabled or deleted
+global $plugin_protected;
+$plugin_protected = array('acl','plugin','config','info','usermanager','revert');
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_plugin extends DokuWiki_Admin_Plugin {
+
+ var $disabled = 0;
+ var $plugin = '';
+ var $cmd = '';
+ var $handler = NULL;
+
+ var $functions = array('delete','update',/*'settings',*/'info'); // require a plugin name
+ var $commands = array('manage','download','enable'); // don't require a plugin name
+ var $plugin_list = array();
+
+ var $msg = '';
+ var $error = '';
+
+ function admin_plugin_plugin() {
+ global $conf;
+ $this->disabled = plugin_isdisabled('plugin');
+ }
+
+ /**
+ * return some info
+ */
+ function getInfo(){
+ $disabled = ($this->disabled) ? '(disabled)' : '';
+
+ return array(
+ 'author' => 'Christopher Smith',
+ 'email' => 'chris@jalakai.co.uk',
+ 'date' => '2009-11-11',
+ 'name' => 'Plugin Manager',
+ 'desc' => "Manage Plugins, including automated plugin installer $disabled",
+ 'url' => 'http://www.dokuwiki.org/plugin:plugin',
+ );
+ }
+
+
+ /**
+ * return sort order for position in admin menu
+ */
+ function getMenuSort() {
+ return 20;
+ }
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ // enable direct access to language strings
+ $this->setupLocale();
+
+
+ $fn = $_REQUEST['fn'];
+ if (is_array($fn)) {
+ $this->cmd = key($fn);
+ $this->plugin = is_array($fn[$this->cmd]) ? key($fn[$this->cmd]) : null;
+ } else {
+ $this->cmd = $fn;
+ $this->plugin = null;
+ }
+ $this->_get_plugin_list();
+
+ // verify $_REQUEST vars
+ if (in_array($this->cmd, $this->commands)) {
+ $this->plugin = '';
+ } else if (!in_array($this->cmd, $this->functions) || !in_array($this->plugin, $this->plugin_list)) {
+ $this->cmd = 'manage';
+ $this->plugin = '';
+ }
+
+ if(($this->cmd != 'manage' || $this->plugin != '') && !checkSecurityToken()){
+ $this->cmd = 'manage';
+ $this->plugin = '';
+ }
+
+ // create object to handle the command
+ $class = "ap_".$this->cmd;
+ @require_once(DOKU_PLUGIN."/plugin/classes/$class.class.php");
+ if (!class_exists($class)){
+ $class = 'ap_manage';
+ }
+
+ $this->handler = new $class($this, $this->plugin);
+ $this->msg = $this->handler->process();
+
+ }
+
+ /**
+ * output appropriate html
+ */
+ function html() {
+ // enable direct access to language strings
+ $this->setupLocale();
+ $this->_get_plugin_list();
+
+ if ($this->handler === NULL) $this->handler = new ap_manage($this, $this->plugin);
+
+ ptln('<div id="plugin__manager">');
+ $this->handler->html();
+ ptln('</div><!-- #plugin_manager -->');
+ }
+
+ /**
+ * Returns a list of all plugins, including the disabled ones
+ */
+ function _get_plugin_list() {
+ if (empty($this->plugin_list)) {
+ $list = plugin_list('',true); // all plugins, including disabled ones
+ sort($list);
+ trigger_event('PLUGIN_PLUGINMANAGER_PLUGINLIST',$list);
+ $this->plugin_list = $list;
+ }
+ return $this->plugin_list;
+ }
+
+}
+
+
+
+
+
+
diff --git a/lib/plugins/plugin/classes/ap_delete.class.php b/lib/plugins/plugin/classes/ap_delete.class.php
new file mode 100644
index 000000000..581a6295f
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_delete.class.php
@@ -0,0 +1,28 @@
+<?php
+class ap_delete extends ap_manage {
+
+ function process() {
+
+ if (!$this->dir_delete(DOKU_PLUGIN.plugin_directory($this->manager->plugin))) {
+ $this->manager->error = sprintf($this->lang['error_delete'],$this->manager->plugin);
+ } else {
+ msg(sprintf($this->lang['deleted'],$this->plugin));
+ $this->refresh();
+ }
+ }
+
+ function html() {
+ parent::html();
+
+ ptln('<div class="pm_info">');
+ ptln('<h2>'.$this->lang['deleting'].'</h2>');
+
+ if ($this->manager->error) {
+ ptln('<div class="error">'.str_replace("\n","<br />",$this->manager->error).'</div>');
+ } else {
+ ptln('<p>'.sprintf($this->lang['deleted'],$this->plugin).'</p>');
+ }
+ ptln('</div>');
+ }
+}
+
diff --git a/lib/plugins/plugin/classes/ap_download.class.php b/lib/plugins/plugin/classes/ap_download.class.php
new file mode 100644
index 000000000..b2571f632
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_download.class.php
@@ -0,0 +1,294 @@
+<?php
+class ap_download extends ap_manage {
+
+ var $overwrite = true;
+
+ /**
+ * Initiate the plugin download
+ */
+ function process() {
+ global $lang;
+
+ $plugin_url = $_REQUEST['url'];
+ $this->download($plugin_url, $this->overwrite);
+ return '';
+ }
+
+ /**
+ * Print results of the download
+ */
+ function html() {
+ parent::html();
+
+ ptln('<div class="pm_info">');
+ ptln('<h2>'.$this->lang['downloading'].'</h2>');
+
+ if ($this->manager->error) {
+ ptln('<div class="error">'.str_replace("\n","<br />",$this->manager->error).'</div>');
+ } else if (count($this->downloaded) == 1) {
+ ptln('<p>'.sprintf($this->lang['downloaded'],$this->downloaded[0]).'</p>');
+ } else if (count($this->downloaded)) { // more than one plugin in the download
+ ptln('<p>'.$this->lang['downloads'].'</p>');
+ ptln('<ul>');
+ foreach ($this->downloaded as $plugin) {
+ ptln('<li><div class="li">'.$plugin.'</div></li>',2);
+ }
+ ptln('</ul>');
+ } else { // none found in download
+ ptln('<p>'.$this->lang['download_none'].'</p>');
+ }
+ ptln('</div>');
+ }
+
+ /**
+ * Process the downloaded file
+ */
+ function download($url, $overwrite=false) {
+ global $lang;
+ // check the url
+ $matches = array();
+ if (!preg_match("/[^\/]*$/", $url, $matches) || !$matches[0]) {
+ $this->manager->error = $this->lang['error_badurl']."\n";
+ return false;
+ }
+
+ $file = $matches[0];
+
+ if (!($tmp = io_mktmpdir())) {
+ $this->manager->error = $this->lang['error_dircreate']."\n";
+ return false;
+ }
+
+ if (!$file = io_download($url, "$tmp/", true, $file, 0)) {
+ $this->manager->error = sprintf($this->lang['error_download'],$url)."\n";
+ }
+
+ if (!$this->manager->error && !$this->decompress("$tmp/$file", $tmp)) {
+ $this->manager->error = sprintf($this->lang['error_decompress'],$file)."\n";
+ }
+
+ // search $tmp for the folder(s) that has been created
+ // move the folder(s) to lib/plugins/
+ if (!$this->manager->error) {
+ $result = array('old'=>array(), 'new'=>array());
+ if($this->find_folders($result,$tmp)){
+ // choose correct result array
+ if(count($result['new'])){
+ $install = $result['new'];
+ }else{
+ $install = $result['old'];
+ }
+
+ // now install all found items
+ foreach($install as $item){
+ // where to install?
+ if($item['type'] == 'template'){
+ $target = DOKU_INC.'lib/tpl/'.$item['base'];
+ }else{
+ $target = DOKU_INC.'lib/plugins/'.$item['base'];
+ }
+
+ // check to make sure we aren't overwriting anything
+ if (!$overwrite && @file_exists($target)) {
+ // remember our settings, ask the user to confirm overwrite, FIXME
+ continue;
+ }
+
+ $instruction = @file_exists($target) ? 'update' : 'install';
+
+ // copy action
+ if ($this->dircopy($item['tmp'], $target)) {
+ $this->downloaded[] = $item['base'];
+ $this->plugin_writelog($target, $instruction, array($url));
+ } else {
+ $this->manager->error .= sprintf($this->lang['error_copy']."\n", $item['base']);
+ }
+ }
+
+ } else {
+ $this->manager->error = $this->lang['error']."\n";
+ }
+ }
+
+ // cleanup
+ if ($tmp) $this->dir_delete($tmp);
+
+ if (!$this->manager->error) {
+ msg(sprintf($this->lang['packageinstalled'], count($this->downloaded), join(',',$this->downloaded)),1);
+ $this->refresh();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * 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 arrayref $result - results are stored here
+ * @param string $base - the temp directory where the package was unpacked to
+ * @param string $dir - a subdirectory. do not set. used by recursion
+ * @return bool - false on error
+ */
+ function find_folders(&$result,$base,$dir=''){
+ $dh = @opendir("$base/$dir");
+ if(!$dh) return false;
+ while (false !== ($f = readdir($dh))) {
+ if ($f == '.' || $f == '..' || $f == 'tmp') continue;
+
+ if(!is_dir("$base/$dir/$f")){
+ // it's a file -> check for config
+ if($f == 'plugin.info.txt'){
+ $info = array();
+ $info['type'] = 'plugin';
+ $info['tmp'] = "$base/$dir";
+ $conf = confToHash("$base/$dir/$f");
+ $info['base'] = basename($conf['base']);
+ if(!$info['base']) $info['base'] = basename("$base/$dir");
+ $result['new'][] = $info;
+ }elseif($f == 'template.info.txt'){
+ $info = array();
+ $info['type'] = 'template';
+ $info['tmp'] = "$base/$dir";
+ $conf = confToHash("$base/$dir/$f");
+ $info['base'] = basename($conf['base']);
+ if(!$info['base']) $info['base'] = basename("$base/$dir");
+ $result['new'][] = $info;
+ }
+ }else{
+ // it's a directory -> add to dir list for old method, then recurse
+ if(!$dir){
+ $info = array();
+ $info['type'] = 'plugin';
+ $info['tmp'] = "$base/$dir/$f";
+ $info['base'] = $f;
+ $result['old'][] = $info;
+ }
+ $this->find_folders($result,$base,"$dir/$f");
+ }
+ }
+ closedir($dh);
+ return true;
+ }
+
+
+ /**
+ * Decompress a given file to the given target directory
+ *
+ * Determines the compression type from the file extension
+ */
+ function decompress($file, $target) {
+ global $conf;
+
+ // decompression library doesn't like target folders ending in "/"
+ if (substr($target, -1) == "/") $target = substr($target, 0, -1);
+
+ $ext = $this->guess_archive($file);
+ if (in_array($ext, array('tar','bz','gz'))) {
+ switch($ext){
+ case 'bz':
+ $compress_type = TarLib::COMPRESS_BZIP;
+ break;
+ case 'gz':
+ $compress_type = TarLib::COMPRESS_GZIP;
+ break;
+ default:
+ $compress_type = TarLib::COMPRESS_NONE;
+ }
+
+ $tar = new TarLib($file, $compress_type);
+ if($tar->_initerror < 0){
+ if($conf['allowdebug']){
+ msg('TarLib Error: '.$tar->TarErrorStr($tar->_initerror),-1);
+ }
+ return false;
+ }
+ $ok = $tar->Extract(TarLib::FULL_ARCHIVE, $target, '', 0777);
+
+ if($ok<1){
+ if($conf['allowdebug']){
+ msg('TarLib Error: '.$tar->TarErrorStr($ok),-1);
+ }
+ return false;
+ }
+ return true;
+ } else if ($ext == 'zip') {
+
+ $zip = new ZipLib();
+ $ok = $zip->Extract($file, $target);
+
+ // FIXME sort something out for handling zip error messages meaningfully
+ return ($ok==-1?false:true);
+
+ }
+
+ // unsupported file type
+ return false;
+ }
+
+ /**
+ * 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>
+ * @returns false if the file can't be read, otherwise an "extension"
+ */
+ function guess_archive($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
+ */
+ 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 {
+ $exists = @file_exists($dst);
+
+ if (!@copy($src,$dst)) return false;
+ if (!$exists && !empty($conf['fperm'])) chmod($dst, $conf['fperm']);
+ @touch($dst,filemtime($src));
+ }
+
+ return true;
+ }
+
+
+}
+
diff --git a/lib/plugins/plugin/classes/ap_enable.class.php b/lib/plugins/plugin/classes/ap_enable.class.php
new file mode 100644
index 000000000..35450a907
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_enable.class.php
@@ -0,0 +1,49 @@
+<?php
+
+class ap_enable extends ap_manage {
+
+ var $enabled = array();
+
+ function process() {
+ global $plugin_protected;
+ $count_enabled = $count_disabled = 0;
+
+ $this->enabled = isset($_REQUEST['enabled']) ? $_REQUEST['enabled'] : array();
+
+ foreach ($this->manager->plugin_list as $plugin) {
+ if (in_array($plugin, $plugin_protected)) continue;
+
+ $new = in_array($plugin, $this->enabled);
+ $old = !plugin_isdisabled($plugin);
+
+ if ($new != $old) {
+ switch ($new) {
+ // enable plugin
+ case true :
+ if(plugin_enable($plugin)){
+ msg(sprintf($this->lang['enabled'],$plugin),1);
+ $count_enabled++;
+ }else{
+ msg(sprintf($this->lang['notenabled'],$plugin),-1);
+ }
+ break;
+ case false:
+ if(plugin_disable($plugin)){
+ msg(sprintf($this->lang['disabled'],$plugin),1);
+ $count_disabled++;
+ }else{
+ msg(sprintf($this->lang['notdisabled'],$plugin),-1);
+ }
+ break;
+ }
+ }
+ }
+
+ // refresh plugins, including expiring any dokuwiki cache(s)
+ if ($count_enabled || $count_disabled) {
+ $this->refresh();
+ }
+ }
+
+}
+
diff --git a/lib/plugins/plugin/classes/ap_info.class.php b/lib/plugins/plugin/classes/ap_info.class.php
new file mode 100644
index 000000000..44926c035
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_info.class.php
@@ -0,0 +1,144 @@
+<?php
+
+class ap_info extends ap_manage {
+
+ var $plugin_info = array(); // the plugin itself
+ var $details = array(); // any component plugins
+
+ function process() {
+
+ // sanity check
+ if (!$this->manager->plugin) { return; }
+
+ $component_list = $this->get_plugin_components($this->manager->plugin);
+ usort($component_list, array($this,'component_sort'));
+
+
+ foreach ($component_list as $component) {
+ if (($obj = &plugin_load($component['type'],$component['name'],false,true)) === NULL) continue;
+
+ $compname = explode('_',$component['name']);
+ if($compname[1]){
+ $compname = '['.$compname[1].']';
+ }else{
+ $compname = '';
+ }
+
+ $this->details[] = array_merge(
+ $obj->getInfo(),
+ array(
+ 'type' => $component['type'],
+ 'compname' => $compname
+ ));
+ unset($obj);
+ }
+
+ // review details to simplify things
+ foreach($this->details as $info) {
+ foreach($info as $item => $value) {
+ if (!isset($this->plugin_info[$item])) { $this->plugin_info[$item] = $value; continue; }
+ if ($this->plugin_info[$item] != $value) $this->plugin_info[$item] = '';
+ }
+ }
+ }
+
+ function html() {
+
+ // output the standard menu stuff
+ parent::html();
+
+ // sanity check
+ if (!$this->manager->plugin) { return; }
+
+ ptln('<div class="pm_info">');
+ ptln("<h2>".$this->manager->getLang('plugin')." {$this->manager->plugin}</h2>");
+
+ // collect pertinent information from the log
+ $installed = $this->plugin_readlog($this->manager->plugin, 'installed');
+ $source = $this->plugin_readlog($this->manager->plugin, 'url');
+ $updated = $this->plugin_readlog($this->manager->plugin, 'updated');
+ if (strrpos($updated, "\n") !== false) $updated = substr($updated, strrpos($updated, "\n")+1);
+
+ ptln("<dl>",2);
+ ptln("<dt>".$this->manager->getLang('source').'</dt><dd>'.($source ? $source : $this->manager->getLang('unknown'))."</dd>",4);
+ ptln("<dt>".$this->manager->getLang('installed').'</dt><dd>'.($installed ? $installed : $this->manager->getLang('unknown'))."</dd>",4);
+ if ($updated) ptln("<dt>".$this->manager->getLang('lastupdate').'</dt><dd>'.$updated."</dd>",4);
+ ptln("</dl>",2);
+
+ if (count($this->details) == 0) {
+ ptln("<p>".$this->manager->getLang('noinfo')."</p>",2);
+ } else {
+
+ ptln("<dl>",2);
+ if ($this->plugin_info['name']) ptln("<dt>".$this->manager->getLang('name')."</dt><dd>".$this->out($this->plugin_info['name'])."</dd>",4);
+ if ($this->plugin_info['date']) ptln("<dt>".$this->manager->getLang('date')."</dt><dd>".$this->out($this->plugin_info['date'])."</dd>",4);
+ if ($this->plugin_info['type']) ptln("<dt>".$this->manager->getLang('type')."</dt><dd>".$this->out($this->plugin_info['type'])."</dd>",4);
+ if ($this->plugin_info['desc']) ptln("<dt>".$this->manager->getLang('desc')."</dt><dd>".$this->out($this->plugin_info['desc'])."</dd>",4);
+ if ($this->plugin_info['author']) ptln("<dt>".$this->manager->getLang('author')."</dt><dd>".$this->manager->email($this->plugin_info['email'], $this->plugin_info['author'])."</dd>",4);
+ if ($this->plugin_info['url']) ptln("<dt>".$this->manager->getLang('www')."</dt><dd>".$this->manager->external_link($this->plugin_info['url'], '', 'urlextern')."</dd>",4);
+ ptln("</dl>",2);
+
+ if (count($this->details) > 1) {
+ ptln("<h3>".$this->manager->getLang('components')."</h3>",2);
+ ptln("<div>",2);
+
+ foreach ($this->details as $info) {
+
+ ptln("<dl>",4);
+ ptln("<dt>".$this->manager->getLang('name')."</dt><dd>".$this->out($info['name'].' '.$info['compname'])."</dd>",6);
+ if (!$this->plugin_info['date']) ptln("<dt>".$this->manager->getLang('date')."</dt><dd>".$this->out($info['date'])."</dd>",6);
+ if (!$this->plugin_info['type']) ptln("<dt>".$this->manager->getLang('type')."</dt><dd>".$this->out($info['type'])."</dd>",6);
+ if (!$this->plugin_info['desc']) ptln("<dt>".$this->manager->getLang('desc')."</dt><dd>".$this->out($info['desc'])."</dd>",6);
+ if (!$this->plugin_info['author']) ptln("<dt>".$this->manager->getLang('author')."</dt><dd>".$this->manager->email($info['email'], $info['author'])."</dd>",6);
+ if (!$this->plugin_info['url']) ptln("<dt>".$this->manager->getLang('www')."</dt><dd>".$this->manager->external_link($info['url'], '', 'urlextern')."</dd>",6);
+ ptln("</dl>",4);
+
+ }
+ ptln("</div>",2);
+ }
+ }
+ ptln("</div>");
+ }
+
+ // simple output filter, make html entities safe and convert new lines to <br />
+ function out($text) {
+ return str_replace("\n",'<br />',htmlspecialchars($text));
+ }
+
+
+ /**
+ * return a list (name & type) of all the component plugins that make up this plugin
+ *
+ * @todo can this move to pluginutils?
+ */
+ function get_plugin_components($plugin) {
+
+ global $plugin_types;
+
+ $components = array();
+ $path = DOKU_PLUGIN.plugin_directory($plugin).'/';
+
+ foreach ($plugin_types as $type) {
+ if (@file_exists($path.$type.'.php')) { $components[] = array('name'=>$plugin, 'type'=>$type); continue; }
+
+ if ($dh = @opendir($path.$type.'/')) {
+ while (false !== ($cp = readdir($dh))) {
+ if ($cp == '.' || $cp == '..' || strtolower(substr($cp,-4)) != '.php') continue;
+
+ $components[] = array('name'=>$plugin.'_'.substr($cp, 0, -4), 'type'=>$type);
+ }
+ closedir($dh);
+ }
+ }
+
+ return $components;
+ }
+
+ /**
+ * usort callback to sort plugin components
+ */
+ function component_sort($a, $b) {
+ if ($a['name'] == $b['name']) return 0;
+ return ($a['name'] < $b['name']) ? -1 : 1;
+ }
+}
diff --git a/lib/plugins/plugin/classes/ap_manage.class.php b/lib/plugins/plugin/classes/ap_manage.class.php
new file mode 100644
index 000000000..12480e922
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_manage.class.php
@@ -0,0 +1,197 @@
+<?php
+
+class ap_manage {
+
+ var $manager = NULL;
+ var $lang = array();
+ var $plugin = '';
+ var $downloaded = array();
+
+ function ap_manage(&$manager, $plugin) {
+ $this->manager = & $manager;
+ $this->plugin = $plugin;
+ $this->lang = & $manager->lang;
+ }
+
+ function process() {
+ return '';
+ }
+
+ function html() {
+ print $this->manager->locale_xhtml('admin_plugin');
+ $this->html_menu();
+ }
+
+ // build our standard menu
+ function html_menu($listPlugins = true) {
+ global $ID;
+
+ ptln('<div class="pm_menu">');
+
+ ptln('<div class="common">');
+ ptln(' <h2>'.$this->lang['download'].'</h2>');
+ ptln(' <form action="'.wl($ID).'" method="post">');
+ ptln(' <fieldset class="hidden">',4);
+ ptln(' <input type="hidden" name="do" value="admin" />');
+ ptln(' <input type="hidden" name="page" value="plugin" />');
+ formSecurityToken();
+ ptln(' </fieldset>');
+ ptln(' <fieldset>');
+ ptln(' <legend>'.$this->lang['download'].'</legend>');
+ ptln(' <label for="dw__url">'.$this->lang['url'].'<input name="url" id="dw__url" class="edit" type="text" maxlength="200" /></label>');
+ ptln(' <input type="submit" class="button" name="fn[download]" value="'.$this->lang['btn_download'].'" />');
+ ptln(' </fieldset>');
+ ptln(' </form>');
+ ptln('</div>');
+
+ if ($listPlugins) {
+ ptln('<h2>'.$this->lang['manage'].'</h2>');
+
+ ptln('<form action="'.wl($ID).'" method="post" class="plugins">');
+
+ ptln(' <fieldset class="hidden">');
+ ptln(' <input type="hidden" name="do" value="admin" />');
+ ptln(' <input type="hidden" name="page" value="plugin" />');
+ formSecurityToken();
+ ptln(' </fieldset>');
+
+ $this->html_pluginlist();
+
+ ptln(' <fieldset class="buttons">');
+ ptln(' <input type="submit" class="button" name="fn[enable]" value="'.$this->lang['btn_enable'].'" />');
+ ptln(' </fieldset>');
+
+ // ptln(' </div>');
+ ptln('</form>');
+ }
+
+ ptln('</div>');
+ }
+
+ function html_pluginlist() {
+ global $ID;
+ global $plugin_protected;
+
+ foreach ($this->manager->plugin_list as $plugin) {
+
+ $disabled = plugin_isdisabled($plugin);
+ $protected = in_array($plugin,$plugin_protected);
+
+ $checked = ($disabled) ? '' : ' checked="checked"';
+ $check_disabled = ($protected) ? ' disabled="disabled"' : '';
+
+ // determine display class(es)
+ $class = array();
+ if (in_array($plugin, $this->downloaded)) $class[] = 'new';
+ if ($disabled) $class[] = 'disabled';
+ if ($protected) $class[] = 'protected';
+
+ $class = count($class) ? ' class="'.join(' ', $class).'"' : '';
+
+ ptln(' <fieldset'.$class.'>');
+ ptln(' <legend>'.$plugin.'</legend>');
+ ptln(' <input type="checkbox" class="enable" name="enabled[]" id="dw__p_'.$plugin.'" value="'.$plugin.'"'.$checked.$check_disabled.' />');
+ ptln(' <h3 class="legend"><label for="dw__p_'.$plugin.'">'.$plugin.'</label></h3>');
+
+ $this->html_button($plugin, 'info', false, 6);
+ if (in_array('settings', $this->manager->functions)) {
+ $this->html_button($plugin, 'settings', !@file_exists(DOKU_PLUGIN.$plugin.'/settings.php'), 6);
+ }
+ $this->html_button($plugin, 'update', !$this->plugin_readlog($plugin, 'url'), 6);
+ $this->html_button($plugin, 'delete', $protected, 6);
+
+ ptln(' </fieldset>');
+ }
+ }
+
+ function html_button($plugin, $btn, $disabled=false, $indent=0) {
+ $disabled = ($disabled) ? 'disabled="disabled"' : '';
+ ptln('<input type="submit" class="button" '.$disabled.' name="fn['.$btn.']['.$plugin.']" value="'.$this->lang['btn_'.$btn].'" />',$indent);
+ }
+
+ /**
+ * Refresh plugin list
+ */
+ function refresh() {
+ global $config_cascade;
+
+ // expire dokuwiki caches
+ // touching local.php expires wiki page, JS and CSS caches
+ @touch(reset($config_cascade['main']['local']));
+
+ // update latest plugin date - FIXME
+ global $ID;
+ send_redirect(wl($ID,array('do'=>'admin','page'=>'plugin'),true, '&'));
+ }
+
+ /**
+ * Write a log entry to the given target directory
+ */
+ function plugin_writelog($target, $cmd, $data) {
+
+ $file = $target.'/manager.dat';
+
+ switch ($cmd) {
+ case 'install' :
+ $url = $data[0];
+ $date = date('r');
+ if (!$fp = @fopen($file, 'w')) return;
+ fwrite($fp, "installed=$date\nurl=$url\n");
+ fclose($fp);
+ break;
+
+ case 'update' :
+ $date = date('r');
+ if (!$fp = @fopen($file, 'a')) return;
+ fwrite($fp, "updated=$date\n");
+ fclose($fp);
+ break;
+ }
+ }
+
+ function plugin_readlog($plugin, $field) {
+ static $log = array();
+ $file = DOKU_PLUGIN.plugin_directory($plugin).'/manager.dat';
+
+ if (!isset($log[$plugin])) {
+ $tmp = @file_get_contents($file);
+ if (!$tmp) return '';
+ $log[$plugin] = & $tmp;
+ }
+
+ if ($field == 'ALL') {
+ return $log[$plugin];
+ }
+
+ $match = array();
+ if (preg_match_all('/'.$field.'=(.*)$/m',$log[$plugin], $match))
+ return implode("\n", $match[1]);
+
+ return '';
+ }
+
+ /**
+ * delete, with recursive sub-directory support
+ */
+ function dir_delete($path) {
+ if (!is_string($path) || $path == "") return false;
+
+ if (is_dir($path) && !is_link($path)) {
+ if (!$dh = @opendir($path)) return false;
+
+ while ($f = readdir($dh)) {
+ if ($f == '..' || $f == '.') continue;
+ $this->dir_delete("$path/$f");
+ }
+
+ closedir($dh);
+ return @rmdir($path);
+ } else {
+ return @unlink($path);
+ }
+
+ return false;
+ }
+
+
+}
diff --git a/lib/plugins/plugin/classes/ap_update.class.php b/lib/plugins/plugin/classes/ap_update.class.php
new file mode 100644
index 000000000..c43429a1b
--- /dev/null
+++ b/lib/plugins/plugin/classes/ap_update.class.php
@@ -0,0 +1,38 @@
+<?php
+require_once(DOKU_PLUGIN."/plugin/classes/ap_download.class.php");
+class ap_update extends ap_download {
+
+ var $overwrite = true;
+
+ function process() {
+ global $lang;
+
+ $plugin_url = $this->plugin_readlog($this->plugin, 'url');
+ $this->download($plugin_url, $this->overwrite);
+ return '';
+ }
+
+ function html() {
+ parent::html();
+
+ ptln('<div class="pm_info">');
+ ptln('<h2>'.$this->lang['updating'].'</h2>');
+
+ if ($this->manager->error) {
+ ptln('<div class="error">'.str_replace("\n","<br />", $this->manager->error).'</div>');
+ } else if (count($this->downloaded) == 1) {
+ ptln('<p>'.sprintf($this->lang['updated'],$this->downloaded[0]).'</p>');
+ } else if (count($this->downloaded)) { // more than one plugin in the download
+ ptln('<p>'.$this->lang['updates'].'</p>');
+ ptln('<ul>');
+ foreach ($this->downloaded as $plugin) {
+ ptln('<li><div class="li">'.$plugin.'</div></li>',2);
+ }
+ ptln('</ul>');
+ } else { // none found in download
+ ptln('<p>'.$this->lang['update_none'].'</p>');
+ }
+ ptln('</div>');
+ }
+}
+
diff --git a/lib/plugins/plugin/lang/af/lang.php b/lib/plugins/plugin/lang/af/lang.php
new file mode 100644
index 000000000..669fdd5ce
--- /dev/null
+++ b/lib/plugins/plugin/lang/af/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['btn_download'] = 'Af laai';
+$lang['btn_enable'] = 'Store';
+$lang['url'] = 'URL';
+$lang['unknown'] = 'unbekende';
+$lang['name'] = 'Naam:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Tipe:';
+$lang['www'] = 'Web-werf:';
diff --git a/lib/plugins/plugin/lang/ar/admin_plugin.txt b/lib/plugins/plugin/lang/ar/admin_plugin.txt
new file mode 100644
index 000000000..2ef9fd595
--- /dev/null
+++ b/lib/plugins/plugin/lang/ar/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== إدارة الإضافات ======
+
+على هذه الصفحة يمكنك إدارة كل ما يتعلق ب[[doku>plugins|إضافات]] دوكو ويكي. لتتمكن من تنزيل و تثبيت الإضافات يجب أن يكون دليل الاضافات قابلا للكتابة من خادوم الوب.
+
diff --git a/lib/plugins/plugin/lang/ar/lang.php b/lib/plugins/plugin/lang/ar/lang.php
new file mode 100644
index 000000000..fbc6d3c36
--- /dev/null
+++ b/lib/plugins/plugin/lang/ar/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['menu'] = 'إدارة الملحقات';
+$lang['download'] = 'نزّل و ثبت اضافة جديدة';
+$lang['manage'] = 'الإضافات المثبتة';
+$lang['btn_info'] = 'معلومات';
+$lang['btn_update'] = 'حدّث';
+$lang['btn_delete'] = 'احذف';
+$lang['btn_settings'] = 'إعدادات';
+$lang['btn_download'] = 'نزل';
+$lang['btn_enable'] = 'احفظ';
+$lang['url'] = 'رابط';
+$lang['installed'] = 'ثُبتت:';
+$lang['lastupdate'] = 'آخر تحديث:';
+$lang['source'] = 'المصدر:';
+$lang['unknown'] = 'مجهول';
+$lang['updating'] = 'تُحدث ...';
+$lang['updated'] = 'الاضافة %s حُدثت بنجاح';
+$lang['updates'] = 'الاضافة التالية حُدثت بنجاح';
+$lang['update_none'] = 'لا يوجد تحديثات.';
+$lang['deleting'] = 'تُحذف ... ';
+$lang['deleted'] = 'حُذفت الإضافة %s.';
+$lang['downloading'] = 'يُنزل ...';
+$lang['downloaded'] = 'الاضافة %s ثبتت بنجاح';
+$lang['downloads'] = 'الاضافة التالية ثبتت بنجاح:';
+$lang['download_none'] = 'لم يجد إضافة، أو ان هناك مشكلة غير معروفة أثناء التنزيل و التثبيت.';
+$lang['plugin'] = 'الإضافة:';
+$lang['components'] = 'المكون:';
+$lang['noinfo'] = 'لم تعطي الإضافة أية معلومة، قد تكون معطوبة.';
+$lang['name'] = 'الاسم :';
+$lang['date'] = 'التاريخ :';
+$lang['type'] = 'النوع :';
+$lang['desc'] = 'الوصف :';
+$lang['author'] = 'الكاتب :';
+$lang['www'] = 'الشابكة :';
+$lang['error'] = 'حث خطأ مجهول.';
+$lang['error_download'] = 'تعذر تنزيل ملف الاضافة: %s';
+$lang['error_badurl'] = 'اشتبه بعنوان خاطئ - تعذر الحصول على الاسم من العنوان';
+$lang['error_dircreate'] = 'تعذر إنشاء مجلد مؤقت للتنزيل';
+$lang['error_decompress'] = 'تعذر على مدير الاضافات فك ضغط الملف المُنزّل. قد يكون ذلك نتيجة لتنزيل خاطئ، في هذه الحالة أعد المحاولة; أو ان هيئة الضغط غير معروفة، في هذه الحالة عليك تنزيل و تثبيت الاضافة يدويا.';
+$lang['error_copy'] = 'كان هناك خطأ في نسخ ملف عند محاولة تثبيت ملفات للإضافة <em>%s</em>: قد يكون القرص ممتلئا أو أن صلاحيات الوصول للملف خاطئة. لربما نتج عن ذلك اضافة مثبته جزئيا تجعل نظام الويكي غير ثابت.';
+$lang['error_delete'] = 'كان هناك خطأ عند محاولة حذف الاضافة <em>%s</em>. السبب الاكثر احتمالا هو صلاحيات غير كافية على الملف أو المجلد';
+$lang['enabled'] = 'الاضافة %s فُعلت. ';
+$lang['notenabled'] = 'تعذر تفعيل الاضافة %s، تحقق من اذونات الملف.';
+$lang['disabled'] = 'عُطلت الإضافة %s.';
+$lang['notdisabled'] = 'تعذر تعطيل الإضافة %s، تحقق من اذونات الملف.';
diff --git a/lib/plugins/plugin/lang/bg/admin_plugin.txt b/lib/plugins/plugin/lang/bg/admin_plugin.txt
new file mode 100644
index 000000000..bad73e136
--- /dev/null
+++ b/lib/plugins/plugin/lang/bg/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Управление на приставките ======
+
+От тази страница можете на управлявате [[doku>plugins|приставките]] на Dokuwiki. За да свалите и инсталирате приставка, е необходимо писането в директорията .../lib/plugins/ да е позволено на сървъра.
diff --git a/lib/plugins/plugin/lang/bg/lang.php b/lib/plugins/plugin/lang/bg/lang.php
new file mode 100644
index 000000000..09ac35229
--- /dev/null
+++ b/lib/plugins/plugin/lang/bg/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * bulgarian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['menu'] = 'Управление на приставките';
+$lang['download'] = 'Сваляне и инсталиране на нова приставка';
+$lang['manage'] = 'Инсталирани приставки';
+$lang['btn_info'] = 'информация';
+$lang['btn_update'] = 'обновяване';
+$lang['btn_delete'] = 'изтриване';
+$lang['btn_settings'] = 'настройки';
+$lang['btn_download'] = 'Сваляне';
+$lang['btn_enable'] = 'Запис';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Инсталирана:';
+$lang['lastupdate'] = 'Актуализирана:';
+$lang['source'] = 'Източник:';
+$lang['unknown'] = 'непознат';
+$lang['updating'] = 'Актуализиране ...';
+$lang['updated'] = 'Приставката %s е качена успешно';
+$lang['updates'] = 'Следните приставки са актуализирани успешно';
+$lang['update_none'] = 'Не са намерени нови версии.';
+$lang['deleting'] = 'Изтриване ...';
+$lang['deleted'] = 'Приставката %s е изтрита успешно.';
+$lang['downloading'] = 'Сваляне ...';
+$lang['downloaded'] = 'Приставката %s е инсталирана успешно ';
+$lang['downloads'] = 'Следните приставки са инсталирани успешно:';
+$lang['download_none'] = 'Не са намерени приставки или е възникнала непозната грешка при свалянето и инсталирането.';
+$lang['plugin'] = 'Приставка:';
+$lang['components'] = 'Компоненти';
+$lang['noinfo'] = 'Приставка не върна информация, може да е повредена.';
+$lang['name'] = 'Име:';
+$lang['date'] = 'Дата:';
+$lang['type'] = 'Тип:';
+$lang['desc'] = 'Описание:';
+$lang['author'] = 'Автор:';
+$lang['www'] = 'Уебстраница:';
+$lang['error'] = 'Възникна непозната грешка.';
+$lang['error_download'] = 'Свалянето на приставката %s е невъзможно.';
+$lang['error_badurl'] = 'Предполагаем грешен адрес - не може да се определи име на файла от URL адреса';
+$lang['error_dircreate'] = 'Създаването на временна директория за сваляне не е възможно.';
+$lang['error_decompress'] = 'Разархивирането на сваленият файл е невъзможно. Вероятно е резултат от грешка при свалянето, в този случай трябва да опитате отново; или формата на компресия е непознат - тогава трябва да свалите и инсталирате приставката ръчно.';
+$lang['error_copy'] = 'Възникна грешка при копиране на файл по време на инсталиране на приставката <em>%s</em>: вероятно дискът е пълен или правата за достъп до файловете са грешни. Може да доведе до частично инсталирана приставка и да причини нестабилно функциониране на wiki-то ви.';
+$lang['error_delete'] = 'Възникна грешка при изтриването на приставката <em>%s</em>. Най-вероятната причина е в правата за достъп до файл или директория';
+$lang['enabled'] = 'Приставката %s е включена.';
+$lang['notenabled'] = 'Приставката %s не може да бъде включена, моля проверете правата за файловете.';
+$lang['disabled'] = 'Приставката %s е изключена.';
+$lang['notdisabled'] = 'Приставката %s не е изключена, моля проверете правата за файловете.';
+$lang['packageinstalled'] = 'Пакетът е инсталиран успешно (%d приставка: %s).';
diff --git a/lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt b/lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt
new file mode 100644
index 000000000..6b5a95838
--- /dev/null
+++ b/lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Gestor de plúgins ======
+
+Des d'esta pàgina pot gestionar tot lo relacionat en els [[doku>plugins|plúgins]] de DokuWiki. Per a poder descarregar i instalar un plúgin, el servidor web deu poder escriure en la carpeta de plúgins.
+
diff --git a/lib/plugins/plugin/lang/ca-valencia/lang.php b/lib/plugins/plugin/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..3fbdb134d
--- /dev/null
+++ b/lib/plugins/plugin/lang/ca-valencia/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * valencian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Bernat Arlandis i Mañó <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['menu'] = 'Gestor de plúgins';
+$lang['download'] = 'Descarregar i instalar un nou plúgin';
+$lang['manage'] = 'Plúgins instalats';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualisar';
+$lang['btn_delete'] = 'borrar';
+$lang['btn_settings'] = 'ajusts';
+$lang['btn_download'] = 'Descarregar';
+$lang['btn_enable'] = 'Guardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalat:';
+$lang['lastupdate'] = 'Última actualisació:';
+$lang['source'] = 'Font:';
+$lang['unknown'] = 'desconegut';
+$lang['updating'] = 'Actualisant ...';
+$lang['updated'] = 'Plúgin %s actualisat correctament';
+$lang['updates'] = 'Els següents plúgins s\'han actualisat correctament:';
+$lang['update_none'] = 'No s\'han trobat actualisacions.';
+$lang['deleting'] = 'Borrant ...';
+$lang['deleted'] = 'Plúgin %s borrat.';
+$lang['downloading'] = 'Descarregant ...';
+$lang['downloaded'] = 'Plúgin %s instalat correctament';
+$lang['downloads'] = 'Els següents plúgins s\'han instalat correctament:';
+$lang['download_none'] = 'No s\'han trobat plúgins o ha hagut algun problema descarregant i instalant.';
+$lang['plugin'] = 'Plúgin:';
+$lang['components'] = 'Components';
+$lang['noinfo'] = 'Este plúgin no ha tornat informació, pot ser invàlit.';
+$lang['name'] = 'Nom:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Classe:';
+$lang['desc'] = 'Descripció:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ha ocorregut un erro desconegut.';
+$lang['error_download'] = 'No es pot descarregar l\'archiu del plúgin: %s';
+$lang['error_badurl'] = 'Possible URL roïn - no es pot determinar el nom de l\'archiu a partir de la URL';
+$lang['error_dircreate'] = 'No es pot crear la carpeta temporal per a rebre descàrregues';
+$lang['error_decompress'] = 'El gestor de plúgins no ha pogut descomprimir l\'archiu descarregat. Açò pot ser degut a una descàrrega fallida, en eixe cas deuria intentar-ho de nou; o el format de compressió pot ser desconegut, en eixe cas necessitarà descarregar i instalar el plúgin manualment.';
+$lang['error_copy'] = 'Ha ocorregut un erro copiant archius a l\'instalar archius del plúgin <em>%s</em>: el disc podria estar ple o els permissos d\'accés a l\'archiu estar mal. El plúgin podria haver quedat parcialment instalat i deixar el wiki inestable.';
+$lang['error_delete'] = 'Ha ocorregut un erro intentant borrar el plúgin <em>%s</em>. La causa més provable és que els permissos d\'accés a l\'archiu o el directori no siguen suficients';
+$lang['enabled'] = 'Plúgin %s activat.';
+$lang['notenabled'] = 'No s\'ha pogut activar el plúgin %s, comprove els permissos dels archius.';
+$lang['disabled'] = 'Plúgin %s desactivat.';
+$lang['notdisabled'] = 'No s\'ha pogut desactivar el plúgin %s, comprove els permissos dels archius.';
diff --git a/lib/plugins/plugin/lang/ca/admin_plugin.txt b/lib/plugins/plugin/lang/ca/admin_plugin.txt
new file mode 100644
index 000000000..c21e3f502
--- /dev/null
+++ b/lib/plugins/plugin/lang/ca/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gestió de connectors ======
+
+En aquesta pàgina podeu gestionar tot allò referent als [[doku>plugins|connectors]] de Dokuwiki. Per a baixar i instal·lar connectors, cal que el servidor web tingui permís d'escriptura en la carpeta de connectors. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/ca/lang.php b/lib/plugins/plugin/lang/ca/lang.php
new file mode 100644
index 000000000..0e3ef05df
--- /dev/null
+++ b/lib/plugins/plugin/lang/ca/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ */
+$lang['menu'] = 'Gestió de connectors';
+$lang['download'] = 'Baixa i instal·la un nou connector';
+$lang['manage'] = 'Connectors instal·lats';
+$lang['btn_info'] = 'informació';
+$lang['btn_update'] = 'actualitza';
+$lang['btn_delete'] = 'suprimeix';
+$lang['btn_settings'] = 'paràmetres';
+$lang['btn_download'] = 'Baixa';
+$lang['btn_enable'] = 'Desa';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instal·lació:';
+$lang['lastupdate'] = 'Darrera actualitació:';
+$lang['source'] = 'Font:';
+$lang['unknown'] = 'desconegut';
+$lang['updating'] = 'S\'està actualitzant...';
+$lang['updated'] = 'El connector %s s\'ha actualitzat amb èxit.';
+$lang['updates'] = 'Els connectors següents s\'han actualitzat amb èxit';
+$lang['update_none'] = 'No s\'han trobat actualitzacions.';
+$lang['deleting'] = 'S\'està suprimint...';
+$lang['deleted'] = 'S\'ha suprimit el connector %s.';
+$lang['downloading'] = 'S\'està baixant...';
+$lang['downloaded'] = 'El connector %s s\'ha instal·lat amb èxit';
+$lang['downloads'] = 'Els connectors següents s\'han instal·lat amb èxit:';
+$lang['download_none'] = 'No s\'han trobat connectors, o hi ha hagut un problema desconegut durant el procés de baixada i instal·lació.';
+$lang['plugin'] = 'Connector:';
+$lang['components'] = 'Components';
+$lang['noinfo'] = 'Aquest connector no ha retornat informació. Potser no és vàlid.';
+$lang['name'] = 'Nom:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipus:';
+$lang['desc'] = 'Descripció:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'S\'ha produït un error desconegut.';
+$lang['error_download'] = 'No s\'ha pogut baixar el fitxer del connector: %s';
+$lang['error_badurl'] = 'L\'URL no sembla vàlid: no permet determinar el nom del fitxer';
+$lang['error_dircreate'] = 'No s\'ha pogut crear una carpeta temporal per rebre la baixada';
+$lang['error_decompress'] = 'El gestor de connectors no ha pogut descomprimir el fitxer baixat. Potser no s\'ha baixat correctament, en el qual cas podríeu tornar a intentar-ho. O el format de compressió podria ser desconegut, en el qual cas hauríeu de baixar i instal·lar el connector manualment.';
+$lang['error_copy'] = 'S\'ha produït un error de còpia de fitxers quan s\'estaven instal·lant els fitxers del connector <em>%s</em>: potser el disc està ple o els permisos d\'accés són incorrectes. Això pot haver causat una instal·lació incompleta del connector i per tant el vostre wiki pot haver quedat en un estat inestable.';
+$lang['error_delete'] = 'S\'ha produït un error quan s\'intentava suprimir el connector <em>%s</em>. La causa més probable d\'això són uns permisos d\'accés insuficients al fitxer o al directori. ';
+$lang['enabled'] = 'S\'ha habilitat el connector %s.';
+$lang['notenabled'] = 'No s\'ha pogut habilitar el connector %s. Comproveu els permisos dels fitxers.';
+$lang['disabled'] = 'S\'ha inhabilitat el connector %s.';
+$lang['notdisabled'] = 'No s\'ha pogut inhabilitar el connector %s. Comproveu els permisos dels fitxers.';
diff --git a/lib/plugins/plugin/lang/cs/admin_plugin.txt b/lib/plugins/plugin/lang/cs/admin_plugin.txt
new file mode 100644
index 000000000..6ebf1e78f
--- /dev/null
+++ b/lib/plugins/plugin/lang/cs/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Správa pluginů ======
+
+Na této stránce lze spravovat pluginy DokuWiki [[doku>plugins|plugins]]. Aby bylo možné stahovat a instalovat pluginy, musí mít webový server přístup pro zápis do adresáře //plugin//.
diff --git a/lib/plugins/plugin/lang/cs/lang.php b/lib/plugins/plugin/lang/cs/lang.php
new file mode 100644
index 000000000..0ccabf344
--- /dev/null
+++ b/lib/plugins/plugin/lang/cs/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Tomas Valenta <t.valenta@sh.cvut.cz>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['menu'] = 'Správa pluginů';
+$lang['download'] = 'Stáhnout a instalovat plugin';
+$lang['manage'] = 'Seznam instalovaných pluginů';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'aktualizovat';
+$lang['btn_delete'] = 'smazat';
+$lang['btn_settings'] = 'nastavení';
+$lang['btn_download'] = 'Stáhnout';
+$lang['btn_enable'] = 'Uložit';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalován:';
+$lang['lastupdate'] = 'Poslední aktualizace:';
+$lang['source'] = 'Zdroj:';
+$lang['unknown'] = 'neznámý';
+$lang['updating'] = 'Aktualizuji ...';
+$lang['updated'] = 'Modul %s úspěšně aktualizován';
+$lang['updates'] = 'Následující pluginy byly úspěšně aktualizovány';
+$lang['update_none'] = 'Žádné aktualizace nenalezeny.';
+$lang['deleting'] = 'Probíhá mazání ...';
+$lang['deleted'] = 'Plugin %s smazán.';
+$lang['downloading'] = 'Stahuji ...';
+$lang['downloaded'] = 'Plugin %s nainstalován';
+$lang['downloads'] = 'Následující pluginy byly úspěšně instalovány:';
+$lang['download_none'] = 'Žádné pluginy nebyly nenalezeny, nebo se vyskytla nějaká chyba při
+stahování a instalaci.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Součásti';
+$lang['noinfo'] = 'Plugin nevrátil žádné informace. Může být poškozen nebo špatný.';
+$lang['name'] = 'Jméno:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Popis:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Nastala neznámá chyba.';
+$lang['error_download'] = 'Nelze stáhnout soubor s pluginem: %s';
+$lang['error_badurl'] = 'URL je zřejmě chybná - nelze z ní určit název souboru';
+$lang['error_dircreate'] = 'Nelze vytvořit dočasný adresář ke stažení dat';
+$lang['error_decompress'] = 'Správce pluginů nemůže rozbalit stažený soubor. Toto může být způsobeno chybou při stahování. Můžete se pokusit stahování opakovat. Chyba může být také v kompresním formátu souboru. V tom případě bude nutné stáhnout a nainstalovat plugin ručně.';
+$lang['error_copy'] = 'Došlo k chybě při instalaci pluginu <em>%s</em>. Je možné, že na disku není volné místo, nebo mohou být špatně nastavena přístupová práva. Pozor, mohlo dojít k částečné a tudíž chybné instalaci pluginu a tím může být ohrožena stabilita wiki.';
+$lang['error_delete'] = 'Došlo k chybě při pokusu o smazání pluginu <em>%s</em>. Nejspíše je chyba v nastavení přístupových práv k některým souborům či adresářům.';
+$lang['enabled'] = 'Plugin %s aktivován.';
+$lang['notenabled'] = 'Plugin %s nelze aktivovat, zkontrolujte práva k souborům.';
+$lang['disabled'] = 'Plugin %s deaktivován.';
+$lang['notdisabled'] = 'Plugin %s nelze deaktivovat, zkontrolujte práva k souborům.';
+$lang['packageinstalled'] = 'Balíček pluginů (%d plugin(ů): %s) úspěšně nainstalován.';
diff --git a/lib/plugins/plugin/lang/da/admin_plugin.txt b/lib/plugins/plugin/lang/da/admin_plugin.txt
new file mode 100644
index 000000000..300b6618b
--- /dev/null
+++ b/lib/plugins/plugin/lang/da/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Udvidelsesstyring ======
+
+På denne side kan du kontrollere alle Dokuwikis [[doku>plugins|udvidelser]]. For at hente og opsætte en udvidelse, må din udvidelsesmappe kunne skrives til af serveren.
+
+
diff --git a/lib/plugins/plugin/lang/da/lang.php b/lib/plugins/plugin/lang/da/lang.php
new file mode 100644
index 000000000..841d246df
--- /dev/null
+++ b/lib/plugins/plugin/lang/da/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Lars Næsbye Christensen <larsnaesbye@stud.ku.dk>
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['menu'] = 'Håndter udvidelser';
+$lang['download'] = 'Hent og tilføj ny udvidelse';
+$lang['manage'] = 'Tilføjede udvidelser';
+$lang['btn_info'] = 'oplysninger';
+$lang['btn_update'] = 'opdater';
+$lang['btn_delete'] = 'slet';
+$lang['btn_settings'] = 'indstillinger';
+$lang['btn_download'] = 'Hent';
+$lang['btn_enable'] = 'Gem';
+$lang['url'] = 'URL-adresse';
+$lang['installed'] = 'Tliføjet:';
+$lang['lastupdate'] = 'Sidst opdateret:';
+$lang['source'] = 'Kilde:';
+$lang['unknown'] = 'ukendt';
+$lang['updating'] = 'Opdaterer ...';
+$lang['updated'] = 'Udvidelse %s blev korrekt opdateret';
+$lang['updates'] = 'De følgende udvidelser blev opdateret korrekt:';
+$lang['update_none'] = 'Ingen opdateringer fundet.';
+$lang['deleting'] = 'Sletter ...';
+$lang['deleted'] = 'Udvidelsen %s slettet.';
+$lang['downloading'] = 'Henter ...';
+$lang['downloaded'] = 'Udvidelse %s blev korrekt installeret';
+$lang['downloads'] = 'De følgende udvidelser blev installeret korrekt:';
+$lang['download_none'] = 'Ingen udvidelser blev fundet, eller en ukendt fejl opstod under hentning og opsætning';
+$lang['plugin'] = 'Udvidelse:';
+$lang['components'] = 'Komponenter';
+$lang['noinfo'] = 'Denne udvidelse videregav ingen oplysninger. Den kan være fejlagtig.';
+$lang['name'] = 'Navn:';
+$lang['date'] = 'Dato:';
+$lang['type'] = 'Type:';
+$lang['desc'] = 'Beskrivelse:';
+$lang['author'] = 'Programmør:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'En ukendt fejl opstod.';
+$lang['error_download'] = 'Kunne ikke hente udvidelsesfilen: %s';
+$lang['error_badurl'] = 'Muligvis dårlig netadresse; kunne ikke hente filnavn fra adressen.';
+$lang['error_dircreate'] = 'Kunne ikke oprette midlertidig mappe til hentning';
+$lang['error_decompress'] = 'Udvidelseshåndtering kunne ikke udpakke den hentede fil. Det kan skyldes et fejlagtigt download, i hvilket fald du må prøve igen. Komprimeringsformatet kan også være ukendt, hvorved du du vil være nødt til at hente og opsætte udvidelsen manuelt.';
+$lang['error_copy'] = 'Der opstod en filkopieringsfejl under forsøget på at installere filerne til udvidelsen <em>%s</em>: Disken kan være fuld eller filadgangsrettighederne kan være forkert sat. Dette kan have ført til en delvist installeret udvidelse og efterladt din wiki-opsætning ustabil.';
+$lang['error_delete'] = 'Der opstod en fejl ved forsøget på at slette udvidelsen <em>%s</em>. Dette skyldes sandsynligvis utilstrækkelig adgang til filer eller mapper.';
+$lang['enabled'] = 'Udvidelsen %s blev aktiveret.';
+$lang['notenabled'] = 'Udvidelsen %s kunne ikke aktiveres. Kontroller filtilladelser.';
+$lang['disabled'] = 'Udvidelsen %s blev ikke aktiveret.';
+$lang['notdisabled'] = 'Udvidelsen %s kunne ikke aktiveres. Kontroller filtilladelser.';
diff --git a/lib/plugins/plugin/lang/de-informal/admin_plugin.txt b/lib/plugins/plugin/lang/de-informal/admin_plugin.txt
new file mode 100644
index 000000000..576797d57
--- /dev/null
+++ b/lib/plugins/plugin/lang/de-informal/admin_plugin.txt
@@ -0,0 +1,3 @@
+===== Erweiterungsmanagement =====
+
+Auf dieser Seite kannst du alles anpassen was mit den DokuWiki [[doku>plugins|Erweiterungen]] zu tun hat. Der Ordner der Erweiterungen muss für den Webserver beschreibbar sein, um Erweiterungen herunterladen und installieren zu können. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/de-informal/lang.php b/lib/plugins/plugin/lang/de-informal/lang.php
new file mode 100644
index 000000000..abcdf2c83
--- /dev/null
+++ b/lib/plugins/plugin/lang/de-informal/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Plugins verwalten';
+$lang['download'] = 'Herunterladen und installieren einer neuen Erweiterung';
+$lang['manage'] = 'Installierte Erweiterungen';
+$lang['btn_info'] = 'Information';
+$lang['btn_update'] = 'aktualisieren';
+$lang['btn_delete'] = 'löschen';
+$lang['btn_settings'] = 'Einstellungen';
+$lang['btn_download'] = 'Herunterladen';
+$lang['btn_enable'] = 'Speichern';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installiert:';
+$lang['lastupdate'] = 'Letzte Aktualisierung:';
+$lang['source'] = 'Quellen:';
+$lang['unknown'] = 'unbekannt';
+$lang['updating'] = 'Aktualisiere...';
+$lang['updated'] = 'Erweiterung %s wurde erfolgreich aktualisiert.';
+$lang['updates'] = 'Die folgenden Erweiterungen wurden erfolgreich aktualisiert.';
+$lang['update_none'] = 'Keine Aktualisierungen gefunden.';
+$lang['deleting'] = 'Lösche...';
+$lang['deleted'] = 'Erweiterung %s wurde gelöscht.';
+$lang['downloading'] = 'Herunterladen...';
+$lang['downloaded'] = 'Erweiterung %s wurde erfolgreich installiert';
+$lang['downloads'] = 'Die folgenden Erweiterungen wurden erfolgreich installiert:';
+$lang['download_none'] = 'Keine Erweiterungen gefunden oder es trat ein unbekanntest Problem beim Herunterladen und Installieren auf.';
+$lang['plugin'] = 'Erweiterung:';
+$lang['components'] = 'Komponenten';
+$lang['noinfo'] = 'Diese Erweiterung gab keine Information zurück - sie könnte ungültig sein.';
+$lang['name'] = 'Name:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Beschreibung:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Internet:';
+$lang['error'] = 'Es ist ein unbekannter Fehler aufgetreten.';
+$lang['error_download'] = 'Nicht möglich die Erweiterung herunterzuladen: %s';
+$lang['error_badurl'] = 'Vermute schlechte URL - nicht möglich den Dateinamen aus der URL zu ermitteln';
+$lang['error_dircreate'] = 'Nicht möglich einen temporären Ordner zu erstellen um den Download zu empfangen.';
+$lang['error_decompress'] = 'Dem Erweiterungsmanager war es nicht möglich die heruntergeladene Datei zu dekomprimieren. Dies kann an einem defekten Download liegen, in diesem Fall sollten Sie es erneut versuchen; oder das Format mit dem die Datei komprimiert ist, ist unbekannt, da müssen Sie die Erweiterung manuell herunterladen und installieren. ';
+$lang['error_copy'] = 'Es trat ein Dateifehler beim Kopieren der Installationsdateien für die Erweiterung <em>%s</em> auf: Die Festplatte könnte voll oder die Zugriffsrechte verweigert worden sein. Dies führt zu einer teilweise installierten Erweiterung und belässt dein Wiki in einem instabilen Zustand.';
+$lang['error_delete'] = 'Es trat ein Fehler beim Löschen der Erweiterung <em>%s</em> auf. Die wahrscheinlichste Ursache ist eine unzureichende Datei- oder Ordnerzugriffserlaubnis.';
+$lang['enabled'] = 'Erweiterung %s aktiviert.';
+$lang['notenabled'] = 'Erweiterung %s konnte nicht aktiviert werden. Überprüfen sie die Zugriffsberechtigung der Datei.';
+$lang['disabled'] = 'Erweiterung %s deaktiviert.';
+$lang['notdisabled'] = 'Erweiterung %s konnte nicht deaktiviert werden - überprüfe Dateiberechtigungen';
+$lang['packageinstalled'] = 'Plugin-Paket (%d Plugin(s): %s) erfolgreich installiert.';
diff --git a/lib/plugins/plugin/lang/de/admin_plugin.txt b/lib/plugins/plugin/lang/de/admin_plugin.txt
new file mode 100644
index 000000000..f3b2caa0c
--- /dev/null
+++ b/lib/plugins/plugin/lang/de/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Verwaltung der Plugins ======
+
+Auf dieser Seite kannst du alles machen, was mit DokuWiki [[doku>plugins|Plugins]] zu tun hat. Um Plugins automatisch herunterladen und installieren zu können, muss der Webserver im Plugin-Ordner schreiben dürfen.
+
+
diff --git a/lib/plugins/plugin/lang/de/lang.php b/lib/plugins/plugin/lang/de/lang.php
new file mode 100644
index 000000000..8708d7836
--- /dev/null
+++ b/lib/plugins/plugin/lang/de/lang.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * german language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Plugins verwalten';
+$lang['download'] = 'Neues Plugin herunterladen und installieren';
+$lang['manage'] = 'Installierte Plugins';
+$lang['btn_info'] = 'Info';
+$lang['btn_update'] = 'Update';
+$lang['btn_delete'] = 'Löschen';
+$lang['btn_settings'] = 'Einstellungen';
+$lang['btn_download'] = 'Herunterladen';
+$lang['btn_enable'] = 'Speichern';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installiert:';
+$lang['lastupdate'] = 'Letzte Version:';
+$lang['source'] = 'Quelle:';
+$lang['unknown'] = 'unbekannt';
+$lang['updating'] = 'Lade Update ...';
+$lang['updated'] = 'Update von Plugin %s erfolgreich installiert';
+$lang['updates'] = 'Die folgenden Plugins wurden erfolgreich aktualisiert';
+$lang['update_none'] = 'Keine Updates gefunden.';
+$lang['deleting'] = 'Löschen ...';
+$lang['deleted'] = 'Plugin %s gelöscht.';
+$lang['downloading'] = 'Lade herunter ...';
+$lang['downloaded'] = 'Plugin %s erfolgreich installiert';
+$lang['downloads'] = 'Die folgenden Plugins wurden erfolgreich installiert:';
+$lang['download_none'] = 'Keine Plugins gefunden oder es trat ein Fehler beim Herunterladen auf.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Komponenten';
+$lang['noinfo'] = 'Dieses Plugin liefert keine Informationen, möglicherweise ist es fehlerhaft.';
+$lang['name'] = 'Name:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Beschreibung:';
+$lang['author'] = 'Entwickler:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ein unbekannter Fehler ist aufgetreten.';
+$lang['error_download'] = 'Konnte das Plugin %s nicht installieren';
+$lang['error_badurl'] = 'Wahrscheinlich ungültige URL, konnte keinen Dateinamen ausfindig machen';
+$lang['error_dircreate'] = 'Konnte keinen temporären Ordner für die Downloads erstellen';
+$lang['error_decompress'] = 'Der Plugin Manager konnte das Plugin-Archiv nicht entpacken. Entweder ist der Download fehlerhaft oder das Komprimierungsverfahren wird nicht unterstützt. Bitte versuchen Sie es erneut oder downloaden und installieren Sie das Plugin manuell.';
+$lang['error_copy'] = 'Beim Kopieren der Dateien des Plugins trat ein Fehler auf <em>%s</em>: möglicherweise ist die Festplatte voll oder die Dateiberechtigungen falsch. Möglicherweise wurde das Plugin nur teilweise installiert. Sie sollten das Plugin manuell entfernen um Instabilitäten zu vermeiden.';
+$lang['error_delete'] = 'Es gab einem Fehler beim Versuch das Plugin zu löschen <em>%s</em>. Dies liegt wahrscheinlich an fehlenden Dateiberechtigungen.';
+$lang['enabled'] = 'Plugin %s wurde aktiviert.';
+$lang['notenabled'] = 'Plugin %s konnte nicht aktiviert werden, überprüfen Sie die Dateirechte.';
+$lang['disabled'] = 'Plugin %s wurde deaktiviert.';
+$lang['notdisabled'] = 'Plugin %s konnte nicht deaktiviert werden, überprüfen Sie die Dateirechte.';
+$lang['packageinstalled'] = 'Plugin-Paket (%d Plugin(s): %s) erfolgreich installiert.';
diff --git a/lib/plugins/plugin/lang/el/admin_plugin.txt b/lib/plugins/plugin/lang/el/admin_plugin.txt
new file mode 100644
index 000000000..8b292935d
--- /dev/null
+++ b/lib/plugins/plugin/lang/el/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Διαχείριση Επεκτάσεων ======
+
+Σε αυτή την σελίδα μπορείτε να διαχειριστείτε τις [[doku>plugins|επεκτάσεις]] του Dokuwiki σας. Για να μπορέσετε να εγκαταστήσετε νέες επεκτάσεις, ο αντίστοιχος φάκελος συστήματος θα πρέπει να είναι εγγράψιμος από τον χρήστη κάτω από τον οποίο εκτελείται η εφαρμογή του εξυπηρετητή σας.
+
+
diff --git a/lib/plugins/plugin/lang/el/lang.php b/lib/plugins/plugin/lang/el/lang.php
new file mode 100644
index 000000000..bd6dc2013
--- /dev/null
+++ b/lib/plugins/plugin/lang/el/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['menu'] = 'Διαχείριση Επεκτάσεων';
+$lang['download'] = 'Κατεβάστε και εγκαταστήστε μια νέα επέκταση (plugin)';
+$lang['manage'] = 'Εγκατεστημένες επεκτάσεις';
+$lang['btn_info'] = 'πληροφορίες';
+$lang['btn_update'] = 'ενημέρωση';
+$lang['btn_delete'] = 'διαγραφή';
+$lang['btn_settings'] = 'ρυθμίσεις';
+$lang['btn_download'] = 'Μεταφόρτωση';
+$lang['btn_enable'] = 'Αποθήκευση';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Εγκατεστημένη:';
+$lang['lastupdate'] = 'Τελευταία ενημέρωση:';
+$lang['source'] = 'Προέλευση:';
+$lang['unknown'] = 'άγνωστο';
+$lang['updating'] = 'Σε διαδικασία ενημέρωσης ...';
+$lang['updated'] = 'Η επέκταση %s ενημερώθηκε με επιτυχία';
+$lang['updates'] = 'Οι παρακάτω επεκτάσεις ενημερώθηκαν με επιτυχία:';
+$lang['update_none'] = 'Δεν βρέθηκαν ενημερώσεις.';
+$lang['deleting'] = 'Σε διαδικασία διαγραφής ...';
+$lang['deleted'] = 'Η επέκταση %s διαγράφηκε.';
+$lang['downloading'] = 'Σε διαδικασία μεταφόρτωσης ...';
+$lang['downloaded'] = 'Η επέκταση %s εγκαταστάθηκε με επιτυχία';
+$lang['downloads'] = 'Οι παρακάτω επεκτάσεις εγκαταστάθηκαν με επιτυχία:';
+$lang['download_none'] = 'Δεν βρέθηκαν επεκτάσεις ή εμφανίστηκε κάποιο πρόβλημα κατά την σχετική διαδικασία.';
+$lang['plugin'] = 'Επέκταση:';
+$lang['components'] = 'Συστατικά';
+$lang['noinfo'] = 'Αυτή η επέκταση δεν επέστρεψε κάποια πληροφορία - η επέκταση μπορεί να μην λειτουργεί κανονικά.';
+$lang['name'] = 'Όνομα:';
+$lang['date'] = 'Ημερομηνία:';
+$lang['type'] = 'Τύπος:';
+$lang['desc'] = 'Περιγραφή:';
+$lang['author'] = 'Συγγραφέας:';
+$lang['www'] = 'Διεύθυνση στο διαδίκτυο:';
+$lang['error'] = 'Εμφανίστηκε άγνωστο σφάλμα.';
+$lang['error_download'] = 'Δεν είναι δυνατή η μεταφόρτωση του αρχείου: %s';
+$lang['error_badurl'] = 'Το URL είναι μάλλον λανθασμένο - είναι αδύνατον να εξαχθεί το όνομα αρχείου από αυτό το URL';
+$lang['error_dircreate'] = 'Δεν είναι δυνατή η δημιουργία ενός προσωρινού φακέλου αποθήκευσης των μεταφορτώσεων';
+$lang['error_decompress'] = 'Δεν είναι δυνατή η αποσυμπίεση των μεταφορτώσεων. Αυτό μπορεί να οφείλεται σε μερική λήψη των μεταφορτώσεων, οπότε θα πρέπει να επαναλάβετε την διαδικασία ή το σύστημά σας δεν μπορεί να διαχειριστεί το συγκεκριμένο είδος συμπίεσης, οπότε θα πρέπει να εγκαταστήσετε την επέκταση χειροκίνητα.';
+$lang['error_copy'] = 'Εμφανίστηκε ένα σφάλμα αντιγραφής αρχείων κατά την διάρκεια εγκατάστασης της επέκτασης <em>%s</em>: ο δίσκος μπορεί να είναι γεμάτος ή να μην είναι σωστά ρυθμισμένα τα δικαιώματα πρόσβασης. Αυτό το γεγονός μπορεί να οδήγησε σε μερική εγκατάσταση της επέκτασης και άρα η DokuWiki εγκατάστασή σας να εμφανίσει προβλήματα σταθερότητας.';
+$lang['error_delete'] = 'Εμφανίστηκε ένα σφάλμα κατά την διαδικασία διαγραφής της επέκτασης <em>%s</em>. Η πιθανότερη αιτία είναι να μην είναι σωστά ρυθμισμένα τα δικαιώματα πρόσβασης.';
+$lang['enabled'] = 'Η επέκταση %s ενεργοποιήθηκε.';
+$lang['notenabled'] = 'Η επέκταση %s δεν μπορεί να ενεργοποιηθεί. Ελέγξτε τα δικαιώματα πρόσβασης.';
+$lang['disabled'] = 'Η επέκταση %s απενεργοποιήθηκε.';
+$lang['notdisabled'] = 'Η επέκταση %s δεν μπορεί να απενεργοποιηθεί. Ελέγξτε τα δικαιώματα πρόσβασης.';
+$lang['packageinstalled'] = 'Το πακέτο της επέκτασης (%d επέκταση(εις): %s) εγκαστήθηκε επιτυχημένα.';
diff --git a/lib/plugins/plugin/lang/en/admin_plugin.txt b/lib/plugins/plugin/lang/en/admin_plugin.txt
new file mode 100644
index 000000000..cb23b1e02
--- /dev/null
+++ b/lib/plugins/plugin/lang/en/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Plugin Management ======
+
+On this page you can manage everything to do with Dokuwiki [[doku>plugins|plugins]]. To be able to download and install a plugin your plugin folder must be writeable by the webserver.
+
+
diff --git a/lib/plugins/plugin/lang/en/lang.php b/lib/plugins/plugin/lang/en/lang.php
new file mode 100644
index 000000000..87570a708
--- /dev/null
+++ b/lib/plugins/plugin/lang/en/lang.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+
+$lang['menu'] = 'Manage Plugins';
+
+// custom language strings for the plugin
+$lang['download'] = "Download and install a new plugin";
+$lang['manage'] = "Installed Plugins";
+
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'update';
+$lang['btn_delete'] = 'delete';
+$lang['btn_settings'] = 'settings';
+$lang['btn_download'] = 'Download';
+$lang['btn_enable'] = 'Save';
+
+$lang['url'] = 'URL';
+
+$lang['installed'] = 'Installed:';
+$lang['lastupdate'] = 'Last updated:';
+$lang['source'] = 'Source:';
+$lang['unknown'] = 'unknown';
+
+// ..ing = header message
+// ..ed = success message
+
+$lang['updating'] = 'Updating ...';
+$lang['updated'] = 'Plugin %s updated successfully';
+$lang['updates'] = 'The following plugins have been updated successfully';
+$lang['update_none'] = 'No updates found.';
+
+$lang['deleting'] = 'Deleting ...';
+$lang['deleted'] = 'Plugin %s deleted.';
+
+$lang['downloading'] = 'Downloading ...';
+$lang['downloaded'] = 'Plugin %s installed successfully';
+$lang['downloads'] = 'The following plugins have been installed successfully:';
+$lang['download_none'] = 'No plugins found, or there has been an unknown problem during downloading and installing.';
+
+// info titles
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Components';
+$lang['noinfo'] = 'This plugin returned no information, it may be invalid.';
+$lang['name'] = 'Name:';
+$lang['date'] = 'Date:';
+$lang['type'] = 'Type:';
+$lang['desc'] = 'Description:';
+$lang['author'] = 'Author:';
+$lang['www'] = 'Web:';
+
+// error messages
+$lang['error'] = 'An unknown error occurred.';
+$lang['error_download'] = 'Unable to download the plugin file: %s';
+$lang['error_badurl'] = 'Suspect bad url - unable to determine file name from the url';
+$lang['error_dircreate'] = 'Unable to create temporary folder to receive download';
+$lang['error_decompress'] = 'The plugin manager was 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 the plugin manually.';
+$lang['error_copy'] = 'There was a file copy error while attempting to install files for plugin '.
+ '<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['error_delete'] = 'There was an error while attempting to delete plugin <em>%s</em>. '.
+ 'The most probably cause is insufficient file or directory access permissions';
+
+$lang['enabled'] = 'Plugin %s enabled.';
+$lang['notenabled'] = 'Plugin %s could not be enabled, check file permissions.';
+$lang['disabled'] = 'Plugin %s disabled.';
+$lang['notdisabled'] = 'Plugin %s could not be disabled, check file permissions.';
+$lang['packageinstalled'] = 'Plugin package (%d plugin(s): %s) successfully installed.';
+
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/plugin/lang/eo/admin_plugin.txt b/lib/plugins/plugin/lang/eo/admin_plugin.txt
new file mode 100644
index 000000000..8cc59843b
--- /dev/null
+++ b/lib/plugins/plugin/lang/eo/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Administrado de Kromaĵoj ======
+
+En tiu ĉi paĝo vi povas administri ĉion pri DokuWiki-aj [[doku&gt;plugins|kromaĵoj]]. Por sukcesi elŝuti kaj instali kromaĵon, via dosierujo de kromaĵoj devas esti konservebla por la retservilo.
diff --git a/lib/plugins/plugin/lang/eo/lang.php b/lib/plugins/plugin/lang/eo/lang.php
new file mode 100644
index 000000000..ab9af73e1
--- /dev/null
+++ b/lib/plugins/plugin/lang/eo/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas (cxe) gmail (punkto) com>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['menu'] = 'Administri Kromaĵojn';
+$lang['download'] = 'Elŝuti kaj instali novan kromaĵon';
+$lang['manage'] = 'Instalitaj kromaĵoj';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'ĝisdatigo';
+$lang['btn_delete'] = 'forigi';
+$lang['btn_settings'] = 'agordoj';
+$lang['btn_download'] = 'Elŝuti';
+$lang['btn_enable'] = 'Konservi';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalite:';
+$lang['lastupdate'] = 'Laste ĝisdatigite:';
+$lang['source'] = 'Fonto:';
+$lang['unknown'] = 'nekonate';
+$lang['updating'] = 'Ĝisdatiganta ...';
+$lang['updated'] = 'Kromaĵo %s estas sukcese ĝisdatigita';
+$lang['updates'] = 'La jenaj kromaĵoj estas sukcese ĝisdatigitaj';
+$lang['update_none'] = 'Neniu ĝisdatigo troviĝas.';
+$lang['deleting'] = 'Foriganta ...';
+$lang['deleted'] = 'Kromaĵo %s estas forigita.';
+$lang['downloading'] = 'Elŝutanta ...';
+$lang['downloaded'] = 'La kromaĵo %s estas sukcese instalita';
+$lang['downloads'] = 'La jenaj kromaĵoj estas sukcese instalitaj:';
+$lang['download_none'] = 'Neniu kromaĵo troveblas, aŭ eble okazis nekonata problemo dum elŝuto kaj instalo.';
+$lang['plugin'] = 'Kromaĵo:';
+$lang['components'] = 'Komponeroj';
+$lang['noinfo'] = 'Tiu ĉi kromaĵo liveris neniun informon: eble ĝi ne validas.';
+$lang['name'] = 'Nomo:';
+$lang['date'] = 'Dato:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Priskribo:';
+$lang['author'] = 'Aŭtoro:';
+$lang['www'] = 'Retpaĝo:';
+$lang['error'] = 'Nekonata eraro okazis.';
+$lang['error_download'] = 'Maleblas elŝuti la kromaĵan dosieron: %s';
+$lang['error_badurl'] = 'Suspektinda malbona URL - maleblas difini la dosieran nomon el la URL';
+$lang['error_dircreate'] = 'Maleblas krei provizoran dosierujon por ricevi elŝutaĵon';
+$lang['error_decompress'] = 'La administrilo de kromaĵoj ne kapablis malkompakti la elŝutitan dosieron. Tio povas esti pro malkompleta elŝuto, tiaokaze vi devus provi refoje; aŭ eble la kompakta formato ne estas konata, tiaokaze vi bezonos elŝuti kaj instali la kromaĵon permane.';
+$lang['error_copy'] = 'Okazis eraro de dosierkopio dum provo instali dosierojn por la kromaĵo &lt;em&gt;%s&lt;/em&gt;: la disko povus esti plenplena aŭ aliro-rajtoj povus esti misdifinitaj. Tio povus rezulti en malkomplete instalita kromaĵo kaj igi vian vikion malstabila.';
+$lang['error_delete'] = 'Okazis eraro dum provo forigi la kromaĵon &lt;em&gt;%s&lt;/em&gt;. Plejprobable tio sekvas de nesufiĉa rajto por aliri la dosieron aŭ ties ujon.';
+$lang['enabled'] = 'La kromaĵo %s estas ebligita.';
+$lang['notenabled'] = 'La kromaĵo %s ne povis esti ebligita, kontrolu dosier-permesojn.';
+$lang['disabled'] = 'La kromaĵo %s estas malebligita.';
+$lang['notdisabled'] = 'La kromaĵo %s ne povis esti malebligita, kontrolu dosier-permesojn.';
+$lang['packageinstalled'] = 'Kromaĵa pakaĵo (%d kromaĵo(j): %s) sukcese instalitaj.';
diff --git a/lib/plugins/plugin/lang/es/admin_plugin.txt b/lib/plugins/plugin/lang/es/admin_plugin.txt
new file mode 100644
index 000000000..973789f03
--- /dev/null
+++ b/lib/plugins/plugin/lang/es/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Administración de Plugin (agregados) ======
+
+En esta página tu puedes administrar todo lo que tenga que ver con los [[doku>plugins|plugins]] de Dokuwiki. Para poder descargar e instalar un plugin el usuario correspondiente al servidor de web debe poder escribir en el directorio de plugins.
diff --git a/lib/plugins/plugin/lang/es/lang.php b/lib/plugins/plugin/lang/es/lang.php
new file mode 100644
index 000000000..ac548245b
--- /dev/null
+++ b/lib/plugins/plugin/lang/es/lang.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * spanish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Miguel Pagano <miguel.pagano@gmail.com>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['menu'] = 'Administración de Plugins';
+$lang['download'] = 'Descargar e instalar un nuevo plugin';
+$lang['manage'] = 'Plugins instalados';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualizar';
+$lang['btn_delete'] = 'borrar';
+$lang['btn_settings'] = 'configuraciones';
+$lang['btn_download'] = 'Descargar';
+$lang['btn_enable'] = 'Guardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalado:';
+$lang['lastupdate'] = 'Última actualización:';
+$lang['source'] = 'Origen:';
+$lang['unknown'] = 'desconocido';
+$lang['updating'] = 'Actualizando ...';
+$lang['updated'] = 'El plugin %s ha sido actualizado con éxito';
+$lang['updates'] = 'Los siguientes plugins han sido actualizados con éxito';
+$lang['update_none'] = 'No se encontraron actualizaciones.';
+$lang['deleting'] = 'Eliminando ...';
+$lang['deleted'] = 'El plugin %s ha sido eliminado.';
+$lang['downloading'] = 'Descargando ...';
+$lang['downloaded'] = 'El plugin %s ha sido instalado con éxito';
+$lang['downloads'] = 'Los siguientes plugins han sido instalados con éxito:';
+$lang['download_none'] = 'No se han encontrado plugins, o hubo algún problema durante la descarga o la instalación.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Componentes';
+$lang['noinfo'] = 'Este plugin no devolvió información, puede ser inválido.';
+$lang['name'] = 'Nombre:';
+$lang['date'] = 'Fecha:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descripción:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ha ocurrido un error desconocido.';
+$lang['error_download'] = 'Incapaz de descargar el archivo del plugin: %s';
+$lang['error_badurl'] = 'Se sospecha que la URL es incorrecta - incapaz de determinar el nombre del archivo a partir de la URL.';
+$lang['error_dircreate'] = 'Incapaz de crear el directorio temporal para la descarga';
+$lang['error_decompress'] = 'El administrador de plugins fue incapaz de descomprimir el fichero descargado. Esto puede ser por una descarga errónea, en cuyo caso debieras intentar nuevamente; o el formato de compresión es desconocido, en este caso deberás descargar e instalar el plugin manualmente.';
+$lang['error_copy'] = 'Hubo un error al copiar el fichero mientras se intentaban instalar ficheros para el plugin <em>%s</em>: el disco puede estar lleno o los permisos del fichero pueden ser incorrectos. Esto puede haber terminado con una instalación parcial del plugin y haber dejado la instalación del wiki en una situación inestable';
+$lang['error_delete'] = 'Hubo un error al intentar eliminar el plugin <em>%s</em>. La causa más probable es que no se cuente con los permisos necesarios en el fichero o en el directorio';
+$lang['enabled'] = 'Plugin %s habilitado.';
+$lang['notenabled'] = 'Plugin %s no puede ser habilitado, verifica los permisos del archivo.';
+$lang['disabled'] = 'Plugin %s desabilitado.';
+$lang['notdisabled'] = 'Plugin %s no puede ser desabilitado, verifica los permisos de archivo.';
+$lang['packageinstalled'] = 'Plugin (%d plugin(s): %s) instalado exitosamente.';
diff --git a/lib/plugins/plugin/lang/et/lang.php b/lib/plugins/plugin/lang/et/lang.php
new file mode 100644
index 000000000..088acf39b
--- /dev/null
+++ b/lib/plugins/plugin/lang/et/lang.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
+$lang['manage'] = 'Paigaldatud pluginad';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'uuenda';
+$lang['btn_delete'] = 'kustuta';
+$lang['btn_settings'] = 'seaded';
+$lang['btn_download'] = 'Lae alla';
+$lang['btn_enable'] = 'Salvesta';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Paigaldatud:';
+$lang['lastupdate'] = 'Viimati uuendatud:';
+$lang['source'] = 'Allikas:';
+$lang['unknown'] = 'tundmatu';
+$lang['updating'] = 'Uuendamine ...';
+$lang['update_none'] = 'Uuendusi ei leitud.';
+$lang['deleting'] = 'Kustutamine ...';
+$lang['deleted'] = 'Plugin %s on kustutatud.';
+$lang['downloading'] = 'Allalaadimine ...';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Komponendid';
+$lang['name'] = 'Nimi:';
+$lang['date'] = 'Kuupäev';
+$lang['type'] = 'Tüüp:';
+$lang['desc'] = 'Kirjeldus:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Veeb:';
diff --git a/lib/plugins/plugin/lang/eu/admin_plugin.txt b/lib/plugins/plugin/lang/eu/admin_plugin.txt
new file mode 100644
index 000000000..367cf37ee
--- /dev/null
+++ b/lib/plugins/plugin/lang/eu/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Plugin Kudeaketa ======
+
+Orri honetan Dokuwiki [[doku>plugins|plugin-ekin]] erlazionatutako edozer kudeatu dezakezu. Plugin-en bat deskargatu eta instalatu ahal izateko, plugin-en direktorioak web zerbitzariarengatik idazgarria izan behar du.
diff --git a/lib/plugins/plugin/lang/eu/lang.php b/lib/plugins/plugin/lang/eu/lang.php
new file mode 100644
index 000000000..56c03325f
--- /dev/null
+++ b/lib/plugins/plugin/lang/eu/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['menu'] = 'Plugin-ak Kudeatu';
+$lang['download'] = 'Plugin berri bat deskargatu eta instalatu';
+$lang['manage'] = 'Instalatutako Plugin-ak';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'eguneratu';
+$lang['btn_delete'] = 'ezabatu';
+$lang['btn_settings'] = 'ezarpenak';
+$lang['btn_download'] = 'Deskargatu';
+$lang['btn_enable'] = 'Gorde';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalatua:';
+$lang['lastupdate'] = 'Azken aldiz eguneratua:';
+$lang['source'] = 'Iturria:';
+$lang['unknown'] = 'ezezaguna';
+$lang['updating'] = 'Eguneratzen ...';
+$lang['updated'] = 'Arrakastaz eguneratu da %s plugin-a';
+$lang['updates'] = 'Ondorengo plugin-ak ondo eguneratu dira';
+$lang['update_none'] = 'Ez da eguneraketarik aurkitu.';
+$lang['deleting'] = 'Ezabatzen ...';
+$lang['deleted'] = '%s plugin-a ezabatua.';
+$lang['downloading'] = 'Deskargatzen ...';
+$lang['downloaded'] = '%s Plugin-a arrakastaz instalatua';
+$lang['downloads'] = 'Ondorengo plugin-ak arrakastaz instalatu dira:';
+$lang['download_none'] = 'Ez da plugin-ik aurkitu, edo arazo ezezagunen bat egon da deskargatu eta instalatzerako garaian.';
+$lang['plugin'] = 'Plugin-a:';
+$lang['components'] = 'Osagaiak';
+$lang['noinfo'] = 'Plugin honek ez du informaziorik itzuli, agian ez da erabilgarria.';
+$lang['name'] = 'izena:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Mota:';
+$lang['desc'] = 'Deskribapena:';
+$lang['author'] = 'Egilea:';
+$lang['www'] = 'Web-gunea:';
+$lang['error'] = 'Akats ezezagun bat gertatu da.';
+$lang['error_download'] = 'Ezin izan da plugin-aren honako fitxategia deskargatu: %s';
+$lang['error_badurl'] = 'Ustezko url okerra - ezin izan da fitxategi izena url-tik zehaztu';
+$lang['error_dircreate'] = 'Ezin izan da aldiroko karpeta sortu deskarga jasotzeko';
+$lang['error_decompress'] = 'Plugin kudeatzaileak ezin izan du deskargatutako fitxategia erauzi. Deskarga oker baten ondorioa izan daiteke, eta hala bada berriz saiatu beharko zenuke; edo agian trinkotze formatua ezezaguna da, hala izanik plugin-a eskuz deskargatu eta instalatu beharko zenuelarik.';
+$lang['error_copy'] = 'Fitxategi kopia akats bat egon da <em>%s</em> plugin-arentzat fitxategiak instalatzen saiatzean: diska betea egon liteke edo fitxategi atzipen baimena okerra izan daiteke. Honek partzialki instalatutako plugin bat eta wiki instalazioa ezegonkor utzi dezake.';
+$lang['error_delete'] = 'Akats bat gertatu da <em>%s</em> plugin-a ezabatzeko saiakera egitean. Arrazoia ziurrenik fitxategi edo direktorio atzipen baimen nahikoak ez izatea da.';
+$lang['enabled'] = '%s Plugin-a gaitua.';
+$lang['notenabled'] = '%s Plugin-a ezin izan da gaitu, egiaztatu fitxategi baimenak.';
+$lang['disabled'] = '%s Plugin-a ezgaitua.';
+$lang['notdisabled'] = '%s Plugin-a ezin izan da ezgaitu, egiaztatu fitxategi baimenak. ';
+$lang['packageinstalled'] = 'Plugin paketea (%d plugin(s): %s) arrakastaz instalatua izan da.';
diff --git a/lib/plugins/plugin/lang/fa/admin_plugin.txt b/lib/plugins/plugin/lang/fa/admin_plugin.txt
new file mode 100644
index 000000000..cd11fb460
--- /dev/null
+++ b/lib/plugins/plugin/lang/fa/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== مدیریت افزونه‌ها ======
+
+در این صفحه شما می‌توانید [[doku>plugins|افزونه‌های]] Dokuwiki را مدیریت کنید. برای امکان دریافت و نصب افزونه‌ها، باید به شاخه‌ی افزونه‌ها (lib/plugin) دسترسی نوشتن برای وب‌سرور را محیا کنید. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/fa/lang.php b/lib/plugins/plugin/lang/fa/lang.php
new file mode 100644
index 000000000..8f3fb8a41
--- /dev/null
+++ b/lib/plugins/plugin/lang/fa/lang.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['menu'] = 'مدیریت افزونه‌ها';
+$lang['download'] = 'دریافت و نصب افزونه';
+$lang['manage'] = 'افزونه‌های نصب شده';
+$lang['btn_info'] = 'مشخصات';
+$lang['btn_update'] = 'بروزرسانی';
+$lang['btn_delete'] = 'حذف';
+$lang['btn_settings'] = 'تنظیمات';
+$lang['btn_download'] = 'دانلود';
+$lang['btn_enable'] = 'ذخیره';
+$lang['url'] = 'آدرس';
+$lang['installed'] = 'نصب شده:';
+$lang['lastupdate'] = 'آخرین بروزرسانی:';
+$lang['source'] = 'منبع:';
+$lang['unknown'] = 'ناشناس';
+$lang['updating'] = 'در حال به روز رسانی...';
+$lang['updated'] = 'افزونه‌ی %s با موفقیت به روز رسانی شد';
+$lang['updates'] = 'افزونه‌های زیر با موفقیت به روز رسانی شده است.';
+$lang['update_none'] = 'به روز رسانی‌ای یافت نشد .';
+$lang['deleting'] = 'در حال حذف...';
+$lang['deleted'] = 'افزونه‌ی %s پاک شد.';
+$lang['downloading'] = 'در حال دریافت...';
+$lang['downloaded'] = 'افزونه‌ی %s با موفقیت نصب شد';
+$lang['downloads'] = 'افزونه‌های زیر با موفقیت نصب شدند:';
+$lang['download_none'] = 'هیچ افزونه‌ای یافت نشد، یا یک مشکل ناشناخته در زمان دریافت و نصب پیش آمده است.';
+$lang['plugin'] = 'افزونه:';
+$lang['components'] = 'کامپوننت';
+$lang['noinfo'] = 'این افزونه هیچ اطلاعاتی را برنگردانده است، ممکن است بی‌اعتبار باشد.';
+$lang['name'] = 'اسم:';
+$lang['date'] = 'تاریخ:';
+$lang['type'] = 'نوع:';
+$lang['desc'] = 'توضیحات:';
+$lang['author'] = 'نویسنده:';
+$lang['www'] = 'وب‌سایت:';
+$lang['error'] = 'یک مشکل ناشناخته پیش آمده.';
+$lang['error_download'] = 'توانایی دریافت افزونه‌ی %s نمی‌باشد.';
+$lang['error_badurl'] = 'آدرس مشکل دارد - توانایی تشخیص نام فایل از آدرس وجود ندارد';
+$lang['error_dircreate'] = 'امکان ایجاد شاخه‌ی موقتی برای دریافت فایل نیست.';
+$lang['error_decompress'] = 'باز کردن فایل با مشکل مواجه شد. این اشکال ممکن است به خاطر دریافت ناقصِ فایل باشد که باید دوباره تلاش کنید، یا فرمت فشرده‌سازی شناخته شده نیست، که باید این افزونه رو دستی نصب کنید.';
+$lang['error_copy'] = 'توانایی کپی کردن فایل‌های افزونه‌ی <em>%s</em> در زمان نصب وجود ندارد. ممکن است دسترسی شاخه‌ی افزونه‌ها مشکل داشته باشد. این مشکل ممکن است باعث نصب ناقص افزونه شود و ویکی را با مشکل مواجه کند.';
+$lang['error_delete'] = 'توانایی حذف افزونه‌ی <em>%s</em> وجود ندارد. این مشکل به خاطر دسترسی فایل یا شاخه‌ی افزونه پیش می‌آید.';
+$lang['enabled'] = 'افزونه‌ی %s فعال شد.';
+$lang['notenabled'] = 'افزونه‌ی %s قابلیت فعال کردن ندارد، دسترسی‌ها را چک کنید.';
+$lang['disabled'] = 'افزونه‌ی %s غیرفعال شد.';
+$lang['notdisabled'] = 'افزونه‌ی %s قابلیت غیرفعال کردن ندارد، دسترسی‌ها را چک کنید.';
+$lang['packageinstalled'] = 'بسته افزونه (%d افزونه: %s) به درستی نصب شد.';
diff --git a/lib/plugins/plugin/lang/fi/admin_plugin.txt b/lib/plugins/plugin/lang/fi/admin_plugin.txt
new file mode 100644
index 000000000..9cdfa1c11
--- /dev/null
+++ b/lib/plugins/plugin/lang/fi/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Liitännäisten hallinta ======
+
+Tällä sivulla voit hallita DokuWikin [[doku>plugins|liitännäisiä]]. Voidaksesi ladata ja asentaa liitännäisiä pitää web-palvelimella olla kirjoitusoikeudet plugin hakemistoon.
diff --git a/lib/plugins/plugin/lang/fi/lang.php b/lib/plugins/plugin/lang/fi/lang.php
new file mode 100644
index 000000000..923029a6f
--- /dev/null
+++ b/lib/plugins/plugin/lang/fi/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['menu'] = 'Ylläpidä liitännäisiä';
+$lang['download'] = 'Lataa ja asenna uusi liitännäinen';
+$lang['manage'] = 'Asennetut liitännäiset';
+$lang['btn_info'] = 'tietoa';
+$lang['btn_update'] = 'päivitä';
+$lang['btn_delete'] = 'poista';
+$lang['btn_settings'] = 'asetukset';
+$lang['btn_download'] = 'Lataa';
+$lang['btn_enable'] = 'Tallenna';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Asennettu:';
+$lang['lastupdate'] = 'Päivitetty viimeksi:';
+$lang['source'] = 'Lähde:';
+$lang['unknown'] = 'tuntematon';
+$lang['updating'] = 'Päivitetään ...';
+$lang['updated'] = 'Liitännäinen %s päivitetty onnistuneesti';
+$lang['updates'] = 'Seuraavat liitännäiset on päivitetty onnistuneesti';
+$lang['update_none'] = 'Päivityksiä ei löytynyt';
+$lang['deleting'] = 'Poistetaan ...';
+$lang['deleted'] = 'Liitännäinen %s poistettu.';
+$lang['downloading'] = 'Ladataan ...';
+$lang['downloaded'] = 'Liitännäinen %s asennettu onnistuneesti';
+$lang['downloads'] = 'Seuraavat liitännäiset on asennettu onnistuneesti';
+$lang['download_none'] = 'Liitännäisiä ei löytynyt tai on tapahtunut joku tuntematon virhe latauksen ja asennuksen aikana.';
+$lang['plugin'] = 'Liitännäinen:';
+$lang['components'] = 'Osa';
+$lang['noinfo'] = 'Liitännäinen ei palauttanut mitään tietoa ja se voi olla epäkelpo.';
+$lang['name'] = 'Nimi:';
+$lang['date'] = 'Päiväys:';
+$lang['type'] = 'Tyyppi:';
+$lang['desc'] = 'Kuvaus:';
+$lang['author'] = 'Tekijä:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Tapahtui tuntematon virhe.';
+$lang['error_download'] = 'Liitännäistiedoston %s latauksessa tapahtui tuntematon virhe.';
+$lang['error_badurl'] = 'URL vaikuttaa olleen virheellinen. Siitä ei pystytty päättelemään tiedoston nimeä';
+$lang['error_dircreate'] = 'Ei pystytty luomaan väliaikaista hakemistoa latausta varten';
+$lang['error_decompress'] = 'Liitännäishallinta ei pystynyt purkamaan ladattua tiedostoa. Lataus voi olla epäonnistunut. Siinä tapauksessa voit yrittää uudestaan. Pakkaustapa voi myös olla tuntematon. Siinä tapauksessa sinun pitää ladata ja asentaa liitännäinen käsin.';
+$lang['error_copy'] = 'Tiedoston kopioinnissa tapahtui liitännäisen <em>%s</em> asennuksen aikana virhe. Levy voi olla täynnä tai kansioiden oikeudet voivat olla väärin. Liitännäinen voi olla osittain asennettu ja tämä voi jättää wikiasennukseesi epävakaaseen tilaan.';
+$lang['error_delete'] = 'Liitännäisen <em>%s</em> poistossa tapahtui virhe. Todennäköisin syy on puutteelliset tiedoston tai hakemiston oikeudet';
+$lang['enabled'] = 'Liitännäinen %s käytössä';
+$lang['notenabled'] = 'Liitännäistä %s ei voitu ottaa käyttöön. Tarkista tiedostojen oikeudet.';
+$lang['disabled'] = 'Liitännäinen %s pois käytössä';
+$lang['notdisabled'] = 'Liitännäistä %s ei voitu ottaa pois käytöstä. Tarkista tiedostojen oikeudet.';
+$lang['packageinstalled'] = 'Pluginpaketti (%d plugin: %s:) asennettu onnistuneesti.';
diff --git a/lib/plugins/plugin/lang/fr/admin_plugin.txt b/lib/plugins/plugin/lang/fr/admin_plugin.txt
new file mode 100644
index 000000000..f90b627f3
--- /dev/null
+++ b/lib/plugins/plugin/lang/fr/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Gestion des modules externes ======
+
+Cette page vous permet de gérer tout ce qui a trait aux [[doku>fr:plugins|modules externes]] de DokuWiki. Pour télécharger et installer un module, le répertoire « ''plugin'' » doit être accessible en écriture pour le serveur Web.
+
diff --git a/lib/plugins/plugin/lang/fr/lang.php b/lib/plugins/plugin/lang/fr/lang.php
new file mode 100644
index 000000000..bb0b49872
--- /dev/null
+++ b/lib/plugins/plugin/lang/fr/lang.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * french language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Guy Brand <gb@unistra.fr>
+ * @author Delassaux Julien <julien@delassaux.fr>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['menu'] = 'Gestion des modules externes';
+$lang['download'] = 'Télécharger et installer un nouveau module';
+$lang['manage'] = 'Modules installés';
+$lang['btn_info'] = 'Info';
+$lang['btn_update'] = 'Mettre à jour';
+$lang['btn_delete'] = 'Supprimer';
+$lang['btn_settings'] = 'Paramètres';
+$lang['btn_download'] = 'Télécharger';
+$lang['btn_enable'] = 'Enregistrer';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installé :';
+$lang['lastupdate'] = 'Dernière mise à jour :';
+$lang['source'] = 'Source :';
+$lang['unknown'] = 'inconnu';
+$lang['updating'] = 'Mise à jour…';
+$lang['updated'] = 'Modules %s mis à jour avec succès';
+$lang['updates'] = 'Les modules suivants ont été mis à jour avec succès';
+$lang['update_none'] = 'Aucune mise à jour n\'a été trouvée.';
+$lang['deleting'] = 'Suppression…';
+$lang['deleted'] = 'Module %s supprimé.';
+$lang['downloading'] = 'Téléchargement…';
+$lang['downloaded'] = 'Module %s installé avec succès';
+$lang['downloads'] = 'Les modules suivants ont été installés avec succès :';
+$lang['download_none'] = 'Aucun module n\'était trouvé, ou un problème inconnu est survenu durant le téléchargement et l\'installation.';
+$lang['plugin'] = 'Module :';
+$lang['components'] = 'Composants';
+$lang['noinfo'] = 'Ce module externe n\'a transmis aucune information, il pourrait être invalide.';
+$lang['name'] = 'Nom :';
+$lang['date'] = 'Date :';
+$lang['type'] = 'Type :';
+$lang['desc'] = 'Description :';
+$lang['author'] = 'Auteur :';
+$lang['www'] = 'Site web :';
+$lang['error'] = 'Une erreur inconnue est survenue.';
+$lang['error_download'] = 'Impossible de télécharger le fichier du module : %s';
+$lang['error_badurl'] = 'URL suspecte. Impossible de déterminer le nom du fichier à partir de l\'URL';
+$lang['error_dircreate'] = 'Impossible de créer le répertoire temporaire pour réceptionner le téléchargement';
+$lang['error_decompress'] = 'Le gestionnaire de modules externes a été incapable de décompresser le fichier téléchargé. Ceci peut être le résultat d\'un mauvais téléchargement, auquel cas vous devriez réessayer ; ou bien le format de compression est inconnu, auquel cas vous devez télécharger et installer le module manuellement.';
+$lang['error_copy'] = 'Une erreur de copie est survenue lors de l\'installation des fichiers du module <em>%s</em> : votre disque est peut-être plein ou les droits d\'accès au fichier sont incorrects. Il a pu en résulter une installation partielle du module rendant votre installation du wiki instable.';
+$lang['error_delete'] = 'Une erreur est survenue à la suppression du module <em>%s</em>. La raison la plus probable est l\'insuffisance des droits sur les fichiers ou le répertoire.';
+$lang['enabled'] = 'Module %s activé.';
+$lang['notenabled'] = 'Le module %s n\'a pas pu être activé, vérifiez le fichier des permissions.';
+$lang['disabled'] = 'Module %s désactivé.';
+$lang['notdisabled'] = 'Le module %s n\'a pas pu être désactivé, vérifiez le fichier des permissions.';
+$lang['packageinstalled'] = 'Ensemble de modules (%d module(s): %s) installé avec succès.';
diff --git a/lib/plugins/plugin/lang/gl/admin_plugin.txt b/lib/plugins/plugin/lang/gl/admin_plugin.txt
new file mode 100644
index 000000000..216285a8d
--- /dev/null
+++ b/lib/plugins/plugin/lang/gl/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Xestión de Extensións ======
+
+Nesta páxina podes xestionar todas as accións posíbeis cos [[doku>plugins|extensións]] do DokuWiki. Para poder descargar e instalar unha extensión, o teu cartafol de extensións debe ser escribíbel polo servidor web.
diff --git a/lib/plugins/plugin/lang/gl/lang.php b/lib/plugins/plugin/lang/gl/lang.php
new file mode 100644
index 000000000..a314b71b9
--- /dev/null
+++ b/lib/plugins/plugin/lang/gl/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['menu'] = 'Xestionar Extensións';
+$lang['download'] = 'Descargar e instalar unha nova extensión';
+$lang['manage'] = 'Extensións Instalados';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualización';
+$lang['btn_delete'] = 'eliminar';
+$lang['btn_settings'] = 'configuración';
+$lang['btn_download'] = 'Descargar';
+$lang['btn_enable'] = 'Gardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalado:';
+$lang['lastupdate'] = 'Última actualización:';
+$lang['source'] = 'Fonte:';
+$lang['unknown'] = 'descoñecido';
+$lang['updating'] = 'Actualizando...';
+$lang['updated'] = 'Actualizouse correctamente a extensión %s';
+$lang['updates'] = 'Actualizáronse correctamente as seguintes extensións';
+$lang['update_none'] = 'Non se atoparon actualizacións.';
+$lang['deleting'] = 'Eliminando...';
+$lang['deleted'] = 'Eliminado a extensión %s.';
+$lang['downloading'] = 'Descargando...';
+$lang['downloaded'] = 'Instalouse correctamente a extensión %s';
+$lang['downloads'] = 'Instaláronse correctamente as seguintes extensións:';
+$lang['download_none'] = 'Non se atoparon extensións, ou aconteceu un problema descoñecido durante a descarga e instalación.';
+$lang['plugin'] = 'Extensión:';
+$lang['components'] = 'Compoñentes';
+$lang['noinfo'] = 'Esta extensión non devolveu información ningunha. Pode que non sexa válida.';
+$lang['name'] = 'Nome:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descrición:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Houbo un erro descoñecido.';
+$lang['error_download'] = 'Non se puido descargar o arquivo de extensión: %s';
+$lang['error_badurl'] = 'URL posiblemente incorrecto - non se puido determinar o nome do arquivo mediante o URL';
+$lang['error_dircreate'] = 'Non se puido crear un cartafol temporal para recibir a descarga';
+$lang['error_decompress'] = 'O xestor de extensións non foi quen de descomprimir o arquivo descargado. Isto podería ser causado por unha descarga corrupta, polo que, en tal caso, podes tentalo de novo; ou pode que o formato de compresión sexa descoñecido, co que precisarás descargar e instalar a extensión de xeito manual.';
+$lang['error_copy'] = 'Houbo un erro de copia de arquivo ao tentar instalar a extensión <em>%s</em>: pode que o disco estea cheo ou que os permisos de acceso sexan incorrectos. Isto podería dar lugar a unha instalación parcial da extensión e facer que a túa instalación do wiki se volva inestable.';
+$lang['error_delete'] = 'Houbo un erro ao tentar eliminar a extensión <em>%s</em>. O máis probable é que sexa causado por permisos de acceso ao arquivo ou directorio insuficientes.';
+$lang['enabled'] = 'Extensión %s activado.';
+$lang['notenabled'] = 'A extensión %s non puido ser activada, comproba os permisos de arquivo.';
+$lang['disabled'] = 'Extensión %s desactivada.';
+$lang['notdisabled'] = 'A extensión %s non puido ser desactivada, comproba os permisos de arquivo.';
+$lang['packageinstalled'] = 'Paquete de extensión (%d plugin(s): %s) instalado axeitadamente.';
diff --git a/lib/plugins/plugin/lang/he/admin_plugin.txt b/lib/plugins/plugin/lang/he/admin_plugin.txt
new file mode 100644
index 000000000..206d368db
--- /dev/null
+++ b/lib/plugins/plugin/lang/he/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== ניהול הרחבות ======
+
+בדף זה ניתן לנהל כל דבר הקשור ל[[doku>plugins|הרחבות]] של DokuWiki. כדי שניתן יהיה להוריד ולהתקין הרחבה על תיקית ה-plugins שלך להיות ברת כתיבה על ידי שרת הרשת.
+
+
diff --git a/lib/plugins/plugin/lang/he/lang.php b/lib/plugins/plugin/lang/he/lang.php
new file mode 100644
index 000000000..47253e335
--- /dev/null
+++ b/lib/plugins/plugin/lang/he/lang.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * hebrew language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author DoK <kamberd@yahoo.com>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['menu'] = 'ניהול הרחבות';
+$lang['download'] = 'הורדת והתקנת הרחבה חדשה';
+$lang['manage'] = 'הרחבות מותקנות';
+$lang['btn_info'] = 'מידע';
+$lang['btn_update'] = 'עידכון';
+$lang['btn_delete'] = 'מחיקה';
+$lang['btn_settings'] = 'הגדרות';
+$lang['btn_download'] = 'הורדה';
+$lang['btn_enable'] = 'שמירה';
+$lang['url'] = 'URL';
+$lang['installed'] = 'מותקנות:';
+$lang['lastupdate'] = 'עודכנו לאחרונה:';
+$lang['source'] = 'מקור:';
+$lang['unknown'] = 'לא ידוע';
+$lang['updating'] = 'מעדכן ...';
+$lang['updated'] = 'ההרחבה %s עודכנה בהצלחה';
+$lang['updates'] = 'ההרחבות הבאות עודכנו בהצלחה';
+$lang['update_none'] = 'לא נמצאו עידכונים.';
+$lang['deleting'] = 'מוחק ...';
+$lang['deleted'] = 'ההרחבה %s נמחקה.';
+$lang['downloading'] = 'מוריד ...';
+$lang['downloaded'] = 'ההרחבה %s הותקנה בהצלחה';
+$lang['downloads'] = 'ההרחבות הבאות הותקנו בהצלחה:';
+$lang['download_none'] = 'לא נמצאו הרחבות או שחלה בעיה בלתי ידועה במהלך ההורדה וההתקנה.';
+$lang['plugin'] = 'הרחבה:';
+$lang['components'] = 'רכיבים';
+$lang['noinfo'] = 'הרחבה זו לא השיבה מידע, יתכן כי היא אינה בתוקף.';
+$lang['name'] = 'שם:';
+$lang['date'] = 'תאריך:';
+$lang['type'] = 'סוג:';
+$lang['desc'] = 'תיאור:';
+$lang['author'] = 'מחבר:';
+$lang['www'] = 'רשת:';
+$lang['error'] = 'שגיאה לא ידועה ארעה.';
+$lang['error_download'] = 'כשל בהורדת קובץ ההרחבה: %s';
+$lang['error_badurl'] = 'כנראה כתובת שגויה - כשל בקביעת שם הקובץ מהכתובת';
+$lang['error_dircreate'] = 'כשל ביצירת תיקיה זמנית לקבלת ההורדה';
+$lang['error_decompress'] = 'מנהל ההרחבות כשל בפרישת הקובץ שהורד. יתכן כי זו תוצאה של הורדה תקולה ובמקרה זה עליך לנסות שנית; או שיתכן כי תסדיר הכיווץ אינו ידוע, במקרה זה יהיה עליך להוריד ולהתקין את ההרחבה ידנית.';
+$lang['error_copy'] = 'חלה שגיאה בהעתקת הקובץ בניסיון להתקין קבצים להרחבה <em>%s</em>: ייתכן כי הדיסק מלא או שהרשאות הגישה לקבצים שגויות. יתכן כי בשל כך נוצרה התקנה חלקית של ההרחבה שתשאיר את התקנת הויקי שלך לא יציבה.';
+$lang['error_delete'] = 'חלה שגיאה בעת ניסיון למחיקת ההרחבה <em>%s</em>. הסיבה הסבירה ביותר היא הרשאות גישה לקבצים ולספריות שאינן מספקות';
+$lang['enabled'] = 'תוסף %s מופעל.';
+$lang['notenabled'] = 'לא ניתן להפעיל את התוסף %s, בדוק הרשאות קבצים.';
+$lang['disabled'] = 'תוסף %s מושבת.';
+$lang['notdisabled'] = 'לא ניתן להשבית את התוסף %s, בדוק הרשאות קבצים.';
diff --git a/lib/plugins/plugin/lang/hi/lang.php b/lib/plugins/plugin/lang/hi/lang.php
new file mode 100644
index 000000000..ab29c6550
--- /dev/null
+++ b/lib/plugins/plugin/lang/hi/lang.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
+$lang['unknown'] = 'अज्ञात';
+$lang['deleted'] = 'मिटाया हुआ';
+$lang['date'] = 'दिनांक:';
+$lang['author'] = 'लेखक:';
+$lang['error'] = 'अज्ञात त्रुटि हुइ';
diff --git a/lib/plugins/plugin/lang/hr/lang.php b/lib/plugins/plugin/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/plugin/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/plugin/lang/hu/admin_plugin.txt b/lib/plugins/plugin/lang/hu/admin_plugin.txt
new file mode 100644
index 000000000..afa08d349
--- /dev/null
+++ b/lib/plugins/plugin/lang/hu/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Bővítménykezelő ======
+
+Ezen az oldalon a Dokuwiki [[doku>plugins|bővítményeivel]] kapcsolatos teendőket láthatod el. A webszervernek tudni kell írnia a //plugin// könyvtárat, hogy új bővítményeket tudj ezen a felületen keresztül letölteni és telepíteni.
+
diff --git a/lib/plugins/plugin/lang/hu/lang.php b/lib/plugins/plugin/lang/hu/lang.php
new file mode 100644
index 000000000..34309a53f
--- /dev/null
+++ b/lib/plugins/plugin/lang/hu/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['menu'] = 'Bővítménykezelő';
+$lang['download'] = 'Új bővítmény letöltése és telepítése';
+$lang['manage'] = 'Telepített bővítmények';
+$lang['btn_info'] = 'infó';
+$lang['btn_update'] = 'frissítés';
+$lang['btn_delete'] = 'törlés';
+$lang['btn_settings'] = 'beállítások';
+$lang['btn_download'] = 'Letöltés';
+$lang['btn_enable'] = 'Mentés';
+$lang['url'] = 'URL:';
+$lang['installed'] = 'Telepítve:';
+$lang['lastupdate'] = 'Utolsó frissítés:';
+$lang['source'] = 'Forrás:';
+$lang['unknown'] = 'ismeretlen';
+$lang['updating'] = 'Frissítés...';
+$lang['updated'] = 'A %s bővítmény sikeresen frissült.';
+$lang['updates'] = 'A következő bővítmények sikeresen frissültek:';
+$lang['update_none'] = 'Nem találtam újabb verziót.';
+$lang['deleting'] = 'Törlés...';
+$lang['deleted'] = 'A %s bővítményt eltávolítottam.';
+$lang['downloading'] = 'Letöltés...';
+$lang['downloaded'] = 'A %s bővítmény sikeresen feltelepült.';
+$lang['downloads'] = 'A következő bővítmények sikeresen feltelepültek:';
+$lang['download_none'] = 'Nem találtam bővítményt, vagy ismeretlen hiba történt a letöltés/telepítés közben.';
+$lang['plugin'] = 'Bővítmény:';
+$lang['components'] = 'Részek';
+$lang['noinfo'] = 'Ez a bővítmény nem tartalmaz infót, lehet, hogy hibás.';
+$lang['name'] = 'Név:';
+$lang['date'] = 'Dátum:';
+$lang['type'] = 'Típus:';
+$lang['desc'] = 'Leírás:';
+$lang['author'] = 'Szerző:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ismeretlen hiba lépett fel.';
+$lang['error_download'] = 'Nem tudom letölteni a bővítmény fájlt: %s';
+$lang['error_badurl'] = 'Feltehetően rossz URL - nem tudom meghatározni a fájlnevet az URL-ből.';
+$lang['error_dircreate'] = 'Nem tudom létrehozni az átmeneti könyvtárat a letöltéshez.';
+$lang['error_decompress'] = 'A Bővítménykezelő nem tudta a letöltött állományt kicsomagolni. Ennek oka lehet hibás letöltés, ebben az esetben újra letöltéssel próbálkozhatsz, esetleg a tömörítés módja ismeretlen, ebben az esetben kézzel kell letölteni és telepíteni a bővítményt.';
+$lang['error_copy'] = 'Fájl másolási hiba történt a(z) <em>%s</em> bővítmény telepítése közben: vagy a lemezterület fogyott el, vagy az állomány hozzáférési jogosultságok nem megfelelőek. Emiatt előfordulhat, hogy a bővítményt csak részben sikerült telepíteni, és a wiki összeomolhat.';
+$lang['error_delete'] = 'Hiba történt a(z) <em>%s</em> bővítmény eltávolítása közben. A legvalószínűbb ok, hogy a könyvtár vagy állomány hozzáférési jogosultságok nem megfelelőek.';
+$lang['enabled'] = 'A(z) %s bővítmény bekapcsolva.';
+$lang['notenabled'] = 'A(z) %s bővítmény engedélyezése nem sikerült. Ellenőrizze a fájl-hozzáférési engedélyeket.';
+$lang['disabled'] = 'A(z) %s bővítmény kikapcsolva.';
+$lang['notdisabled'] = 'A(z) %s bővítmény kikapcsolása nem sikerült. Ellenőrizze a fájl-hozzáférési engedélyeket.';
+$lang['packageinstalled'] = 'A bővítmény csomag(ok) feltelepült(ek): %d plugin(s): %s';
diff --git a/lib/plugins/plugin/lang/ia/admin_plugin.txt b/lib/plugins/plugin/lang/ia/admin_plugin.txt
new file mode 100644
index 000000000..c7f758c16
--- /dev/null
+++ b/lib/plugins/plugin/lang/ia/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gestion de plug-ins ======
+
+In iste pagina tu pote gerer omne cosas con relation al [[doku>plugins|plug-ins]] de DokuWiki. Pro poter discargar e installar un plug-in, le directorio de plug-ins debe permitter le accesso de scriptura al servitor web. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/ia/lang.php b/lib/plugins/plugin/lang/ia/lang.php
new file mode 100644
index 000000000..523f8581d
--- /dev/null
+++ b/lib/plugins/plugin/lang/ia/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['menu'] = 'Gestion de plug-ins';
+$lang['download'] = 'Discargar e installar un nove plug-in';
+$lang['manage'] = 'Plug-ins installate';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualisar';
+$lang['btn_delete'] = 'deler';
+$lang['btn_settings'] = 'configurationes';
+$lang['btn_download'] = 'Discargar';
+$lang['btn_enable'] = 'Salveguardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installate:';
+$lang['lastupdate'] = 'Ultime actualisation:';
+$lang['source'] = 'Origine:';
+$lang['unknown'] = 'incognite';
+$lang['updating'] = 'Actualisation…';
+$lang['updated'] = 'Actualisation del plug-in %s succedite';
+$lang['updates'] = 'Le sequente plug-ins ha essite actualisate con successo';
+$lang['update_none'] = 'Nulle actualisation trovate.';
+$lang['deleting'] = 'Deletion…';
+$lang['deleted'] = 'Le plug-in %s ha essite delite.';
+$lang['downloading'] = 'Discargamento…';
+$lang['downloaded'] = 'Installation del plug-in %s succedite.';
+$lang['downloads'] = 'Le sequente plug-ins ha essite installate con successo:';
+$lang['download_none'] = 'Nulle plug-in trovate, o il ha occurrite un problema incognite durante le discargamento e installation.';
+$lang['plugin'] = 'Plug-in:';
+$lang['components'] = 'Componentes';
+$lang['noinfo'] = 'Iste plug-in retornava nulle information; illo pote esser invalide.';
+$lang['name'] = 'Nomine:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Typo:';
+$lang['desc'] = 'Description:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Un error incognite ha occurrite.';
+$lang['error_download'] = 'Impossibile discargar le file del plug-in: %s';
+$lang['error_badurl'] = 'URL probabilemente invalide; impossibile determinar le nomine del file ex le URL';
+$lang['error_dircreate'] = 'Impossibile crear le dossier temporari pro reciper le discargamento';
+$lang['error_decompress'] = 'Le gestor de plug-ins non poteva decomprimer le file discargate. Isto pote esser le resultato de un discargamento defectuose, in le qual caso tu deberea probar lo de novo; o le formato de compression pote esser incognite, in le qual caso tu debe discargar e installar le plug-in manualmente.';
+$lang['error_copy'] = 'Il occurreva un error durante le tentativa de installar files pro le plugin <em>%s</em>: le disco pote esser plen o le permissiones de accesso a files pote esser incorrecte. Isto pote haber resultate in un plug-in partialmente installate e lassar tu installation del wiki instabile.';
+$lang['error_delete'] = 'Il occurreva un error durante le tentativa de deler le plug-in <em>%s</em>. Le causa le plus probabile es insufficiente permissiones de files o directorios.';
+$lang['enabled'] = 'Plug-in %s activate.';
+$lang['notenabled'] = 'Le plug-in %s non poteva esser activate; verifica le permissiones de accesso a files.';
+$lang['disabled'] = 'Plug-in %s disactivate.';
+$lang['notdisabled'] = 'Le plug-in %s non poteva esser disactivate; verifica le permissiones de accesso a files.';
diff --git a/lib/plugins/plugin/lang/id-ni/lang.php b/lib/plugins/plugin/lang/id-ni/lang.php
new file mode 100644
index 000000000..d367340b7
--- /dev/null
+++ b/lib/plugins/plugin/lang/id-ni/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/plugin/lang/id/lang.php b/lib/plugins/plugin/lang/id/lang.php
new file mode 100644
index 000000000..f3a1fe4e6
--- /dev/null
+++ b/lib/plugins/plugin/lang/id/lang.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Irwan Butar Butar <irwansah.putra@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['btn_info'] = 'Info';
+$lang['btn_update'] = 'Baharui';
+$lang['btn_delete'] = 'Hapus';
+$lang['btn_settings'] = 'Pengaturan';
+$lang['btn_download'] = 'Unduh';
+$lang['btn_enable'] = 'Simpan';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instal';
+$lang['lastupdate'] = 'Pembaharuan terakhir:';
+$lang['source'] = 'Sumber:';
+$lang['unknown'] = 'Tidak kenal';
+$lang['updating'] = 'Terbaharui ...';
+$lang['update_none'] = 'Tidak ditemukan pembaharuan';
+$lang['deleting'] = 'Terhapus ...';
+$lang['deleted'] = 'Hapus Plugin %s.';
+$lang['downloading'] = 'Unduh ...';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Komponen';
+$lang['name'] = 'Nama:';
+$lang['date'] = 'Tanggal:';
+$lang['type'] = 'Tipe:';
+$lang['desc'] = 'Penjelasan:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
diff --git a/lib/plugins/plugin/lang/is/lang.php b/lib/plugins/plugin/lang/is/lang.php
new file mode 100644
index 000000000..0ef1243ef
--- /dev/null
+++ b/lib/plugins/plugin/lang/is/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['menu'] = 'Umsýsla viðbóta';
+$lang['download'] = 'Hlaða niður og innsetja viðbót';
+$lang['manage'] = 'Uppsettar viðbætur';
+$lang['btn_info'] = 'upplýsingar';
+$lang['btn_update'] = 'uppfæra';
+$lang['btn_delete'] = 'eyða';
+$lang['btn_settings'] = 'stillingar';
+$lang['btn_download'] = 'Niðurhal';
+$lang['btn_enable'] = 'Vista';
+$lang['url'] = 'Veffang';
+$lang['installed'] = 'Innsett:';
+$lang['lastupdate'] = 'Síðast uppfærð:';
+$lang['source'] = 'Gjafi:';
+$lang['unknown'] = 'óþekkt';
+$lang['updating'] = 'Uppfæri viðbót';
+$lang['updated'] = '%s viðbótin hefur verið uppfærð';
+$lang['updates'] = 'Eftirfarandi viðbætur hafa verið uppfærðar';
+$lang['update_none'] = 'Engar uppfærslur fundust.';
+$lang['deleting'] = 'Eyði viðbót';
+$lang['deleted'] = 'Viðbót %s eytt';
+$lang['downloading'] = 'Hleð viðbót niður ...';
+$lang['downloaded'] = 'Viðbót %s hlóðst inn';
+$lang['downloads'] = 'Eftirfarandi viðbótum hefur verið hlaðið inn:';
+$lang['download_none'] = 'Engin viðbót finnst, hugsanlega hefur komið upp villa við niðurhal eða uppsetningu.';
+$lang['plugin'] = 'Viðbót:';
+$lang['components'] = 'Einingar';
+$lang['noinfo'] = 'Þessi viðbót skilaði ekki upplýsingum og er hugsanlega ónýt.';
+$lang['name'] = 'Nafn:';
+$lang['date'] = 'Dagsetning:';
+$lang['type'] = 'Tegund:';
+$lang['desc'] = 'Lýsing:';
+$lang['author'] = 'Höfundur:';
+$lang['www'] = 'Vefur:';
+$lang['error'] = 'Óskilgreind villa';
+$lang['error_download'] = 'Niðurhal viðbótar %s mistókst';
+$lang['error_decompress'] = 'Viðbótastjórinn gat ekki afþjappað skránna. Þetta gæti verið vegna misheppnaðs niðurhals, ef svo er reyndu niðurhal aftur. Það er einnig mögulegt að skráin sé þjöppuð með aðferð sem að er Dokuwiki óþekkt, í því tilfelli er best að vista viðhengið á tölvunni þinni, afþjappa hana þar og svo hlaða skránum upp handvirkt.';
+$lang['enabled'] = 'Viðbót %s hefur verið ræst.';
+$lang['notenabled'] = 'Ekki var hægt að ræsa %s viðbótina. Athugaðu stillingar á skráaleyfum.';
+$lang['disabled'] = 'Viðbót %s var gerð óvirk';
diff --git a/lib/plugins/plugin/lang/it/admin_plugin.txt b/lib/plugins/plugin/lang/it/admin_plugin.txt
new file mode 100644
index 000000000..5591f08fe
--- /dev/null
+++ b/lib/plugins/plugin/lang/it/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gestione Plugin ======
+
+In questa pagina puoi gestire tutto ciò che riguarda i [[doku>plugins|plugin]] di DokuWiki. Per poter scaricare e installare un plugin, il webserver deve avere accesso in scrittura alla directory dei plugin. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/it/lang.php b/lib/plugins/plugin/lang/it/lang.php
new file mode 100644
index 000000000..e675c5530
--- /dev/null
+++ b/lib/plugins/plugin/lang/it/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Silvia Sargentoni <polinnia@tin.it>
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['menu'] = 'Gestione Plugin';
+$lang['download'] = 'Scarica e installa un nuovo plugin';
+$lang['manage'] = 'Plugin installati';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'aggiorna';
+$lang['btn_delete'] = 'elimina';
+$lang['btn_settings'] = 'configurazione';
+$lang['btn_download'] = 'Scarica';
+$lang['btn_enable'] = 'Salva';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installato:';
+$lang['lastupdate'] = 'Ultimo aggiornamento:';
+$lang['source'] = 'Origine:';
+$lang['unknown'] = 'sconosciuto';
+$lang['updating'] = 'Aggiornamento in corso ...';
+$lang['updated'] = 'Aggiornamento plugin %s riuscito';
+$lang['updates'] = 'Aggiornamento dei seguenti plugin riuscito:';
+$lang['update_none'] = 'Nessun aggiornamento trovato.';
+$lang['deleting'] = 'Eliminazione in corso ...';
+$lang['deleted'] = 'Plugin %s eliminato.';
+$lang['downloading'] = 'Scaricamento in corso ...';
+$lang['downloaded'] = 'Installazione plugin %s riuscita';
+$lang['downloads'] = 'Installazione dei seguenti plugin riuscita:';
+$lang['download_none'] = 'Nessun plugin trovato, oppure si è verificato un problema sconosciuto durante il download e l\'installazione.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Componenti';
+$lang['noinfo'] = 'Questo plugin non ha fornito alcuna informazione, potrebbe non essere valido.';
+$lang['name'] = 'Nome:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descrizione:';
+$lang['author'] = 'Autore:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Si è verificato un errore sconosciuto.';
+$lang['error_download'] = 'Impossibile scaricare il plugin: %s';
+$lang['error_badurl'] = 'Possibile URL non corretta - impossibile determinare il nome del file dalla URL fornita';
+$lang['error_dircreate'] = 'Impossibile creare la directory temporanea dove scaricare il file';
+$lang['error_decompress'] = 'Impossibile decomprimere il file scaricato. Questo potrebbe essere il risultato di un download incompleto, in tal caso dovresti provare di nuovo; oppure il formato di compressione potrebbe essere sconosciuto, in questo caso è necessario scaricare e installare il plugin manualmente.';
+$lang['error_copy'] = 'Si è verificato un errore nella copia di un file durante l\'installazione del plugin <em>%s</em>: il disco potrebbe essere pieno oppure i permessi di accesso al file potrebbero non essere corretti. Il plugin potrebbe essere stato installato solo parzialmente, questo potrebbe causare instabilità al sistema.';
+$lang['error_delete'] = 'Si è verificato un errore durante l\'eliminazione del plugin <em>%s</em>. Molto probabilmente i permessi di acesso ai file o alla directory non sono sufficienti';
+$lang['enabled'] = 'Plugin %s abilitato.';
+$lang['notenabled'] = 'Impossibile abilitare il plugin %s, verifica i permessi dei file.';
+$lang['disabled'] = 'Plugin %s disabilitato.';
+$lang['notdisabled'] = 'Impossibile disabilitare il plugin %s, verifica i permessi dei file.';
diff --git a/lib/plugins/plugin/lang/ja/admin_plugin.txt b/lib/plugins/plugin/lang/ja/admin_plugin.txt
new file mode 100644
index 000000000..c3b85351a
--- /dev/null
+++ b/lib/plugins/plugin/lang/ja/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== プラグイン管理 ======
+
+この画面で、DokuWikiで使用するプラグイン [[doku>plugins|plugins]] の管理を行うことが出来ます。 プラグインをダウンロード・インストールするためには、サーバー内のプラグイン用フォルダーを 書き込み可にしておく必要があります。
+
+
diff --git a/lib/plugins/plugin/lang/ja/lang.php b/lib/plugins/plugin/lang/ja/lang.php
new file mode 100644
index 000000000..a96dcc9be
--- /dev/null
+++ b/lib/plugins/plugin/lang/ja/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * japanese language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['menu'] = 'プラグイン管理';
+$lang['download'] = 'プラグインのダウンロードとインストール';
+$lang['manage'] = 'インストール済みプラグイン';
+$lang['btn_info'] = '情報';
+$lang['btn_update'] = '更新';
+$lang['btn_delete'] = '削除';
+$lang['btn_settings'] = '設定';
+$lang['btn_download'] = 'ダウンロード';
+$lang['btn_enable'] = '保存';
+$lang['url'] = 'URL';
+$lang['installed'] = 'インストール:';
+$lang['lastupdate'] = '最終更新日:';
+$lang['source'] = 'ソース:';
+$lang['unknown'] = '不明';
+$lang['updating'] = '更新中...';
+$lang['updated'] = 'プラグイン %s は更新されました';
+$lang['updates'] = '次のプラグインが更新されました:';
+$lang['update_none'] = 'プラグインの更新データはありません。';
+$lang['deleting'] = '削除中...';
+$lang['deleted'] = 'プラグイン %s は削除されました。';
+$lang['downloading'] = 'ダウンロード中...';
+$lang['downloaded'] = 'プラグイン %s がインストールされました';
+$lang['downloads'] = '次のプラグインがインストールされました:';
+$lang['download_none'] = 'プラグインが見つかりませんでした。もしくはダウンロードかインストールの最中に予期せぬエラーが発生しました。';
+$lang['plugin'] = 'プラグイン:';
+$lang['components'] = 'コンポーネント';
+$lang['noinfo'] = 'このプラグインに関する情報がありません。有効なプラグインではないかも知れません。';
+$lang['name'] = '名前:';
+$lang['date'] = '日付:';
+$lang['type'] = 'タイプ:';
+$lang['desc'] = '説明:';
+$lang['author'] = '作者:';
+$lang['www'] = 'ウェブサイト:';
+$lang['error'] = '予期せぬエラーが発生しました。';
+$lang['error_download'] = 'プラグインファイルをダウンロードできません:%s';
+$lang['error_badurl'] = 'URLが正しくないようです - ファイル名が特定できません';
+$lang['error_dircreate'] = 'ダウンロードしたファイルを一時的に保管しておくフォルダが作成できません';
+$lang['error_decompress'] = 'ダウンロードしたファイルを解凍できませんでした。ダウンロードに失敗した可能性があります(もう一度、実行してください);もしくは、不明な圧縮形式であるかもしれません(手動でインストールする必要があります)';
+$lang['error_copy'] = 'プラグインをインストール中にファイルのコピーに失敗しました。<em>%s</em>:ディスク容量や書き込みの権限を確認してください。このエラーによりプラグインのインストールが完全に行われず、Wikiが不安定な状態です。';
+$lang['error_delete'] = 'プラグインの削除中にエラーが発生しました <em>%s</em>。プラグインが不完全なファイルであったか、ディレクトリの権限が正しくないことが原因であると考えられます。';
+$lang['enabled'] = 'プラグイン %s が有効です。';
+$lang['notenabled'] = 'プラグイン %s を有効にすることができません。権限を確認してください。';
+$lang['disabled'] = 'プラグイン %s が無効です。';
+$lang['notdisabled'] = 'プラグイン %s を無効にすることができません。権限を確認してください。';
+$lang['packageinstalled'] = 'プラグインパッケージ(%d plugin(s): %s)は正しくインストールされました。';
diff --git a/lib/plugins/plugin/lang/kk/lang.php b/lib/plugins/plugin/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/plugin/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/plugin/lang/ko/admin_plugin.txt b/lib/plugins/plugin/lang/ko/admin_plugin.txt
new file mode 100644
index 000000000..22ce0e6e6
--- /dev/null
+++ b/lib/plugins/plugin/lang/ko/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== 플러그인 관리 ======
+
+이 페이지에서 Dokuwiki[[doku>plugins|plugins]]에 관련된 모든 관리 작업을 합니다. 플러그인을 다운로드하거나 설치하기 위해서 웹서버가 플러그인 디렉토리에 대해 쓰기 권한을 가지고 있어야 합니다.
+
+
diff --git a/lib/plugins/plugin/lang/ko/lang.php b/lib/plugins/plugin/lang/ko/lang.php
new file mode 100644
index 000000000..c77c3259d
--- /dev/null
+++ b/lib/plugins/plugin/lang/ko/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * korean language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author jk Lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['menu'] = '플러그인 관리자';
+$lang['download'] = '새로운 플러그인 다운로드 및 설치';
+$lang['manage'] = '이미 설치된 플러그인들';
+$lang['btn_info'] = '정보';
+$lang['btn_update'] = '갱신';
+$lang['btn_delete'] = '삭제';
+$lang['btn_settings'] = '설정';
+$lang['btn_download'] = '다운로드';
+$lang['btn_enable'] = '저장';
+$lang['url'] = 'URL';
+$lang['installed'] = '설치된:';
+$lang['lastupdate'] = '가장 최근에 갱신된:';
+$lang['source'] = '소스:';
+$lang['unknown'] = '알 수 없는';
+$lang['updating'] = '갱신 중 ...';
+$lang['updated'] = '%s 플러그인이 성공적으로 갱신되었습니다.';
+$lang['updates'] = '다음 플러그인들이 성공적으로 갱신되었습니다:';
+$lang['update_none'] = '갱신 가능한 플러그인이 없습니다.';
+$lang['deleting'] = '삭제 중 ...';
+$lang['deleted'] = '%s 플러그인이 삭제되었습니다.';
+$lang['downloading'] = '다운로드 중 ...';
+$lang['downloaded'] = '%s 플러그인이 성공적으로 설치되었습니다.';
+$lang['downloads'] = '다음 플러그인들이 성공적으로 설치되었습니다:';
+$lang['download_none'] = '플러그인이 없거나 다운로드/설치 중에 알수 없는 문제가 발생했습니다.';
+$lang['plugin'] = '플러그인:';
+$lang['components'] = '콤퍼넌트들';
+$lang['noinfo'] = '이 플러그인은 어떤 정보도 없습니다. 유효한 플러그인이 아닐 지도 모릅니다.';
+$lang['name'] = '이름:';
+$lang['date'] = '날짜:';
+$lang['type'] = '타입:';
+$lang['desc'] = '설명:';
+$lang['author'] = '제작자:';
+$lang['www'] = '웹:';
+$lang['error'] = '알 수 없는 문제가 발생했습니다.';
+$lang['error_download'] = '플러그인 파일을 다운로드 할 수 없습니다: %s';
+$lang['error_badurl'] = '잘못된 URL같습니다. - URL에서 파일 이름을 알 수 없습니다.';
+$lang['error_dircreate'] = '다운로드를 받기 위한 임시 디렉토리를 만들 수 없습니다.';
+$lang['error_decompress'] = '플러그인 매니저가 다운로드 받은 파일을 압축해제할 수 없습니다.잘못 다운로드 받았을 수도 있으니 다시 한번 시도해보기 바랍니다; 압축 포맷을 알 수 없는 경우에는 다운로드 후 수동으로 직접 설치하기 바랍니다.';
+$lang['error_copy'] = '플러그인 설치하는 동안 파일 복사 에러가 발생했습니다. <em>%s</em>: 디스크가 꽉 찼거나 파일 접근 권한이 잘못된 경우입니다. 플러그인 설치가 부분적으로만 이루어졌을 것입니다.설치가 불완전합니다.';
+$lang['error_delete'] = '<em>%s</em> 플러그인 삭제 도중 에러가 발생했습니다. 대부분의 경우, 불완전한 파일이거나 디렉토리 접근 권한이 잘못된 경우입니다.';
+$lang['enabled'] = '%s 플러그인을 켰습니다.';
+$lang['notenabled'] = '%s 플러그인을 킬 수 없습니다. 파일 권한을 확인하십시오.';
+$lang['disabled'] = '%s 플러그인을 껐습니다.';
+$lang['notdisabled'] = '%s 플러그인을 끌 수 없습니다. 파일 권한을 확인하십시오.';
+$lang['packageinstalled'] = '플러그인 패키지(%d 개의 플러그인: %s)가 성공적으로 설치되었습니다.';
diff --git a/lib/plugins/plugin/lang/la/admin_plugin.txt b/lib/plugins/plugin/lang/la/admin_plugin.txt
new file mode 100644
index 000000000..2a41977fc
--- /dev/null
+++ b/lib/plugins/plugin/lang/la/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Addendorum Administratio ======
+
+In hac pagina omnia uicis [[doku>plugins|plugins]] mutare et administrare potes. Vt addenda capere et his uti, in scrinio addendorum scribere et legere potest. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/la/lang.php b/lib/plugins/plugin/lang/la/lang.php
new file mode 100644
index 000000000..cd2d81cbd
--- /dev/null
+++ b/lib/plugins/plugin/lang/la/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['menu'] = 'Addendorum administratio';
+$lang['download'] = 'Noua addenda cape';
+$lang['manage'] = 'Addenta in usu';
+$lang['btn_info'] = 'Notae';
+$lang['btn_update'] = 'Nouare';
+$lang['btn_delete'] = 'Delere';
+$lang['btn_settings'] = 'Optiones';
+$lang['btn_download'] = 'Capere';
+$lang['btn_enable'] = 'Seruare';
+$lang['url'] = 'VRL';
+$lang['installed'] = 'In usu:';
+$lang['lastupdate'] = 'Extrema renouatio:';
+$lang['source'] = 'Fons:';
+$lang['unknown'] = 'Ignotum';
+$lang['updating'] = 'Nouans...';
+$lang['updated'] = 'Addenda %s nouata feliciter';
+$lang['updates'] = 'Hae addenda nouata feliciter sunt';
+$lang['update_none'] = 'Nulla renouatio inuenta';
+$lang['deleting'] = 'Delens...';
+$lang['deleted'] = 'Addenda %s deleta.';
+$lang['downloading'] = 'Capens ...';
+$lang['downloaded'] = 'Addenda %s recte in usu';
+$lang['downloads'] = 'Hae addenda feliciter in usu:';
+$lang['download_none'] = 'Nulla addenda reperta aut errores in capiendo sunt.';
+$lang['plugin'] = 'Addenda:';
+$lang['components'] = 'Partes';
+$lang['noinfo'] = 'Addenda alias notas non habent.';
+$lang['name'] = 'Nomen:';
+$lang['date'] = 'Dies:';
+$lang['type'] = 'Genus:';
+$lang['desc'] = 'Descriptio:';
+$lang['author'] = 'Auctor:';
+$lang['www'] = 'Situs interretialis:';
+$lang['error'] = 'Error ignotus.';
+$lang['error_download'] = 'Addenda quae non renouantur: %s';
+$lang['error_badurl'] = 'VRL malum';
+$lang['error_dircreate'] = 'Scrinium temporaneum non creatur, sic nihil capi potest';
+$lang['error_decompress'] = 'Addendorum administrator nouare non potest. Rursum capere nouationes temptat aut manu addenda noua.';
+$lang['error_copy'] = 'Exemplar malum in scrinio addendorum <em>%s</em> est: facultates documenti scrinique fortasse illegitimae sunt. Hic accidit cum addenda partim nouata sunt.';
+$lang['error_delete'] = 'Addenda <em>%s</em> non delentur.';
+$lang['enabled'] = 'Addenda %s apta facta.';
+$lang['notenabled'] = 'Addenda %s quae apta fieri non possunt.';
+$lang['disabled'] = 'Addenda %s non in usu.';
+$lang['notdisabled'] = 'Addenda %s quae inepta fieri non possunt.';
diff --git a/lib/plugins/plugin/lang/lb/admin_plugin.txt b/lib/plugins/plugin/lang/lb/admin_plugin.txt
new file mode 100644
index 000000000..223de10e8
--- /dev/null
+++ b/lib/plugins/plugin/lang/lb/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Plugin Management ======
+
+Op dëser Säit kanns de alles verwalte wat mat Dokuwiki [[doku>plugins|Pluginen]] ze dinn huet. Fir e Plugin kënnen z'installéieren, muss däi Pluginverzeechnës vum Webserver schreiwbar sinn.
+
diff --git a/lib/plugins/plugin/lang/lb/lang.php b/lib/plugins/plugin/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/plugin/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/plugin/lang/lt/admin_plugin.txt b/lib/plugins/plugin/lang/lt/admin_plugin.txt
new file mode 100644
index 000000000..1254b776c
--- /dev/null
+++ b/lib/plugins/plugin/lang/lt/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Priedų Administravimas ======
+
+Šiame puslapyje galite administruoti, darbui su Dokuwiki, reikalingu įrankius [[doku>plugins|plugins]]. Tam kad parsiųsti ir įdiegti kokį nors priedą jūsų web serveris privalo turėti įrašymo teises priedų kataloge.
diff --git a/lib/plugins/plugin/lang/lt/lang.php b/lib/plugins/plugin/lang/lt/lang.php
new file mode 100644
index 000000000..c5b2fa11e
--- /dev/null
+++ b/lib/plugins/plugin/lang/lt/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['name'] = 'Vardas:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipas:';
+$lang['desc'] = 'Aprašas:';
+$lang['author'] = 'Autorius:';
+$lang['www'] = 'Tinklapis:';
diff --git a/lib/plugins/plugin/lang/lv/admin_plugin.txt b/lib/plugins/plugin/lang/lv/admin_plugin.txt
new file mode 100644
index 000000000..80335062f
--- /dev/null
+++ b/lib/plugins/plugin/lang/lv/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Moduļu pārvaldīšana ======
+
+Šajā lapā varat pārvaldīt visu, kas saistīts ar Dokuwiki [[doku>plugins|moduļiem]]. Lai varētu lejupielādēt un uzstādīt moduļus, to direktorijai serverī vajag rakstīšanas tiesības.
diff --git a/lib/plugins/plugin/lang/lv/lang.php b/lib/plugins/plugin/lang/lv/lang.php
new file mode 100644
index 000000000..0f6103899
--- /dev/null
+++ b/lib/plugins/plugin/lang/lv/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Latvian, Lettish language file
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['menu'] = 'Moduļu pārvaldība';
+$lang['download'] = 'Lejupielādēt un instalēt jaunu moduli.';
+$lang['manage'] = 'Instalētie moduļi';
+$lang['btn_info'] = 'uzziņa';
+$lang['btn_update'] = 'atjaunināt';
+$lang['btn_delete'] = 'dzēst';
+$lang['btn_settings'] = 'parametri';
+$lang['btn_download'] = 'Lejupielādēt';
+$lang['btn_enable'] = 'Saglabāt';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalēts:';
+$lang['lastupdate'] = 'Atjaunināts:';
+$lang['source'] = 'Avots:';
+$lang['unknown'] = 'nav zināms';
+$lang['updating'] = 'Atjauninu...';
+$lang['updated'] = 'Modulis %s veiksmīgi atjaunināts';
+$lang['updates'] = 'Veiksmīgi atjaunināti moduļi:';
+$lang['update_none'] = 'Jauninājums nav atrasts';
+$lang['deleting'] = 'Dzēšu...';
+$lang['deleted'] = 'Modulis %s dzēsts';
+$lang['downloading'] = 'Lejupielādēju...';
+$lang['downloaded'] = 'Modulis %s veiksmīgi instalēts';
+$lang['downloads'] = 'Veiksmīgi instalēti moduļi: ';
+$lang['download_none'] = 'Neviens modulis nav atrasts vai arī gadījusies nezinām kļūme lejupielādes un instalācijas gaitā.';
+$lang['plugin'] = 'Modulis:';
+$lang['components'] = 'Sastāvdaļas';
+$lang['noinfo'] = 'Modulis nesniedz informāciju, tas varbūt ir bojāts.';
+$lang['name'] = 'Nosaukums:';
+$lang['date'] = 'Datums:';
+$lang['type'] = 'Tips:';
+$lang['desc'] = 'Apraksts:';
+$lang['author'] = 'Autors:';
+$lang['www'] = 'Mājaslapa:';
+$lang['error'] = 'Gadījās nezināma kļūme.';
+$lang['error_download'] = 'Nevar lejupielādēt moduļa failu %s';
+$lang['error_badurl'] = 'Aizdomas par aplamu URL - jo no tā nevar noteikt faila vārdu.';
+$lang['error_dircreate'] = 'Nevar izveidot pagaidu direktoriju, kur saglabāt lejupielādēto. ';
+$lang['error_decompress'] = 'Moduļu pārvaldnieks nevar atspiest lejupielādēto failu. Vai nu neizdevusi es lejupielāde, mēģiniet atkārtot, vai arī nezinām arhīva formāts un tad modulis jāielādē un jāinstalē tev pašam.';
+$lang['error_copy'] = 'Faila kopēšanas kļūda instalējot moduli<em>%s</em>: disks pārpildīts vai aplamas piekļuves tiesības. Rezultātā var iegūt daļēji instalētu moduli un nestabilu Wiki sistēmu.';
+$lang['error_delete'] = 'Kļūme dzēšot moduli <em>%s</em>. Ticamākais iemesls ir direktorijas pieejas tiesību trūkums. ';
+$lang['enabled'] = 'Modulis %s pieslēgts.';
+$lang['notenabled'] = 'Moduli %s nevar pieslēgt, pārbaudi failu tiesības.';
+$lang['disabled'] = 'Modulis %s atslēgts.';
+$lang['notdisabled'] = 'Moduli %s nevar atslēgt, pārbaudi failu tiesības.';
diff --git a/lib/plugins/plugin/lang/mk/lang.php b/lib/plugins/plugin/lang/mk/lang.php
new file mode 100644
index 000000000..747d61638
--- /dev/null
+++ b/lib/plugins/plugin/lang/mk/lang.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
+$lang['menu'] = 'Уреди ги приклучоците';
+$lang['download'] = 'Симни и инсталирај нов приклучок';
+$lang['manage'] = 'Инсталирани приклучоци';
+$lang['btn_info'] = 'информации';
+$lang['btn_update'] = 'ажурирај';
+$lang['btn_delete'] = 'избриши';
+$lang['btn_settings'] = 'поставувања';
+$lang['btn_download'] = 'Симни';
+$lang['btn_enable'] = 'Зачувај';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Инсталирани:';
+$lang['lastupdate'] = 'Последно ажурирани:';
+$lang['source'] = 'Извор:';
+$lang['unknown'] = 'непознат';
+$lang['updating'] = 'Ажурирам...';
+$lang['updated'] = 'Приклучокот %s е успешно ажуриран';
+$lang['updates'] = 'Следниве приклучоци се успешно ажурирани';
+$lang['update_none'] = 'Нема потребни ажурирања.';
+$lang['deleting'] = 'Бришам...';
+$lang['deleted'] = 'Приклучокот %s е избришан.';
+$lang['downloading'] = 'Симнувам...';
+$lang['downloaded'] = 'Приклучокот %s е успешно инсталиран';
+$lang['downloads'] = 'Следниве приклучоци се успешно инсталирани';
+$lang['download_none'] = 'Нема пронајдени приклучоци, или имаше непознат проблем при симнување и инсталирање.';
+$lang['plugin'] = 'Приклучок:';
+$lang['components'] = 'Компоненти';
+$lang['noinfo'] = 'Овој приклучок не врати информации, може да не е валиден.';
+$lang['name'] = 'Име:';
+$lang['date'] = 'Датум:';
+$lang['type'] = 'Тип:';
+$lang['desc'] = 'Опис:';
+$lang['author'] = 'Автор:';
+$lang['www'] = 'Веб:';
+$lang['error'] = 'Се појави непозната грешка.';
+$lang['error_download'] = 'Не сум во можност да ја симнам датотеката за приклучокот: %s';
+$lang['enabled'] = 'Приклучокот %s е овозможен.';
+$lang['disabled'] = 'Приклучокот %s е оневозможен.';
diff --git a/lib/plugins/plugin/lang/mr/admin_plugin.txt b/lib/plugins/plugin/lang/mr/admin_plugin.txt
new file mode 100644
index 000000000..a925a560f
--- /dev/null
+++ b/lib/plugins/plugin/lang/mr/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== प्लगिन व्यवस्थापन ======
+
+या पानावर तुम्ही डॉक्युविकि [[doku>plugins|प्लगिन]] च्या सर्व बाबींची व्यवस्था लावू शकता.
+प्लगिन डाउनलोड व इन्स्टॉल करण्यासाठी तुमच्या प्लगिन फोल्डरवर तुमच्या वेबसर्वरला लेखनाची परवानगी असली पाहिजे. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/mr/lang.php b/lib/plugins/plugin/lang/mr/lang.php
new file mode 100644
index 000000000..3f81739fa
--- /dev/null
+++ b/lib/plugins/plugin/lang/mr/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['menu'] = 'प्लगिनची व्यवस्था लावा';
+$lang['download'] = 'नवीन प्लगिन डाउनलोड करून इन्स्टॉल करा';
+$lang['manage'] = 'इन्स्टॉल केलेले प्लगिन';
+$lang['btn_info'] = 'माहिती';
+$lang['btn_update'] = 'अद्ययावत';
+$lang['btn_delete'] = 'डिलीट';
+$lang['btn_settings'] = 'सेटिंग';
+$lang['btn_download'] = 'डाउनलोड';
+$lang['btn_enable'] = 'सुरक्षित';
+$lang['url'] = 'URL';
+$lang['installed'] = 'इन्स्टॉलची वेळ :';
+$lang['lastupdate'] = 'शेवटच्या बदलाची वेळ :';
+$lang['source'] = 'स्त्रोत :';
+$lang['unknown'] = 'अगम्य';
+$lang['updating'] = 'अद्ययावत करतोय ...';
+$lang['updated'] = 'प्लगिन %s यशास्विरित्य अद्ययावत केला.';
+$lang['updates'] = 'खालील प्लगिन यशस्वीरीत्या अद्ययावत झाले';
+$lang['update_none'] = 'काही बदल मिळाले नाहीत.';
+$lang['deleting'] = 'डिलीट करतोय ...';
+$lang['deleted'] = '%s प्लगिन डिलीट केला.';
+$lang['downloading'] = 'डाउनलोड करतोय ...';
+$lang['downloaded'] = '%s प्लगिन यशस्वीरीत्या इन्स्टॉल झाला.';
+$lang['downloads'] = 'खालील प्लगिन यशस्वीरीत्या इन्स्टॉल झाले : ';
+$lang['download_none'] = 'एकही प्लगिन मिळाला नाही, किंवा डाउनलोड आणि इन्स्टॉल मधे काही अज्ञात अडचण आली असावी.';
+$lang['plugin'] = 'प्लगिन : ';
+$lang['components'] = 'भाग : ';
+$lang['noinfo'] = 'या प्लगिनने काही माहिती दिली नाही. बहुधा हा अवैध असावा.';
+$lang['name'] = 'नाव :';
+$lang['date'] = 'दिनांक :';
+$lang['type'] = 'टाइप : ';
+$lang['desc'] = 'वर्णन : ';
+$lang['author'] = 'लेखक : ';
+$lang['www'] = 'वेब : ';
+$lang['error'] = 'अज्ञात अडचण आली.';
+$lang['error_download'] = 'डाउनलोड न झालेली प्लगिन फाइल : %s';
+$lang['error_badurl'] = 'बहुधा चुकीचे URL - URL वरून फाइलचे नाव ठरवता आले नाही.';
+$lang['error_dircreate'] = 'डाउनलोड साठवण्यासाठी तात्पुरता फोल्डर तयार करू शकलो नाही';
+$lang['error_decompress'] = 'प्लगिन व्यवस्थापक डाउनलोड केलेली फाइल विस्तारित करू शकला नाही. हे कदाचित डाउनलोड नीट न झाल्यामुळे असावं; असे असल्यास तुमची परत डाउनलोड करण्याचा प्रयत्न करू शकता; किंवा प्लगिन संक्षिप्त करण्यास वापरलेली पद्धत अनाकलनीय आहे; तसे असल्यास तुम्हाला स्वतः प्लगिन डाउनलोड व इन्स्टॉल करावा लागेल.';
+$lang['error_copy'] = '<em>%s</em> प्लगिनसाठी फाइल इन्स्टॉल करताना फाइल कॉपी करू शकलो नाही : डिस्क भरली असेल किंवा फाइल वरील परवानग्या बरोबर नसतील. यामुळे प्लगिन अर्धवट इन्स्टॉल जाला असण्याची व त्यामुळे तुमची विकी ख़राब होण्याची शक्यता आहे.';
+$lang['error_delete'] = '<em>%s</em> प्लगिन डिलीट करताना काही चूक झाली आहे. फाइल किंवा डिरेक्टरी वरील परवानग्या बरोबर नसणे हे याचं मुख्य कारण असू शकतं.';
+$lang['enabled'] = '%s प्लगइन चालू केला.';
+$lang['notenabled'] = '%s प्लगइन चालू करू शकलो नाही, फाइलच्या परवानग्या तपासा.';
+$lang['disabled'] = '%s प्लगइन बंद केला.';
+$lang['notdisabled'] = '%s प्लगइन बंद करू शकलो नाही, फाइलच्या परवानग्या तपासा.';
diff --git a/lib/plugins/plugin/lang/ms/lang.php b/lib/plugins/plugin/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/plugin/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/plugin/lang/ne/lang.php b/lib/plugins/plugin/lang/ne/lang.php
new file mode 100644
index 000000000..27c4f3b60
--- /dev/null
+++ b/lib/plugins/plugin/lang/ne/lang.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['menu'] = 'प्लगिन व्यवस्थापन गर्नुहोस।';
+$lang['download'] = 'नयाँ प्लगिन डाउनलोड गरी स्थापना गर्नुहोस्';
+$lang['manage'] = 'स्थापित प्लगिनहरु';
+$lang['btn_info'] = 'जानकारी';
+$lang['btn_update'] = 'अध्यावधिक गर्नुहोस';
+$lang['btn_delete'] = 'मेटाउनुहोस्';
+$lang['btn_settings'] = 'व्यवस्थापन';
+$lang['btn_download'] = 'डाउनलोड गर्नुहोस्';
+$lang['btn_enable'] = 'वचत गर्नुहोस्';
+$lang['url'] = 'URL';
+$lang['installed'] = 'स्थापित';
+$lang['lastupdate'] = 'अन्तिम अध्यावधिक :';
+$lang['source'] = 'स्रोत:';
+$lang['unknown'] = 'थाह नभएको';
+$lang['updating'] = 'अध्यावधिक गर्दै......';
+$lang['updated'] = 'प्लगिन %s सफलतापूर्वक अध्यावधिक भयो ';
+$lang['updates'] = 'निम्न प्लगिनहरु सफलतापूर्वक अध्यावधिक भए।';
+$lang['update_none'] = 'कुनै पनि अध्यावधिकम भेटिएन ।';
+$lang['deleting'] = 'हटाउदै ......';
+$lang['deleted'] = 'प्लगिन %s हटाइयो ।';
+$lang['downloading'] = 'डाउनलोड गर्दै ........';
+$lang['downloaded'] = 'प्लगिन %s सफलतापूर्वक स्थापित भयो ';
+$lang['downloads'] = 'निम्न प्लगिनहरु सफलतापूर्वक स्थापित भए';
+$lang['download_none'] = 'कुनै पनि प्लगइन भेटिएन, या डाउनलोड गर्दा र स्थापना गर्दा त्रुटि भयो ।';
+$lang['plugin'] = 'प्लगिन:';
+$lang['components'] = 'पुर्जाहरु ';
+$lang['noinfo'] = 'यो प्लगइनले कुनै पनि जनाकारी दिएन , यो अमान्य हुनसक्छ ।';
+$lang['name'] = 'नाम:';
+$lang['date'] = 'मिति:';
+$lang['type'] = 'प्रकार :';
+$lang['desc'] = 'जानकारी:';
+$lang['author'] = 'जारीकर्ता:';
+$lang['www'] = 'वेब:';
+$lang['error'] = 'अज्ञात त्रुटि फेला पर्‌यो ।';
+$lang['error_download'] = 'प्लहइन फाइल: %s डाउनलोड गर्न असमर्थ ।';
+$lang['error_badurl'] = 'शंकास्पद खराब url - Url बाट फाइल नाम निश्चित गर्न असमर्थ ।';
+$lang['error_dircreate'] = 'डाउनलोड प्राप्त गर्नको निमि्त्त अस्थाइ फोल्डर निर्माण गर्न असमर्थ ।';
diff --git a/lib/plugins/plugin/lang/nl/admin_plugin.txt b/lib/plugins/plugin/lang/nl/admin_plugin.txt
new file mode 100644
index 000000000..36731b0b0
--- /dev/null
+++ b/lib/plugins/plugin/lang/nl/admin_plugin.txt
@@ -0,0 +1,3 @@
+===== Pluginmanager =====
+
+Op deze pagina kunt u alle DokuWiki [[doku>plugins|plugins]] beheren. Om plugins te kunnen downloaden en installeren, moet de plugin-directory schrijfbaar zijn voor de webserver. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/nl/lang.php b/lib/plugins/plugin/lang/nl/lang.php
new file mode 100644
index 000000000..0599c3184
--- /dev/null
+++ b/lib/plugins/plugin/lang/nl/lang.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Dutch language file
+ *
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['menu'] = 'Plugins beheren';
+$lang['download'] = 'Download en installeer een nieuwe plugin';
+$lang['manage'] = 'Geïnstalleerde plugins';
+$lang['btn_info'] = 'informatie';
+$lang['btn_update'] = 'bijwerken';
+$lang['btn_delete'] = 'verwijderen';
+$lang['btn_settings'] = 'instellingen';
+$lang['btn_download'] = 'Download';
+$lang['btn_enable'] = 'Opslaan';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Geïnstalleerd:';
+$lang['lastupdate'] = 'Laatst bijgewerkt:';
+$lang['source'] = 'Bron:';
+$lang['unknown'] = 'onbekend';
+$lang['updating'] = 'Bijwerken ...';
+$lang['updated'] = 'Plugin %s succesvol bijgewerkt';
+$lang['updates'] = 'De volgende plugins zijn succesvol bijgewerkt';
+$lang['update_none'] = 'Geen updates gevonden.';
+$lang['deleting'] = 'Verwijderen ...';
+$lang['deleted'] = 'Plugin %s verwijderd.';
+$lang['downloading'] = 'Downloaden ...';
+$lang['downloaded'] = 'Plugin %s succesvol geïnstalleerd';
+$lang['downloads'] = 'De volgende plugins zijn succesvol geïnstalleerd:';
+$lang['download_none'] = 'Geen plugins gevonden, of er is een onbekende fout opgetreden tijdens het downloaden en installeren.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Onderdelen';
+$lang['noinfo'] = 'Deze plugin gaf geen informatie terug, misschien is hij defect.';
+$lang['name'] = 'Naam:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Type:';
+$lang['desc'] = 'Omschrijving:';
+$lang['author'] = 'Auteur:';
+$lang['www'] = 'Weblocatie:';
+$lang['error'] = 'Er is een onbekende fout opgetreden.';
+$lang['error_download'] = 'Kan het volgende plugin bestand niet downloaden: %s';
+$lang['error_badurl'] = 'Vermoedelijk onjuiste url - kan de filename niet uit de url afleiden';
+$lang['error_dircreate'] = 'Kan geen tijdelijke directory aanmaken voor de download';
+$lang['error_decompress'] = 'De pluginmanager kan het gedownloade bestand niet uitpakken. Dit kan het resultaat zijn van een mislukte download: probeer het opnieuw; of het compressieformaat is onbekend: in dat geval moet je de plugin handmatig downloaden en installeren.';
+$lang['error_copy'] = 'Er was een probleem met het kopiëren van een bestand tijdens de installatie van plugin <em>%s</em>: de schijf kan vol zijn of onjuiste toegangsrechten hebben. Dit kan tot gevolg hebben dat de plugin slechts gedeeltelijk geïnstalleerd is en kan uw wiki onstabiel maken.';
+$lang['error_delete'] = 'Er is een probleem opgetreden tijdens het verwijderen van plugin <em>%s</em>. De meest voorkomende oorzaak is onjuiste toegangsrechten op bestanden of directory\'s.';
+$lang['enabled'] = 'Plugin %s ingeschakeld.';
+$lang['notenabled'] = 'Plugin %s kon niet worden ingeschakeld, controleer bestandsrechten.';
+$lang['disabled'] = 'Plugin %s uitgeschakeld.';
+$lang['notdisabled'] = 'Plugin %s kon niet worden uitgeschakeld, controleer bestandsrechten.';
+$lang['packageinstalled'] = 'Plugin package (%d plugin%s: %s) succesvol geïnstalleerd.';
diff --git a/lib/plugins/plugin/lang/no/admin_plugin.txt b/lib/plugins/plugin/lang/no/admin_plugin.txt
new file mode 100644
index 000000000..1765b671d
--- /dev/null
+++ b/lib/plugins/plugin/lang/no/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Behandle programtillegg ======
+
+På denne siden kan du behandle alt som har å gjøre med DokuWikis [[doku>plugins|tillegg]]. For å kunne laste ned og installere et tillegg må webserveren ha skrivetilgang til mappen for tillegg.
diff --git a/lib/plugins/plugin/lang/no/lang.php b/lib/plugins/plugin/lang/no/lang.php
new file mode 100644
index 000000000..829d29387
--- /dev/null
+++ b/lib/plugins/plugin/lang/no/lang.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Norwegianlanguage file
+ *
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['menu'] = 'Behandle programtillegg';
+$lang['download'] = 'Last ned og installer et programtillegg';
+$lang['manage'] = 'Installerte programtillegg';
+$lang['btn_info'] = 'informasjon';
+$lang['btn_update'] = 'oppdater';
+$lang['btn_delete'] = 'slett';
+$lang['btn_settings'] = 'innstillinger';
+$lang['btn_download'] = 'Last ned';
+$lang['btn_enable'] = 'Lagre';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Installert:';
+$lang['lastupdate'] = 'Sist oppdatert:';
+$lang['source'] = 'Kilde:';
+$lang['unknown'] = 'ukjent';
+$lang['updating'] = 'Oppdaterer ...';
+$lang['updated'] = 'Tillegget %s er oppdatert';
+$lang['updates'] = 'Følgende programtillegg har blitt oppdatert';
+$lang['update_none'] = 'Ingen oppdateringer funnet.';
+$lang['deleting'] = 'Sletter ...';
+$lang['deleted'] = 'Tillegget %s ble slettet.';
+$lang['downloading'] = 'Laster ned ...';
+$lang['downloaded'] = 'Tillegget %s ble installert';
+$lang['downloads'] = 'De følgende tilleggene ble installert';
+$lang['download_none'] = 'Ingen tillegg funnet, eller det har vært et ukjent problem under nedlasting og installering.';
+$lang['plugin'] = 'Tillegg:';
+$lang['components'] = 'Komponenter';
+$lang['noinfo'] = 'Tillegget ga ikke noe informasjon. Det kan være ugyldig.';
+$lang['name'] = 'Navn:';
+$lang['date'] = 'Dato:';
+$lang['type'] = 'Type:';
+$lang['desc'] = 'Beskrivelse:';
+$lang['author'] = 'Forfatter:';
+$lang['www'] = 'Nett:';
+$lang['error'] = 'En ukjent feil oppstod.';
+$lang['error_download'] = 'Klarte ikke å laste ned tillegget i filen: %s';
+$lang['error_badurl'] = 'Mistenker feil URL - klarte ikke å finne filnavnet i URLen';
+$lang['error_dircreate'] = 'Klarte ikke å lage en midlertidig mappe for å laste ned';
+$lang['error_decompress'] = 'Tilleggsbehandleren klarte ikke å dekomprimere den nedlastede filen. Dette kan være på grunn av en feilet nedlasting, i så fall bør du prøve igjen, eller kompresjonsformatet kan være ukjent, i så fall må du laste ned og installere tillegget manuelt.';
+$lang['error_copy'] = 'Det skjedde en feil ved kopiering av en fil under installasjonen av <em>%s</em>: disken kan være full eller rettighetene satt feil. Dette kan ha ført til et delvist installert tillegg og gjort wikien ubrukelig.';
+$lang['error_delete'] = 'Det skjedde en feil under forsøket på å slette tillegget <em>%s</em>. Den mest sannsynlige grunnen er utilstrekkelige rettigheter for filene eller mappene.';
+$lang['enabled'] = 'Tillegget %s aktivert';
+$lang['notenabled'] = 'Plugin %s kunne ikke aktiveres, sjekk filrettighetene.';
+$lang['disabled'] = 'Plugin %s deaktivert';
+$lang['notdisabled'] = 'Plugin %s kunne ikke deaktiveres, sjekk filrettighetene.';
+$lang['packageinstalled'] = 'Installasjonen av tilleggspakka (%d tillegg: %s) var vellykka';
diff --git a/lib/plugins/plugin/lang/pl/admin_plugin.txt b/lib/plugins/plugin/lang/pl/admin_plugin.txt
new file mode 100644
index 000000000..f01048198
--- /dev/null
+++ b/lib/plugins/plugin/lang/pl/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Menadżer wtyczek ======
+
+Na tej stronie możesz zarządzać wszystkim co jest związane z [[doku>plugins|wtyczkami]] Dokuwiki. Aby móc ściągnąć i zainstalować wtyczkę, serwer WWW musi mieć prawo do zapisu w katalogu ''plugins''.
+
+
diff --git a/lib/plugins/plugin/lang/pl/lang.php b/lib/plugins/plugin/lang/pl/lang.php
new file mode 100644
index 000000000..02459f1de
--- /dev/null
+++ b/lib/plugins/plugin/lang/pl/lang.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * polish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Michał Tkacz <mehow@autocom.pl>
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['menu'] = 'Menadżer wtyczek';
+$lang['download'] = 'Ściągnij i zainstaluj nową wtyczkę';
+$lang['manage'] = 'Zainstalowane Wtyczki';
+$lang['btn_info'] = 'Informacje';
+$lang['btn_update'] = 'Aktualizuj';
+$lang['btn_delete'] = 'Usuń';
+$lang['btn_settings'] = 'Ustawienia';
+$lang['btn_download'] = 'Pobierz';
+$lang['btn_enable'] = 'Zapisz';
+$lang['url'] = 'Adres URL';
+$lang['installed'] = 'Instalacja:';
+$lang['lastupdate'] = 'Ostatnio zaktualizowana:';
+$lang['source'] = 'Źródło:';
+$lang['unknown'] = 'nieznane';
+$lang['updating'] = 'Aktualizuję...';
+$lang['updated'] = 'Aktualizacja wtyczki %s pomyślnie ściągnięta';
+$lang['updates'] = 'Aktualizacje następujących wtyczek zostały pomyślnie ściągnięte';
+$lang['update_none'] = 'Nie znaleziono aktualizacji.';
+$lang['deleting'] = 'Usuwam...';
+$lang['deleted'] = 'Wtyczka %s usunięta.';
+$lang['downloading'] = 'Pobieram...';
+$lang['downloaded'] = 'Wtyczka %s pomyślnie zainstalowana';
+$lang['downloads'] = 'Następujące wtyczki zostały pomyślnie zainstalowane:';
+$lang['download_none'] = 'Nie znaleziono wtyczek lub wystąpił nieznany problem podczas ściągania i instalacji.';
+$lang['plugin'] = 'Wtyczka:';
+$lang['components'] = 'Składniki';
+$lang['noinfo'] = 'Ta wtyczka nie zwróciła żadnych informacji, może być niepoprawna.';
+$lang['name'] = 'Nazwa:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Opis:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'WWW:';
+$lang['error'] = 'Wystąpił nieznany błąd.';
+$lang['error_download'] = 'Nie powiodło się ściągnięcie pliku wtyczki: %s';
+$lang['error_badurl'] = 'Prawdopodobnie zły url - nie da się ustalić nazwy pliku na podstawie urla';
+$lang['error_dircreate'] = 'Nie powiodło się stworzenie tymczasowego katalogu na pobrane pliki';
+$lang['error_decompress'] = 'Menadżer wtyczek nie był w stanie rozpakować ściągniętego pliku. Może to być spowodowane przez nieudany transfer (w takim przypadku powinieneś spróbować ponownie) lub nieznany format kompresji (w takim przypadku będziesz musiał ściągnąć i zainstalować wtyczkę ręcznie).';
+$lang['error_copy'] = 'Wystąpił błąd podczas kopiowania pliku w trakcie instalacji wtyczki %s: być może dysk jest pełny lub prawa dostępu są niepoprawne. Efektem może być częściowo zainstalowana wtyczka co może spowodować niestabilność Twojej instalacji wiki.';
+$lang['error_delete'] = 'Wystąpił błąd przy próbie usunięcia wtyczki <em>%s</em>. Prawdopodobną przyczyną są niewystarczające uprawnienia do katalogu.';
+$lang['enabled'] = 'Wtyczka %s włączona.';
+$lang['notenabled'] = 'Nie udało się uruchomić wtyczki %s, sprawdź uprawnienia dostępu do plików.';
+$lang['disabled'] = 'Wtyczka %s wyłączona.';
+$lang['notdisabled'] = 'Nie udało się wyłączyć wtyczki %s, sprawdź uprawnienia dostępu do plików.';
+$lang['packageinstalled'] = 'Pakiet wtyczek (%d wtyczki:% s) zainstalowany pomyślnie.';
diff --git a/lib/plugins/plugin/lang/pt-br/admin_plugin.txt b/lib/plugins/plugin/lang/pt-br/admin_plugin.txt
new file mode 100644
index 000000000..9e49f5136
--- /dev/null
+++ b/lib/plugins/plugin/lang/pt-br/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gerenciamento de Plug-ins ======
+
+Nesta página você pode gerenciar tudo relacionado aos [[doku>plugins|plug-ins]] do DokuWiki. Para você baixar e instalar um plug-in o servidor web deve ter permissão de escrita na pasta onde ficam os plug-ins.
diff --git a/lib/plugins/plugin/lang/pt-br/lang.php b/lib/plugins/plugin/lang/pt-br/lang.php
new file mode 100644
index 000000000..26e73f4fc
--- /dev/null
+++ b/lib/plugins/plugin/lang/pt-br/lang.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['menu'] = 'Gerenciar Plug-ins';
+$lang['download'] = 'Baixar e instalar um novo plug-in';
+$lang['manage'] = 'Plug-ins instalados';
+$lang['btn_info'] = 'informações';
+$lang['btn_update'] = 'atualizar';
+$lang['btn_delete'] = 'excluir';
+$lang['btn_settings'] = 'configurações';
+$lang['btn_download'] = 'Baixar';
+$lang['btn_enable'] = 'Salvar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalação:';
+$lang['lastupdate'] = 'Última atualização:';
+$lang['source'] = 'Fonte:';
+$lang['unknown'] = 'desconhecida';
+$lang['updating'] = 'Atualizando...';
+$lang['updated'] = 'O plug-in %s foi atualizado com sucesso';
+$lang['updates'] = 'Os seguintes plug-ins foram atualizados com sucesso';
+$lang['update_none'] = 'Não foi encontrada nenhuma atualização.';
+$lang['deleting'] = 'Excluindo...';
+$lang['deleted'] = 'O plug-in %s foi excluído.';
+$lang['downloading'] = 'Baixando...';
+$lang['downloaded'] = 'O plug-in %s foi instalado com sucesso';
+$lang['downloads'] = 'Os seguintes plug-ins foram instalados com sucesso:';
+$lang['download_none'] = 'O plug-in não foi encontrado ou então ocorreu um problema desconhecido durante a transferência e instalação.';
+$lang['plugin'] = 'Plug-in:';
+$lang['components'] = 'Componentes';
+$lang['noinfo'] = 'Esse plug-in não retornou nenhuma informação. Ele pode ser inválido.';
+$lang['name'] = 'Nome:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descrição:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ocorreu um erro desconhecido.';
+$lang['error_download'] = 'Não foi possível baixar o arquivo de plug-in: %s';
+$lang['error_badurl'] = 'Suspeita de URL mal formatada - não foi possível determinar o nome do arquivo a partir da URL';
+$lang['error_dircreate'] = 'Não foi possível criar a pasta temporária para receber a transferência';
+$lang['error_decompress'] = 'O gerenciador de plug-ins não conseguiu descompactar o arquivo transferido. Isso pode ser resultado de: uma corrupção do arquivo durante a transferência, nesse caso, você deve tentar novamente; ou o formato da compactação pode ser desconhecido, nesse caso você deve transferir e instalar o plug-in manualmente.';
+$lang['error_copy'] = 'Ocorreu um erro de cópia de arquivo na tentativa de instalar o plug-in <em>%s</em>: o disco pode estar cheio ou as permissões de acesso ao arquivo podem estar erradas. Isso pode resultar em um plug-in parcialmente instalado e tornar o seu wiki instável.';
+$lang['error_delete'] = 'Ocorreu um erro na tentativa de excluir o plug-in <em>%s</em>. A causa mais provável é a permissão de acesso insuficiente ao diretório ou ao arquivo.';
+$lang['enabled'] = 'O plug-in %s foi habilitado.';
+$lang['notenabled'] = 'Não foi possível habilitar o plug-in %s. Verifique as permissões de acesso.';
+$lang['disabled'] = 'O plug-in %s foi desabilitado.';
+$lang['notdisabled'] = 'Não foi possível desabilitar o plug-in %s. Verifique as permissões de acesso.';
+$lang['packageinstalled'] = 'O pacote do plugin (%d plugin(s): %s) foi instalado com sucesso.';
diff --git a/lib/plugins/plugin/lang/pt/admin_plugin.txt b/lib/plugins/plugin/lang/pt/admin_plugin.txt
new file mode 100644
index 000000000..2cc470193
--- /dev/null
+++ b/lib/plugins/plugin/lang/pt/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Gestor de Plugins ======
+
+Nesta página pode gerir tudo o que tenha a haver com [[doku>plugins|plugins]] DokuWiki. Atenção que a pasta que contém os plugins precisa de ter permissões de escrita para se poder efectuar o download. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/pt/lang.php b/lib/plugins/plugin/lang/pt/lang.php
new file mode 100644
index 000000000..dccd4f738
--- /dev/null
+++ b/lib/plugins/plugin/lang/pt/lang.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Portugueselanguage file
+ *
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['menu'] = 'Gerir Plugins';
+$lang['download'] = 'Descarregar e instalar um novo plugin';
+$lang['manage'] = 'Plugins Instalados';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualizar';
+$lang['btn_delete'] = 'remover';
+$lang['btn_settings'] = 'configurações';
+$lang['btn_download'] = 'Descarregar';
+$lang['btn_enable'] = 'Guardar';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalado em:';
+$lang['lastupdate'] = 'Actualizado em:';
+$lang['source'] = 'Fonte:';
+$lang['unknown'] = 'desconhecida';
+$lang['updating'] = 'Actualizando ...';
+$lang['updated'] = 'Plugin %s actualizado com sucesso.';
+$lang['updates'] = 'Os seguintes plguins foram actualizados com sucesso:';
+$lang['update_none'] = 'Não foram encontradas actualizações.';
+$lang['deleting'] = 'Removendo ...';
+$lang['deleted'] = 'Plugin %s removido.';
+$lang['downloading'] = 'Descarregando ...';
+$lang['downloaded'] = 'Plugin %s instalado com sucesso.';
+$lang['downloads'] = 'Os seguintes plguins foram instalados com sucesso:';
+$lang['download_none'] = 'Nenhum plugin encontrado ou ocorreu um problema ao descarregar ou instalar.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Componentes';
+$lang['noinfo'] = 'Este plugin não retornou qualquer informação, pode estar inválido.';
+$lang['name'] = 'Nome:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipo:';
+$lang['desc'] = 'Descrição:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Sítio:';
+$lang['error'] = 'Ocorreu um erro desconhecido.';
+$lang['error_download'] = 'Impossível descarregar o ficheiro do plugin: %s';
+$lang['error_badurl'] = 'URL suspeito ou errado - impossível determinar o ficheiro a partir do URL';
+$lang['error_dircreate'] = 'Impossível criar pasta temporária para receber os ficheiros a descarregar';
+$lang['error_decompress'] = 'O gestor de plugins foi incapaz de descomprimir o ficheiro transferido. Isto pode ter sido causado por uma má transferência, caso no qual você deverá tentar de novo, ou por um formato de compressão desconhecido, caso no qual você deve instalar o plugin manualmente.';
+$lang['error_copy'] = 'Ocorreu um erro na cópia do ficheiro na tentativa de instalar o plugin <em>%s</em>: o disco pode estar cheio ou as permissões de acesso do ficheiro podem estar erradas. Isto pode resultar em um plugin parcialmente instalado e deixar a instalação do seu wiki instável.';
+$lang['error_delete'] = 'Ocorreu um erro na tentativa de remover o plug-in <em>%s</em>. A causa mais provável é a permissão de acesso à directoria ou ao ficheiro insuficiente.';
+$lang['enabled'] = 'Plugin %s habilitado.';
+$lang['notenabled'] = 'Plugin %s não pôde ser habilitado, verifique as permissões.';
+$lang['disabled'] = 'Plugin %s desabilitado.';
+$lang['notdisabled'] = 'Plugin %s não pôde ser desabilitado, verifique as permissões.';
+$lang['packageinstalled'] = 'Pacote de Plugins (%d plugin(s): %s) instalado com sucesso.';
diff --git a/lib/plugins/plugin/lang/ro/admin_plugin.txt b/lib/plugins/plugin/lang/ro/admin_plugin.txt
new file mode 100644
index 000000000..a2956e45d
--- /dev/null
+++ b/lib/plugins/plugin/lang/ro/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Managementul Plugin-urilor ======
+
+In această pagină puteţi administra orice [[doku>plugins|plugin]] Dokuwiki. Pentru a descărca şi instala un plugin, directorul acestora trebuie să ofere webserver-ului acces la scriere.
diff --git a/lib/plugins/plugin/lang/ro/lang.php b/lib/plugins/plugin/lang/ro/lang.php
new file mode 100644
index 000000000..798ada1c7
--- /dev/null
+++ b/lib/plugins/plugin/lang/ro/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['menu'] = 'Administrează plugin-uri';
+$lang['download'] = 'Descarcă şi instalează un nou plugin';
+$lang['manage'] = 'Plugin-uri instalate';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'actualizare';
+$lang['btn_delete'] = 'ştergere';
+$lang['btn_settings'] = 'setări';
+$lang['btn_download'] = 'Descarcă';
+$lang['btn_enable'] = 'Salvează';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Instalat:';
+$lang['lastupdate'] = 'Ultima actualizare:';
+$lang['source'] = 'Sursa:';
+$lang['unknown'] = 'necunoscut';
+$lang['updating'] = 'Se actualizează ...';
+$lang['updated'] = 'Plugin-ul %s a fost actualizat cu succes';
+$lang['updates'] = 'Următoarele plugin-uri au fost actualizate cu succes';
+$lang['update_none'] = 'Nu a fost găsită nici o actualizare.';
+$lang['deleting'] = 'Se şterge ...';
+$lang['deleted'] = 'Plugin-ul %s a fost şters.';
+$lang['downloading'] = 'Se descarcă ...';
+$lang['downloaded'] = 'Plugin-ul %s a fost instalat cu succes';
+$lang['downloads'] = 'Următoarele plugin-uri au fost instalate cu succes';
+$lang['download_none'] = 'Nici un plugin nu a fost găsit, sau o problemă necunoscută a apărut în timpul descărcării şi instalării.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Componente';
+$lang['noinfo'] = 'Acest plugin nu a furnizat nici o informaţie; ar putea fi invalid.';
+$lang['name'] = 'Nume:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tip:';
+$lang['desc'] = 'Descriere:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'A intervenit o eroare necunoscută.';
+$lang['error_download'] = 'Nu a fost posibilă descărcarea plugin-ului: %s';
+$lang['error_badurl'] = 'url suspectat ca fiind eronat - nu a putut fi determinat numele fişierului din url';
+$lang['error_dircreate'] = 'Nu a putut fi creat directorul temporar pentru descărcarea fişierului';
+$lang['error_decompress'] = 'Administratorul de plugin-uri nu a putut dezarhiva fişierul descărcat. Aceasta se poate datora unei erori la descărcare, caz în care trebuie să încercaţi din nou; sau formatul de arhivare este necunoscut, caz în care va trebui să descărcaţi şi să instalaţi plugin-ul manual.';
+$lang['error_copy'] = 'O eroare la copiere a apărut la instalarea fişierelor plugin-ului <em>%s</em>: discul poate fi plin sau drepturile de acces ale fişierelor sunt incorecte. Aceasta poate avea ca rezultat o instalare parţială a plugin-ului şi o instabilitate a instalării wiki.';
+$lang['error_delete'] = 'O eroare a apărut la ştergerea plugin-ului <em>%s</em>. Cea mai probabilă cauză sunt drepturile de acces insuficiente ale fişierului sau directorului.';
+$lang['enabled'] = 'Plugin %s activat.';
+$lang['notenabled'] = 'Plugin-ul %s nu poate fi activat, verificaţi permisiunile fişierului.';
+$lang['disabled'] = 'Plugin %s dezactivat.';
+$lang['notdisabled'] = 'Plugin-ul %s nu poate fi dezactivat, verificaţi permisiunile fişierului.';
+$lang['packageinstalled'] = 'Pachet modul (%d modul(e): %s) instalat cu succes.';
diff --git a/lib/plugins/plugin/lang/ru/admin_plugin.txt b/lib/plugins/plugin/lang/ru/admin_plugin.txt
new file mode 100644
index 000000000..3e00e4150
--- /dev/null
+++ b/lib/plugins/plugin/lang/ru/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Управление плагинами ======
+
+Здесь вы можете делать всё, что связано с [[doku>plugins|плагинами]] «ДокуВики». Для того, чтобы скачивать и устанавливать плагины, директория плагинов должна быть доступна для записи веб-сервером.
+
+
diff --git a/lib/plugins/plugin/lang/ru/lang.php b/lib/plugins/plugin/lang/ru/lang.php
new file mode 100644
index 000000000..757b607f5
--- /dev/null
+++ b/lib/plugins/plugin/lang/ru/lang.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * russian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Andrew Pleshakov <beotiger@mail.ru>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['menu'] = 'Управление плагинами';
+$lang['download'] = 'Скачать и установить новый плагин';
+$lang['manage'] = 'Установленные плагины';
+$lang['btn_info'] = 'данные';
+$lang['btn_update'] = 'обновить';
+$lang['btn_delete'] = 'удалить';
+$lang['btn_settings'] = 'настройки';
+$lang['btn_download'] = 'Скачать';
+$lang['btn_enable'] = 'Сохранить';
+$lang['url'] = 'Адрес';
+$lang['installed'] = 'Установлен:';
+$lang['lastupdate'] = 'Последнее обновление:';
+$lang['source'] = 'Источник:';
+$lang['unknown'] = 'неизвестно';
+$lang['updating'] = 'Обновление...';
+$lang['updated'] = 'Плагин %s успешно обновлён';
+$lang['updates'] = 'Следующие плагины были успешно обновлены';
+$lang['update_none'] = 'Обновления не найдены.';
+$lang['deleting'] = 'Удаление...';
+$lang['deleted'] = 'Плагин %s удалён.';
+$lang['downloading'] = 'Скачивание...';
+$lang['downloaded'] = 'Плагин %s успешно установлен';
+$lang['downloads'] = 'Следующие плагины были успешно установлены:';
+$lang['download_none'] = 'Плагины не найдены или возникла неизвестная проблема в процессе скачивания и установки.';
+$lang['plugin'] = 'Плагин:';
+$lang['components'] = 'Компоненты';
+$lang['noinfo'] = 'Этот плагин не сообщил никаких данных, он может быть нерабочим.';
+$lang['name'] = 'Название:';
+$lang['date'] = 'Дата:';
+$lang['type'] = 'Тип:';
+$lang['desc'] = 'Описание:';
+$lang['author'] = 'Автор:';
+$lang['www'] = 'Странца:';
+$lang['error'] = 'Произошла неизвестная ошибка.';
+$lang['error_download'] = 'Не могу скачать файл плагина: %s';
+$lang['error_badurl'] = 'Возможно неправильный адрес — не могу определить имя файла из адреса';
+$lang['error_dircreate'] = 'Не могу создать временную директорию для скачивания';
+$lang['error_decompress'] = 'Менеджеру плагинов не удалось распаковать скачанный файл. Это может быть результатом ошибки при скачивании, в этом случае вы можете попробовать снова, или же плагин упакован неизвестным архиватором, тогда вам необходимо скачать и установить плагин вручную.';
+$lang['error_copy'] = 'Произошла ошибка копирования при попытке установки файлов для плагина <em>%s</em>: переполнение диска или неправильные права доступа. Это могло привести к частичной установке плагина и неустойчивости вашей вики.';
+$lang['error_delete'] = 'Произошла ошибка при попытке удалить плагин <em>%s</em>. Наиболее вероятно, что нет необходимых прав доступа к файлам или директориям';
+$lang['enabled'] = 'Плагин %s включён.';
+$lang['notenabled'] = 'Не удалось включить плагин %s. Проверьте системные права доступа к файлам.';
+$lang['disabled'] = 'Плагин %s отключён.';
+$lang['notdisabled'] = 'Не удалось отключить плагин %s. Проверьте системные права доступа к файлам.';
diff --git a/lib/plugins/plugin/lang/sk/admin_plugin.txt b/lib/plugins/plugin/lang/sk/admin_plugin.txt
new file mode 100644
index 000000000..ad3ae7f58
--- /dev/null
+++ b/lib/plugins/plugin/lang/sk/admin_plugin.txt
@@ -0,0 +1,4 @@
+====== Správa pluginov ======
+
+Na tejto stránke je možné spravovať [[doku>plugins|pluginy]] Dokuwiki. Aby bolo možné sťahovať a inštalovať pluginy, musí mať webový server prístup pre zápis do adresára //plugin//.
+
diff --git a/lib/plugins/plugin/lang/sk/lang.php b/lib/plugins/plugin/lang/sk/lang.php
new file mode 100644
index 000000000..5024872f1
--- /dev/null
+++ b/lib/plugins/plugin/lang/sk/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Slovak language file
+ *
+ * @author Ondrej Végh <ov@vsieti.sk>
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['menu'] = 'Správa pluginov';
+$lang['download'] = 'Stiahnuť a nainštalovať plugin';
+$lang['manage'] = 'Nainštalované pluginy';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'aktualizovať';
+$lang['btn_delete'] = 'zmazať';
+$lang['btn_settings'] = 'nastavenia';
+$lang['btn_download'] = 'Stiahnuť';
+$lang['btn_enable'] = 'Uložiť';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Nainštalovaný:';
+$lang['lastupdate'] = 'Aktualizovaný:';
+$lang['source'] = 'Zdroj:';
+$lang['unknown'] = 'neznámy';
+$lang['updating'] = 'Aktualizuje sa ...';
+$lang['updated'] = 'Plugin %s bol úspešne aktualizovaný';
+$lang['updates'] = 'Nasledujúce pluginy bol úspešne aktualizované:';
+$lang['update_none'] = 'Neboli nájdené žiadne aktualizácie.';
+$lang['deleting'] = 'Vymazáva sa ...';
+$lang['deleted'] = 'Plugin %s bol zmazaný.';
+$lang['downloading'] = 'Sťahuje sa ...';
+$lang['downloaded'] = 'Plugin %s bol úspešne stiahnutý';
+$lang['downloads'] = 'Nasledujúce pluginy bol úspešne stiahnuté:';
+$lang['download_none'] = 'Neboli nájdené žiadne pluginy alebo nastal neznámy problém počas sťahovania a inštalácie pluginov.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Súčasti';
+$lang['noinfo'] = 'Tento plugin neobsahuje žiadne informácie, je možné, že je chybný.';
+$lang['name'] = 'názov:';
+$lang['date'] = 'Dátum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Popis:';
+$lang['author'] = 'Autor:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Nastala neznáma chyba.';
+$lang['error_download'] = 'Nie je možné stiahnuť súbor pluginu: %s';
+$lang['error_badurl'] = 'Pravdepodobne zlá url adresa - nie je možné z nej určiť meno súboru';
+$lang['error_dircreate'] = 'Nie je možné vytvoriť dočasný adresár pre uloženie sťahovaného súboru';
+$lang['error_decompress'] = 'Správca pluginov nedokáže dekomprimovať stiahnutý súbor. Môže to byť dôsledok zlého stiahnutia, v tom prípade to skúste znovu, alebo môže ísť o neznámy formát súboru, v tom prípade musíte stiahnuť a nainštalovať plugin manuálne.';
+$lang['error_copy'] = 'Nastala chyba kopírovania súboru počas pokusu inštalovať súbory pluginu<em>%s</em>: disk môže byť plný alebo prístupové práva k súboru môžu byť nesprávne. Toto môže mať za následok čiastočne nainštalovanie pluginu a nestabilitu vašej DokuWiki.';
+$lang['error_delete'] = 'Nastala chyba počas pokusu o zmazanie pluginu <em>%s</em>. Najpravdepodobnejším dôvodom môžu byť nedostatočné prístupové práva pre súbor alebo adresár';
+$lang['enabled'] = 'Plugin %s aktivovaný.';
+$lang['notenabled'] = 'Plugin %s nemôže byť aktivovaný, skontrolujte prístupové práva.';
+$lang['disabled'] = 'Plugin %s deaktivovaný.';
+$lang['notdisabled'] = 'Plugin %s nemôže byť deaktivovaný, skontrolujte prístupové práva.';
+$lang['packageinstalled'] = 'Plugin package (%d plugin(s): %s) úspešne inštalovaný.';
diff --git a/lib/plugins/plugin/lang/sl/admin_plugin.txt b/lib/plugins/plugin/lang/sl/admin_plugin.txt
new file mode 100644
index 000000000..5fd02e1ba
--- /dev/null
+++ b/lib/plugins/plugin/lang/sl/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Upravljanje vstavkov ======
+
+Na tej strani je mogoče spreminjati in prilagajati nastavitve DokuWiki [[doku>plugins|vstavkov]]. Za prejemanje in nameščanje vstavkov v ustrezne mape, morajo imeti te določena ustrezna dovoljenja za pisanje spletnega strežnika.
diff --git a/lib/plugins/plugin/lang/sl/lang.php b/lib/plugins/plugin/lang/sl/lang.php
new file mode 100644
index 000000000..3e5f8c8af
--- /dev/null
+++ b/lib/plugins/plugin/lang/sl/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Dejan Levec <webphp@gmail.com>
+ * @author Boštjan Seničar <senicar@gmail.com>
+ * @author Gregor Skumavc (grega.skumavc@gmail.com)
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['menu'] = 'Upravljanje vstavkov';
+$lang['download'] = 'Prejmi in namesti nov vstavek';
+$lang['manage'] = 'Nameščeni vstavki';
+$lang['btn_info'] = 'Podrobnosti';
+$lang['btn_update'] = 'Posodobi';
+$lang['btn_delete'] = 'Izbriši';
+$lang['btn_settings'] = 'Nastavitve';
+$lang['btn_download'] = 'Prejmi';
+$lang['btn_enable'] = 'Shrani';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Nameščeno:';
+$lang['lastupdate'] = 'Nazadnje posodobljeno:';
+$lang['source'] = 'Vir:';
+$lang['unknown'] = 'neznano';
+$lang['updating'] = 'Posodabljanje ...';
+$lang['updated'] = 'Vstavek %s je uspešno posodobljen';
+$lang['updates'] = 'Navedeni vstavki so uspešno posodobljeni';
+$lang['update_none'] = 'Posodobitev ni mogoče najti.';
+$lang['deleting'] = 'Brisanje ...';
+$lang['deleted'] = 'Vstavek %s je izbrisan.';
+$lang['downloading'] = 'Prejemanje ...';
+$lang['downloaded'] = 'Vstavek %s je uspešno nameščen';
+$lang['downloads'] = 'Navedeni vstavki so uspešno nameščeni:';
+$lang['download_none'] = 'Vstavkov ni mogoče najti ali pa je prišlo do napake med prejemanjem in nameščanjem.';
+$lang['plugin'] = 'Vstavek:';
+$lang['components'] = 'Sestavni deli';
+$lang['noinfo'] = 'Vstavek nima vpisanih podrobnih podatkov, kar pomeni, da je morda neveljaven.';
+$lang['name'] = 'Ime:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Vrsta:';
+$lang['desc'] = 'Opis:';
+$lang['author'] = 'Avtor:';
+$lang['www'] = 'Spletna stran:';
+$lang['error'] = 'Prišlo je do neznane napake.';
+$lang['error_download'] = 'Ni mogoče prejeti datoteke vstavka: %s';
+$lang['error_badurl'] = 'Napaka naslova URL - ni mogoče določiti imena datoteke iz naslova URL';
+$lang['error_dircreate'] = 'Ni mogoče ustvariti začasne mape za prejemanje';
+$lang['error_decompress'] = 'Z upravljalnikom vstavkov ni mogoče razširiti prejetega arhiva vstavka. Najverjetneje je prišlo do napake med prejemanjem datoteke ali pa zapis arhiva ni znan. Poskusite znova ali pa napako odpravite z ročnim nameščanjem vstavka.';
+$lang['error_copy'] = 'Prišlo je do napake med nameščanjem datotek vstavka <em>%s</em>: najverjetneje so težave s prostorom za namestitev ali pa ni ustreznih dovoljenj za nameščanje. Zaradi nepopolne namestitve lahko nastopijo težave v delovanju sistema Wiki.';
+$lang['error_delete'] = 'Prišlo je do napake med brisanjem vstavka <em>%s</em>: najverjetneje ni ustreznih dovoljenj za dostop do datoteke ali mape';
+$lang['enabled'] = 'Vstavek %s je omogočen.';
+$lang['notenabled'] = 'Vstavka %s ni mogoče omogočiti zaradi neustreznih dovoljen.';
+$lang['disabled'] = 'Vstavek %s je onemogočen.';
+$lang['notdisabled'] = 'Vstavka %s ni mogoče onemogočiti zaradi neustreznih dovoljen.';
+$lang['packageinstalled'] = 'Paket vstavka (%d vstavkov: %s) je uspešno nameščen.';
diff --git a/lib/plugins/plugin/lang/sq/admin_plugin.txt b/lib/plugins/plugin/lang/sq/admin_plugin.txt
new file mode 100644
index 000000000..2e1f19234
--- /dev/null
+++ b/lib/plugins/plugin/lang/sq/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Menaxhimi i Plugin-eve ======
+
+Në këtë faqe mund të menaxhoni çdo gjë që ka të bëjë me [[doku>plugins|plugin-et]] Dokuwiki. Që të jetë në gjendje për të shkarkuar dhe instaluar një plugin, dosja e plugin-it duhet të jetë e shkrueshme nga webserver-i. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/sq/lang.php b/lib/plugins/plugin/lang/sq/lang.php
new file mode 100644
index 000000000..9ddcf527f
--- /dev/null
+++ b/lib/plugins/plugin/lang/sq/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['menu'] = 'Menaxho Plugin-et';
+$lang['download'] = 'Shkarko dhe instalo një plugin të ri';
+$lang['manage'] = 'Plugin-et e Instaluar';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'përditëso';
+$lang['btn_delete'] = 'fshi';
+$lang['btn_settings'] = 'settings';
+$lang['btn_download'] = 'Shkarko';
+$lang['btn_enable'] = 'Ruaj';
+$lang['url'] = 'URL';
+$lang['installed'] = 'Të instaluar:';
+$lang['lastupdate'] = 'Përditësuar së fundmi:';
+$lang['source'] = 'Kodi Burim:';
+$lang['unknown'] = 'e panjohur';
+$lang['updating'] = 'Duke u përditësuar...';
+$lang['updated'] = 'Plugini %s u përditësua me sukses';
+$lang['updates'] = 'Plugin-et e mëposhtme u përditësuan me sukses';
+$lang['update_none'] = 'Nuk u gjetën përditësime.';
+$lang['deleting'] = 'Duke fshirë...';
+$lang['deleted'] = 'Plugini %s u fshi.';
+$lang['downloading'] = 'Duke shkarkuar...';
+$lang['downloaded'] = 'Plugini %s u instalua me sukses';
+$lang['downloads'] = 'Plugin-et e mëposhtëm u instaluan me sukses:';
+$lang['download_none'] = 'Asnjë plugin nuk u gjend, ose ka ndodhur një gabim i panjohur gjatë shkarkimit dhe instalimit.';
+$lang['plugin'] = 'Plugin:';
+$lang['components'] = 'Përbërësit:';
+$lang['noinfo'] = 'Ky plugin nuk ktheu asnjë informacion, mund të jetë i pavlefshëm.';
+$lang['name'] = 'Emri:';
+$lang['date'] = 'Data:';
+$lang['type'] = 'Tipi:';
+$lang['desc'] = 'Përshkrimi:';
+$lang['author'] = 'Autori:';
+$lang['www'] = 'Web:';
+$lang['error'] = 'Ndodhi një gabim i panjohur.';
+$lang['error_download'] = 'Nuk mundi të shkarkohej skedari i plugin-it: %s';
+$lang['error_badurl'] = 'Dyshohet url e prishur - nuk mund të gjendet emri i skedarit nga url-ja';
+$lang['error_dircreate'] = 'Nuk mundi të krijohej dosja e përkohshme për të marë shkarkimin.';
+$lang['error_decompress'] = 'Menaxhuesi i plugin-eve nuk ishte në gjendje të dekompresonte skedarin e shkarkuar. Kjo mund të jetë si rezultat i një shkarkimi të keq, në këtë rast duhet të provoni përsëri; ose formati i kompresimit mund të jetë i panjohur, në këtë rast do t\'ju duhet ta shkarkoni dhe instaloni plugin-in manualisht.';
+$lang['error_copy'] = 'Ndodhi gabim kopjim-skedari gjatë përpjekjes për të instaluar skedarët për plugin-in <em>%s</em>: disku mund të jetë plotë ose të drejtat për aksesim skedari mund të jenë të gabuara. Kjo mund të ketë shkaktuar një instalim të pjesshëm të plugin-it dhe ta lërë instalimin e wiki-t tënd të paqëndrueshëm.';
+$lang['error_delete'] = 'Ndodhi një gabim gjatë përpjekjes për të fshirë plugin-in <em>%s</em>. Shkaku më i mundshëm është të drejta të pamjaftueshme për aksesim skedari ose dosjeje.';
+$lang['enabled'] = 'Plugini %s u aktivizua.';
+$lang['notenabled'] = 'Plugini %s nuk mundi të aktivizohej, kontrollo të drejtat e aksesit për skedarin.';
+$lang['disabled'] = 'Plugin %s është i paaktivizuar.';
+$lang['notdisabled'] = 'Plugini %s nuk mundi të çaktivizohej, kontrollo të drejtat e aksesit për skedarin.';
diff --git a/lib/plugins/plugin/lang/sr/admin_plugin.txt b/lib/plugins/plugin/lang/sr/admin_plugin.txt
new file mode 100644
index 000000000..6262ece40
--- /dev/null
+++ b/lib/plugins/plugin/lang/sr/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Управљач додацима ======
+
+На овој страни можете управљати са свим у вези DokuWiki [[doku>plugins|додацима]]. Да бисте имали могућност преузимања и инсталирања додатака, фасцикла за додатке мора имати дозволу за писање. \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/sr/lang.php b/lib/plugins/plugin/lang/sr/lang.php
new file mode 100644
index 000000000..bc22770a1
--- /dev/null
+++ b/lib/plugins/plugin/lang/sr/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['menu'] = 'Управљач додацима';
+$lang['download'] = 'Преузми и инсталирај нови додатак';
+$lang['manage'] = 'Инсталирани додаци';
+$lang['btn_info'] = 'инфо';
+$lang['btn_update'] = 'ажурирај';
+$lang['btn_delete'] = 'обриши';
+$lang['btn_settings'] = 'поставке';
+$lang['btn_download'] = 'Преузми';
+$lang['btn_enable'] = 'Сачувај';
+$lang['url'] = 'УРЛ';
+$lang['installed'] = 'Инсталирани:';
+$lang['lastupdate'] = 'Последњи пут ажурирани:';
+$lang['source'] = 'Извор:';
+$lang['unknown'] = 'непознат';
+$lang['updating'] = 'Ажурирање:';
+$lang['updated'] = 'Додатак %s је успешно ажуриран';
+$lang['updates'] = 'Следећи додаци су успешно ажурирани';
+$lang['update_none'] = 'Нема доступних ажурирања.';
+$lang['deleting'] = 'Брисање...';
+$lang['deleted'] = 'Додатак %s је обрисан.';
+$lang['downloading'] = 'Преузимање...';
+$lang['downloaded'] = 'Додатак %s је успешно инсталиран';
+$lang['downloads'] = 'Следећи додаци су успешно инсталирани:';
+$lang['download_none'] = 'Нема додатака, или се јавио непознат проблем током преузимања или инсталирања.';
+$lang['plugin'] = 'Додатак:';
+$lang['components'] = 'Компоненте';
+$lang['noinfo'] = 'Овај додатак не враћа никакве информације, можда је неисправан.';
+$lang['name'] = 'Име:';
+$lang['date'] = 'Датум:';
+$lang['type'] = 'Врста:';
+$lang['desc'] = 'Опис:';
+$lang['author'] = 'Аутор:';
+$lang['www'] = 'Веб:';
+$lang['error'] = 'Десила се непозната грешка.';
+$lang['error_download'] = 'Немогуће је преузети додатак: %s';
+$lang['error_badurl'] = 'Сумњам на лош УРЛ - немогу да одредим назив датотеке ';
+$lang['error_dircreate'] = 'Немогућност прављења привремене фасцикле за преузимање';
+$lang['error_decompress'] = 'Управљач додацима није у могућности да распакује преузету датотеку. Разлог може да буде лошег преузимања, у том случају пробајте још једном; или је непознат облик компресије, у том случају ручно преузмите и инсталирајте додатак.';
+$lang['error_copy'] = 'Појавила се грешка у копирању у току иснталације додатка <em>%s</em>: складиште је можда пуно или дозволе за уписивање нису постављене како треба. Резултат може бити делимично инсталиран додатак и вики у нестабилном стању.';
+$lang['error_delete'] = 'Појавила се грешка у покушају брисања додатка <em>%s</em>. Нејчешћи узрок је недостатак потребних дозвола за операције са датотекама или фасциклама';
+$lang['enabled'] = 'Додатај %s је укључен.';
+$lang['notenabled'] = 'Додатак %s није могуће укључити, проверите дозволе приступа.';
+$lang['disabled'] = 'Додатај %s је исукључен.';
+$lang['notdisabled'] = 'Додатак %s није могуће исукључити, проверите дозволе приступа.';
diff --git a/lib/plugins/plugin/lang/sv/admin_plugin.txt b/lib/plugins/plugin/lang/sv/admin_plugin.txt
new file mode 100644
index 000000000..e490e5e60
--- /dev/null
+++ b/lib/plugins/plugin/lang/sv/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== Hantera insticksmoduler ======
+
+På den här sidan kan man hantera allting som har att göra med Dokuwikis [[doku>plugins|insticksmoduler]]. För att man ska kunna ladda ned och installera en modul måste katalogen för insticksmoduler vara skrivbar av webbservern.
+
+
diff --git a/lib/plugins/plugin/lang/sv/lang.php b/lib/plugins/plugin/lang/sv/lang.php
new file mode 100644
index 000000000..5892e42b5
--- /dev/null
+++ b/lib/plugins/plugin/lang/sv/lang.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * swedish language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['menu'] = 'Hantera insticksmoduler';
+$lang['download'] = 'Ladda ned och installera en ny insticksmodul';
+$lang['manage'] = 'Installerade insticksmoduler';
+$lang['btn_info'] = 'info';
+$lang['btn_update'] = 'uppdatera';
+$lang['btn_delete'] = 'radera';
+$lang['btn_settings'] = 'inställningar';
+$lang['btn_download'] = 'Ladda ned';
+$lang['btn_enable'] = 'Spara';
+$lang['url'] = 'Webbadress';
+$lang['installed'] = 'Installerad:';
+$lang['lastupdate'] = 'Senast uppdaterad:';
+$lang['source'] = 'Källa:';
+$lang['unknown'] = 'okänd';
+$lang['updating'] = 'Uppdaterar ...';
+$lang['updated'] = 'Insticksmodulen %s uppdaterades';
+$lang['updates'] = 'Följande Insticksmoduler har uppdaterats';
+$lang['update_none'] = 'Inga uppdateringar hittades.';
+$lang['deleting'] = 'Raderar ...';
+$lang['deleted'] = 'Insticksmodulen %s raderad.';
+$lang['downloading'] = 'Laddar ned ...';
+$lang['downloaded'] = 'Insticksmodulen %s installerades';
+$lang['downloads'] = 'Följande insticksmoduler har installerats:';
+$lang['download_none'] = 'Inga insticksmoduler hittades, eller så har det uppstått ett okänt fel under nedladdning och installation.';
+$lang['plugin'] = 'Insticksmodul:';
+$lang['components'] = 'Komponenter';
+$lang['noinfo'] = 'Den här insticksmodulen returnerade ingen information, den kan vara ogiltig.';
+$lang['name'] = 'Namn:';
+$lang['date'] = 'Datum:';
+$lang['type'] = 'Typ:';
+$lang['desc'] = 'Beskrivning:';
+$lang['author'] = 'Författare:';
+$lang['www'] = 'Webb:';
+$lang['error'] = 'Ett okänt fel har inträffat.';
+$lang['error_download'] = 'Kan inte ladda ned fil till insticksmodul: %s';
+$lang['error_badurl'] = 'Misstänkt felaktig webbadress - kan inte bestämma filnamnet från webbadressen';
+$lang['error_dircreate'] = 'Kan inte skapa tillfällig katalog för nedladdade filer';
+$lang['error_decompress'] = 'Hanteraren för insticksmoduler kunde inte dekomprimera den nedladdade filen. Detta kan vara resultatet av en misslyckad nedladdning, och i så fall bör du försöka igen; eller så kan det komprimerade formatet vara okänt, och då måste du ladda ned och installera insticksmodulen manuellt.';
+$lang['error_copy'] = 'Ett filkopieringsfel uppstod under försöket att installera filerna till insticksmodulen <em>%s</em>: disken kan vara full eller så kan filskyddet vara felaktigt. Detta kan ha lett till en delvis installerad insticksmodul, och gjort din wiki-installation instabil.';
+$lang['error_delete'] = 'Ett fel uppstod vid försöket att radera insticksmodulen <em>%s</em>. Den troligaste orsaken är otillräcklig behörighet till filer eller kataloger';
+$lang['enabled'] = 'Tilläggsmodulen %s är aktiverad.';
+$lang['notenabled'] = 'Tilläggsmodulen %s kunde inte aktiveras, kontrollera filrättigheterna.';
+$lang['disabled'] = 'Tiläggsmodulen %s är avaktiverad.';
+$lang['notdisabled'] = 'Tilläggsmodulen %s kunde inte avaktiveras, kontrollera filrättigheterna.';
diff --git a/lib/plugins/plugin/lang/th/admin_plugin.txt b/lib/plugins/plugin/lang/th/admin_plugin.txt
new file mode 100644
index 000000000..8611654be
--- /dev/null
+++ b/lib/plugins/plugin/lang/th/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== ตัวจัดการโปรแกรมเสริม ======
+
+ในหน้านี้คุณสามารถจัดการทุกๆอย่างที่จะต้องทำงานกับ [[doku>plugins|plugins]]โดกุวิกิ เพื่อที่จะสามารถดาวน์โหลดและติดตั้งโปรแกรมเสริม ตัวโฟลเดอร์โปรแกรมเสริม(plugin) จะต้องสามารถเขียนได้โดยเว็บเซิร์ฟเวอร์ \ No newline at end of file
diff --git a/lib/plugins/plugin/lang/th/lang.php b/lib/plugins/plugin/lang/th/lang.php
new file mode 100644
index 000000000..dab094bcd
--- /dev/null
+++ b/lib/plugins/plugin/lang/th/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Arthit Suriyawongkul <arthit@gmail.com>
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['menu'] = 'จัดการปลั๊กอิน';
+$lang['download'] = 'ดาวน์โหลดและติดตั้งปลั๊กอินใหม่';
+$lang['manage'] = 'ปลั๊กอินที่ติดตั้งไว้แล้ว';
+$lang['btn_info'] = 'ข้อมูล';
+$lang['btn_update'] = 'ปรับปรุง';
+$lang['btn_delete'] = 'ลบ';
+$lang['btn_settings'] = 'ตั้งค่า';
+$lang['btn_download'] = 'ดาวน์โหลด';
+$lang['btn_enable'] = 'บันทึก';
+$lang['url'] = 'ที่อยู่เว็บ';
+$lang['installed'] = 'ติดตั้งแล้ว:';
+$lang['lastupdate'] = 'ปรับปรุงล่าสุด:';
+$lang['source'] = 'ต้นกำเนิด';
+$lang['unknown'] = 'ไม่มีข้อมูล';
+$lang['updating'] = 'กำลังปรับปรุง ...';
+$lang['updated'] = 'โปรแกรมเสริม %s ได้รับการปรับปรุงสำเร็จแล้ว';
+$lang['updates'] = 'โปรแกรมเสริมต่อไปนี้ได้รับการปรับปรุงสำเร็จแล้ว';
+$lang['update_none'] = 'ไม่พบการปรับปรุงใดๆ';
+$lang['deleting'] = 'กำลังลบ ...';
+$lang['deleted'] = 'โปรแกรมเสริม %s ถูกลบแล้ว';
+$lang['downloading'] = 'กำลังดาวโหลด ...';
+$lang['downloaded'] = 'โปรแกรมเสริม %s ถูกติดตั้งสำเร็จแล้ว';
+$lang['downloads'] = 'โปรแกรมเสริมต่อไปนี้ได้รับการปรับปรุงสำเร็จแล้ว:';
+$lang['download_none'] = 'ไม่พบโปรแกรมเสริม, หรือมีปัญหาบางประการเกิดขึ้นระหว่างการดาวน์โหลด และติดตั้ง';
+$lang['plugin'] = 'โปรแกรมเสริม:';
+$lang['components'] = '่สวนประกอบ';
+$lang['noinfo'] = 'โปรแกรมเสริมนี้ไม่บอกข้อมูล, มันอาจไม่ใช่โปรแกรมเสริมจริง';
+$lang['name'] = 'ชื่อ:';
+$lang['date'] = 'วันที่:';
+$lang['type'] = 'ชนิด:';
+$lang['desc'] = 'รายละเอียด:';
+$lang['author'] = 'ผู้แต่ง:';
+$lang['www'] = 'เว็บ:';
+$lang['error'] = 'เกิดความผิดพลาดที่ระบุไม่ได้';
+$lang['error_download'] = 'ไม่สามารถดาวน์โหลดไฟล์โปรแกรมเสริม: %s';
+$lang['error_dircreate'] = 'ไม่สามารถสร้างโฟลเดอร์ชั่วคราวเพื่อที่จะรองรับการดาวน์โหลด';
+$lang['enabled'] = 'เปิดใช้งานโปรแกรมเสริม %s แล้ว';
+$lang['notenabled'] = 'โปรแกรมเสริม %s ไม่สามารถเปิดใช้งาน, กรุณาตรวจสอบสิทธิ์ของไฟล์';
+$lang['disabled'] = 'ปิดการใช้งานโปรแกรมเสริม %s แล้ว';
+$lang['notdisabled'] = 'โปรแกรมเสริม %s ไม่สามารถปิดการใช้งานได้, กรุณาตรวจสอบสิทธิ์ของไฟล์';
diff --git a/lib/plugins/plugin/lang/tr/admin_plugin.txt b/lib/plugins/plugin/lang/tr/admin_plugin.txt
new file mode 100644
index 000000000..956d701f6
--- /dev/null
+++ b/lib/plugins/plugin/lang/tr/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== Eklenti Yönetimi ======
+
+Bu sayfada DokuWiki [[doku>plugins|eklentileri]] ile ilgili herşeyi düzenleyebilirsiniz. Eklenti kurup indirmek için, eklenti dizininin yazılabilir olması gerekmektedir.
diff --git a/lib/plugins/plugin/lang/tr/lang.php b/lib/plugins/plugin/lang/tr/lang.php
new file mode 100644
index 000000000..9a655e400
--- /dev/null
+++ b/lib/plugins/plugin/lang/tr/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['menu'] = 'Eklenti Yönetimi';
+$lang['download'] = 'Yeni bir eklenti indirip kur';
+$lang['manage'] = 'Kurulmuş Eklentiler';
+$lang['btn_info'] = 'bilgi';
+$lang['btn_update'] = 'güncelle';
+$lang['btn_delete'] = 'sil';
+$lang['btn_settings'] = 'Ayarlar';
+$lang['btn_download'] = 'İndir';
+$lang['btn_enable'] = 'Kaydet';
+$lang['url'] = 'Web Adresi';
+$lang['installed'] = 'Kuruldu:';
+$lang['lastupdate'] = 'Son güncelleştirme:';
+$lang['source'] = 'Kaynak:';
+$lang['unknown'] = 'bilinmiyor';
+$lang['updating'] = 'Güncelleştiriyor ...';
+$lang['updated'] = '%s eklentisi başarıyla güncellendi';
+$lang['updates'] = 'Şu eklentiler başarıyla güncellendi';
+$lang['update_none'] = 'Yeni bir güncelleme bulunamadı.';
+$lang['deleting'] = 'Siliniyor ...';
+$lang['deleted'] = '%s eklentisi silindi.';
+$lang['downloading'] = 'İndiriyor ...';
+$lang['downloaded'] = '%s eklentisi başarıyla kuruldu';
+$lang['downloads'] = 'Şu eklentiler başarıyla kuruldu:';
+$lang['download_none'] = 'Eklenti bulunamadı veya indirirken/kurarken bilinmeyen bir hata oluştu.';
+$lang['plugin'] = 'Eklenti:';
+$lang['components'] = 'Parçalar';
+$lang['noinfo'] = 'Bu eklentinin bilgileri alınamadı, geçerli bir eklenti olmayabilir.';
+$lang['name'] = 'Ad:';
+$lang['date'] = 'Tarih:';
+$lang['type'] = 'Tür:';
+$lang['desc'] = 'Açıklama:';
+$lang['author'] = 'Yazar:';
+$lang['www'] = 'Web Adresi:';
+$lang['error'] = 'Bilinmeyen bir hata oluştu.';
+$lang['error_download'] = 'Şu eklenti indirilemedi: %s';
+$lang['error_badurl'] = 'Yanlış adres olabilir - verilen adresten dosya adı alınamadı';
+$lang['error_dircreate'] = 'İndirmek için geçici klasör oluşturulamadı';
+$lang['error_decompress'] = 'Eklenti yöneticisi indirilen sıkıştırılmış dosyayı açamadı. Bu yanlış indirmeden kaynaklanabilir (bu durumda tekrar denemelisiniz). Ya da indirilen dosyanın sıkıştırma biçimi bilinmemektedir (bu durumda eklentiyi indirerek kendiniz kurmalısınız).';
+$lang['error_copy'] = '<em>%s</em> eklentisi dosyalarını kurmaya çalışırken kopyalama hatası ortaya çıktı. Sürücü dolu olabilir veya yazma yetkisi bulunmuyor olabilir. Bunun sebebi tam kurulmamış bir eklentinin wiki kurulumunu bozması olabilir.';
+$lang['error_delete'] = '<em>%s</em> eklentisini silerken bir hata oluştu. Bu hata yetersiz dosya/klasör erişim yetkisinden kaynaklanabilir.';
+$lang['enabled'] = '%s eklentisi etkinleştirildi.';
+$lang['notenabled'] = '%s eklentisi etkinleştirilemedi, dosya yetkilerini kontrol edin.';
+$lang['disabled'] = '%s eklentisi devre dışı bırakıldı.';
+$lang['notdisabled'] = '%s eklentisi devre dışı bırakılamadı, dosya yetkilerini kontrol edin.';
diff --git a/lib/plugins/plugin/lang/uk/admin_plugin.txt b/lib/plugins/plugin/lang/uk/admin_plugin.txt
new file mode 100644
index 000000000..7bdf8e5e5
--- /dev/null
+++ b/lib/plugins/plugin/lang/uk/admin_plugin.txt
@@ -0,0 +1,7 @@
+====== Керування доданками ======
+
+Тут ви можете керувати [[doku>plugins|доданками]] ДокуВікі. Для того, щоб завантажувати та встановлювати доданки, папка доданків повинна бути доступна для запису веб-сервером.
+
+
+
+
diff --git a/lib/plugins/plugin/lang/uk/lang.php b/lib/plugins/plugin/lang/uk/lang.php
new file mode 100644
index 000000000..036900f4e
--- /dev/null
+++ b/lib/plugins/plugin/lang/uk/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * ukrainian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oleksiy Voronin (ovoronin@gmail.com)
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ * @author Kate Arzamastseva pshns@ukr.net
+ */
+$lang['menu'] = 'Керування доданками';
+$lang['download'] = 'Завантажити та встановити новий доданок';
+$lang['manage'] = 'Встановлені доданки';
+$lang['btn_info'] = 'дані';
+$lang['btn_update'] = 'оновити';
+$lang['btn_delete'] = 'видалити';
+$lang['btn_settings'] = 'параметри';
+$lang['btn_download'] = 'Завантажити';
+$lang['btn_enable'] = 'Зберегти';
+$lang['url'] = 'Адреса';
+$lang['installed'] = 'Встановлено:';
+$lang['lastupdate'] = 'Останнє оновлення:';
+$lang['source'] = 'Джерело:';
+$lang['unknown'] = 'невідомо';
+$lang['updating'] = 'Оновлення ...';
+$lang['updated'] = 'Доданок %s успішно оновлено';
+$lang['updates'] = 'Наступні доданки були успішно оновлені';
+$lang['update_none'] = 'Оновлення не знайдено.';
+$lang['deleting'] = 'Видалення ...';
+$lang['deleted'] = 'Доданок %s видалено.';
+$lang['downloading'] = 'Завантаження ...';
+$lang['downloaded'] = 'Доданок %s успішно встановлено';
+$lang['downloads'] = 'Наступні доданки були успішно встановлені:';
+$lang['download_none'] = 'Доданки не знайдено або виникла невідома проблема в процессі завантаження та установки.';
+$lang['plugin'] = 'Доданок:';
+$lang['components'] = 'Компоненти';
+$lang['noinfo'] = 'Цей доданок не повідомив ніяких даних, він може бути не працюючим.';
+$lang['name'] = 'Назва:';
+$lang['date'] = 'Дата:';
+$lang['type'] = 'Тип:';
+$lang['desc'] = 'Опис:';
+$lang['author'] = 'Автор:';
+$lang['www'] = 'Сторінка:';
+$lang['error'] = 'Виникла невідома помилка.';
+$lang['error_download'] = 'Не можу завантажити файл доданка: %s';
+$lang['error_badurl'] = 'Можливо, невірна адреса - не можливо визначити ім\'я файлу з адреси';
+$lang['error_dircreate'] = 'Не можливо створити тимчасову папку для завантаження';
+$lang['error_decompress'] = 'Менеджеру доданків не вдалося розпакувати завантажений файл. Це може бути результатом помилки при завантаженні, в цьому разі ви можете спробувати знову; або ж доданок упакований невідомим архіватором, тоді вам необхідно завантажити та встановити доданок вручну.';
+$lang['error_copy'] = 'Виникла помилка копіювання при спробі установки файлів для доданка <em>%s</em>: переповнення диску або невірні права доступу. Це могло привести до часткової установки доданка и нестійкості вашої Вікі.';
+$lang['error_delete'] = 'При спробі вилучення доданка <em>%s</em> виникла помилка. Найбільш вірогідно, що немає необхідних прав доступу до файлів або директорії';
+$lang['enabled'] = 'Доданок %s увімкнено.';
+$lang['notenabled'] = 'Не вдається увімкнути доданок %s. Перевірте права доступу до файлу.';
+$lang['disabled'] = 'Доданок %s вимкнено.';
+$lang['notdisabled'] = 'Не вдається вимкнути доданок %s. Перевірте права доступу до файлу.';
+$lang['packageinstalled'] = 'Пакет плагінів (%d plugin(s): %s) успішно встановлений.';
diff --git a/lib/plugins/plugin/lang/zh-tw/admin_plugin.txt b/lib/plugins/plugin/lang/zh-tw/admin_plugin.txt
new file mode 100644
index 000000000..84d095f51
--- /dev/null
+++ b/lib/plugins/plugin/lang/zh-tw/admin_plugin.txt
@@ -0,0 +1,3 @@
+====== 插件管理器 ======
+
+您可以用本頁管理與 Dokuwiki [[doku>plugins|插件]] 相關的選項。若要正常下載及安裝插件,插件所在的資料夾必須允許網頁伺服器寫入。
diff --git a/lib/plugins/plugin/lang/zh-tw/lang.php b/lib/plugins/plugin/lang/zh-tw/lang.php
new file mode 100644
index 000000000..54234212d
--- /dev/null
+++ b/lib/plugins/plugin/lang/zh-tw/lang.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Chinese Traditional language file
+ *
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '管理插件 (Plugins)';
+$lang['download'] = '下載與安裝插件';
+$lang['manage'] = '已安裝的插件';
+$lang['btn_info'] = '資訊';
+$lang['btn_update'] = '更新';
+$lang['btn_delete'] = '刪除';
+$lang['btn_settings'] = '設定';
+$lang['btn_download'] = '下載';
+$lang['btn_enable'] = '儲存';
+$lang['url'] = 'URL';
+$lang['installed'] = '安裝:';
+$lang['lastupdate'] = '上次更新:';
+$lang['source'] = '來源:';
+$lang['unknown'] = '未知';
+$lang['updating'] = '更新中 ...';
+$lang['updated'] = '插件 %s 成功地更新';
+$lang['updates'] = '以下的插件已經成功地更新';
+$lang['update_none'] = '找不到更新';
+$lang['deleting'] = '刪除中 ...';
+$lang['deleted'] = '插件 %s 已刪除。';
+$lang['downloading'] = '下載中 ...';
+$lang['downloaded'] = '插件 %s 已成功地安裝';
+$lang['downloads'] = '以下的插件已成功地安裝:';
+$lang['download_none'] = '找不到插件,或在下載與安裝時發生了未知的問題';
+$lang['plugin'] = '插件:';
+$lang['components'] = '元件';
+$lang['noinfo'] = '此插件沒有回傳任何資訊,可能是無效的';
+$lang['name'] = '名稱:';
+$lang['date'] = '日期:';
+$lang['type'] = '類型:';
+$lang['desc'] = '描述:';
+$lang['author'] = '作者:';
+$lang['www'] = '網頁:';
+$lang['error'] = '一個未知的錯誤發生。';
+$lang['error_download'] = '無法下載插件檔案: %s';
+$lang['error_badurl'] = 'URL 可能有問題 - 從 URL 中無法得知文件名';
+$lang['error_dircreate'] = '無法建立暫存目錄來接收下載的內容';
+$lang['error_decompress'] = '插件管理器無法解壓下載的文件。這可能是由於下載出現錯誤,遇到這種情況,請您再次嘗試;或者是壓縮格式無法識別,遇到這種情況,您需要手動下載並安裝該插件。';
+$lang['error_copy'] = '嘗試安裝插件 <em>%s</em> 的相關文件時發生複製錯誤:可能是磁碟空間不足或檔案存取權限錯誤。這可能是由於未安裝完全的插件使維基系統不穩定導致。';
+$lang['error_delete'] = '嘗試刪除插件 <em>%s</em> 時發生錯誤。最可能原因是檔案或目錄存取權限不足';
+$lang['enabled'] = '插件 %s 已啟用。';
+$lang['notenabled'] = '插件 %s 無法啟用,請檢查檔案權限。';
+$lang['disabled'] = '插件 %s 已停用。';
+$lang['notdisabled'] = '插件 %s 無法停用,請檢查檔案權限。';
+$lang['packageinstalled'] = '插件 (%d 插件%s: %s) 已成功地安裝。';
diff --git a/lib/plugins/plugin/lang/zh/admin_plugin.txt b/lib/plugins/plugin/lang/zh/admin_plugin.txt
new file mode 100644
index 000000000..1618071a4
--- /dev/null
+++ b/lib/plugins/plugin/lang/zh/admin_plugin.txt
@@ -0,0 +1,5 @@
+====== 插件管理器 ======
+
+本页中您可以管理与 Dokuwiki [[doku>plugins|插件]] 相关的选项。 要通过插件管理器正常下载并安装插件,插件所在的文件夹必须可写。
+
+
diff --git a/lib/plugins/plugin/lang/zh/lang.php b/lib/plugins/plugin/lang/zh/lang.php
new file mode 100644
index 000000000..58f05fbd9
--- /dev/null
+++ b/lib/plugins/plugin/lang/zh/lang.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '插件管理器';
+$lang['download'] = '下载并安装新的插件';
+$lang['manage'] = '已安装的插件';
+$lang['btn_info'] = '信息';
+$lang['btn_update'] = '升级';
+$lang['btn_delete'] = '删除';
+$lang['btn_settings'] = '设置';
+$lang['btn_download'] = '下载';
+$lang['btn_enable'] = '保存';
+$lang['url'] = 'URL';
+$lang['installed'] = '已安装:';
+$lang['lastupdate'] = '最后更新于:';
+$lang['source'] = '来源:';
+$lang['unknown'] = '未知';
+$lang['updating'] = '正在升级...';
+$lang['updated'] = '插件 %s 升级成功';
+$lang['updates'] = '下列插件升级成功:';
+$lang['update_none'] = '未找到更新。';
+$lang['deleting'] = '正在删除...';
+$lang['deleted'] = '插件 %s 已删除';
+$lang['downloading'] = '正在下载...';
+$lang['downloaded'] = '插件 %s 安装成功';
+$lang['downloads'] = '下列插件安装成功:';
+$lang['download_none'] = '未找到插件,或下载和安装过程中出现了未知错误。';
+$lang['plugin'] = '插件:';
+$lang['components'] = '组件';
+$lang['noinfo'] = '该插件没有任何信息,有可能是无效插件。';
+$lang['name'] = '名称:';
+$lang['date'] = '日期:';
+$lang['type'] = '类别:';
+$lang['desc'] = '描述:';
+$lang['author'] = '作者:';
+$lang['www'] = '网址:';
+$lang['error'] = '产生了未知错误。';
+$lang['error_download'] = '无法下载插件:%s';
+$lang['error_badurl'] = 'URL 可能有问题 - 从 URL 中无法得知文件名';
+$lang['error_dircreate'] = '无法创建用于接收下载文件的';
+$lang['error_decompress'] = '插件管理器无法解压下载的文件。这可能是由于下载出现错误,遇到这种情况,请您再次尝试;或者是压缩格式无法识别,遇到这种情况,您需要手动下载并安装该插件。';
+$lang['error_copy'] = '尝试安装插件 <em>%s</em> 的相关文件时产生一个复制错误:磁盘空间已满或文件访问权限错误。这可能是由于一个安装了一部分的插件,并使得您的维基系统不稳定。';
+$lang['error_delete'] = '尝试删除插件 <em>%s</em> 时产生一个错误。最有可能的情况是文件或路径的访问权限不够';
+$lang['enabled'] = '%s 插件启用';
+$lang['notenabled'] = '%s插件启用失败,请检查文件权限。';
+$lang['disabled'] = '%s 插件禁用';
+$lang['notdisabled'] = '%s插件禁用失败,请检查文件权限。';
+$lang['packageinstalled'] = '插件 (%d plugin%s: %s) 已成功安装。';
diff --git a/lib/plugins/plugin/rtl.css b/lib/plugins/plugin/rtl.css
new file mode 100644
index 000000000..6ababd8e0
--- /dev/null
+++ b/lib/plugins/plugin/rtl.css
@@ -0,0 +1,51 @@
+
+#plugin__manager .pm_menu,
+#plugin__manager .pm_info,
+#plugin__manager p,
+#plugin__manager label {
+ text-align: right;
+}
+
+#plugin__manager .pm_menu {
+ float: right;
+}
+
+#plugin__manager .pm_info {
+ float: left;
+}
+
+#plugin__manager .pm_info dt {
+ float: right;
+ clear: right;
+}
+
+#plugin__manager .pm_info dd {
+ margin: 0 7em 0 0;
+}
+
+#plugin__manager .common fieldset {
+ text-align: right;
+}
+
+
+#plugin__manager .plugins .legend {
+ text-align: right;
+ float: right;
+}
+
+#plugin__manager .plugins .enable {
+ float: right;
+ margin-right: 0;
+ margin-left: 0.5em;
+}
+
+#plugin__manager .plugins .button {
+ float: left;
+ margin-right: 0.5em;
+}
+
+
+#plugin__manager .plugins fieldset.buttons .button {
+ float: right;
+}
+
diff --git a/lib/plugins/plugin/style.css b/lib/plugins/plugin/style.css
new file mode 100644
index 000000000..de6cca579
--- /dev/null
+++ b/lib/plugins/plugin/style.css
@@ -0,0 +1,156 @@
+/*
+ * admin plugin extension - style additions
+ *
+ * @author Christopher Smith chris@jalakai.co.uk
+ * @link http://wiki.jalakai.co.uk/dokuwiki/doku.php/tutorials/adminplugin
+ */
+
+#plugin__manager h2 {
+ margin-left: 0;
+}
+
+#plugin__manager form {
+ display: block;
+ margin: 0;
+ padding: 0;
+}
+
+#plugin__manager legend {
+ display: none;
+}
+
+#plugin__manager fieldset {
+ width: auto;
+}
+
+#plugin__manager .button {
+ margin: 0;
+}
+
+#plugin__manager p,
+#plugin__manager label {
+ text-align: left;
+}
+
+#plugin__manager .hidden {
+ display: none;
+}
+
+#plugin__manager .new {
+ background: #dee7ec;
+}
+
+/* IE won't understand but doesn't require it */
+#plugin__manager input[disabled] {
+ color: #ccc;
+ border-color: #ccc;
+}
+
+#plugin__manager .pm_menu,
+#plugin__manager .pm_info {
+ margin-left: 0;
+ text-align: left;
+}
+
+#plugin__manager .pm_menu {
+ float: left;
+ width: 48%;
+}
+
+#plugin__manager .pm_info {
+ float: right;
+ width: 50%;
+}
+
+#plugin__manager .common fieldset {
+ margin: 0;
+ padding: 0 0 1.0em 0;
+ text-align: left;
+ border: none;
+}
+
+#plugin__manager .common label {
+ padding: 0 0 0.5em 0;
+}
+
+#plugin__manager .common input.edit {
+ width: 24em;
+ margin: 0.5em;
+}
+
+#plugin__manager .plugins fieldset {
+ color: #000;
+ background: #fff;
+ text-align: right;
+ border-top: none;
+ border-right: none;
+ border-left: none;
+}
+
+#plugin__manager .plugins fieldset.protected {
+ background: #fdd;
+ color: #000;
+}
+
+#plugin__manager .plugins fieldset.disabled {
+ background: #e0e0e0;
+ color: #a8a8a8;
+}
+
+#plugin__manager .plugins .legend {
+ color: #000;
+ background: inherit;
+ display: block;
+ margin: 0;
+ padding: 0;
+ font-size: 1em;
+ line-height: 1.4em;
+ font-weight: normal;
+ text-align: left;
+ float: left;
+ padding: 0;
+ clear: none;
+}
+
+#plugin__manager .plugins .button {
+ font-size: 95%;
+}
+
+#plugin__manager .plugins fieldset.buttons {
+ border: none;
+}
+
+#plugin__manager .plugins fieldset.buttons .button {
+ float: left;
+}
+
+#plugin__manager .pm_info h3 {
+ margin-left: 0;
+}
+
+#plugin__manager .pm_info dl {
+ margin: 1em 0;
+ padding: 0;
+}
+
+#plugin__manager .pm_info dt {
+ width: 6em;
+ float: left;
+ clear: left;
+ margin: 0;
+ padding: 0;
+}
+
+#plugin__manager .pm_info dd {
+ margin: 0 0 0 7em;
+ padding: 0;
+ background: none;
+}
+
+#plugin__manager .plugins .enable {
+ float: left;
+ width: auto;
+ margin-right: 0.5em;
+}
+
+/* end admin plugin styles */
diff --git a/lib/plugins/popularity/action.php b/lib/plugins/popularity/action.php
new file mode 100644
index 000000000..bf11efba6
--- /dev/null
+++ b/lib/plugins/popularity/action.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Popularity Feedback Plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+require_once(DOKU_PLUGIN.'action.php');
+require_once(DOKU_PLUGIN.'popularity/admin.php');
+
+class action_plugin_popularity extends Dokuwiki_Action_Plugin {
+ var $helper;
+
+ function action_plugin_popularity(){
+ $this->helper = $this->loadHelper('popularity', false);
+ }
+
+ /**
+ * Register its handlers with the dokuwiki's event controller
+ */
+ function register(&$controller) {
+ $controller->register_hook('INDEXER_TASKS_RUN', 'AFTER', $this, '_autosubmit', array());
+ }
+
+ function _autosubmit(&$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)
+ */
+ function _isTooEarlyToSubmit(){
+ $lastSubmit = $this->helper->lastSentTime();
+ return $lastSubmit + 24*60*60*30 > time();
+ }
+}
diff --git a/lib/plugins/popularity/admin.php b/lib/plugins/popularity/admin.php
new file mode 100644
index 000000000..a04e98a66
--- /dev/null
+++ b/lib/plugins/popularity/admin.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Popularity Feedback 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();
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_popularity extends DokuWiki_Admin_Plugin {
+ var $version;
+ var $helper;
+ var $sentStatus = null;
+
+ function admin_plugin_popularity(){
+ $this->helper = $this->loadHelper('popularity', false);
+
+ $pluginInfo = $this->getInfo();
+ $this->version = $pluginInfo['date'];
+ }
+
+ /**
+ * return prompt for admin menu
+ */
+ function getMenuText($language) {
+ return $this->getLang('name');
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ function getMenuSort() {
+ return 2000;
+ }
+
+ /**
+ * Accessible for managers
+ */
+ function forAdminOnly() {
+ return false;
+ }
+
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ //Send the data
+ if ( isset($_REQUEST['data']) ){
+ $this->sentStatus = $this->helper->sendData( $_REQUEST['data'] );
+ if ( $this->sentStatus === '' ){
+ //Update the last time we sent the data
+ touch ( $this->helper->popularityLastSubmitFile );
+ }
+ //Deal with the autosubmit option
+ $this->_enableAutosubmit( isset($_REQUEST['autosubmit']) );
+ }
+ }
+
+ /**
+ * Enable or disable autosubmit
+ * @param bool $enable If TRUE, it will enable autosubmit. Else, it will disable it.
+ */
+ function _enableAutosubmit( $enable ){
+ if ( $enable ){
+ io_saveFile( $this->helper->autosubmitFile, ' ');
+ } else {
+ @unlink($this->helper->autosubmitFile);
+ }
+ }
+
+ /**
+ * Output HTML form
+ */
+ function html() {
+ if ( ! isset($_REQUEST['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', $_REQUEST['data']);
+ }
+ }
+ }
+
+
+ /**
+ * Build the form which presents the data to be sent
+ * @param string $submit 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 The form, as an html string
+ */
+ 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 .= '<input type="submit" class="button" value="'.$this->getLang('submit').'"/>'
+ .'</fieldset>'
+ .'</form>';
+ return $form;
+ }
+}
diff --git a/lib/plugins/popularity/helper.php b/lib/plugins/popularity/helper.php
new file mode 100644
index 000000000..af1e8a706
--- /dev/null
+++ b/lib/plugins/popularity/helper.php
@@ -0,0 +1,292 @@
+<?php
+/**
+ * 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
+ */
+ var $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
+ */
+ var $autosubmitFile;
+
+ /**
+ * File where the last error which happened when we tried to autosubmit, will be log
+ */
+ var $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)
+ */
+ var $popularityLastSubmitFile;
+
+
+ function helper_plugin_popularity(){
+ global $conf;
+ $this->autosubmitFile = $conf['cachedir'].'/autosubmit.txt';
+ $this->autosubmitErrorFile = $conf['cachedir'].'/autosubmitError.txt';
+ $this->popularityLastSubmitFile = $conf['cachedir'].'/lastSubmitTime.txt';
+ }
+
+ function getMethods(){
+ $result = array();
+ $result[] = array(
+ 'name' => 'isAutoSubmitEnabled',
+ 'desc' => 'Check if autosubmit is enabled',
+ 'params' => array(),
+ 'return' => array('result' => 'bool')
+ );
+ $result[] = array(
+ 'name' => 'sendData',
+ 'desc' => 'Send the popularity data',
+ 'params' => array('data' => 'string'),
+ 'return' => array()
+ );
+ $result[] = array(
+ 'name' => 'gatherAsString',
+ 'desc' => 'Gather the popularity data',
+ 'params' => array(),
+ 'return' => array('data' => 'string')
+ );
+ $result[] = array(
+ 'name' => 'lastSentTime',
+ 'desc' => 'Compute the last time popularity data was sent',
+ 'params' => array(),
+ 'return' => array('data' => 'int')
+ );
+ return $result;
+
+ }
+
+ /**
+ * Check if autosubmit is enabled
+ * @return TRUE if we should send data once a month, FALSE otherwise
+ */
+ function isAutoSubmitEnabled(){
+ return @file_exists($this->autosubmitFile);
+ }
+
+ /**
+ * Send the data, to the submit url
+ * @param string $data The popularity data
+ * @return An empty string if everything worked fine, a string describing the error otherwise
+ */
+ function sendData($data){
+ $error = '';
+ $httpClient = new DokuHTTPClient();
+ $status = $httpClient->sendRequest($this->submitUrl, $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.
+ */
+ function lastSentTime(){
+ $manualSubmission = @filemtime($this->popularityLastSubmitFile);
+ $autoSubmission = @filemtime($this->autosubmitFile);
+
+ return max((int) $manualSubmission, (int) $autoSubmission);
+ }
+
+ /**
+ * Gather all information
+ * @return The popularity data as a string
+ */
+ 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 The popularity data as an array
+ */
+ function _gather(){
+ global $conf;
+ global $auth;
+ $data = array();
+ $phptime = ini_get('max_execution_time');
+ @set_time_limit(0);
+
+ // version
+ $data['anon_id'] = md5(auth_cookiesalt());
+ $data['version'] = getVersion();
+ $data['popversion'] = $this->version;
+ $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,'_search_count'),'','');
+ $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,'_search_count'),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,'_search_count'),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,'_search_count'),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,'_search_count'),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,'_search_count'),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'] = $this->_to_byte(ini_get('memory_limit'));
+ $data['php_exectime'] = $phptime;
+ $data['php_extension'] = get_loaded_extensions();
+
+ return $data;
+ }
+
+ function _search_count(&$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;
+ }
+
+ /**
+ * Convert php.ini shorthands to byte
+ *
+ * @author <gilthans dot NO dot SPAM at gmail dot com>
+ * @link http://de3.php.net/manual/en/ini.core.php#79564
+ */
+ function _to_byte($v){
+ $l = substr($v, -1);
+ $ret = substr($v, 0, -1);
+ switch(strtoupper($l)){
+ case 'P':
+ $ret *= 1024;
+ case 'T':
+ $ret *= 1024;
+ case 'G':
+ $ret *= 1024;
+ case 'M':
+ $ret *= 1024;
+ case 'K':
+ $ret *= 1024;
+ break;
+ }
+ return $ret;
+ }
+}
diff --git a/lib/plugins/popularity/lang/af/lang.php b/lib/plugins/popularity/lang/af/lang.php
new file mode 100644
index 000000000..ab5e4f609
--- /dev/null
+++ b/lib/plugins/popularity/lang/af/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['submit'] = 'Stuir Data';
diff --git a/lib/plugins/popularity/lang/ar/intro.txt b/lib/plugins/popularity/lang/ar/intro.txt
new file mode 100644
index 000000000..a81fede51
--- /dev/null
+++ b/lib/plugins/popularity/lang/ar/intro.txt
@@ -0,0 +1,9 @@
+====== Popularity Feedback ======
+
+تجمع هذه الأداة بيانات مجهولة الاسم وتسمح لك بردها لمطوري دوكو ويكي. يساعدهم ذلك على معرفة كيفية استخدام دوكو ويكي من المستخدمين والتأكد من أن التطويرات المستقبلية مدعومة بتقارير استخدام حقيقية.
+
+نشجعك على تكرار هذه الخطوة من وقت لآخر لابقاء المطورين على علم بنمو الويكي خاصتك. بياناتك المرسلة مكررا ستحتفظ ب ID بلا اسماء يميزها.
+
+البيانات المرسلة تحتوي معلومات مثل اصدار دوكو ويكي، عدد وحجم صفحاتك وملفاتك، الاضافات المركبة و معلومات عن PHP عندك.
+
+البيانات التي سترسل معروضة صرفا أسفله. رجاء استخدم زر "أرسل البيانات" لنقل المعلومات. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ar/lang.php b/lib/plugins/popularity/lang/ar/lang.php
new file mode 100644
index 000000000..481668505
--- /dev/null
+++ b/lib/plugins/popularity/lang/ar/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['name'] = 'رد الشعبية (قد يأخذ بعض الوقت ليحمل)';
+$lang['submit'] = 'أرسل البيانات';
+$lang['autosubmit'] = 'ارسل البيانات آليا كل شهر';
+$lang['submissionFailed'] = 'تعذر إرسال البيانات بسبب الخطأ التالي:';
+$lang['submitDirectly'] = 'يمكنك إرسال البيانات يدويا بارسال النموذج التالي.';
+$lang['autosubmitError'] = 'فشلت آخر محاولة للإرسال، بسبب الخطأ التالي:';
+$lang['lastSent'] = 'أرسلت البيانات';
diff --git a/lib/plugins/popularity/lang/ar/submitted.txt b/lib/plugins/popularity/lang/ar/submitted.txt
new file mode 100644
index 000000000..085e3bd98
--- /dev/null
+++ b/lib/plugins/popularity/lang/ar/submitted.txt
@@ -0,0 +1,3 @@
+====== رد الشعبية ======
+
+أرسلت البيانات بنجاح. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/bg/intro.txt b/lib/plugins/popularity/lang/bg/intro.txt
new file mode 100644
index 000000000..35023b897
--- /dev/null
+++ b/lib/plugins/popularity/lang/bg/intro.txt
@@ -0,0 +1,9 @@
+====== Обратна връзка ======
+
+Инструментът събира данни за вашето Wiki и ви позволява да ги изпратите да разработчиците на DokuWiki. Информацията ще им помогне да разберат как DokuWiki се ползва от потребителите и че статистиката е в подкрепа на поетата насока за развитие.
+
+Моля, ползвайте функцията, от време на време, когато уебстраницата ви се разраства, за да информирате разработчиците. Изпратените данни ще бъдат идентифицирани с анонимен идентификатор.
+
+Събираните данни съдържат информация като версията на DokuWiki, броя и размера на вашите страници и файлове, инсталирани приставки и информация за локалната инсталация на PHP.
+
+Данните, които ще бъдат изпратени са изобразени отдолу. Моля, натиснете бутона "Изпращане на данните", за да бъдат изпратени. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/bg/lang.php b/lib/plugins/popularity/lang/bg/lang.php
new file mode 100644
index 000000000..ba731c0fc
--- /dev/null
+++ b/lib/plugins/popularity/lang/bg/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Bulgarian language file
+ *
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['name'] = 'Обратна връзка (зареждането изисква време)';
+$lang['submit'] = 'Изпращане на данните';
+$lang['autosubmit'] = 'Автоматично изпращане на данните веднъж в месеца';
+$lang['submissionFailed'] = 'Данните не могат да бъдат изпратени поради следната грешка:';
+$lang['submitDirectly'] = 'Можете да изпратите данните ръчно чрез следния формуляр.';
+$lang['autosubmitError'] = 'Последното автоматично изпращане се провали, поради следната грешка:';
+$lang['lastSent'] = 'Данните са изпратени';
diff --git a/lib/plugins/popularity/lang/bg/submitted.txt b/lib/plugins/popularity/lang/bg/submitted.txt
new file mode 100644
index 000000000..3ecd24f96
--- /dev/null
+++ b/lib/plugins/popularity/lang/bg/submitted.txt
@@ -0,0 +1,3 @@
+====== Обратна връзка ======
+
+Данните са изпратени успешно. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ca-valencia/intro.txt b/lib/plugins/popularity/lang/ca-valencia/intro.txt
new file mode 100644
index 000000000..cf14e0864
--- /dev/null
+++ b/lib/plugins/popularity/lang/ca-valencia/intro.txt
@@ -0,0 +1,9 @@
+====== Retroalimentació de popularitat ======
+
+Esta ferramenta arreplega senyes anònimes sobre el wiki i permet enviar-les als desenrolladors de DokuWiki. Açò els ajuda a comprendre cóm utilisen DokuWiki els usuaris i assegura que les decisions futures de desenroll estaran recolzades per estadístiques d'us real.
+
+L'animem a que repetixca este procés de tant en tant per a mantindre informats als desenrolladors quan el wiki creixca. Els seus conjunts reiteratius de senyes s'identificaran en un ID anònim.
+
+Les senyes arreplegades contenen informació com la versió del DokuWiki, el número i tamany de les pàgines i els archius, plúgins instalats i informació sobre l'instalació de PHP.
+
+Les senyes reals que s'enviaran es mostren ací avall. Per favor, utilise el botó "Enviar senyes" per a transferir l'informació.
diff --git a/lib/plugins/popularity/lang/ca-valencia/lang.php b/lib/plugins/popularity/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..1bbe5e5f5
--- /dev/null
+++ b/lib/plugins/popularity/lang/ca-valencia/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Valencian language file
+ *
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['name'] = 'Retro-alimentació de popularitat (pot tardar un poc en carregar)';
+$lang['submit'] = 'Enviar senyes';
diff --git a/lib/plugins/popularity/lang/ca/intro.txt b/lib/plugins/popularity/lang/ca/intro.txt
new file mode 100644
index 000000000..f5ded3f1c
--- /dev/null
+++ b/lib/plugins/popularity/lang/ca/intro.txt
@@ -0,0 +1,9 @@
+====== Retroacció sobre popularitat ======
+
+Aquesta eina recull dades anònimes sobre el vostre wiki i us permet enviar-les als desenvolupadors de DokuWiki. Això els ajudarà a entendre com utilitzen DokuWiki els usuaris i farà que futures decisions de desenvolupament es prenguin sobre la base d'estadístiques d'ús reals.
+
+Els desenvolupadors de DokuWiki us preguen que repetiu aquest pas de tant en tant per tal de mantenir-los ben informats a mesura que creix el vostre wiki. Els conjunts de dades que envieu al llarg del temps quedaran identificats per un ID anònim.
+
+Les dades que es recullen contenen informació com ara la vostra versió de DokuWiki, el nombre i la mida de pàgines i fitxers, els connectors instal·lats i informació sobre la vostra instal·lació de PHP.
+
+Més avall es mostren les dades crues que s'enviaran. Feu servir el botó "Envia dades" per transferir aquesta informació. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ca/lang.php b/lib/plugins/popularity/lang/ca/lang.php
new file mode 100644
index 000000000..e6fdcd533
--- /dev/null
+++ b/lib/plugins/popularity/lang/ca/lang.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@cent.uji.es
+ */
+$lang['name'] = 'Retroacció sobre popularitat (pot trigar una mica a carregar)';
+$lang['submit'] = 'Envia dades';
diff --git a/lib/plugins/popularity/lang/cs/intro.txt b/lib/plugins/popularity/lang/cs/intro.txt
new file mode 100644
index 000000000..4b386568a
--- /dev/null
+++ b/lib/plugins/popularity/lang/cs/intro.txt
@@ -0,0 +1,9 @@
+===== Průzkum používání =====
+
+Tento nástroj jednorázově shromáždí anonymní data o vaší wiki a umožní vám odeslat je vývojářům DokuWiki. To jim pomůže lépe porozumět, jak uživatelé DokuWiki používají, a jejich rozhodnutí při dalším vývoji budou založena na statistikách z reálného používání DokuWiki.
+
+Chcete-li pomoci vývojářům, čas od času, jak vaše wiki poroste, použijte tento nástroj. Vaše data budou pokaždé označena stejným anonymním identifikátorem.
+
+Shromážděná data budou obsahovat informace, jako je instalovaná verze DokuWiki, počet a velikosti stránek a souborů, instalované pluginy a informace o nainstalovaném PHP.
+
+Čistá data, která se odešlou, budou vidět níže. K odeslání informací použijte prosím tlačítko "Odeslat data". \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/cs/lang.php b/lib/plugins/popularity/lang/cs/lang.php
new file mode 100644
index 000000000..287bcf3b0
--- /dev/null
+++ b/lib/plugins/popularity/lang/cs/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['name'] = 'Průzkum používání (může chviličku trvat, než se natáhne)';
+$lang['submit'] = 'Odeslat data';
+$lang['autosubmit'] = 'Automaticky odesílat data jednou měsíčně';
+$lang['submissionFailed'] = 'Data nemohla být odeslána kvůli následující chybě:';
+$lang['submitDirectly'] = 'Data můžete odeslat ručně zasláním následujícího formuláře.';
+$lang['autosubmitError'] = 'Poslední automatické odeslání selhalo kvůli následující chybě:';
+$lang['lastSent'] = 'Data byla odeslána.';
diff --git a/lib/plugins/popularity/lang/cs/submitted.txt b/lib/plugins/popularity/lang/cs/submitted.txt
new file mode 100644
index 000000000..ff1f41c9f
--- /dev/null
+++ b/lib/plugins/popularity/lang/cs/submitted.txt
@@ -0,0 +1,3 @@
+===== Průzkum používání =====
+
+Data byla úspěšně odeslána. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/da/intro.txt b/lib/plugins/popularity/lang/da/intro.txt
new file mode 100644
index 000000000..e2122c94d
--- /dev/null
+++ b/lib/plugins/popularity/lang/da/intro.txt
@@ -0,0 +1,9 @@
+====== Tilbagemelding om popularitet ======
+
+Dette værktøj samler anonyme oplysninge rom din wiki og giver dig mulighed for at sende det tilbage til DokuWiki-udviklerne. Dette hjælper dem til at sætte sig ind i, hvordan DokuWiki bruges af dets brugere og sikrer, at fremtidige beslutninger inden for udviklingen har grund i faktiske brugsstatistikker.
+
+Vi anbefaler dig til at gentage dette trin fra tid til anden for at holde udviklerne underrettede eftersom din wiki vokser. Dine anonyme datasamlinger vil blive tilkendegivet ved et anonymt navn.
+
+Opsamlede data indeholder oplysninger som eksempelvis din udgave af DokuWiki, antallet og størrelsen af dens sider, tilføjede udvidelse og oplysninger om din PHP-opsætning.
+
+De egentlige data, som vil blive sendt, er vist herunder. Brug venligst knappen 'Send Data' for at videresende oplysningerne. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/da/lang.php b/lib/plugins/popularity/lang/da/lang.php
new file mode 100644
index 000000000..325fd6568
--- /dev/null
+++ b/lib/plugins/popularity/lang/da/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['name'] = 'Tilbagemelding om popularitet (vil måske tage en del tid at indlæse)';
+$lang['submit'] = 'Send data';
diff --git a/lib/plugins/popularity/lang/de-informal/intro.txt b/lib/plugins/popularity/lang/de-informal/intro.txt
new file mode 100644
index 000000000..ddae9347d
--- /dev/null
+++ b/lib/plugins/popularity/lang/de-informal/intro.txt
@@ -0,0 +1,9 @@
+===== Rückmeldung zur Zufriedenheit =====
+
+Dieses Werkzeug sammelt anonym Daten über dein Wiki und erlaubt es dir diese an die Entwickler von DokuWiki zu senden. Dies hilft ihnen zu verstehen, wie DokuWiki von den Nutzern verwendet wird und stellt somit sicher, dass Entscheidungen für zukünftige Entwicklungen mit reellen Nutzungsstatistiken belegbar sind.
+
+Bitte wiederhole diesen Schritt von Zeit zu Zeit, um die Entwickler zu informieren wenn dein Wiki wächst. Deine aktuelleren Datensätze werden anhand einer anonymen Identifikationsnummer zugeordnet.
+
+Die gesammelten Daten enthalten Informationen über deine Version von DokuWiki, die Anzahl und Größe der Seiten und Dateien, installierte Erweiterungen und Informationen über deine PHP-Version.
+
+Die Rohdaten die gesendet werden, werden unten gezeigt. Bitte nutze den "Sende Daten" Knopf um die Informationen zu übermitteln. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/de-informal/lang.php b/lib/plugins/popularity/lang/de-informal/lang.php
new file mode 100644
index 000000000..40e6c4343
--- /dev/null
+++ b/lib/plugins/popularity/lang/de-informal/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['name'] = 'Popularitätsrückmeldung (kann eine Weile dauern, bis es fertig geladen wurde)';
+$lang['submit'] = 'Sende Daten';
+$lang['autosubmit'] = 'Daten einmal im Monat automatisch senden';
+$lang['submissionFailed'] = 'Die Daten konnten aufgrund des folgenden Fehlers nicht gesendet werden: ';
+$lang['submitDirectly'] = 'Du kannst die Daten durch Betätigung des Buttons manuell versenden.';
+$lang['autosubmitError'] = 'Beim letzten automatischen Versuch die Daten zu senden, ist folgender Fehler aufgetreten: ';
+$lang['lastSent'] = 'Die Daten wurden gesendet';
diff --git a/lib/plugins/popularity/lang/de-informal/submitted.txt b/lib/plugins/popularity/lang/de-informal/submitted.txt
new file mode 100644
index 000000000..e7b45b5b7
--- /dev/null
+++ b/lib/plugins/popularity/lang/de-informal/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitäts-Feedback ======
+
+Die Daten wurden erfolgreich versandt. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/de/intro.txt b/lib/plugins/popularity/lang/de/intro.txt
new file mode 100644
index 000000000..dc014e029
--- /dev/null
+++ b/lib/plugins/popularity/lang/de/intro.txt
@@ -0,0 +1,11 @@
+====== Popularitäts-Feedback ======
+
+Dieses [[doku>popularity|Werkzeug]] sammelt verschiedene anonyme Daten über Ihr Wiki und erlaubt es Ihnen, diese an die DokuWiki-Entwickler zurückzusenden. Diese Daten helfen den Entwicklern besser zu verstehen, wie DokuWiki eingesetzt wird und stellt sicher, dass zukünftige, die Weiterentwicklung von DokuWiki betreffende, Entscheidungen auf Basis echter Nutzerdaten getroffen werden.
+
+Bitte wiederholen Sie das Versenden der Daten von Zeit zu Zeit, um die Entwickler über das Wachstum Ihres Wikis auf dem Laufenden zu halten. Ihre wiederholten Dateneinsendungen werden über eine anonyme ID identifiziert.
+
+Die gesammelten Daten enthalten Informationen wie Ihre DokuWiki-Version, die Anzahl und Größe Ihrer Seiten und Dateien, installierte Plugins und die eingesetzte PHP-Installation.
+
+Die zu übertragenen Roh-Daten werden in der untenstehenden Box angezeigt. Bitte drücken Sie die "Daten senden" Schaltfläche um die Information zu übertragen.
+
+
diff --git a/lib/plugins/popularity/lang/de/lang.php b/lib/plugins/popularity/lang/de/lang.php
new file mode 100644
index 000000000..42bdc14d5
--- /dev/null
+++ b/lib/plugins/popularity/lang/de/lang.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * German language file
+ *
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['name'] = 'Popularitäts-Feedback (Eventuell längere Ladezeit)';
+$lang['submit'] = 'Daten senden';
+$lang['autosubmit'] = 'Daten einmal im Monat automatisch senden';
+$lang['submissionFailed'] = 'Die Daten konnten aufgrund des folgenden Fehlers nicht gesendet werden: ';
+$lang['submitDirectly'] = 'Sie können die Daten durch Betätigung des Buttons manuell versenden.';
+$lang['autosubmitError'] = 'Beim letzten automatischen Versuch die Daten zu senden, ist folgender Fehler aufgetreten: ';
+$lang['lastSent'] = 'Die Daten wurden gesendet';
diff --git a/lib/plugins/popularity/lang/de/submitted.txt b/lib/plugins/popularity/lang/de/submitted.txt
new file mode 100644
index 000000000..e7b45b5b7
--- /dev/null
+++ b/lib/plugins/popularity/lang/de/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitäts-Feedback ======
+
+Die Daten wurden erfolgreich versandt. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/el/intro.txt b/lib/plugins/popularity/lang/el/intro.txt
new file mode 100644
index 000000000..22d54290a
--- /dev/null
+++ b/lib/plugins/popularity/lang/el/intro.txt
@@ -0,0 +1,9 @@
+====== Αναφορά Δημοτικότητας ======
+
+Το εργαλείο αυτό συλλέγει ανώνυμα δεδομένα για το wiki σας και σας επιτρέπει να τα στείλετε στους δημιουργούς της εφαρμογής DokuWiki. Αυτό τους βοηθά να καταλάβουν με ποιούς τρόπους χρησιμοποιείται η εφαρμογή DokuWiki από τους χρήστες της και εξασφαλίζει ότι οι μελλοντικές αποφάσεις σχεδίασης θα στηρίζονται σε πραγματικά δεδομένα χρήσης.
+
+Σας προτρέπουμε να επαναλαμβάνετε αυτή τη διαδικασία κατά διαστήματα ώστε οι δημιουργοί της εφαρμογής DokuWiki να μένουν ενήμεροι όταν το wiki σας μεγαλώνει. Τα διαδοχικά σύνολα δεδομένων που αποστέλλετε αναγνωρίζονται από έναν ανώνυμο κωδικό.
+
+Τα δεδομένα περιέχουν πληροφορίες όπως η έκδοση του DokuWiki σας, ο αριθμός και το μέγεθος των σελίδων και αρχείων σας, οι εγκατεστημένες επεκτάσεις και στοιχεία για την PHP που χρησιμοποιείτε.
+
+Τα ακριβή δεδομένα τα οποία θα αποσταλούν εμφανίζονται παρακάτω. Παρακαλούμε πατήστε στο κουμπί "Αποστολή Δεδομένων" για να τα αποστείλετε. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/el/lang.php b/lib/plugins/popularity/lang/el/lang.php
new file mode 100644
index 000000000..32558b060
--- /dev/null
+++ b/lib/plugins/popularity/lang/el/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Greek language file
+ *
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['name'] = 'Αναφορά Δημοτικότητας (ίσως αργήσει λίγο να εμφανιστεί)';
+$lang['submit'] = 'Αποστολή Δεδομένων';
+$lang['autosubmit'] = 'Να αποστέλονται τα δεδομένα αυτόματα μια φορά το μήνα.';
+$lang['submissionFailed'] = 'Τα δεδομένα δεν ήταν δυνατό να αποσταλλούν λόγω του παρακάτω σφάλματος:';
+$lang['submitDirectly'] = 'Μπορείτε να αποστείλλετε τα δεδομένα χειροκίνητα με την υποβολή της παρακάτω φόρμας.';
+$lang['autosubmitError'] = 'Η τελευταία αυτόματη υποβολή των δεδομένων απέτυχε με το παρακάτω μήνυμα σφάλματος:';
+$lang['lastSent'] = 'Τα δεδομένα έχουν σταλεί.';
diff --git a/lib/plugins/popularity/lang/el/submitted.txt b/lib/plugins/popularity/lang/el/submitted.txt
new file mode 100644
index 000000000..8004f9997
--- /dev/null
+++ b/lib/plugins/popularity/lang/el/submitted.txt
@@ -0,0 +1,3 @@
+====== Αποτέλεσμα Υποβολής Δημοσιότητας ======
+
+Τα δεδομένα στάλθηκαν επιτυχώς. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/en/intro.txt b/lib/plugins/popularity/lang/en/intro.txt
new file mode 100644
index 000000000..e1d6d940a
--- /dev/null
+++ b/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/lib/plugins/popularity/lang/en/lang.php b/lib/plugins/popularity/lang/en/lang.php
new file mode 100644
index 000000000..af6797cb2
--- /dev/null
+++ b/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/lib/plugins/popularity/lang/en/submitted.txt b/lib/plugins/popularity/lang/en/submitted.txt
new file mode 100644
index 000000000..30f2784aa
--- /dev/null
+++ b/lib/plugins/popularity/lang/en/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularity Feedback ======
+
+The data has been sent succesfully.
diff --git a/lib/plugins/popularity/lang/eo/intro.txt b/lib/plugins/popularity/lang/eo/intro.txt
new file mode 100644
index 000000000..8d9b3dde8
--- /dev/null
+++ b/lib/plugins/popularity/lang/eo/intro.txt
@@ -0,0 +1,9 @@
+====== Populareca enketo ======
+
+Tiu ĉi ilo prenas anoniman datenaron pri via vikio kaj ebligas al vi sendi ĝin reen al la kodumantoj de DokuWiki. Tio helpas ke ili komprenu kiel DokuWiki estas uzata kaj certigas ke estontaj disvolviĝaj decidoj estos subtenataj de statistikoj pri reala aplikado.
+
+Ni instigas vin ripeti tiun agon iam kaj tiam por teni la disvolvigantojn informitaj, dum via vikio kreskas. Viaj resendotaj datenaroj estos identigitaj per anonima ID.
+
+La kolektita datenaro enhavas informon pri versio de la instalita DokuWiki, nombro kaj grandeco de la paĝoj kaj dosieroj, instalitaj kromaĵoj kaj informoj pri via PHP-sistemo.
+
+La kruda datenaro sendota estas montrita sube. Bonvole uzu la butonon &quot;Sendi datumaron&quot; por transŝuti tiun informaron. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/eo/lang.php b/lib/plugins/popularity/lang/eo/lang.php
new file mode 100644
index 000000000..e992e12ce
--- /dev/null
+++ b/lib/plugins/popularity/lang/eo/lang.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Esperanto language file
+ *
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['name'] = 'Populareca enketo (eble la ŝargo prokrastos iomete)';
+$lang['submit'] = 'Sendi datumaron';
+$lang['autosubmit'] = 'Aŭtomate sendi datumaron monate';
+$lang['submissionFailed'] = 'La datumaro ne povis esti sendata pro la jena eraro:';
+$lang['submitDirectly'] = 'Vi povas sendi vi mem la datumaron per la sekva informilo.';
+$lang['autosubmitError'] = 'La lasta aŭtomata sendo malsukcesis, pro la jena eraro:';
+$lang['lastSent'] = 'La datumaro estas sendita';
diff --git a/lib/plugins/popularity/lang/eo/submitted.txt b/lib/plugins/popularity/lang/eo/submitted.txt
new file mode 100644
index 000000000..c2bce4e9f
--- /dev/null
+++ b/lib/plugins/popularity/lang/eo/submitted.txt
@@ -0,0 +1,3 @@
+====== Enketo pri Populareco ======
+
+La datumoj estis senditaj sukcese. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/es/intro.txt b/lib/plugins/popularity/lang/es/intro.txt
new file mode 100644
index 000000000..cc776a398
--- /dev/null
+++ b/lib/plugins/popularity/lang/es/intro.txt
@@ -0,0 +1,10 @@
+====== Retroalimentación (feedback) del plugin Popularity ======
+
+Esta herramienta recopila datos anónimos sobre tu wiki y te permite enviarlos a los desarrolladores de DokuWiki. Esto les ayuda a comprender cómo usan DokuWiki sus usuarios y asegura que las decisiones del desarrollo futuro del programa estén basadas en las estadísticas de uso del mundo real.
+
+Te animamos a repetir este paso de vez en cuando para mantener informados a los desarrolladores a medida que tu wiki crece. Tus paquetes repetidos de datos se identifican por un ID anónimo.
+
+Los datos recopilados contienen información como tu versión de DokuWiki, el número y tamaño de tus páginas y ficheros, plugins instalados e información sobre tu instalación de PHP.
+
+Los datos que se enviarán se muestran más abajo. Por favor, usa el botón "Enviar Datos" para transferir la información.
+
diff --git a/lib/plugins/popularity/lang/es/lang.php b/lib/plugins/popularity/lang/es/lang.php
new file mode 100644
index 000000000..752fb7da4
--- /dev/null
+++ b/lib/plugins/popularity/lang/es/lang.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Spanish language file
+ *
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['name'] = 'Retroinformación (Feedback) plugin Popularity';
+$lang['submit'] = 'Enviar datos';
+$lang['autosubmit'] = 'Enviar automáticamente datos una vez al mes';
+$lang['submissionFailed'] = 'Los datos no se pudo enviar debido al error siguiente:';
+$lang['submitDirectly'] = 'Puede enviar los datos de forma manual mediante la presentación de la siguiente forma.';
+$lang['autosubmitError'] = 'El último auto no pudo presentar, debido al error siguiente:';
+$lang['lastSent'] = 'Los datos se han enviado';
diff --git a/lib/plugins/popularity/lang/es/submitted.txt b/lib/plugins/popularity/lang/es/submitted.txt
new file mode 100644
index 000000000..bb1754cdd
--- /dev/null
+++ b/lib/plugins/popularity/lang/es/submitted.txt
@@ -0,0 +1,3 @@
+====== Retroinformación Popularity ======
+
+Los datos se han enviado con éxito. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/et/lang.php b/lib/plugins/popularity/lang/et/lang.php
new file mode 100644
index 000000000..ca1410ab0
--- /dev/null
+++ b/lib/plugins/popularity/lang/et/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
diff --git a/lib/plugins/popularity/lang/eu/intro.txt b/lib/plugins/popularity/lang/eu/intro.txt
new file mode 100644
index 000000000..2d2846f1b
--- /dev/null
+++ b/lib/plugins/popularity/lang/eu/intro.txt
@@ -0,0 +1,9 @@
+====== Popularitate Feedback-a ======
+
+Tresna honek datu anonimoak hartzen ditu zure wiki-ari buruz eta hauek DokuWiki garatzaileei bidaltzea ahalbidetzen dizu. Honek, DokuWiki erabiltzaileek nola erabiltzen duten ulertzen laguntzen die, etorkizuneko garapen erabakiak mundu errealeko erabilpen estatistikekin indartuz.
+
+Pauso hau denboran zehar errepikatzera animatzen zaitugu, modu horretan garatzaileak informatuz zure wiki-a handitzen den ahala. Zure datu bidalketak identifikatzaile anonimo batez identifikatuak izango dira.
+
+Jasotako datuek daramaten informazioa DokuWiki bertsioa, zure orri eta fitxategien kopuru eta tamaina, instalatutako plugin-ak, zure PHP instalazioari buruzko informazioa eta antzerako informazioa da.
+
+Bidaliko diren prozesatu gabeko datuak behean erakusten dira. Mesedez, erabili "Datuak Bidali" botoia informazioa bidaltzeko.
diff --git a/lib/plugins/popularity/lang/eu/lang.php b/lib/plugins/popularity/lang/eu/lang.php
new file mode 100644
index 000000000..05e4262de
--- /dev/null
+++ b/lib/plugins/popularity/lang/eu/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['name'] = 'Popularitate Feedback-a (denbora dezente iraun dezake kargatzen)';
+$lang['submit'] = 'Datuak Bidali';
+$lang['autosubmit'] = 'Automatikoki bidali informazioa hilabetean behin';
+$lang['submissionFailed'] = 'Informazioa ezin izan da bidali ondorengo errorea dela eta:';
+$lang['submitDirectly'] = 'Informazioa eskuz bidali dezakezu ondorengo formularioa bidaliz.';
+$lang['autosubmitError'] = 'Azken bidalketa automatikoak huts egin zuen ondorengo errorea dela eta:';
+$lang['lastSent'] = 'Informazioa bidalia izan da';
diff --git a/lib/plugins/popularity/lang/eu/submitted.txt b/lib/plugins/popularity/lang/eu/submitted.txt
new file mode 100644
index 000000000..94c81a528
--- /dev/null
+++ b/lib/plugins/popularity/lang/eu/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitate Feedback-a ======
+
+Informazioa arrakastaz bidalia izan da. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fa/intro.txt b/lib/plugins/popularity/lang/fa/intro.txt
new file mode 100644
index 000000000..e8521af5f
--- /dev/null
+++ b/lib/plugins/popularity/lang/fa/intro.txt
@@ -0,0 +1,9 @@
+====== بازخورد محبوبیت ======
+
+این ابزار اطلاعات ناشناسی از ویکی شما را برای توسعه‌دهندگان DokuWiki ارسال می‌کند. این اطلاعات به توسعه‌دهندگان کمک می‌کند تا بفهمند کاربران DokuWiki از آن چگونه استفاده می‌کنند تا بتوانند در نسخه‌های آتی، تصمیمات بهتری اتخاذ کنند.
+
+ما امیدواریم شما این حرکت را در زمان‌های مختلف که ویکی‌تان بزرگ‌تر شد، انجام دهید و این اطلاعات ناشناس ارسال خواهد شد.
+
+اطلاعات جمع‌آوری شده حامل اطلاعاتی مثل نسخه‌ی DokuWiki، تعداد و حجم صفحات و فایل‌ها، افزونه‌های نصب شده و اطلاعات PHP سرور می‌باشد.
+
+اطلاعات خامی که ارسال می‌شود در زیر آمده است. خواهشمندیم از دکمه‌ی «ارسال اطلاعات» برای فرستاده شدن استفاده کنید. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fa/lang.php b/lib/plugins/popularity/lang/fa/lang.php
new file mode 100644
index 000000000..70c65f1b3
--- /dev/null
+++ b/lib/plugins/popularity/lang/fa/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['name'] = 'بازخورد محبوبیت (ممکن است اندکی زمان ببرد)';
+$lang['submit'] = 'ارسال اطلاعات';
+$lang['autosubmit'] = 'ارسال خودکار اطلاعات به صورت ماهیانه';
+$lang['submissionFailed'] = 'اطلاعات به علت بروز خطای زیر قابل ارسال نیستند:';
+$lang['submitDirectly'] = 'شما میتوانید اطلاعات را با تکمیل این فرم به صورت دستی ارسال کنید.';
+$lang['autosubmitError'] = 'آخرین ارسال خودکار با خطای مواجه شد, به علت زیر:';
+$lang['lastSent'] = 'اطلاعات ارسال شد.';
diff --git a/lib/plugins/popularity/lang/fa/submitted.txt b/lib/plugins/popularity/lang/fa/submitted.txt
new file mode 100644
index 000000000..63eec47ba
--- /dev/null
+++ b/lib/plugins/popularity/lang/fa/submitted.txt
@@ -0,0 +1,2 @@
+====== بازخورد محبوبیت ======
+اطلاعات ارسال شد. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fi/intro.txt b/lib/plugins/popularity/lang/fi/intro.txt
new file mode 100644
index 000000000..f68c2b8e1
--- /dev/null
+++ b/lib/plugins/popularity/lang/fi/intro.txt
@@ -0,0 +1,9 @@
+====== Suosion palaute ======
+
+Tämä työkalu kerää tietoja wikistäsi ilman tunnistetietoja, jotka voit lähettää DokuWikin kehittäjille. Tämä auttaa heitä ymmärtämään, kuinka DokuWikiä käytetään ja varmistaa, että tulevaisuuden kehityspäätökset tehdään tosielämän käyttökokemusten perusteella.
+
+Toivomme sinun toistavan tämän aiheen silloin tällöin, jotta kehittäjät pysyvät tietoisina, miten wikisi kehittyy. Uudelleenlähettämäsi tiedot identifioidaan tunnisteella, jota ei voida jäljittää takaisin sinuun.
+
+Kerätty tieto pitää sisällään tietoa esimerkiksi DokuWikisi versiosta, sivujen koosta ja lukumäärästä, asennetuista liitännäisistä, sekä PHP asennuksestasi.
+
+Raaka tieto, joka lähetetään näkyy alla. Lähetä tieto painamalla "Lähetä tiedot" nappia. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fi/lang.php b/lib/plugins/popularity/lang/fi/lang.php
new file mode 100644
index 000000000..d7c230742
--- /dev/null
+++ b/lib/plugins/popularity/lang/fi/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['name'] = 'Suosion palaute (voi kestää jonkun aikaa latautua)';
+$lang['submit'] = 'Lähetä tiedot';
+$lang['autosubmit'] = 'Lähetä tiedot automaattisesti kerran kuussa';
+$lang['submissionFailed'] = 'Tietoja ei voitu lähettää seuraavan virheen vuoksi:';
+$lang['submitDirectly'] = 'Voit lähettää tiedot käsin seuraavan kaavakkeen avulla';
+$lang['autosubmitError'] = 'Edellinen automaattilähetys epäonnistui seuraavan virheen vuoksi:';
+$lang['lastSent'] = 'Tiedot on lähetetty';
diff --git a/lib/plugins/popularity/lang/fi/submitted.txt b/lib/plugins/popularity/lang/fi/submitted.txt
new file mode 100644
index 000000000..31059c880
--- /dev/null
+++ b/lib/plugins/popularity/lang/fi/submitted.txt
@@ -0,0 +1,3 @@
+====== Suosion palaute ======
+
+Tiedot lähetettiin onnistuneesti. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/fr/intro.txt b/lib/plugins/popularity/lang/fr/intro.txt
new file mode 100644
index 000000000..041e65d69
--- /dev/null
+++ b/lib/plugins/popularity/lang/fr/intro.txt
@@ -0,0 +1,10 @@
+====== Enquête de popularité ======
+
+Cet [[doku>popularity|outil]] collecte des données anonymes concernant votre wiki et vous permet de les expédier aux développeurs de DokuWiki. Ceci leur permet de mieux comprendre comment DokuWiki est employé par ses utilisateurs et d'orienter les décisions sur les développements futurs en tenant compte des statistiques d'usage réel.
+
+Vous êtes encouragé à répéter l'opération de collecte et d'envoi des données anonymes de temps en temps afin d'informer les développeurs de la croissance de votre wiki.
+
+Les données collectées contiennent des informations telle que votre version de DokuWiki, le nombre et la taille de vos pages et fichiers, les modules installés ainsi que des informations sur la version de PHP installée.
+
+Les données brutes qui sont envoyées sont affichées ci dessous. Merci d'utiliser le bouton « Envoyer les données » pour expédier l'information.
+
diff --git a/lib/plugins/popularity/lang/fr/lang.php b/lib/plugins/popularity/lang/fr/lang.php
new file mode 100644
index 000000000..9ff7a7e8b
--- /dev/null
+++ b/lib/plugins/popularity/lang/fr/lang.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * French language file
+ *
+ * @author Guy Brand <gb@unistra.fr>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['name'] = 'Enquête de popularité (peut nécessiter un certain temps pour être chargée)';
+$lang['submit'] = 'Envoyer les données';
+$lang['autosubmit'] = 'Envoyer les données automatiquement chaque mois';
+$lang['submissionFailed'] = 'Les données ne peuvent pas être envoyées à cause des erreurs suivantes :';
+$lang['submitDirectly'] = 'Vous pouvez envoyer le données manuellement en soumettant ce formulaire.';
+$lang['autosubmitError'] = 'La dernière soumission automatique a échoué pour les raisons suivantes :';
+$lang['lastSent'] = 'Les données ont été envoyées ';
diff --git a/lib/plugins/popularity/lang/fr/submitted.txt b/lib/plugins/popularity/lang/fr/submitted.txt
new file mode 100644
index 000000000..0bc4cfe71
--- /dev/null
+++ b/lib/plugins/popularity/lang/fr/submitted.txt
@@ -0,0 +1,2 @@
+====== Enquête de popularité ======
+Les données ont été envoyées avec succès. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/gl/intro.txt b/lib/plugins/popularity/lang/gl/intro.txt
new file mode 100644
index 000000000..72f03e012
--- /dev/null
+++ b/lib/plugins/popularity/lang/gl/intro.txt
@@ -0,0 +1,10 @@
+====== Resposta de Popularidade ======
+
+Esta ferramenta recolle datos anónimos verbo do teu wiki e permíteche enviarllos aos desenvolvedores do DokuWiki. Isto axudaralles a ter unha idea do xeito en que se emprega o DokuWiki por parte dos seus usuarios, e asegura que as decisións de desenvolvemento futuro coincidan coas estatísticas de uso no mundo real.
+
+Animámoste a levar a cabo este proceso de cando en vez para manteres informados aos desenvolvedores a medida que o teu wiki vaia medrando. Os teus xogos de datos repetidos seran identificados por un ID anónimo.
+
+Os datos recompilados conteñen información como a versión do teu Dokuwiki, o número e tamaño das túas páxinas e arquivos, as extensións instaladas e información verbo da túa instalación do PHP.
+
+Os datos en bruto que serán enviados amósanse embaixo. Por favor, emprega o botón "Enviar Datos" para transferires a información.
+
diff --git a/lib/plugins/popularity/lang/gl/lang.php b/lib/plugins/popularity/lang/gl/lang.php
new file mode 100644
index 000000000..34bd3935f
--- /dev/null
+++ b/lib/plugins/popularity/lang/gl/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Galician language file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['name'] = 'Resposta de Popularidade (pode demorar un tempo a cargar)';
+$lang['submit'] = 'Enviar Datos';
+$lang['autosubmit'] = 'Enviar datos automáticamente unha vez por mes';
+$lang['submissionFailed'] = 'Os datos non se poden enviar debido ao seguinte erro:';
+$lang['submitDirectly'] = 'Podes enviar os datos de forma manual co seguinte formulario.';
+$lang['autosubmitError'] = 'O último envío automático fallou debido ao seguinte erro:';
+$lang['lastSent'] = 'Os datos foron enviados';
diff --git a/lib/plugins/popularity/lang/gl/submitted.txt b/lib/plugins/popularity/lang/gl/submitted.txt
new file mode 100644
index 000000000..0dec55eef
--- /dev/null
+++ b/lib/plugins/popularity/lang/gl/submitted.txt
@@ -0,0 +1,3 @@
+====== Resposta de Popularidade ======
+
+Os datos foron enviados satisfactoriamente. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/he/intro.txt b/lib/plugins/popularity/lang/he/intro.txt
new file mode 100644
index 000000000..1f2e318f7
--- /dev/null
+++ b/lib/plugins/popularity/lang/he/intro.txt
@@ -0,0 +1,9 @@
+====== משוב פופלריות ======
+
+כלי זה אוסף מידע אנונימי אודות הויקי שלך ומאפשר לך לשלוח אותו חזרה למפתחי דוקוויקי. מידע זה יסיע להם להבין את השימוש שעושים משתמשי דוקוויקי במערכת ויבטיח שהחלטות עתידיות לגבי הפיתוח יתבססו על סטטיסטיקות שימוש אמיתי.
+
+נודה אם תחזור על הפעולה מהעת לעת כדי לודא המפתחים מיודעים כשהויקי שלך גדל. המידע שישלח יזוהה על ידי תג אנונימי.
+
+המידע שנאסף כולל פרטים כמו גרסת הדוקוויקי, מספר וגודל הדפים והקבצים שלך, הרחבות מותקנות ומידע אודות התקנת ה-PHP שלך.
+
+המידע הגולמי שישלח מופיע מטה. נא השתמש בכפתור "שלח מידע" כדי להעבירו. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/he/lang.php b/lib/plugins/popularity/lang/he/lang.php
new file mode 100644
index 000000000..f619127cd
--- /dev/null
+++ b/lib/plugins/popularity/lang/he/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Hebrew language file
+ *
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['name'] = 'משוב פופולריות (יתכן זמן טעינה ארוך)';
+$lang['submit'] = 'שלח מידע';
diff --git a/lib/plugins/popularity/lang/hi/lang.php b/lib/plugins/popularity/lang/hi/lang.php
new file mode 100644
index 000000000..c0085d72a
--- /dev/null
+++ b/lib/plugins/popularity/lang/hi/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
+$lang['submit'] = 'डेटा भेजे';
diff --git a/lib/plugins/popularity/lang/hr/lang.php b/lib/plugins/popularity/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/popularity/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/popularity/lang/hu/intro.txt b/lib/plugins/popularity/lang/hu/intro.txt
new file mode 100644
index 000000000..17bb6fc6f
--- /dev/null
+++ b/lib/plugins/popularity/lang/hu/intro.txt
@@ -0,0 +1,9 @@
+====== Visszajelzés a DokuWiki használatáról ======
+
+Ez az eszköz anonimizált adatokat gyűjt a wikidről, és lehetővé teszi, hogy elküldd a DokuWiki fejlesztőinek. Ez segít meglátni, hogy a felhasználók hogyan használják a DokuWikijüket, ezáltal biztosítja, hogy a későbbi fejlesztési döntések hátterében valós használati statisztikák álljanak.
+
+Szeretnénk megkérni, hogy időről időre ismételd meg ezt a műveletet, hogy a fejlesztők értesülhessenek, hogyan nő a wikid mérete. Az ismételt adatküldéseid egy anoním ID-vel lesznek azonosítva.
+
+Ilyen és hasonló információkat gyűjtünk: DokuWiki verziószáma, a lapok, fájlok mérete és darabszáma, feltelepített bővítmények, PHP installáció adatai.
+
+Az elküldendő nyers adat lent látható. Kérjük, az "Adatok elküldése" gombbal juttasd el hozzánk!
diff --git a/lib/plugins/popularity/lang/hu/lang.php b/lib/plugins/popularity/lang/hu/lang.php
new file mode 100644
index 000000000..5dcd1adf0
--- /dev/null
+++ b/lib/plugins/popularity/lang/hu/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['name'] = 'Visszajelzés a DokuWiki használatáról (sok időt vehet igénybe a betöltése)';
+$lang['submit'] = 'Adatok elküldése';
+$lang['autosubmit'] = 'Adatok havonkénti automatikus elküldése.';
+$lang['submissionFailed'] = 'Az adatok a következő hiba miatt nem kerültek elküldésre:';
+$lang['submitDirectly'] = 'Az adatokat a következő űrlap segítségével lehet elküldeni.';
+$lang['autosubmitError'] = 'Az adatok a következő hiba miatt nem kerültek automatikusan elküldésre:';
+$lang['lastSent'] = 'Az adatokat elküldtük.';
diff --git a/lib/plugins/popularity/lang/hu/submitted.txt b/lib/plugins/popularity/lang/hu/submitted.txt
new file mode 100644
index 000000000..30ab8bd8e
--- /dev/null
+++ b/lib/plugins/popularity/lang/hu/submitted.txt
@@ -0,0 +1,3 @@
+====== Visszajelzés a DokuWiki használatáról ======
+
+Az adatokat sikeresen elküldtük. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ia/intro.txt b/lib/plugins/popularity/lang/ia/intro.txt
new file mode 100644
index 000000000..d31c3653f
--- /dev/null
+++ b/lib/plugins/popularity/lang/ia/intro.txt
@@ -0,0 +1,9 @@
+====== Datos de popularitate ======
+
+Iste instrumento collige datos anonyme super tu wiki e te permitte inviar los retro al disveloppatores de DokuWiki. Isto les adjuta de comprender como DokuWiki es usate per su usatores e assecura que le decisiones super le disveloppamento futur si basate super statisticas de uso ex le mundo real.
+
+Tu es incoragiate a repeter iste procedura de tempore a tempore pro continuar a informar le disveloppatores quando tu wiki cresce. Tu collectiones repetite de datos essera identificate per un ID anonyme.
+
+Le datos colligite contine informationes como tu version de DokuWiki, le numero e dimension de tu paginas e files, plug-ins installate e information super tu installation de PHP.
+
+Le datos crude que essera inviate es monstrate hic infra. Per favor usa le button "Inviar datos" pro transferer le informationes. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ia/lang.php b/lib/plugins/popularity/lang/ia/lang.php
new file mode 100644
index 000000000..4a45f04f3
--- /dev/null
+++ b/lib/plugins/popularity/lang/ia/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['name'] = 'Datos de popularitate (pote prender alcun tempore pro cargar)';
+$lang['submit'] = 'Inviar datos';
diff --git a/lib/plugins/popularity/lang/id-ni/intro.txt b/lib/plugins/popularity/lang/id-ni/intro.txt
new file mode 100644
index 000000000..fb2370935
--- /dev/null
+++ b/lib/plugins/popularity/lang/id-ni/intro.txt
@@ -0,0 +1,7 @@
+====== Popularitas-Fangombakha ======
+
+Fakake anonyme da'e i'owuloi ngawalö data moroi ba Wiki khöu awö wanehegöu wama'ohe'ö DokuWiki ba zangahaogö. Data da'e aoha wangehaogö ba wombohouni mangawuli ba DokuWiki ba biziso miföna abölö aoha wangirö'ö ya'ia bakha ba nahia wamake statistik.
+
+Tola öfa'ohe'ö mangawuli data ero-ero soginötö ba wangehaogö ba bawamohouni Wiki khöndra samazökhi. Data nifa'ohe'öu ifareso dania anonyme ID.
+
+...
diff --git a/lib/plugins/popularity/lang/id-ni/lang.php b/lib/plugins/popularity/lang/id-ni/lang.php
new file mode 100644
index 000000000..d9a36f203
--- /dev/null
+++ b/lib/plugins/popularity/lang/id-ni/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['name'] = 'Sabölö teturia (sito\'ölönia ara ginötö wamokai)';
+$lang['submit'] = 'Fa\'ohe\'ö data';
diff --git a/lib/plugins/popularity/lang/id/lang.php b/lib/plugins/popularity/lang/id/lang.php
new file mode 100644
index 000000000..1867f0f69
--- /dev/null
+++ b/lib/plugins/popularity/lang/id/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/popularity/lang/is/lang.php b/lib/plugins/popularity/lang/is/lang.php
new file mode 100644
index 000000000..9add4cae4
--- /dev/null
+++ b/lib/plugins/popularity/lang/is/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['submit'] = 'Senda gögn';
diff --git a/lib/plugins/popularity/lang/it/intro.txt b/lib/plugins/popularity/lang/it/intro.txt
new file mode 100644
index 000000000..f65310a5a
--- /dev/null
+++ b/lib/plugins/popularity/lang/it/intro.txt
@@ -0,0 +1,9 @@
+====== Raccolta dati sul wiki ======
+
+Questo strumento raccoglie dati anonimi sul tuo wiki e ti permette di inviarli agli sviluppatori di Dokuwiki. Questo aiuta loro a capire come Dokuwiki viene utilizzato dagli utenti e prendere decisioni future sullo sviluppo in base a quelle che sono le reali statistiche di utilizzo da parte degli utenti.
+
+Ti incoraggiamo a ripetere ogni tanto questa operazione per mantenere informati gli sviluppatori sulla crescita del tuo wiki. L'insieme dei dati raccolti saranno identificati tramite un ID anonimo.
+
+I dati raccolti contengono informazioni come la versione di DokuWiki, il numero e le dimensioni delle pagine e dei file, i plugin installati e informazioni sulla versione di PHP presente nel sistema.
+
+A continuazione puoi vedere un'anteprima dei dati che saranno inviati. Utilizza il pulsante "Invia dati" per trasferire le informazioni. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/it/lang.php b/lib/plugins/popularity/lang/it/lang.php
new file mode 100644
index 000000000..a7852f22c
--- /dev/null
+++ b/lib/plugins/popularity/lang/it/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['name'] = 'Raccolta dati sul wiki (può impiegare del tempo per caricarsi)';
+$lang['submit'] = 'Invia dati';
+$lang['autosubmit'] = 'Invia automaticamente i dati una volta al mese';
+$lang['submissionFailed'] = 'È stato impossibile inviare i dati a causa del seguente errore:';
+$lang['submitDirectly'] = 'È possibile inviare i dati manualmente utilizzando il pulsante sottostante.';
+$lang['autosubmitError'] = 'L\'ultimo invio automatico non è andato a buon fine a causa del seguente errore:';
+$lang['lastSent'] = 'I dati sono stati inviati';
diff --git a/lib/plugins/popularity/lang/it/submitted.txt b/lib/plugins/popularity/lang/it/submitted.txt
new file mode 100644
index 000000000..78247154e
--- /dev/null
+++ b/lib/plugins/popularity/lang/it/submitted.txt
@@ -0,0 +1,3 @@
+====== Raccolta dati sul wiki ======
+
+I dati sono stati inviati correttamente. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ja/intro.txt b/lib/plugins/popularity/lang/ja/intro.txt
new file mode 100644
index 000000000..09886f418
--- /dev/null
+++ b/lib/plugins/popularity/lang/ja/intro.txt
@@ -0,0 +1,9 @@
+====== 利用状況調査 ======
+
+このツールは、ご利用中のwikiの情報を収集し、それをDokuWikiの開発者へ匿名で送信するものです。開発者はこのツールにより、DokuWikiが実際にどの様に利用されているかを理解し、そして実際の利用状況に基づいて今後の開発方針の決定することができます。
+
+お使いのwikiの規模が大きくなってきたときは、このステップを定期的に繰り返すことを推奨しています。また、送信されたデータは匿名のIDで識別されます。
+
+DokuWikiのバージョン、ページとファイルの数とサイズ、インストール済みプラグイン、そしてお使いのPHPに関する情報が、送信されるデータに含まれます。
+
+以下に表示されているデータが実際に送信されるデータとなります。"データ送信"ボタンを押して情報を送信してください。 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ja/lang.php b/lib/plugins/popularity/lang/ja/lang.php
new file mode 100644
index 000000000..736924bb1
--- /dev/null
+++ b/lib/plugins/popularity/lang/ja/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Japanese language file
+ *
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ */
+$lang['name'] = '利用状況調査(ロードに少し時間が掛かります)';
+$lang['submit'] = 'データ送信';
+$lang['autosubmit'] = '月に一度は自動的にデータを送付';
+$lang['submissionFailed'] = '次のエラーによりデータが送信できませんでした:';
+$lang['submitDirectly'] = '次のフォームを使ってデータを手動で送信することができます。';
+$lang['autosubmitError'] = '以下のエラーにより最後の自動送信に失敗しました:';
+$lang['lastSent'] = 'データを送信しました。';
diff --git a/lib/plugins/popularity/lang/ja/submitted.txt b/lib/plugins/popularity/lang/ja/submitted.txt
new file mode 100644
index 000000000..604f8e55f
--- /dev/null
+++ b/lib/plugins/popularity/lang/ja/submitted.txt
@@ -0,0 +1,3 @@
+====== 利用状況調査 ======
+
+データの送信に成功しました。 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/kk/lang.php b/lib/plugins/popularity/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/popularity/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/popularity/lang/ko/intro.txt b/lib/plugins/popularity/lang/ko/intro.txt
new file mode 100644
index 000000000..e979b71d5
--- /dev/null
+++ b/lib/plugins/popularity/lang/ko/intro.txt
@@ -0,0 +1,9 @@
+====== 인기도 조사 ======
+
+설치된 위키의 익명 정보를 DokuWiki 개발자들에게 보냅니다. 이 기능은 DokuWiki가 실제 사용자들에게 어떻게 사용되는지 DokuWiki 개발자들에게 알려줌으로써 이 후 개발 시 참고가 됩니다.
+
+설치된 위키가 커짐에 따라서 이 과정을 반복할 필요가 있습니다. 반복된 데이타는 익명 ID로 구별되어집니다.
+
+전송 데이타는 설치 DokuWiki 버전, 페이지와 파일 수, 크기, 설치 플러그인, 설치 PHP 정보등을 포함하고 있습니다.
+
+실제 보내질 자료는 아래와 같습니다. 정보를 보내려면 "자료 보내기" 버튼을 클릭합니다.
diff --git a/lib/plugins/popularity/lang/ko/lang.php b/lib/plugins/popularity/lang/ko/lang.php
new file mode 100644
index 000000000..0f1442d53
--- /dev/null
+++ b/lib/plugins/popularity/lang/ko/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Korean language file
+ *
+ * @author jk lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['name'] = '인기도 조사 (불러오는데 시간이 걸릴 수 있습니다.)';
+$lang['submit'] = '자료 보내기';
+$lang['autosubmit'] = '자료를 자동으로 매달 한번씩 보내기';
+$lang['submissionFailed'] = '다음과 같은 이유로 자료 전송에 실패했습니다 :';
+$lang['submitDirectly'] = '아래의 양식에 맞춰 수동으로 작성된 자료를 보낼 수 있습니다';
+$lang['autosubmitError'] = '다음과 같은 이유로 자동 자료 전송에 실패했습니다 :';
+$lang['lastSent'] = '자료가 전송되었습니다';
diff --git a/lib/plugins/popularity/lang/ko/submitted.txt b/lib/plugins/popularity/lang/ko/submitted.txt
new file mode 100644
index 000000000..e8b434dc5
--- /dev/null
+++ b/lib/plugins/popularity/lang/ko/submitted.txt
@@ -0,0 +1,3 @@
+====== 인기도 조사 ======
+
+자료 전송이 성공적으로 완료되었습니다 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/la/intro.txt b/lib/plugins/popularity/lang/la/intro.txt
new file mode 100644
index 000000000..c3029caf4
--- /dev/null
+++ b/lib/plugins/popularity/lang/la/intro.txt
@@ -0,0 +1,10 @@
+====== Index Fauoris Popularis ======
+
+Haoc instrumentum fauorem popularem mittis sic ut creatores uicis meliorem illum facere possint.
+
+Rursum te fauorem mittere experamus sic ut si mutationes meliores uel peiores esse uidere possimus.
+
+Res mittendae tua forma in usu, numerus et pondus paginarum et aliarum rerum, addenda in usu et de PHP.
+
+Res rudes mittendae subter ostenduntur. "Res mittere" premas ut eas transferas.
+
diff --git a/lib/plugins/popularity/lang/la/lang.php b/lib/plugins/popularity/lang/la/lang.php
new file mode 100644
index 000000000..c7f307c29
--- /dev/null
+++ b/lib/plugins/popularity/lang/la/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['name'] = 'Index fauoris popularis (multum tempus quaerere potest)';
+$lang['submit'] = 'Missum die';
+$lang['autosubmit'] = 'Constanter res omni mense mittuntur';
+$lang['submissionFailed'] = 'Res non mittuntur ea causa:';
+$lang['submitDirectly'] = 'Res tu mittere potes cum hoc exemplar compleas.';
+$lang['autosubmitError'] = 'Extrema missio lapsa est ea causa:';
+$lang['lastSent'] = 'Res missae sunt';
diff --git a/lib/plugins/popularity/lang/la/submitted.txt b/lib/plugins/popularity/lang/la/submitted.txt
new file mode 100644
index 000000000..2b2faf439
--- /dev/null
+++ b/lib/plugins/popularity/lang/la/submitted.txt
@@ -0,0 +1,3 @@
+====== Index fauoris popularis ======
+
+Res feliciter missae sunt. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/lb/lang.php b/lib/plugins/popularity/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/popularity/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/popularity/lang/lt/lang.php b/lib/plugins/popularity/lang/lt/lang.php
new file mode 100644
index 000000000..88df29c50
--- /dev/null
+++ b/lib/plugins/popularity/lang/lt/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['name'] = 'Populiarumo apklausa (gali užtrukti pakrovimas)';
+$lang['submit'] = 'Pateikti';
diff --git a/lib/plugins/popularity/lang/lv/intro.txt b/lib/plugins/popularity/lang/lv/intro.txt
new file mode 100644
index 000000000..dd43f96a5
--- /dev/null
+++ b/lib/plugins/popularity/lang/lv/intro.txt
@@ -0,0 +1,9 @@
+====== Popularitātes atsauksme ======
+
+Šis rīks savāc anonīmus datus par tavu wiki sistēmu un piedāvā tos nodot DokuWiki izstrādātājiem. Tas ļauj zināt kā izmanto DokuWiki un palīdz tālāko attīstību balstīt patiesas izmantošanas statistikā .
+
+Ierosinām laiku pa laikam atkārtoti nosūtīt datus, lai izstrādātāji zinātu, ka tavs wiki aug. Atkārtotos sūtījumus identificēs pēc anonīmā ID.
+
+Savāktie dati satur ziņas par DokuWiki versiju, lapu skaitu un apjomu, instalētajiem spraudņiem un par PHP instalāciju.
+
+Nosūtāmie dati redzami zemāk. Nospied pogu "Nosūtīt datus", lai nodotu ziņas. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/lv/lang.php b/lib/plugins/popularity/lang/lv/lang.php
new file mode 100644
index 000000000..f0c940b6f
--- /dev/null
+++ b/lib/plugins/popularity/lang/lv/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Latvian, Lettish language file
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['name'] = 'Popularitātes atsauksmes (ielāde var aizņemt kādu laiku)';
+$lang['submit'] = 'Nosūtīt datus';
+$lang['autosubmit'] = 'Automātiski reizi mēnesī nosūtīt datus';
+$lang['submissionFailed'] = 'Datus nevar nosūtīt kļūdas dēļ:';
+$lang['submitDirectly'] = 'Jūs pats varat pats nosūtīt datus no šīs veidlapas.';
+$lang['autosubmitError'] = 'Pēdējā automātiskā nosūtīšana kļūdas dēļ:';
+$lang['lastSent'] = 'Dati nosūtīti';
diff --git a/lib/plugins/popularity/lang/lv/submitted.txt b/lib/plugins/popularity/lang/lv/submitted.txt
new file mode 100644
index 000000000..c31338abf
--- /dev/null
+++ b/lib/plugins/popularity/lang/lv/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitātes atsauksmes ======
+
+Dati veiksmīgi nosūtīti \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/mk/lang.php b/lib/plugins/popularity/lang/mk/lang.php
new file mode 100644
index 000000000..6d4530f79
--- /dev/null
+++ b/lib/plugins/popularity/lang/mk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
diff --git a/lib/plugins/popularity/lang/mr/intro.txt b/lib/plugins/popularity/lang/mr/intro.txt
new file mode 100644
index 000000000..df912e483
--- /dev/null
+++ b/lib/plugins/popularity/lang/mr/intro.txt
@@ -0,0 +1,8 @@
+====== लोकप्रियता फीडबॅक ======
+हे टूल तुमच्या विकी संबंधी माहिती गुप्तपणे गोळा करते आणि डॉक्युविकीच्या निर्मात्याना पाठवते. याद्वारे त्यांना डॉक्युविकी प्रत्यक्ष कशी वापरली जाते व त्यानुसार प्रत्यक्ष माहितीवर आधारित पुढील सुधारणा करण्यास मदत होते.
+
+तुम्ही हे टूल ठराविक अंतराने परत वापरत राहिल्यास अधिक चांगले ,कारण तुमची विकी जसजशी वाढेल तसे डेवलपर लोकाना त्याबद्दल माहिती कळण्यास मदत होइल. तुमचा डेटा गुप्त निर्देशकाद्वारे ओळखला जाइल.
+
+या डेटा मधे पुढील प्रकारची माहिती असेल : तुमच्या डॉक्युविकीची आवृत्ति, त्यातील पानांची संख्या व साइज़, इन्स्टॉल केलेले प्लगइन आणि तुमच्या PHP ची आवृत्ति.
+
+जो डेटा प्रत्यक्ष पाठवला जाइल तो खाली दाखवला आहे. "Send Data" बटन वर क्लिक करून हा डेटा पाठवा. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/mr/lang.php b/lib/plugins/popularity/lang/mr/lang.php
new file mode 100644
index 000000000..abf7dd5ed
--- /dev/null
+++ b/lib/plugins/popularity/lang/mr/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['name'] = 'लोकप्रियता फीडबॅक ( लोड होण्यास थोडा वेळ लागेल )';
+$lang['submit'] = 'माहीती पाठवा';
diff --git a/lib/plugins/popularity/lang/ms/lang.php b/lib/plugins/popularity/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/popularity/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/popularity/lang/ne/lang.php b/lib/plugins/popularity/lang/ne/lang.php
new file mode 100644
index 000000000..d6aa56eb7
--- /dev/null
+++ b/lib/plugins/popularity/lang/ne/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['submit'] = 'सामग्री पठाउनुहोस् ';
diff --git a/lib/plugins/popularity/lang/nl/intro.txt b/lib/plugins/popularity/lang/nl/intro.txt
new file mode 100644
index 000000000..3c045c427
--- /dev/null
+++ b/lib/plugins/popularity/lang/nl/intro.txt
@@ -0,0 +1,9 @@
+====== Populariteitsfeedback ======
+
+Dit onderdeel verzamelt anonieme gegevens over uw wiki en stelt u in staat deze te versturen naar de ontwikkelaars van DokuWiki. Dit helpt hen te begrijpen hoe DokuWiki wordt gebruikt door de gebruikers en zorgt er ook voor dat toekomstige ontwikkelkeuzes kunnen worden gestaafd door echte gebruikersstatistieken.
+
+U wordt verzocht deze stap van tijd tot tijd te herhalen om ontwikkelaars op de hoogte te houden terwijl uw wiki groeit. De herhaalde data zal worden geïdentificeerd door een uniek, anoniem ID.
+
+De verzamelde gegevens bevat onder andere gegevens over uw versie van DokuWiki, het aantal- en de grootte van de pagina's en bestanden, geïnstalleerde plugins en informatie over PHP.
+
+De ruwe data die verzonden worden staan hieronder. Gebruik de knop "Verstuur" om de informatie te verzenden.
diff --git a/lib/plugins/popularity/lang/nl/lang.php b/lib/plugins/popularity/lang/nl/lang.php
new file mode 100644
index 000000000..e5e94aab4
--- /dev/null
+++ b/lib/plugins/popularity/lang/nl/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Dutch language file
+ *
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['name'] = 'Populariteitsfeedback (kan even duren om in te laden)';
+$lang['submit'] = 'Verstuur';
+$lang['autosubmit'] = 'Gegevens automatisch maandelijks verzenden';
+$lang['submissionFailed'] = 'De gegevens konden niet verstuurd worden vanwege de volgende fouten:';
+$lang['submitDirectly'] = 'Je kan de gegevens handmatig sturen door het onderstaande formulier te verzenden.';
+$lang['autosubmitError'] = 'De laatste automatische verzending is mislukt vanwege de volgende fout:';
+$lang['lastSent'] = 'De gegevens zijn verstuurd.';
diff --git a/lib/plugins/popularity/lang/nl/submitted.txt b/lib/plugins/popularity/lang/nl/submitted.txt
new file mode 100644
index 000000000..219d80fb6
--- /dev/null
+++ b/lib/plugins/popularity/lang/nl/submitted.txt
@@ -0,0 +1,3 @@
+===== Populariteitsfeedback =====
+
+Het versturen van de gegevens is gelukt. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/no/intro.txt b/lib/plugins/popularity/lang/no/intro.txt
new file mode 100644
index 000000000..a0f360157
--- /dev/null
+++ b/lib/plugins/popularity/lang/no/intro.txt
@@ -0,0 +1,9 @@
+====== Popularitetsfeedback ======
+
+Dette verktøyet samler anonyme data om din wiki og lar deg sende det tilbake til DokuWikis utviklere. Dette hjelper utviklerne å forstå hvordan DokuWiki blir brukt av brukerne, og gjør at fremtidig beslutninger om videre utvikling kan baseres på statistikk fra virkelig bruk.
+
+Du oppfordres herved til å gjenta dette skrittet fra tid til annen for å holde utviklerne informert når din wiki vokser. Ditt gjentatte datasett blir identifisert vha en anonym ID.
+
+De data som samles inn inneholder informasjon som din DokuWiki-versjon, antallet og størrelsen på sider og filer, installerte plugins og informasjon om din installerte PHP.
+
+Rådata som blir sendt vises nedenfor. Bruk knappen "Send data" for å overføre informasjonen. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/no/lang.php b/lib/plugins/popularity/lang/no/lang.php
new file mode 100644
index 000000000..df38f6e0e
--- /dev/null
+++ b/lib/plugins/popularity/lang/no/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Norwegian language file
+ *
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['name'] = 'Popularitetsfeedback (kan ta litt tid å laste)';
+$lang['submit'] = 'Send data';
+$lang['autosubmit'] = 'Send data automatisk en gang i måneden';
+$lang['submissionFailed'] = 'Kunne ikke sende dataene på grunn av følgende feil:';
+$lang['submitDirectly'] = 'Du kan sende dataene manuelt ved å sende inn dette skjemaet.';
+$lang['autosubmitError'] = 'Den siste automatiske innsendingen feilet på grunn av følgende feil:';
+$lang['lastSent'] = 'Dataene er sendt';
diff --git a/lib/plugins/popularity/lang/no/submitted.txt b/lib/plugins/popularity/lang/no/submitted.txt
new file mode 100644
index 000000000..ccec7674e
--- /dev/null
+++ b/lib/plugins/popularity/lang/no/submitted.txt
@@ -0,0 +1,3 @@
+====== Tilbakemelding om popularitet ======
+
+Innsending av dataene var vellykket. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pl/intro.txt b/lib/plugins/popularity/lang/pl/intro.txt
new file mode 100644
index 000000000..d95e7f79c
--- /dev/null
+++ b/lib/plugins/popularity/lang/pl/intro.txt
@@ -0,0 +1,9 @@
+====== Informacja o popularności ======
+
+To narzędzie zbiera anonimowe dane o Twoim wiki i wysyła je do twórców DokuWiki. Zbieranie tych informacji pozwala na lepsze zrozumienie sposobów korzystania z DokuWiki i ułatwia podejmowanie przyszłych decyzji projektowych w oparciu o rzeczywiste dane statystyczne.
+
+Zachęcamy do uruchamiania tej funkcji co pewien czas, by poinformować programistów DokuWiki o rozwoju Twojego wiki. Informacje przesyłane przez Ciebie będą oznaczone anonimowym identyfikatorem.
+
+Zbierane dane zawierają informacje o wersji DokuWiki, ilości i rozmiarze stron i plików, zainstalowanych wtyczkach oraz informację o oprogramowaniu PHP.
+
+Wysyłane dane przedstawione są poniżej. Naciśnij przycisk "Wyślij dane" w celu przesłania informacji. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pl/lang.php b/lib/plugins/popularity/lang/pl/lang.php
new file mode 100644
index 000000000..64d772d54
--- /dev/null
+++ b/lib/plugins/popularity/lang/pl/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Polish language file
+ *
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['name'] = 'Informacja o popularności (ładowanie może zająć dłuższą chwilę)';
+$lang['submit'] = 'Wyślij dane';
+$lang['autosubmit'] = 'Automatycznie wysyłaj dane raz na miesiąc';
+$lang['submissionFailed'] = 'Dane nie mogły być przesłane ze względu na następujące błędy:';
+$lang['submitDirectly'] = 'Możesz wysłać dane ręcznie poprzez następujący formularz:';
+$lang['autosubmitError'] = 'Ostatnie wysyłanie automatyczne nie powiodło się ze względu na następujące błędy:';
+$lang['lastSent'] = 'Dane zostały wysłane:';
diff --git a/lib/plugins/popularity/lang/pl/submitted.txt b/lib/plugins/popularity/lang/pl/submitted.txt
new file mode 100644
index 000000000..195e81388
--- /dev/null
+++ b/lib/plugins/popularity/lang/pl/submitted.txt
@@ -0,0 +1,3 @@
+====== Informacje o popularności ======
+
+Wysyłanie danych powiodło się. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pt-br/intro.txt b/lib/plugins/popularity/lang/pt-br/intro.txt
new file mode 100644
index 000000000..306cb2820
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt-br/intro.txt
@@ -0,0 +1,9 @@
+====== Retorno de Popularidade ======
+
+Essa ferramenta coleta dados anônimos sobre o seu wiki e permite que você os envie para os desenvolvedores do DokuWiki. Isso ajuda-os a compreender como o DokuWiki é utilizado pelos seus usuários e garante que decisões para futuros desenvolvimentos sejam respaldadas por estatísticas de uso real.
+
+Você é encorajado a repetir esse procedimento de tempos em tempos, para manter os desenvolvedores informados quando o seu wiki for alterado. Seus pacotes de dados repetidos serão categorizados por uma identificação anônima.
+
+Os dados coletados contém informações do tipo: a versão do seu DokuWiki, o número e tamanho das suas páginas e arquivos, plug-ins instalados e informações sobre a sua instalação do PHP.
+
+Os dados brutos que serão enviados é mostrado abaixo. Por favor, utilize o botão "Enviar dados" para transferir a informação.
diff --git a/lib/plugins/popularity/lang/pt-br/lang.php b/lib/plugins/popularity/lang/pt-br/lang.php
new file mode 100644
index 000000000..44d811d81
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt-br/lang.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['name'] = 'Retorno de popularidade (pode demorar um pouco para carregar)';
+$lang['submit'] = 'Enviar dados';
+$lang['autosubmit'] = 'Enviar os dados automaticamente uma vez por mês';
+$lang['submissionFailed'] = 'Os dados não puderam ser enviados devido ao seguinte erro:';
+$lang['submitDirectly'] = 'Você pode enviar os dados manualmente, submetendo o formulário baixo.';
+$lang['autosubmitError'] = 'Ocorreu uma falha na última submissão automática, devido ao seguinte erro:';
+$lang['lastSent'] = 'Os dados foram enviados';
diff --git a/lib/plugins/popularity/lang/pt-br/submitted.txt b/lib/plugins/popularity/lang/pt-br/submitted.txt
new file mode 100644
index 000000000..7c0cea8c1
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt-br/submitted.txt
@@ -0,0 +1,3 @@
+====== Retorno de popularidade ======
+
+Os dados foram enviados com sucesso. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pt/intro.txt b/lib/plugins/popularity/lang/pt/intro.txt
new file mode 100644
index 000000000..9ec37e208
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt/intro.txt
@@ -0,0 +1,9 @@
+====== Retorno de Popularidade ======
+
+Esta ferramenta junta dados anónimos sobre o seu wiki e permite estes sejam enviados para a equipa de desenvolvimento do DokuWiki. Isto ajuda-os a compreender como o DokuWiki é usado pelos seus utilizadores de forma a permitir que desenvolvimentos futuros sejam baseadas em estatísticas de uso real.
+
+Você é encorajado a repetir este passo regularmente para manter a equipa informada quando o seu wiki crescer. Os seus dados permanecerão sempre anónimos.
+
+Os dados colectados contêm informação como a versão do DokuWiki que você utiliza, o número e tamanho das suas páginas e ficheiros, os plugins instalados e informação sobre a sua instalação do PHP.
+
+Os dados que serão enviados são mostrados abaixo. Use o botão "Enviar Dados" para transferir a informação. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/pt/lang.php b/lib/plugins/popularity/lang/pt/lang.php
new file mode 100644
index 000000000..ac27dc8c0
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['name'] = 'Retorno (feedback) de Popularidade (pode levar algum tempo a carregar)';
+$lang['submit'] = 'Enviar Dados';
+$lang['autosubmit'] = 'Enviar dados automáticamente uma vez por mês';
+$lang['submissionFailed'] = 'Os dados não foram enviados devido ao seguinte erro:';
+$lang['submitDirectly'] = 'Pode enviar os dados manualmente, submetendo o seguinte formulário.';
+$lang['autosubmitError'] = 'A última auto-submissão falhou, por causa do seguinte erro:';
+$lang['lastSent'] = 'Os dados foram enviados';
diff --git a/lib/plugins/popularity/lang/pt/submitted.txt b/lib/plugins/popularity/lang/pt/submitted.txt
new file mode 100644
index 000000000..d2bb2b7ae
--- /dev/null
+++ b/lib/plugins/popularity/lang/pt/submitted.txt
@@ -0,0 +1,3 @@
+====== Retorno de Popularidade ======
+
+Os dados foram enviados com sucesso. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ro/intro.txt b/lib/plugins/popularity/lang/ro/intro.txt
new file mode 100644
index 000000000..b2dfcbaf1
--- /dev/null
+++ b/lib/plugins/popularity/lang/ro/intro.txt
@@ -0,0 +1,9 @@
+====== Feedback de popularitate ======
+
+Această unealtă colectează date anonime despre wiki-ul dvs. şi vă permite să le trimiteţi înapoi către dezvoltatorii DokuWiki. Aceasta îi ajută să înţeleagă cum este folosit DokuWiki de către utilizatori şi asigură faptul că viitoarele decizii privind dezvoltarea sunt bazate pe statistici ale utilizării în condiţii reale.
+
+Sunteţi încurajat să repetaţi acest pas din când în când pentru a ţine dezvoltatorii la curent cu dezvoltarea wiki-ului dvs. Seturile de date trimise in mod repetat vor fi identificate printr-un ID anonim.
+
+Datele colectate conţin informaţii precum versiunea DokuWiki, numărul şi mărimea paginilor şi a fişierelor dvs., plugin-urile instalate şi informaţii despre versiunea PHP instalată.
+
+Datele brute ce vor fi trimise sunt afişate mai jos. Vă rugăm utilizaţi butonul "Trimite datele" pentru a transfera informaţiile. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ro/lang.php b/lib/plugins/popularity/lang/ro/lang.php
new file mode 100644
index 000000000..f3ca8d37e
--- /dev/null
+++ b/lib/plugins/popularity/lang/ro/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['name'] = 'Feedback de popularitate (încărcarea poate dura mai mult)';
+$lang['submit'] = 'Trimite datele';
+$lang['autosubmit'] = 'Trimite datele automat o dată pe lună';
+$lang['submissionFailed'] = 'Datele nu au fost trimise din cauza următoarei erori:';
+$lang['submitDirectly'] = 'Puteți trimite datele manual prin completarea următorului formular.';
+$lang['autosubmitError'] = 'Ultima trimitere automată a eșuat din cauza următoarei erori:';
+$lang['lastSent'] = 'Datele au fost trimise';
diff --git a/lib/plugins/popularity/lang/ro/submitted.txt b/lib/plugins/popularity/lang/ro/submitted.txt
new file mode 100644
index 000000000..214ffb71f
--- /dev/null
+++ b/lib/plugins/popularity/lang/ro/submitted.txt
@@ -0,0 +1,3 @@
+====== Feedback de popularitate ======
+
+Datele au fost trimise cu succes. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/ru/intro.txt b/lib/plugins/popularity/lang/ru/intro.txt
new file mode 100644
index 000000000..e8118e4eb
--- /dev/null
+++ b/lib/plugins/popularity/lang/ru/intro.txt
@@ -0,0 +1,10 @@
+====== Сбор информации о популярности ======
+
+Этот инструмент собирает анонимные данные о вашей вики и позволяет вам отправить их разработчикам «ДокуВики». Эти данные помогут им понять, как именно используется «ДокуВики», и удостовериться, что принимаемые проектные решения соответствуют жизненным реалиям.
+
+Отправляйте данные время от времени для того, чтобы сообщать разработчикам о том, что ваша вики «подросла». Отправленные вами данные будут идентифицированы по анонимному ID.
+
+Собранные данные содержат такую информацию, как: версия «ДокуВики», количество и размер ваших страниц и файлов, установленные плагины, информацию об установленном PHP.
+
+Данные, которые будут отосланы, представлены ниже. Пожалуйста, используйте кнопку «Отправить данные», чтобы передать информацию.
+
diff --git a/lib/plugins/popularity/lang/ru/lang.php b/lib/plugins/popularity/lang/ru/lang.php
new file mode 100644
index 000000000..79b3e224d
--- /dev/null
+++ b/lib/plugins/popularity/lang/ru/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Russian language file
+ *
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['name'] = 'Сбор информации о популярности (для загрузки может потребоваться некоторое время)';
+$lang['submit'] = 'Отправить данные';
+$lang['autosubmit'] = 'Автоматически отправлять данные один раз в месяц';
+$lang['submissionFailed'] = 'Данные не могут быть отправлены из-за ошибки:';
+$lang['submitDirectly'] = 'Вы можете отправлять данные вручную, заполнив форму:';
+$lang['autosubmitError'] = 'Последнее автоотправление данных не удалось из-за ошибки:';
+$lang['lastSent'] = 'Данные отправлены';
diff --git a/lib/plugins/popularity/lang/ru/submitted.txt b/lib/plugins/popularity/lang/ru/submitted.txt
new file mode 100644
index 000000000..a239943a4
--- /dev/null
+++ b/lib/plugins/popularity/lang/ru/submitted.txt
@@ -0,0 +1,2 @@
+====== Общественная обратная связь ======
+Данные были успешно отправлены. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sk/intro.txt b/lib/plugins/popularity/lang/sk/intro.txt
new file mode 100644
index 000000000..7f580d979
--- /dev/null
+++ b/lib/plugins/popularity/lang/sk/intro.txt
@@ -0,0 +1,9 @@
+====== Prieskum používania ======
+
+Tento nástroj získa anonymné dáta o Vašej wiki a ponúkne Vám možnosť odoslať ich späť k vývojárom DokuWiki. Týmto spôsobom im umožníte lepšie porozumieť, ako je používaná DokuWiki, a podporiť ich budúce rozhodnutia o ďalšom vývoji informáciami z reálneho používania DokuWiki.
+
+Doporučujeme Vám opakovať tento krok z času na čas pri napredovaní Vašej wiki a tak pomôcť vývojárom DokuWiki. Vaše dáta budú označené anonymným ID.
+
+Zozbierané dáta obsahujú informácie ako verziu DokuWiki, počet a veľkosť Vašich stránok a súborov, inštalované pluginy a informácie o inštalovanom PHP.
+
+Dáta, ktoré budú poslané sú zobrazené nižšie. Prosím použite tlačidlo "Poslať dáta" na odoslanie týchto informácií. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sk/lang.php b/lib/plugins/popularity/lang/sk/lang.php
new file mode 100644
index 000000000..bc46b03c5
--- /dev/null
+++ b/lib/plugins/popularity/lang/sk/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Slovak language file
+ *
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['name'] = 'Prieskum používania (môže chvíľu trvať)';
+$lang['submit'] = 'Poslať dáta';
+$lang['autosubmit'] = 'Automaticky zaslať dáta raz mesačne';
+$lang['submissionFailed'] = 'Dáta nemohli byť odoslané z nasledujúceho dôdovu:';
+$lang['submitDirectly'] = 'Dáta môžu byť zaslané manuálne nasledujúcim formulárom:';
+$lang['autosubmitError'] = 'Posledné automatické odoslanie dát zlyhalo z nasledujúceho dôvodu:';
+$lang['lastSent'] = 'Dáta boli odoslané.';
diff --git a/lib/plugins/popularity/lang/sk/submitted.txt b/lib/plugins/popularity/lang/sk/submitted.txt
new file mode 100644
index 000000000..f99fb9fa9
--- /dev/null
+++ b/lib/plugins/popularity/lang/sk/submitted.txt
@@ -0,0 +1,3 @@
+====== Prieskum používania ======
+
+Dáta boli úspešne odoslané. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sl/intro.txt b/lib/plugins/popularity/lang/sl/intro.txt
new file mode 100644
index 000000000..2c029db63
--- /dev/null
+++ b/lib/plugins/popularity/lang/sl/intro.txt
@@ -0,0 +1,9 @@
+====== Poročilo o uporabi ======
+
+To orodje je namenjeno zbiranju brezimnih podatkov o postavljeni DokuWiki strani in omogoča pošiljanje nekaterih podatkov neposredno razvijalcem sistema. S temi podatki lahko razvijalci razumejo načine uporabe sistema, zahteve uporabnikov in pogostost uporabe, kar s statističnimi podatki vpliva tudi na nadaljnji razvoj sistema.
+
+Priporočeno je, da poročilo o uporabi pošljete vsake toliko časa, saj lahko le tako razvijalci dobijo podatke o hitrosti rasti spletišča in pogostosti uporabe. Vsi podatki so poslani označeni s posebno vpisno številko, ki omogoča brezimno sledenje.
+
+Zbrani podatki vsebujejo podrobnosti o različici uporabljenega sistema DokuWiki, število in velikost wiki strani, datotekah, ki so naložene na sistem in podatke o vstavkih ter PHP namestitvi in različici.
+
+Surovi podatki, ki bodo poslani so prikazani spodaj. S pritiskom na gumb "Pošlji podatke", bodo ti poslani na strežnik razvijalcev.
diff --git a/lib/plugins/popularity/lang/sl/lang.php b/lib/plugins/popularity/lang/sl/lang.php
new file mode 100644
index 000000000..5c92dd7c4
--- /dev/null
+++ b/lib/plugins/popularity/lang/sl/lang.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['name'] = 'Poročilo o uporabi (nalaganje strani je lahko dolgotrajno)';
+$lang['submit'] = 'Pošlji podatke';
+$lang['autosubmit'] = 'Samodejno pošlji podatke enkrat mesečno';
+$lang['submissionFailed'] = 'Podatkov zaradi napake ni mogoče poslati:';
+$lang['submitDirectly'] = 'Podatke je mogoče poslati ročno s pošiljanjem preko obrazca.';
+$lang['autosubmitError'] = 'Zadnji poskus samodejnega pošiljanja je spodletel zaradi napake:';
+$lang['lastSent'] = 'Podatki so bili uspešno poslani.';
diff --git a/lib/plugins/popularity/lang/sl/submitted.txt b/lib/plugins/popularity/lang/sl/submitted.txt
new file mode 100644
index 000000000..11ae052f7
--- /dev/null
+++ b/lib/plugins/popularity/lang/sl/submitted.txt
@@ -0,0 +1,3 @@
+====== Poročilo o uporabi ======
+
+Podatki so bili uspešno poslani.
diff --git a/lib/plugins/popularity/lang/sq/intro.txt b/lib/plugins/popularity/lang/sq/intro.txt
new file mode 100644
index 000000000..eb37e5f36
--- /dev/null
+++ b/lib/plugins/popularity/lang/sq/intro.txt
@@ -0,0 +1,9 @@
+====== Informacioni mbi Popullaritetin ======
+
+Ky mjet mbledh të dhëna anonime rreth wiki-t tuaj dhe ju lejon t'ia dërgoni ato zhvilluesve të DokuWiki-t. Kjo i ndihmon ata të kuptojnë sesi DokuWiki përdoret nga përdoruesit e tij dhe siguron që vendimet për zhvillime të ardhshme të jenë të mbështetura mbi statistika të nxjera nga bota e vërtetë.
+
+Ju jeni të inkurajuar ta përsërisni këtë hap shpesh herë për t'i mbajtur zhvilluesit të informuar kur wiki juaj rritet. Bashkësia e të dhënave tuaja të përsëritura do të identifikohen nga një ID anonime.
+
+Të dhënat e mbledhura përmbajnë informacione si versioni i DokuWiki-t tuaj, numri dhe madhësia e faqeve dhe skedarëve, plugin-et e instaluar dhe informacione rreth instalimit të PHP-së.
+
+Të dhënat e papërpunuara që do të dërgohen janë treguar më poshtë. Ju lutem përdorni buttonin "Dërgo Të Dhëna" për të transferuar informacionin. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sq/lang.php b/lib/plugins/popularity/lang/sq/lang.php
new file mode 100644
index 000000000..1954ce04c
--- /dev/null
+++ b/lib/plugins/popularity/lang/sq/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['name'] = 'Informacioni mbi Popullaritetin (mund të marë ca kohë derisa të ngarkohet)';
+$lang['submit'] = 'Dërgo Të Dhënat';
diff --git a/lib/plugins/popularity/lang/sr/intro.txt b/lib/plugins/popularity/lang/sr/intro.txt
new file mode 100644
index 000000000..cbbb46adf
--- /dev/null
+++ b/lib/plugins/popularity/lang/sr/intro.txt
@@ -0,0 +1,9 @@
+====== Мерење популарности ======
+
+Ова алатка анонимно скупља податке о вашем викију и шаље их програмерима DokuWiki-ја. Овим помажете да разумеју како корисници користе DokuWiki и обезбеђујете да се одлуке имају потпору у статистици о коришћењу у реалним условима.
+
+Охрабрујемо вас да поновите овај корак с времена на време да би програмери имали информацију о развоју вашег викија. Ваши поновљени подаци ће бити идентификовани са анонимним ЛИБом.
+
+Сакупљени подаци садрже информације: верзија вашег DokuWiki-ја, број и величина страница и датотека, инсталирани додаци и информације о ПХПу.
+
+Сирова верзија података који се шаљу се налази испод. Користите дугме Пошаљи податке за пренос информација. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/sr/lang.php b/lib/plugins/popularity/lang/sr/lang.php
new file mode 100644
index 000000000..f560b52a8
--- /dev/null
+++ b/lib/plugins/popularity/lang/sr/lang.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['name'] = 'Мерење популарности (може потрајати док се не учита)';
+$lang['submit'] = 'Пошаљи податке';
diff --git a/lib/plugins/popularity/lang/sv/intro.txt b/lib/plugins/popularity/lang/sv/intro.txt
new file mode 100644
index 000000000..2f00c01d7
--- /dev/null
+++ b/lib/plugins/popularity/lang/sv/intro.txt
@@ -0,0 +1,11 @@
+====== Popularitetsfeedback ======
+
+Detta verktyg samlar anonyma data om din wiki och låter dig skicka dessa till DokuWikis utvecklare. Det hjälper utvecklarna att förstå hur DokuWiki används och gör att framtida beslut om DokuWikis utveckling kan grundas på statistik från verkligt bruk.
+
+Upprepa gärna detta steg då och då allteftersom din Wiki växer. Dina rapporter kommer att bli identifierade med hjälp av ett anonymt id.
+
+Data som samlas in innehåller information om bland annat din DokuWiki-version, antalet och storleken på sidorna, installerade plugins samt information om din PHP-installation.
+
+Rådata som kommer att sändas visas här nedanför. Vänligen använd knappen "Sänd data" för att överföra informationen.
+
+
diff --git a/lib/plugins/popularity/lang/sv/lang.php b/lib/plugins/popularity/lang/sv/lang.php
new file mode 100644
index 000000000..8be542e7f
--- /dev/null
+++ b/lib/plugins/popularity/lang/sv/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Swedish language file
+ *
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['name'] = 'Popularitets-feedback (det kan ta en stund att ladda sidan)';
+$lang['submit'] = 'Sänd data';
+$lang['autosubmit'] = 'Skicka data automatiskt varje månad';
+$lang['submissionFailed'] = 'Datan kunde inte skickas för att:';
+$lang['submitDirectly'] = 'Du kan skicka datan manuellt genom att fylla i följande formulär.';
+$lang['autosubmitError'] = 'Senaste automatiska sändning av datan misslyckades för att:';
+$lang['lastSent'] = 'Datan har skickats';
diff --git a/lib/plugins/popularity/lang/sv/submitted.txt b/lib/plugins/popularity/lang/sv/submitted.txt
new file mode 100644
index 000000000..fb8eab773
--- /dev/null
+++ b/lib/plugins/popularity/lang/sv/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularitetsfeedback ======
+
+Datan har skickats utan problem. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/th/lang.php b/lib/plugins/popularity/lang/th/lang.php
new file mode 100644
index 000000000..3ae8a7890
--- /dev/null
+++ b/lib/plugins/popularity/lang/th/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['name'] = 'ส่งข้อมูลความนิยมกลับ (อาจใช้เวลาในการโหลด)';
+$lang['submit'] = 'ส่งข้อมูล';
diff --git a/lib/plugins/popularity/lang/tr/intro.txt b/lib/plugins/popularity/lang/tr/intro.txt
new file mode 100644
index 000000000..a855ff327
--- /dev/null
+++ b/lib/plugins/popularity/lang/tr/intro.txt
@@ -0,0 +1,9 @@
+====== Popülerlik Geribeslemesi ======
+
+Bu araç wiki'niz hakkında genel bilgileri toplayarak bunları DokuWiki geliştiricilerine geri göndermenizi sağlar. Böylece geliştiriciler DokuWiki'nin kullanıcılar tarafından nasıl kullanıldığını anlamalarını sağlar ve ileride gerçek kullanım istatistiklerine göre geliştirme kararları verebilirler.
+
+Wiki'nizin büyümesiyle beraber bu bölümü zaman zaman çalıştırmanız geliştiricileri bilgilendirecektir. Tekrar gönderilen veriler anonim olarak gönderilecektir.
+
+Bu veriler DokuWiki sürümünü, sayısını, sayfaların ve dosyalarım büyüklüklerini, yüklü eklentileri ve PHP sürümünü içermektedir.
+
+Gönderilecek işlenmemiş veriler aşağıda gösterilmektedir. Lütfen "Verileri Gönder" butonuna tıklayarak bilgileri gönderin. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/tr/lang.php b/lib/plugins/popularity/lang/tr/lang.php
new file mode 100644
index 000000000..fe87d1548
--- /dev/null
+++ b/lib/plugins/popularity/lang/tr/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['name'] = 'Popülerlik Geribeslemesi (yüklemesi uzun sürebilir)';
+$lang['submit'] = 'Verileri Gönder';
diff --git a/lib/plugins/popularity/lang/uk/intro.txt b/lib/plugins/popularity/lang/uk/intro.txt
new file mode 100644
index 000000000..3ceb8826e
--- /dev/null
+++ b/lib/plugins/popularity/lang/uk/intro.txt
@@ -0,0 +1,9 @@
+====== Відгук популярності ======
+
+Цей інструмент збирає анонімні дані про вашу вікі і відсилає її розробникам системи. Це допоможе їм зрозуміти, як саме користувачі використовують ДокуВікі і дозволяє врахувати потреби користувачів при подальшому удосконаленні системи.
+
+Ви можете повторно відсилати відгуки час від часу, щоб повідомляти розробників про розвиток вашої ДокуВікі. Повторні відгуки будуть ідентифіковані по анонімному ID.
+
+У зібраних даних є інформація про версію ДокуВікі, кількість і розмір сторінок в ній, встановлені додатки і інформація про налаштування вашого PHP.
+
+Дані, які буде надіслано показано нижче. Для передачі інформації натисніть будь-ласка кнопку "Передати дані" \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/uk/lang.php b/lib/plugins/popularity/lang/uk/lang.php
new file mode 100644
index 000000000..584641482
--- /dev/null
+++ b/lib/plugins/popularity/lang/uk/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Ukrainian language file
+ *
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ * @author Kate Arzamastseva pshns@ukr.net
+ */
+$lang['name'] = 'Відгук популярності (може зайняти деякий час)';
+$lang['submit'] = 'Передати дані';
+$lang['autosubmit'] = 'Автоматично надсилати дані один раз на місяць';
+$lang['submissionFailed'] = 'Дані не можуть бути відправлені через таку помилку:';
+$lang['submitDirectly'] = 'Ви можете надіслати дані вручну, відправивши наступну форму.';
+$lang['autosubmitError'] = 'Останнє автоматичне відправлення не вдалося через таку помилку:';
+$lang['lastSent'] = 'Дані були відправлені';
diff --git a/lib/plugins/popularity/lang/uk/submitted.txt b/lib/plugins/popularity/lang/uk/submitted.txt
new file mode 100644
index 000000000..90213858d
--- /dev/null
+++ b/lib/plugins/popularity/lang/uk/submitted.txt
@@ -0,0 +1,2 @@
+====== Відгук популярності ======
+Дані були успішно відправлені. \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/zh-tw/intro.txt b/lib/plugins/popularity/lang/zh-tw/intro.txt
new file mode 100644
index 000000000..37c63dced
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh-tw/intro.txt
@@ -0,0 +1,10 @@
+====== 人氣回饋 ======
+
+本工具會從您的維基站台收集訊息,並以匿名的方式發送給 DokuWiki 的開發者。這有助於他們了解使用者們如何使用 DokuWiki ,並能基於實際統計資料對未來開發做出更準確的決策。
+
+我們鼓勵您經常重複這個步驟,讓開發者了解您的維基站台的成長情形。您的資料集將會被標識為一個匿名的識別碼 (ID)。
+
+收集的資料包括 DokuWiki 版本、頁面數量、檔案大小、安裝的插件、伺服器的 PHP 資訊。
+
+將被發送的原始資料顯示如下。請點擊「發送資料」按鈕進行傳輸。
+
diff --git a/lib/plugins/popularity/lang/zh-tw/lang.php b/lib/plugins/popularity/lang/zh-tw/lang.php
new file mode 100644
index 000000000..3ced0ee5a
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh-tw/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Chinese Traditional language file
+ *
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['name'] = '人氣回饋(載入可能需要一些時間)';
+$lang['submit'] = '發送資料';
+$lang['autosubmit'] = '每月自動發送';
+$lang['submissionFailed'] = '由於以下原因,資料無法發送:';
+$lang['submitDirectly'] = '你可以利用以下的表單來發手動發送資料.';
+$lang['autosubmitError'] = '由於以下原因,上次自動發送失敗:';
+$lang['lastSent'] = '資料已發送';
diff --git a/lib/plugins/popularity/lang/zh-tw/submitted.txt b/lib/plugins/popularity/lang/zh-tw/submitted.txt
new file mode 100644
index 000000000..6febcd5b8
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh-tw/submitted.txt
@@ -0,0 +1,3 @@
+====== 人氣回饋 ======
+
+資料已發送成功 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/zh/intro.txt b/lib/plugins/popularity/lang/zh/intro.txt
new file mode 100644
index 000000000..40e93dcb0
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh/intro.txt
@@ -0,0 +1,9 @@
+====== 人气反馈 ======
+
+本工具收集关于您维基站点的匿名信息,并允许您将其发送给 DokuWiki 的开发者。这样做有助于我们了解用户是如何使用 DokuWiki 的,并能使我们未来的开发决策建立在现实使用数据上。
+
+我们鼓励您不时重复该步骤,以便我们能了解您的维基站点发展进度。您的数据集将被匿名 ID 标识。
+
+收集的数据包括 DokuWiki 版本、您的页面数量以及文件大小、已安装的插件、服务器上的 PHP 相关信息。
+
+将被发送的原始数据如下所示。请点击“发送数据”按扭进行传输。 \ No newline at end of file
diff --git a/lib/plugins/popularity/lang/zh/lang.php b/lib/plugins/popularity/lang/zh/lang.php
new file mode 100644
index 000000000..9c916c2a5
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh/lang.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Chinese language file
+ *
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['name'] = '人气反馈(载入可能需要一些时间)';
+$lang['submit'] = '发送数据';
+$lang['autosubmit'] = '每月自动发送';
+$lang['submissionFailed'] = '数据由于以下原因不恩你给发送:';
+$lang['submitDirectly'] = '你可以手动提交下面的表单来发送数据。';
+$lang['autosubmitError'] = '印以下原因,上一次自动提交失败:';
+$lang['lastSent'] = '数据已发送';
diff --git a/lib/plugins/popularity/lang/zh/submitted.txt b/lib/plugins/popularity/lang/zh/submitted.txt
new file mode 100644
index 000000000..6039b70e1
--- /dev/null
+++ b/lib/plugins/popularity/lang/zh/submitted.txt
@@ -0,0 +1,3 @@
+====== 人气反馈 ======
+
+数据发送成功。 \ No newline at end of file
diff --git a/lib/plugins/popularity/plugin.info.txt b/lib/plugins/popularity/plugin.info.txt
new file mode 100644
index 000000000..16b148f41
--- /dev/null
+++ b/lib/plugins/popularity/plugin.info.txt
@@ -0,0 +1,7 @@
+base popularity
+author Andreas Gohr
+email andi@splitbrain.org
+date 2011-08-18
+name Popularity Feedback Plugin
+desc Send anonymous data about your wiki to the developers.
+url http://www.dokuwiki.org/plugin:popularity
diff --git a/lib/plugins/revert/admin.php b/lib/plugins/revert/admin.php
new file mode 100644
index 000000000..2aaf1395f
--- /dev/null
+++ b/lib/plugins/revert/admin.php
@@ -0,0 +1,185 @@
+<?php
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_revert extends DokuWiki_Admin_Plugin {
+ var $cmd;
+ // some vars which might need tuning later
+ var $max_lines = 800; // lines to read from changelog
+ var $max_revs = 20; // numer of old revisions to check
+
+
+ /**
+ * Constructor
+ */
+ function admin_plugin_revert(){
+ $this->setupLocale();
+ }
+
+ /**
+ * access for managers
+ */
+ function forAdminOnly(){
+ return false;
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ function getMenuSort() {
+ return 40;
+ }
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ }
+
+ /**
+ * output appropriate html
+ */
+ function html() {
+
+ echo $this->plugin_locale_xhtml('intro');
+
+ $this->_searchform();
+
+ if(is_array($_REQUEST['revert']) && checkSecurityToken()){
+ $this->_revert($_REQUEST['revert'],$_REQUEST['filter']);
+ }elseif(isset($_REQUEST['filter'])){
+ $this->_list($_REQUEST['filter']);
+ }
+ }
+
+ /**
+ * Display the form for searching spam pages
+ */
+ function _searchform(){
+ global $lang;
+ echo '<form action="" method="post"><div class="no">';
+ echo '<label>'.$this->getLang('filter').': </label>';
+ echo '<input type="text" name="filter" class="edit" value="'.hsc($_REQUEST['filter']).'" />';
+ echo '<input type="submit" class="button" value="'.$lang['btn_search'].'" />';
+ echo ' <span>'.$this->getLang('note1').'</span>';
+ echo '</div></form><br /><br />';
+ }
+
+ /**
+ * Start the reversion process
+ */
+ function _revert($revert,$filter){
+ global $conf;
+
+ echo '<hr /><br />';
+ echo '<p>'.$this->getLang('revstart').'</p>';
+
+ echo '<ul>';
+ foreach($revert as $id){
+ global $REV;
+
+ // find the last non-spammy revision
+ $data = '';
+ $old = getRevisions($id, 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
+ */
+ function _list($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 = strftime($conf['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 ' &ndash; '.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 '<input type="submit" class="button" value="'.$this->getLang('revert').'" /> ';
+ printf($this->getLang('note2'),hsc($filter));
+ echo '</p>';
+
+ echo '</div></form>';
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/revert/lang/af/lang.php b/lib/plugins/revert/lang/af/lang.php
new file mode 100644
index 000000000..1fff08db3
--- /dev/null
+++ b/lib/plugins/revert/lang/af/lang.php
@@ -0,0 +1,5 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
diff --git a/lib/plugins/revert/lang/ar/intro.txt b/lib/plugins/revert/lang/ar/intro.txt
new file mode 100644
index 000000000..5839ee0c8
--- /dev/null
+++ b/lib/plugins/revert/lang/ar/intro.txt
@@ -0,0 +1,3 @@
+====== مدير الاسترجاع ======
+
+تساعدك هذه الصفحة في الاستعادة الآلية لهجوم غثاء. للحصول على قائمة بالصفحات المغثاة أولا أدخل نص البحث (مثل. عنوان غثاء), ثم أكد أن الصفحات الموجودة هي غثاء فعلا و استرجع التعديلات. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/ar/lang.php b/lib/plugins/revert/lang/ar/lang.php
new file mode 100644
index 000000000..a073c336d
--- /dev/null
+++ b/lib/plugins/revert/lang/ar/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['menu'] = 'مدير الاسترجاع';
+$lang['filter'] = 'ابحث في الصفحات المتأذاة';
+$lang['revert'] = 'استرجع الصفحات المحددة';
+$lang['reverted'] = '%s استرجعت للاصدار %s';
+$lang['removed'] = 'حُذفت %s ';
+$lang['revstart'] = 'بدأت عملية الاستعادة. قد يستغرق ذلك وقتا طويلا. إذا كان وقت النص البرمجي ينفذ قبل النهاية، عليك استرجاع أجزاء أصغر.
+';
+$lang['revstop'] = 'عملية الاستعادة انتهت بنجاح.';
+$lang['note1'] = 'لاحظ: البحث حساس لحالة الأحرف';
+$lang['note2'] = 'لاحظ: ستسترجع الصفحة إلى آخر اصدار لا يحوي شروط الغثاء <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/bg/intro.txt b/lib/plugins/revert/lang/bg/intro.txt
new file mode 100644
index 000000000..44d5a0938
--- /dev/null
+++ b/lib/plugins/revert/lang/bg/intro.txt
@@ -0,0 +1,4 @@
+====== Възстановяване ======
+
+Страницата помага за автоматично възстановяване след SPAM атака. За да намерите спамнатите страници, въведете текст за търсене (напр. линк от SPAM съобщението), след това потвърдете, че намерените страници са наистина SPAM и възстановете старите им версии.
+
diff --git a/lib/plugins/revert/lang/bg/lang.php b/lib/plugins/revert/lang/bg/lang.php
new file mode 100644
index 000000000..0819de01a
--- /dev/null
+++ b/lib/plugins/revert/lang/bg/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * bulgarian language file
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['menu'] = 'Възстановяване';
+$lang['filter'] = 'Търсене на спамнати страници';
+$lang['revert'] = 'Възстанови избраните страници';
+$lang['reverted'] = '%s върната до версия %s';
+$lang['removed'] = '%s премахната';
+$lang['revstart'] = 'Процесът на възстановяване започна. Това може да отнеме много време. Ако скриптът се просрочи преди да завърши, трябва да възстановявате на по-малки парчета.';
+$lang['revstop'] = 'Процесът на възстановяване завърши успешно.';
+$lang['note1'] = 'Бележка: при търсенето се различават малки от големи букви';
+$lang['note2'] = 'Бележка: страницата ще бъде върната към стара версия без SPAM терминa <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ca-valencia/intro.txt b/lib/plugins/revert/lang/ca-valencia/intro.txt
new file mode 100644
index 000000000..fed2cb9cc
--- /dev/null
+++ b/lib/plugins/revert/lang/ca-valencia/intro.txt
@@ -0,0 +1,4 @@
+====== Gestor de reversions ======
+
+Esta pàgina ajuda en la reversió automàtica d'atacs de spam. Per a
+trobar una llista de pàgines que tinguen spam introduïxca una cadena de busca (p. e. una URL de spam), confirme que les pàgines trobades tenen realment spam i revertixca les edicions.
diff --git a/lib/plugins/revert/lang/ca-valencia/lang.php b/lib/plugins/revert/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..77dd5808e
--- /dev/null
+++ b/lib/plugins/revert/lang/ca-valencia/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * valencian language file
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['menu'] = 'Gestor de reversions';
+$lang['filter'] = 'Buscar pàgines en spam';
+$lang['revert'] = 'Revertir pàgines seleccionades';
+$lang['reverted'] = '%s revertides a la versió %s';
+$lang['removed'] = '%s llevades';
+$lang['revstart'] = 'El procés de reversió ha començat. Açò pot dur prou de temps. Si es talla abans d\'acabar, haurà de revertir per parts.';
+$lang['revstop'] = 'El procés de reversió ha finalisat correctament.';
+$lang['note1'] = 'Nota: esta busca és sensible a mayúscules';
+$lang['note2'] = 'Nota: esta pàgina es revertirà a l\'última versió que no continga el spam definit pel terme <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ca/intro.txt b/lib/plugins/revert/lang/ca/intro.txt
new file mode 100644
index 000000000..0af2e8e6d
--- /dev/null
+++ b/lib/plugins/revert/lang/ca/intro.txt
@@ -0,0 +1,3 @@
+====== Gestió de reversions ======
+
+Aquesta pàgina us ajuda a revertir automàticament els canvis que siguin producte d'un atac amb brossa. Per trobar la llista de pàgines atacades, cerqueu una cadena adequada (p. ex. un URL de propaganda), confirmeu que les pàgines trobades contenen realment brossa i llavors revertiu-les a revisions anteriors. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/ca/lang.php b/lib/plugins/revert/lang/ca/lang.php
new file mode 100644
index 000000000..b8800911f
--- /dev/null
+++ b/lib/plugins/revert/lang/ca/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ */
+$lang['menu'] = 'Gestió de reversions';
+$lang['filter'] = 'Cerca pàgines brossa';
+$lang['revert'] = 'Reverteix les pàgines seleccionades';
+$lang['reverted'] = 'S\'ha revertit %s a la revisió %s';
+$lang['removed'] = 'S\'ha suprimit %s';
+$lang['revstart'] = 'S\'ha iniciat el procés de reversió. Això pot trigar una bona estona. Si s\'excedeix el temps d\'espera màxim del servidor, haureu de tornar a intentar-ho per parts.';
+$lang['revstop'] = 'El procés de reversió ha acabat amb èxit.';
+$lang['note1'] = 'Nota: aquesta cerca distingeix entre majúscules i minúscules.';
+$lang['note2'] = 'Nota: la pàgina es revertirà a la darrera versió que no contingui el terme brossa especificat <em>%s</em>.';
diff --git a/lib/plugins/revert/lang/cs/intro.txt b/lib/plugins/revert/lang/cs/intro.txt
new file mode 100644
index 000000000..1e1cd0fd8
--- /dev/null
+++ b/lib/plugins/revert/lang/cs/intro.txt
@@ -0,0 +1,3 @@
+====== Obnova zaspamovaných stránek ======
+
+Tato stránka pomůže při automatické obnově po spamovém útoku. Pro nalezení seznamu zaspamovaných stránek nejdříve zadejte hledaný výraz (např. spamové URL) a pak potvrďte, že nalezené stránky opravdu obsahují spam a mohou být obnoveny.
diff --git a/lib/plugins/revert/lang/cs/lang.php b/lib/plugins/revert/lang/cs/lang.php
new file mode 100644
index 000000000..cf19381c8
--- /dev/null
+++ b/lib/plugins/revert/lang/cs/lang.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['menu'] = 'Obnova zaspamovaných stránek';
+$lang['filter'] = 'Hledat zaspamované stránky';
+$lang['revert'] = 'Obnovit vybrané stránky';
+$lang['reverted'] = '%s vrácena do verze %s';
+$lang['removed'] = '%s odstraněna';
+$lang['revstart'] = 'Obnova stránek začala. Tento proces může trvat dlouho. Pokud
+skriptu vyprší čas, budete muset obnovovat po menších blocích
+stránek.';
+$lang['revstop'] = 'Proces obnovy stránek byl úspěšně dokončen.';
+$lang['note1'] = 'Poznámka: toto vyhledávání je citlivé na velikost písmen';
+$lang['note2'] = 'Poznámka: tato stránka bude obnovena na poslední verzi, která
+neobsahovala dané spamové slovo <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/da/intro.txt b/lib/plugins/revert/lang/da/intro.txt
new file mode 100644
index 000000000..fdb0c5f32
--- /dev/null
+++ b/lib/plugins/revert/lang/da/intro.txt
@@ -0,0 +1,3 @@
+===== Gendannelsesstyring =====
+
+Denne side hjælper dig med at gendanne sider efter et angreb af uønskede indlæg. For at finde en liste af sider, der muligvis er blevet ændret, så skriv en søgestreng (for eksempel. en uønsket netadresse) og bekræft, at de fundne sider virkeligt er uønskede og gendan ændringerne. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/da/lang.php b/lib/plugins/revert/lang/da/lang.php
new file mode 100644
index 000000000..c94366638
--- /dev/null
+++ b/lib/plugins/revert/lang/da/lang.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['menu'] = 'Gendannelsesstyring';
+$lang['filter'] = 'Søg efter uønskede sider';
+$lang['revert'] = 'Gendan valgte sider';
+$lang['reverted'] = '%s gendannet til ændring %s';
+$lang['removed'] = '%s fjernet';
+$lang['revstart'] = 'Gendannelsesforløbet er startet. Dette kan tage et stykke tid. Hvis kodefilen giver "time out" før processen færdiggøres, skal du gendanne i mindre dele.';
+$lang['revstop'] = 'Gendannelsesforløbet fuldført uden fejl';
+$lang['note1'] = 'Bemærk: Der er forskel på store og små bogstaver i søgningen';
+$lang['note2'] = 'Bemærk: Denne side vil blive gendannet til den seneste udgave, der ikke indeholder det givne uønskede udtryk <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/de-informal/intro.txt b/lib/plugins/revert/lang/de-informal/intro.txt
new file mode 100644
index 000000000..d5a092155
--- /dev/null
+++ b/lib/plugins/revert/lang/de-informal/intro.txt
@@ -0,0 +1,3 @@
+====== Seiten wieder herstellen ======
+
+Dieses Plugin dient der automatischen Wiederherstellung von Seiten nach einem Spam-Angriff. Geben Sie zunächst einen Suchbegriff (z.B. eine Spam URL) ein um eine Liste betroffener Seiten zu erhalten. Nachdem Sie sich vergewissert haben, dass die gefundenen Seiten wirklich Spam enthalten, können Sie die Seiten wieder herstellen.
diff --git a/lib/plugins/revert/lang/de-informal/lang.php b/lib/plugins/revert/lang/de-informal/lang.php
new file mode 100644
index 000000000..c199bb55b
--- /dev/null
+++ b/lib/plugins/revert/lang/de-informal/lang.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Zurückstellungsmanager';
+$lang['filter'] = 'Durchsuche als Spam markierte Seiten';
+$lang['revert'] = 'Setze ausgewählte Seiten zurück.';
+$lang['reverted'] = '%s zu Revision %s zurückgesetzt';
+$lang['removed'] = '%s entfernt';
+$lang['revstart'] = 'Zurückstellungsprozess gestartet. Dies kann eine längere Zeit dauern. Wenn das Skript vor Fertigstellung stoppt, solltest du es in kleineren Stücken versuchen.';
+$lang['revstop'] = 'Zurückstellungsprozess erfolgreich beendet.';
+$lang['note1'] = 'Beachte: Diese Suche berücksichtigt Gross- und Kleinschreibung';
+$lang['note2'] = 'Beachte: Diese Seite wid zurückgestellt auf die letzte Version, die nicht den Spam-Ausdruck <i>%s</i> enthält.';
diff --git a/lib/plugins/revert/lang/de/intro.txt b/lib/plugins/revert/lang/de/intro.txt
new file mode 100644
index 000000000..d5a092155
--- /dev/null
+++ b/lib/plugins/revert/lang/de/intro.txt
@@ -0,0 +1,3 @@
+====== Seiten wieder herstellen ======
+
+Dieses Plugin dient der automatischen Wiederherstellung von Seiten nach einem Spam-Angriff. Geben Sie zunächst einen Suchbegriff (z.B. eine Spam URL) ein um eine Liste betroffener Seiten zu erhalten. Nachdem Sie sich vergewissert haben, dass die gefundenen Seiten wirklich Spam enthalten, können Sie die Seiten wieder herstellen.
diff --git a/lib/plugins/revert/lang/de/lang.php b/lib/plugins/revert/lang/de/lang.php
new file mode 100644
index 000000000..b430ce876
--- /dev/null
+++ b/lib/plugins/revert/lang/de/lang.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Germanlanguage file
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Seiten wieder herstellen';
+$lang['filter'] = 'Nach betroffenen Seiten suchen';
+$lang['revert'] = 'Ausgewählte Seiten wieder herstellen';
+$lang['reverted'] = '%s wieder hergestellt zu Version %s';
+$lang['removed'] = '%s entfernt';
+$lang['revstart'] = 'Wiederherstellung gestartet. Dies kann einige Zeit dauern. Wenn das Script abbricht, bevor alle Seiten wieder hergestellt wurden, reduzieren Sie die Anzahl der Seiten und wiederholen Sie den Vorgang.';
+$lang['revstop'] = 'Wiederherstellung erfolgreich abgeschlossen.';
+$lang['note1'] = 'Anmerkung: diese Suche unterscheidet Groß- und Kleinschreibung';
+$lang['note2'] = 'Anmerkung: die Seite wird zur letzten Version, die nicht den angegebenen Spam Begriff <i>%s</i> enthält, wieder hergestellt.';
diff --git a/lib/plugins/revert/lang/el/intro.txt b/lib/plugins/revert/lang/el/intro.txt
new file mode 100644
index 000000000..9b583bc6b
--- /dev/null
+++ b/lib/plugins/revert/lang/el/intro.txt
@@ -0,0 +1,3 @@
+====== Αποκατάσταση κακόβουλων αλλαγών σελίδων ======
+
+Αυτή η σελίδα σας βοηθά να αποκαταστήσετε αυτόματα τις κακόβουλες αλλαγές σελίδων που προκαλούν οι επιθέσεις spam. Για να βρείτε τις σελίδες που πρέπει να τροποποιηθούν, πρώτα δώστε έναν όρο αναζήτησης (π.χ. έναν σύνδεσμο spam) και έπειτα επιβεβαιώστε ότι οι σελίδες που θα βρεθούν όντως περιέχουν spam και προχωρήστε στην αποκατάστασή τους.
diff --git a/lib/plugins/revert/lang/el/lang.php b/lib/plugins/revert/lang/el/lang.php
new file mode 100644
index 000000000..63454e4e9
--- /dev/null
+++ b/lib/plugins/revert/lang/el/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['menu'] = 'Αποκατάσταση κακόβουλων αλλαγών σελίδων';
+$lang['filter'] = 'Αναζήτηση σελίδων που περιέχουν spam';
+$lang['revert'] = 'Επαναφορά παλαιότερων εκδόσεων των επιλεγμένων σελίδων';
+$lang['reverted'] = 'Η σελίδα %s επεναφέρθηκε στην έκδοση %s';
+$lang['removed'] = 'Η σελίδα %s διαγράφηκε';
+$lang['revstart'] = 'Η διαδικασία αποκατάστασης άρχισε. Αυτό ίσως πάρει αρκετό χρόνο. Εάν η εφαρμογή υπερβεί το διαθέσιμο χρονικό όριο και τερματιστεί πριν τελειώσει, θα χρειαστεί να επαναλάβετε αυτή τη διαδικασία για μικρότερα τμήματα.';
+$lang['revstop'] = 'Η διαδικασία αποκατάστασης ολοκληρώθηκε με επιτυχία.';
+$lang['note1'] = '<br />Σημείωση: η αναζήτηση επηρεάζεται από το εάν οι χαρακτήρες είναι πεζοί ή κεφαλαίοι';
+$lang['note2'] = '<br />Σημείωση: η σελίδα θα επαναφερθεί στην πλέον πρόσφατη έκδοση που δεν περιέχει τον όρο <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/en/intro.txt b/lib/plugins/revert/lang/en/intro.txt
new file mode 100644
index 000000000..b8f355854
--- /dev/null
+++ b/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/lib/plugins/revert/lang/en/lang.php b/lib/plugins/revert/lang/en/lang.php
new file mode 100644
index 000000000..6bf867ded
--- /dev/null
+++ b/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/lib/plugins/revert/lang/eo/intro.txt b/lib/plugins/revert/lang/eo/intro.txt
new file mode 100644
index 000000000..14e831467
--- /dev/null
+++ b/lib/plugins/revert/lang/eo/intro.txt
@@ -0,0 +1,3 @@
+====== Administro de Restarigo ======
+
+Tiu ĉi paĝo helpas vin pri aŭtomata restarigo el spama atako. Por trovi liston de spamecaj paĝoj, unue mendu serĉan liter-ĉenon (ekz. spama URL), do konfirmu, ke la trovitaj paĝoj fakte estas spamaj kaj restarigu la antaŭajn versiojn bonajn.
diff --git a/lib/plugins/revert/lang/eo/lang.php b/lib/plugins/revert/lang/eo/lang.php
new file mode 100644
index 000000000..a893fb145
--- /dev/null
+++ b/lib/plugins/revert/lang/eo/lang.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas (cxe) gmail (punkto) com>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['menu'] = 'Administrado de restarigo';
+$lang['filter'] = 'Serĉi spamecajn paĝojn';
+$lang['revert'] = 'Restarigi la elektitajn paĝojn';
+$lang['reverted'] = '%s estas restarigita al revizio %s';
+$lang['removed'] = '%s estas forigita';
+$lang['revstart'] = 'Restariga procezo estas ekigita. Tio povas daŭri longan tempon. Se la skripto tro prokrastos antaŭ plenumo, vi bezonos restarigi po pli etaj blokoj.';
+$lang['revstop'] = 'Restariga procezo plenumiĝis sukcese.';
+$lang['note1'] = 'Rimarko: tiu ĉi serĉo distingas usklecon';
+$lang['note2'] = 'Rimarko: la paĝo restariĝos al la lasta versio ne enhavanta la menditan spaman terminon &lt;i&gt;%s&lt;/i&gt;.';
diff --git a/lib/plugins/revert/lang/es/intro.txt b/lib/plugins/revert/lang/es/intro.txt
new file mode 100644
index 000000000..39c5b047d
--- /dev/null
+++ b/lib/plugins/revert/lang/es/intro.txt
@@ -0,0 +1,3 @@
+====== Restaurador ======
+
+Esta página te ayuda con la restauración de ataques spam. Para encontrar una lista de páginas con spam introduce una cadena , luego confirma que las páginas encontradas son realmente un spam y restaura la edición. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/es/lang.php b/lib/plugins/revert/lang/es/lang.php
new file mode 100644
index 000000000..e235015d4
--- /dev/null
+++ b/lib/plugins/revert/lang/es/lang.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Spanish language file
+ *
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['menu'] = 'Restaurador';
+$lang['filter'] = 'Buscar páginas con spam';
+$lang['revert'] = 'Restaurar las páginas seleccionadas';
+$lang['reverted'] = '%s ha restaurado la revisión %s';
+$lang['removed'] = '%s borrado';
+$lang['revstart'] = 'El proceso de restaurado ha comenzado. Puede llevar bastante tiempo. Si el script se para antes de acabar, deberías restaurar cadenas más pequeñas.';
+$lang['revstop'] = 'El proceso de restaurado ha finalizado satisfactoriamente.';
+$lang['note1'] = 'Nota: la búsqueda diferencia entre mayúsculas y minúsculas.';
+$lang['note2'] = 'Nota: la página será restaurada a la última versión que no tenga el término de spam dado <em>%s</em>.';
diff --git a/lib/plugins/revert/lang/et/lang.php b/lib/plugins/revert/lang/et/lang.php
new file mode 100644
index 000000000..ca1410ab0
--- /dev/null
+++ b/lib/plugins/revert/lang/et/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
diff --git a/lib/plugins/revert/lang/eu/intro.txt b/lib/plugins/revert/lang/eu/intro.txt
new file mode 100644
index 000000000..c5a5a5afa
--- /dev/null
+++ b/lib/plugins/revert/lang/eu/intro.txt
@@ -0,0 +1,3 @@
+====== Berrezartze Kudeatzailea ======
+
+Orri honek spam eraso baten berrezartze automatikoarekin laguntzen dizu. Spam-a duten orriak bilatzeko, lehenik sartu bilaketa katea (adb. spam URL bat), eta ondoren baieztatu bilatutako orriak benetan spam-a dutela, gero aldaketak berrezartzeko.
diff --git a/lib/plugins/revert/lang/eu/lang.php b/lib/plugins/revert/lang/eu/lang.php
new file mode 100644
index 000000000..e94f07b2a
--- /dev/null
+++ b/lib/plugins/revert/lang/eu/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['menu'] = 'Berrezartze Kudeatzailea';
+$lang['filter'] = 'Bilatu spam duten orriak';
+$lang['revert'] = 'Berrezarri aukeratutako orriak';
+$lang['reverted'] = '%s berrezarria %s berrikuspenera';
+$lang['removed'] = '%s ezabatua';
+$lang['revstart'] = 'Berrezartze prozesua hasi da. Honek denbora luzea eraman dezake.
+Script-a denbora mugara iristen bada, zati txikiagotan berrezarri
+beharko duzu. ';
+$lang['revstop'] = 'Berrezartze prozesua arrakastaz bukatu da.';
+$lang['note1'] = 'Oharra: bilaketa honek maiuskulak eta minuskulak bereizten ditu';
+$lang['note2'] = 'Oharra: orria azken bertsiora berrezarriko da, emandako <i>%s</i> spam terminorik ez duelarik.';
diff --git a/lib/plugins/revert/lang/fa/intro.txt b/lib/plugins/revert/lang/fa/intro.txt
new file mode 100644
index 000000000..0ccdb089a
--- /dev/null
+++ b/lib/plugins/revert/lang/fa/intro.txt
@@ -0,0 +1,3 @@
+====== مدیریت برگشت‌ها ======
+
+این صفحه، در بازیابی صفحاتی که به آن‌ها اسپم ارسال شده است کمک می‌رساند. برای مشاهده‌ی صفحات اسپم شده، ابتدا جستجو کنید، سپس از اسپم شدن صفحه‌ی مورد نظر اطمینان حاصل کنید و تغییرات اعمال شده را برگردانید. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/fa/lang.php b/lib/plugins/revert/lang/fa/lang.php
new file mode 100644
index 000000000..02d2aabd2
--- /dev/null
+++ b/lib/plugins/revert/lang/fa/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['menu'] = 'مدیریت برگشت‌ها';
+$lang['filter'] = 'جستجوی صفحات اسپم شده';
+$lang['revert'] = 'بازگردانی صفحات انتخاب شده';
+$lang['reverted'] = '%s به نگارش %s بازگردانده شد';
+$lang['removed'] = '%s حذف شد';
+$lang['revstart'] = 'در حال بازگرداندن. ممکن است مدتی زمان ببرد. اگر اجرای برنامه، پیش از اتمام به پایان رسید، باید در بخش‌های کوچک‌تری بازگردانی را انجام دهید.';
+$lang['revstop'] = 'بازگرداندن با موفقیت به پایان رسید.';
+$lang['note1'] = 'توجه: جستجو حساس به حروف کوچک و بزرگ است';
+$lang['note2'] = 'توجه: صفحه به آخرین نسخه‌ای که حاوی اسپم <i>%s</i> نیست بازگردانده خواهد شد.';
diff --git a/lib/plugins/revert/lang/fi/intro.txt b/lib/plugins/revert/lang/fi/intro.txt
new file mode 100644
index 000000000..3b3ce5daa
--- /dev/null
+++ b/lib/plugins/revert/lang/fi/intro.txt
@@ -0,0 +1,3 @@
+====== Palautuksenhallinta ======
+
+Tämä sivu auttaa sinua automaattisen palautuksenhallinnan kanssa spam hyökkäyksen jälkeen. Löytääksesi listan spammatyistä sivuista anna ensin hakusana (esim. spm URL), sen jälkeen varmista, että löytyneet sivut todella ovat spammia ja palauta sitten sivut.
diff --git a/lib/plugins/revert/lang/fi/lang.php b/lib/plugins/revert/lang/fi/lang.php
new file mode 100644
index 000000000..fdf9bb81c
--- /dev/null
+++ b/lib/plugins/revert/lang/fi/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['menu'] = 'Palautuksenhallinta';
+$lang['filter'] = 'Etsi spammattyjä sivuja';
+$lang['revert'] = 'Palauta valitut sivut';
+$lang['reverted'] = '%s palautettu versioon %s';
+$lang['removed'] = '%s poistettu';
+$lang['revstart'] = 'Palautusprosessi käynnistetty. Tämä voi viedä pidemmän aikaa. Jos ajo katkeaa aikakatkaisuun ennen loppua, niin sinun pitää palauttaa pienemmissä osissa.';
+$lang['revstop'] = 'Palautusprosessi lopetti onnistuneesti.';
+$lang['note1'] = 'Huomioi: tämä haku on kirjainkoosta riippuva';
+$lang['note2'] = 'Huomioi: tämä sivu palautetaan viimeiseen versioon, jossa ei ole annettua spamtermiä <i>%s</i>';
diff --git a/lib/plugins/revert/lang/fr/intro.txt b/lib/plugins/revert/lang/fr/intro.txt
new file mode 100644
index 000000000..6dcbe74b9
--- /dev/null
+++ b/lib/plugins/revert/lang/fr/intro.txt
@@ -0,0 +1,3 @@
+====== Gestionnaire de réversions ======
+
+Cette page peut vous aider à restaurer des pages après une attaque de spam. Pour trouver la liste des pages vandalisées, entrez un motif de recherche (p. ex. une URL de spam), puis confirmez que les pages trouvées contiennent du spam et annulez leurs éditions.
diff --git a/lib/plugins/revert/lang/fr/lang.php b/lib/plugins/revert/lang/fr/lang.php
new file mode 100644
index 000000000..9c5194b31
--- /dev/null
+++ b/lib/plugins/revert/lang/fr/lang.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * french language file
+ * @author Delassaux Julien <julien@delassaux.fr>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author Guy Brand <gb@unistra.fr>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['menu'] = 'Gestionnaire de réversions';
+$lang['filter'] = 'Trouver les pages spammées ';
+$lang['revert'] = 'Annuler les modifications sélectionnées';
+$lang['reverted'] = '%s restauré à la révision %s';
+$lang['removed'] = '%s supprimé';
+$lang['revstart'] = 'Processus de réversion démarré. Ceci peut prendre longtemps. Si le script dépasse le délai avant de terminer, vous devrez restaurer de plus petits groupes de pages.';
+$lang['revstop'] = 'Processus de réversion terminé avec succès.';
+$lang['note1'] = 'Note : cette recherche est insensible à la casse';
+$lang['note2'] = 'Note : cette page sera révisée à la version précédente ne contenant pas le terme spammeur <em>%s</em>.';
diff --git a/lib/plugins/revert/lang/gl/intro.txt b/lib/plugins/revert/lang/gl/intro.txt
new file mode 100644
index 000000000..6327249fc
--- /dev/null
+++ b/lib/plugins/revert/lang/gl/intro.txt
@@ -0,0 +1,3 @@
+====== Xestor de Reversión ======
+
+Esta páxina axudarache a revertir automaticamente un ataque de correo-lixo. Para atopares unha listaxe de páxinas que conteñan correo-lixo, primeiro debes inserir unha cadea de procura (p.e. un URL do correo-lixo), e logo confirmares que as páxinas atopadas conteñen realmente o tal correo-lixo e reverter as edicións. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/gl/lang.php b/lib/plugins/revert/lang/gl/lang.php
new file mode 100644
index 000000000..a0c5a9785
--- /dev/null
+++ b/lib/plugins/revert/lang/gl/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['menu'] = 'Xestor de Reversión';
+$lang['filter'] = 'Procurar páxinas con correo-lixo';
+$lang['revert'] = 'Revertir as páxinas seleccionadas';
+$lang['reverted'] = '%s revertido á revisión %s';
+$lang['removed'] = '%s eliminado';
+$lang['revstart'] = 'Proceso de reversión iniciado. Isto podería demorar un anaco longo. Se o script fallar por superar o seu límite de tempo denantes de rematar, terás que facer a reversión en anacos máis pequenos.';
+$lang['revstop'] = 'O proceso de reversión rematou correctamente.';
+$lang['note1'] = 'Nota: esta procura distingue entre maiúsculas e minúsculas';
+$lang['note2'] = 'Nota: a páxina revertirase á última versión que non conteña o termo de correo-lixo <i>%s</i> indicado.';
diff --git a/lib/plugins/revert/lang/he/intro.txt b/lib/plugins/revert/lang/he/intro.txt
new file mode 100644
index 000000000..44b78dfea
--- /dev/null
+++ b/lib/plugins/revert/lang/he/intro.txt
@@ -0,0 +1,3 @@
+====== מנהל השחזור ======
+
+דף זה יסיע בידך לשחזר באופן אוטומטי אחרי התקפת ספאם. כדי לקבל את רשימת הדפים עם הספאם עליך ראשית מחרוזת לחיפוש (לדוגמה כתובת ספאם) אחר כך עליך לאשר שהדפים שנמצאו באמת מכילים ספאם ולשחזר את העריכות.
diff --git a/lib/plugins/revert/lang/he/lang.php b/lib/plugins/revert/lang/he/lang.php
new file mode 100644
index 000000000..ac3c3412e
--- /dev/null
+++ b/lib/plugins/revert/lang/he/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Hebrew language file
+ *
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['menu'] = 'מנהל שחזור';
+$lang['filter'] = 'חפש דפים עם ספאם';
+$lang['revert'] = 'שחזר את הדפים הנבחרים';
+$lang['reverted'] = '%s שוחזרו לגרסה %s';
+$lang['removed'] = '%s הוסרו';
+$lang['revstart'] = 'תהליך השחזור החל. התהליך עלול להיות ממושך. אם תסריט מגיע למגבלת פסק הזמן לפני שהסתיים התהליך יהיה צורך לבצע את השחזור במקטעים קטנים יותר.';
+$lang['revstop'] = 'תהליך השחזור הושלם בהצלחה.';
+$lang['note1'] = 'לתשומת לבך: החיפוש ער לגודל האותיות הלועזיות.';
+$lang['note2'] = 'לתשות לבך: הדף ישוחזר לגרסה האחרונה שאינה מכילה את מונח הספאם <i>%s</i>';
diff --git a/lib/plugins/revert/lang/hi/lang.php b/lib/plugins/revert/lang/hi/lang.php
new file mode 100644
index 000000000..d6f78ffd6
--- /dev/null
+++ b/lib/plugins/revert/lang/hi/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
diff --git a/lib/plugins/revert/lang/hr/lang.php b/lib/plugins/revert/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/revert/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/revert/lang/hu/intro.txt b/lib/plugins/revert/lang/hu/intro.txt
new file mode 100644
index 000000000..e2c2dadd9
--- /dev/null
+++ b/lib/plugins/revert/lang/hu/intro.txt
@@ -0,0 +1,3 @@
+====== Visszaállítás kezelő ======
+
+Segítséget nyújtunk SPAM támadások utáni automatikus visszaállításhoz. A fertőzött oldalak kereséséhez meg kell adni egy karaktersorozatot (pl. egy SPAM URL-t). A találatok közül kiválasztva a valóban SPAM-et tartalmazó oldakat, visszaállítjuk őket a lehetséges utolsó SPAM mentes állapotra. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/hu/lang.php b/lib/plugins/revert/lang/hu/lang.php
new file mode 100644
index 000000000..058a63196
--- /dev/null
+++ b/lib/plugins/revert/lang/hu/lang.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['menu'] = 'Visszaállítás kezelő (anti-SPAM)';
+$lang['filter'] = 'SPAM tartalmú oldalak keresése';
+$lang['revert'] = 'Kiválasztott oldalak visszaállítása';
+$lang['reverted'] = '%s a következő változatra lett visszaállítva: %s';
+$lang['removed'] = '%s törölve';
+$lang['revstart'] = 'A visszaállítási folyamat elindult. Ez hosszú ideig eltarthat. Ha időtúllépés miatt nem tud lefutni, kisebb darabbal kell próbálkozni.';
+$lang['revstop'] = 'A visszaállítási folyamat sikeresen befejeződött.';
+$lang['note1'] = 'Megjegyzés: a keresés kisbetű-nagybetűre érzékeny';
+$lang['note2'] = 'Megjegyzés: Az oldalt az utolsó olyan változatra állítjuk vissza, ami nem tartalmazza a megadott spam kifejezést: <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ia/intro.txt b/lib/plugins/revert/lang/ia/intro.txt
new file mode 100644
index 000000000..ae548e9df
--- /dev/null
+++ b/lib/plugins/revert/lang/ia/intro.txt
@@ -0,0 +1,3 @@
+====== Gestion de reversiones ======
+
+Iste pagina te adjuta con le reversion automatic de un attacco de spam. Pro cercar un lista de paginas spammose, primo entra un texto a cercar (p.ex. un URL de spam), postea confirma que le paginas trovate es realmente spam e reverte le modificationes. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/ia/lang.php b/lib/plugins/revert/lang/ia/lang.php
new file mode 100644
index 000000000..bec2eca7b
--- /dev/null
+++ b/lib/plugins/revert/lang/ia/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['menu'] = 'Gestion de reversiones';
+$lang['filter'] = 'Cercar paginas spammose';
+$lang['revert'] = 'Reverter le paginas seligite';
+$lang['reverted'] = '%s revertite al version %s';
+$lang['removed'] = '%s removite';
+$lang['revstart'] = 'Le processo de reversion ha comenciate. Isto pote durar multo. Si le script expira ante de finir, tu debe divider le reversiones in blocos minor.';
+$lang['revstop'] = 'Le processo de reversion ha succedite.';
+$lang['note1'] = 'Nota: iste recerca distingue inter majusculas e minusculas.';
+$lang['note2'] = 'Nota: le pagina essera revertite al ultime version que non contine le termino de spam specificate, <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/id-ni/lang.php b/lib/plugins/revert/lang/id-ni/lang.php
new file mode 100644
index 000000000..d367340b7
--- /dev/null
+++ b/lib/plugins/revert/lang/id-ni/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/revert/lang/id/lang.php b/lib/plugins/revert/lang/id/lang.php
new file mode 100644
index 000000000..c3d485930
--- /dev/null
+++ b/lib/plugins/revert/lang/id/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Irwan Butar Butar <irwansah.putra@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/revert/lang/is/lang.php b/lib/plugins/revert/lang/is/lang.php
new file mode 100644
index 000000000..9de404992
--- /dev/null
+++ b/lib/plugins/revert/lang/is/lang.php
@@ -0,0 +1,10 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['removed'] = '%s eytt';
+$lang['note1'] = 'Athugaðu að þegar leitað er þá skiftir stafsetur máli, það að segja leitarvélin gerir mun á hástöfum og lágstöfum';
diff --git a/lib/plugins/revert/lang/it/intro.txt b/lib/plugins/revert/lang/it/intro.txt
new file mode 100644
index 000000000..a5ef14680
--- /dev/null
+++ b/lib/plugins/revert/lang/it/intro.txt
@@ -0,0 +1,3 @@
+====== Gestore di ripristini ======
+
+Questa pagina aiuta il controllo automatico degli attacchi spam. Per cercare una lista delle pagine con spam, inserisci innanzitutto una stringa di ricerca (ad esempio l'URL di un sito di spam), quindi Verifica che le pagine trovate contengano realmente spam e ripristinale ad una versione precedente.
diff --git a/lib/plugins/revert/lang/it/lang.php b/lib/plugins/revert/lang/it/lang.php
new file mode 100644
index 000000000..79565655b
--- /dev/null
+++ b/lib/plugins/revert/lang/it/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['menu'] = 'Gestore di ripristini';
+$lang['filter'] = 'Cerca pagine con spam';
+$lang['revert'] = 'Ripristina le pagine selezionate';
+$lang['reverted'] = '%s ripristinata alla versione %s';
+$lang['removed'] = '%s rimossa';
+$lang['revstart'] = 'Processo di ripristino avviato. Può essere necessario molto tempo. Se lo script non fa in tempo a finire, sarà necessario ripristinare in blocchi più piccoli.';
+$lang['revstop'] = 'Processo di ripristino finito con successo.';
+$lang['note1'] = 'Nota: questa ricerca distingue le maiuscole';
+$lang['note2'] = 'Nota: la pagina verrà ripristinata all\'ultima versione non contenente la parola di spam data <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ja/intro.txt b/lib/plugins/revert/lang/ja/intro.txt
new file mode 100644
index 000000000..995a57fd7
--- /dev/null
+++ b/lib/plugins/revert/lang/ja/intro.txt
@@ -0,0 +1,3 @@
+====== 復元管理 ======
+
+このページは、スパムにより編集されたページを自動的に復元するための機能を管理します。 スパムを受けたページを検索するため、スパムURLなどのキーワードを入力してください。 その後、検索結果に含まれているページがスパムされていることを確認してから復元を行います。
diff --git a/lib/plugins/revert/lang/ja/lang.php b/lib/plugins/revert/lang/ja/lang.php
new file mode 100644
index 000000000..0cd8c6f9b
--- /dev/null
+++ b/lib/plugins/revert/lang/ja/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * japanese language file
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['menu'] = '復元管理';
+$lang['filter'] = 'スパムを受けたページを検索';
+$lang['revert'] = '選択したページを検索';
+$lang['reverted'] = '%s はリビジョン %s へ復元されました';
+$lang['removed'] = '%s は削除されました';
+$lang['revstart'] = '復元処理中です。時間が掛かる可能性がありますが、もしタイムアウトした場合は、復元を複数回に分けて行ってください。';
+$lang['revstop'] = '復元処理が正しく完了しました。';
+$lang['note1'] = '注意:検索語句は大文字・小文字を区別します';
+$lang['note2'] = '注意:最新の内容に検索したスパムキーワード <i>%s</i> が含まれていないページが復元されます。';
diff --git a/lib/plugins/revert/lang/kk/lang.php b/lib/plugins/revert/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/revert/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/revert/lang/ko/intro.txt b/lib/plugins/revert/lang/ko/intro.txt
new file mode 100644
index 000000000..a0164dc4f
--- /dev/null
+++ b/lib/plugins/revert/lang/ko/intro.txt
@@ -0,0 +1,3 @@
+====== 복구 관리자 ======
+
+스팸 공격으로 부터 자동으로 복구하는데 이페이지는 도움이 될 수 있습니다. 스팸 공격받은 페이지 목록을 찾으려면 문자열을 입력하기 바랍니다(예. 스팸 URL), 그 후 검색된 페이지들이 스팸 공격받았는지 확인하고 복구합니다.
diff --git a/lib/plugins/revert/lang/ko/lang.php b/lib/plugins/revert/lang/ko/lang.php
new file mode 100644
index 000000000..0163d2754
--- /dev/null
+++ b/lib/plugins/revert/lang/ko/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Korean language file
+ *
+ * @author jk lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['menu'] = '복구 관리자';
+$lang['filter'] = '스팸 페이지 검색 ';
+$lang['revert'] = '선택 페이지들 복구';
+$lang['reverted'] = '%s를 이전 버전 %s 으로 복구';
+$lang['removed'] = '%s 삭제';
+$lang['revstart'] = '복구 작업을 시작합니다. 오랜 시간이 걸릴 수 있습니다. 완료되기 전에 스크립트 time out이 발생한다면 더 작은 작업들로 나누어서 복구하기 바랍니다. ';
+$lang['revstop'] = '복구 작업이 성공적으로 끝났습니다.';
+$lang['note1'] = '주의: 대소문자 구별하여 검색합니다.';
+$lang['note2'] = '주의: 이 페이지는 스팸 단어 <i>%s</i>를 포함하지 않은 가장 최근 과거 문서 버전으로 복구됩니다. ';
diff --git a/lib/plugins/revert/lang/la/intro.txt b/lib/plugins/revert/lang/la/intro.txt
new file mode 100644
index 000000000..99a206f63
--- /dev/null
+++ b/lib/plugins/revert/lang/la/intro.txt
@@ -0,0 +1,3 @@
+====== Restituendi Administrator ======
+
+Haec pagina contra mala interretialia paginas restituta. Vt paginas aegras quaeras, malum VRL scribe, deinde paginas malas eligas. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/la/lang.php b/lib/plugins/revert/lang/la/lang.php
new file mode 100644
index 000000000..af4203437
--- /dev/null
+++ b/lib/plugins/revert/lang/la/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['menu'] = 'Restituendi administrator';
+$lang['filter'] = 'Malas paginas quaerere';
+$lang['revert'] = 'Electas paginas restituere';
+$lang['reverted'] = '%s restitutur ut %s recenseas';
+$lang['removed'] = '%s deletur';
+$lang['revstart'] = 'Restitutio agens. Hic multo tempore agere potest. Si nimium tempus transit, manu restituis.';
+$lang['revstop'] = 'Restitutio feliciter perfecta.';
+$lang['note1'] = 'Caue: litteras maiores et minores discernit';
+$lang['note2'] = 'Caue: pagina in recentiori forma sine malis uerbis "<i>%s</i>" restituetur';
diff --git a/lib/plugins/revert/lang/lb/intro.txt b/lib/plugins/revert/lang/lb/intro.txt
new file mode 100644
index 000000000..59c5dfc14
--- /dev/null
+++ b/lib/plugins/revert/lang/lb/intro.txt
@@ -0,0 +1,3 @@
+====== Revert Manager ======
+
+Dës Säit hëlleft bei der automatescher zerécksetzung no enger Spamattack. Fir eng Lëscht vun zougespamte Säiten ze fannen, gëff fir d'éischt e Sichbegrëff an (z.B. eng Spamadress). Konfirméier dann dass déi Säite wierklech zougespamt goufen a setz se dann zréck. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/lb/lang.php b/lib/plugins/revert/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/revert/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/revert/lang/lt/lang.php b/lib/plugins/revert/lang/lt/lang.php
new file mode 100644
index 000000000..103485864
--- /dev/null
+++ b/lib/plugins/revert/lang/lt/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
diff --git a/lib/plugins/revert/lang/lv/intro.txt b/lib/plugins/revert/lang/lv/intro.txt
new file mode 100644
index 000000000..edcdab2cd
--- /dev/null
+++ b/lib/plugins/revert/lang/lv/intro.txt
@@ -0,0 +1,3 @@
+====== Piemēsloto lapu atjaunotājs ======
+
+Šī lapa palīdzēs automātiski atjaunot saturu pēc huligānisma . Lai atrastu piedrazotās lapas ieraksti meklējamo izteiksmi (piem. smaperu URL), tad apstiprini, ka atrastās ir "mēslapas" un atcel izdarītās izmaiņas .
diff --git a/lib/plugins/revert/lang/lv/lang.php b/lib/plugins/revert/lang/lv/lang.php
new file mode 100644
index 000000000..012d6cc4c
--- /dev/null
+++ b/lib/plugins/revert/lang/lv/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Latvian, Lettish language file
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['menu'] = 'Piemēsloto lapu atjaunotājs';
+$lang['filter'] = 'Meklēt piemēslotās lapas';
+$lang['revert'] = 'Atjaunot norādītās lapas ';
+$lang['reverted'] = '%s atjaunots uz %s stāvokli';
+$lang['removed'] = '%s dzēsts';
+$lang['revstart'] = 'Atjaunošana uzsākta. Tas var aizņemt ilgāku laiku. Ja darbība pārtrūkst noilguma dēļ, atjaunošana jāveic pa mazākām porcijām.';
+$lang['revstop'] = 'Atjaunošana veiksmīgi pabeigta. ';
+$lang['note1'] = 'Ievēro: Meklēšana atšķir lielos un mazos burtus.';
+$lang['note2'] = 'Ievēro: Lapu atjaunos ar pēdējo versiju, kas nesatur uzdoto spama vārdu <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/mk/lang.php b/lib/plugins/revert/lang/mk/lang.php
new file mode 100644
index 000000000..6d4530f79
--- /dev/null
+++ b/lib/plugins/revert/lang/mk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
diff --git a/lib/plugins/revert/lang/mr/intro.txt b/lib/plugins/revert/lang/mr/intro.txt
new file mode 100644
index 000000000..efca2430d
--- /dev/null
+++ b/lib/plugins/revert/lang/mr/intro.txt
@@ -0,0 +1,5 @@
+====== फेरबदल व्यवस्थापक ======
+
+ह्या पानाद्वारे तुम्ही भंकस हल्ल्याद्वारे झालेले बदल आपोआप फेरबदल करू शकता.
+भंकस पानांची यादी बनवण्यासाठी प्रथम एखादा शब्दसमूह टाका ( उदा. एखादं भंकस URL ),
+मग जी पाने सापडतील टी भंकस असल्याचे नक्की करा आणि त्यातील बदल रद्द करा. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/mr/lang.php b/lib/plugins/revert/lang/mr/lang.php
new file mode 100644
index 000000000..3912bb967
--- /dev/null
+++ b/lib/plugins/revert/lang/mr/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['menu'] = 'फेर बदल व्यवस्थापक';
+$lang['filter'] = 'भंकस पाने शोधा';
+$lang['revert'] = 'निवडलेली पानातील बदल रद्द करा';
+$lang['reverted'] = '%s फेरबदलून %s आवृत्तिमधे आणला आहे';
+$lang['removed'] = '%s काढला आहे.';
+$lang['revstart'] = 'फेरबदलाची प्रक्रिया चालु झाली आहे.याला बराच वेळ लागू शकतो. जर स्क्रिप्ट सम्पण्याआधि त्याची कालमर्यादा उलटून गेली तर छोट्या-छोट्या तुकड्यांमधे फेरबदल करा.';
+$lang['revstop'] = 'फेरबदलाची प्रक्रिया यशस्वीरीत्या पूर्ण झाली.';
+$lang['note1'] = 'टीप : हा शोध केस-सेंसिटिव आहे ( फ़क्त इंग्रजीसाठी लागू )';
+$lang['note2'] = 'टीप : हे पान फेरबदल करून ज्या शेवटच्या आवृत्तिमधे <i>%s</i> हा दिलेला भंकस शब्द नाही त्यात बदलले जाईल.';
diff --git a/lib/plugins/revert/lang/ms/lang.php b/lib/plugins/revert/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/revert/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/revert/lang/ne/lang.php b/lib/plugins/revert/lang/ne/lang.php
new file mode 100644
index 000000000..4fd337532
--- /dev/null
+++ b/lib/plugins/revert/lang/ne/lang.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['menu'] = 'पूर्वस्थिती व्यवस्थापक';
+$lang['filter'] = 'स्प्यामयुक्त पृष्ठहरु खोज्नुहोस् ';
+$lang['revert'] = 'छानिएक पृष्ठहरुलाई पूर्वस्थितिमा फर्काउनुहोस् ।';
+$lang['reverted'] = '%s लाई %s संस्करणमा फर्काइयो ।';
+$lang['removed'] = '%s लाई हटाइयो ।';
+$lang['revstart'] = 'पूर्वस्थितिमा फर्काउने कार्य सुरु भयो । यसले लामो समय लिन सक्छ। यदि स्क्रिप्टको समय का्र्य सकिनु पूर्व सकियो भने । तपाईले सानो सानो टुक्रा लिएर पुर्वरुपमा फर्काउनु पर्ने हुन्छ ।';
+$lang['revstop'] = 'पूर्वस्थितिमा फर्काउने कार्य सफलतापूर्वक सकियो ।';
+$lang['note1'] = 'नोट: यो खोज वर्ण सम्वेदनशील छ';
diff --git a/lib/plugins/revert/lang/nl/intro.txt b/lib/plugins/revert/lang/nl/intro.txt
new file mode 100644
index 000000000..db8f5a06c
--- /dev/null
+++ b/lib/plugins/revert/lang/nl/intro.txt
@@ -0,0 +1,3 @@
+===== Herstelmanager =====
+
+Deze pagina helpt u bij het herstellen van pagina's na een spam-aanval. Vul een zoekterm in (bijvoorbeeld een spam url) om een lijst te krijgen van bekladde pagina's, bevestig dat de pagina's inderdaad spam bevatten en herstel de wijzigingen.
diff --git a/lib/plugins/revert/lang/nl/lang.php b/lib/plugins/revert/lang/nl/lang.php
new file mode 100644
index 000000000..32e14c2c4
--- /dev/null
+++ b/lib/plugins/revert/lang/nl/lang.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Dutch language file
+ *
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['menu'] = 'Herstelmanager';
+$lang['filter'] = 'Zoek naar bekladde pagina\'s';
+$lang['revert'] = 'Herstel geselecteerde pagina\'s';
+$lang['reverted'] = '%s hersteld naar revisie %s';
+$lang['removed'] = '%s verwijderd';
+$lang['revstart'] = 'Herstelproces begonnen. Dit kan een lange tijd duren. Als het script een timeout genereerd voor het klaar is, moet je in kleinere selecties herstellen.';
+$lang['revstop'] = 'Herstelproces succesvol afgerond.';
+$lang['note1'] = 'NB: deze zoekopdracht is hoofdlettergevoelig';
+$lang['note2'] = 'NB: de pagina zal hersteld worden naar de laatste versie waar de opgegeven spam-term <i>%s</i> niet op voorkomt.';
diff --git a/lib/plugins/revert/lang/no/intro.txt b/lib/plugins/revert/lang/no/intro.txt
new file mode 100644
index 000000000..f48b98749
--- /dev/null
+++ b/lib/plugins/revert/lang/no/intro.txt
@@ -0,0 +1,3 @@
+====== Tilbakestillingsbehandler ======
+
+Denne siden hjelper deg å automatisk reversere forsøpling av sidene. For å finne en liste over forsøplede sider, skriv inn en søkestreng (f.eks. en søppel-URL). Bekreft deretter at de funnede sidene virkelig er forsøplet og tilbakestill endringene.
diff --git a/lib/plugins/revert/lang/no/lang.php b/lib/plugins/revert/lang/no/lang.php
new file mode 100644
index 000000000..299b12ea7
--- /dev/null
+++ b/lib/plugins/revert/lang/no/lang.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Norwegianlanguage file
+ *
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['menu'] = 'Tilbakestillingsbehandler';
+$lang['filter'] = 'Søk etter søppelmeldinger';
+$lang['revert'] = 'Tilbakestill valgte sider';
+$lang['reverted'] = '%s tilbakestilt til revisjon %s';
+$lang['removed'] = '%s fjernet';
+$lang['revstart'] = 'Prosessen med tilbakestilling er startet. Hvis det skjer et
+tidsavbrudd før prosessen er ferdig, må du tilbakestille
+færre sider om gangen.';
+$lang['revstop'] = 'Tilbakestillingen er fullført.';
+$lang['note1'] = 'Merk: søket skiller mellom store og små bokstaver';
+$lang['note2'] = 'Merk: siden vil bli tilbakestilt til den siste versjonen som ikke inneholder det oppgitte søppel-ordet <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/pl/intro.txt b/lib/plugins/revert/lang/pl/intro.txt
new file mode 100644
index 000000000..410948a2f
--- /dev/null
+++ b/lib/plugins/revert/lang/pl/intro.txt
@@ -0,0 +1,3 @@
+====== Menadżer przywracania ======
+
+Menadżer przywracania przeznaczony jest do automatycznego naprawiania stron, które uległy wandalizmom. W celu naprawienia uszkodzonych stron, wyszukaj je a następnie oznacz i przywróć poprzednie wersje.
diff --git a/lib/plugins/revert/lang/pl/lang.php b/lib/plugins/revert/lang/pl/lang.php
new file mode 100644
index 000000000..30ab60fda
--- /dev/null
+++ b/lib/plugins/revert/lang/pl/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * polish language file
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['menu'] = 'Menadżer przywracania';
+$lang['filter'] = 'Wyszukaj uszkodzone strony';
+$lang['revert'] = 'Napraw zaznaczone strony';
+$lang['reverted'] = 'Stronę %s zastąpiono wersją %s';
+$lang['removed'] = 'Stronę %s usunięto';
+$lang['revstart'] = 'Naprawa rozpoczęta. To może zająć kilka minut. Jeśli strona przestanie się ładować, spróbuj ponownie zaznaczając mniejszą liczbę stron.';
+$lang['revstop'] = 'Naprawa zakończona pomyślnie!';
+$lang['note1'] = 'Uwaga: duże i małe litery są rozróżniane';
+$lang['note2'] = 'Uwaga: zostanie przywrócona ostatnia wersja strony niezawierająca wyrażenia <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/pt-br/intro.txt b/lib/plugins/revert/lang/pt-br/intro.txt
new file mode 100644
index 000000000..5ce9890db
--- /dev/null
+++ b/lib/plugins/revert/lang/pt-br/intro.txt
@@ -0,0 +1,3 @@
+====== Gerenciador de Reversões ======
+
+Essa página ajuda a reverter automaticamente um ataque de spam. Para encontrar as páginas que sofreram ataque, primeiro entre com um termo na busca (ex.: a URL do spam), então confirme que as páginas encontradas são realmente spam e reverta as edições.
diff --git a/lib/plugins/revert/lang/pt-br/lang.php b/lib/plugins/revert/lang/pt-br/lang.php
new file mode 100644
index 000000000..c4a2f742b
--- /dev/null
+++ b/lib/plugins/revert/lang/pt-br/lang.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['menu'] = 'Gerenciador de reversões';
+$lang['filter'] = 'Procura por páginas com spam';
+$lang['revert'] = 'Reverte as páginas selecionadas';
+$lang['reverted'] = '%s revertida para a revisão %s';
+$lang['removed'] = '%s removida';
+$lang['revstart'] = 'O processo de reversão foi iniciado. Isso pode levar muito tempo. Se o tempo de execução do script expirar antes dele encerrar, você deverá tentar novamente usando blocos menores.';
+$lang['revstop'] = 'O processo de reversão terminou com sucesso.';
+$lang['note1'] = 'Nota: esta busca diferencia maiúsculas/minúsculas';
+$lang['note2'] = 'Nota: a página será revertida para a última versão que não contém o termo de spam <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/pt/intro.txt b/lib/plugins/revert/lang/pt/intro.txt
new file mode 100644
index 000000000..7adfe5f21
--- /dev/null
+++ b/lib/plugins/revert/lang/pt/intro.txt
@@ -0,0 +1,3 @@
+====== Gerir Reversões ======
+
+Esta página ajuda a reverter automaticamente de um ataque spam. Para encontrar as páginas afectadas insira primeiro um texto de pesquisa (i.e spam URL), confirme as páginas encontradas como sendo resultantes de um ataque spam e reverta essas edições. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/pt/lang.php b/lib/plugins/revert/lang/pt/lang.php
new file mode 100644
index 000000000..3b2850f41
--- /dev/null
+++ b/lib/plugins/revert/lang/pt/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['menu'] = 'Gestor de Reversões';
+$lang['filter'] = 'Pesquisar por páginas "spammy"';
+$lang['revert'] = 'Reverter páginas seleccionadas';
+$lang['reverted'] = '%s revertida para revisão %s';
+$lang['removed'] = '%s removidas.';
+$lang['revstart'] = 'Processo de reversão iniciado. A sua execução pode demorar. Se der timeout antes de terminar então é preciso escolher quantidades menores de páginas a reverter.';
+$lang['revstop'] = 'Processo de reversão bem sucedido.';
+$lang['note1'] = 'Nota: a pesquisa é case-sensitive';
+$lang['note2'] = 'Nota: a página será revertida para a versão anterior que não contém os termos spam pesquisados: <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ro/intro.txt b/lib/plugins/revert/lang/ro/intro.txt
new file mode 100644
index 000000000..3a030359b
--- /dev/null
+++ b/lib/plugins/revert/lang/ro/intro.txt
@@ -0,0 +1,3 @@
+====== Manager Reveniri ======
+
+Această pagină ajută revenirea automată în cazul unui atac spam. Pentru a găsi o listă a paginilor cu spam, întroduceţi mai întâi un şir de căutat (de ex. Un URL spam), apoi confirmaţi dacă paginile găsite conţin într-adevăr spam şi anulaţi editările.
diff --git a/lib/plugins/revert/lang/ro/lang.php b/lib/plugins/revert/lang/ro/lang.php
new file mode 100644
index 000000000..094f4dc71
--- /dev/null
+++ b/lib/plugins/revert/lang/ro/lang.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['menu'] = 'Manager Reveniri';
+$lang['filter'] = 'Caută pagini cu posibil spam';
+$lang['revert'] = 'Revenire pentru paginile selectate';
+$lang['reverted'] = '%s revenită la versiunea %s';
+$lang['removed'] = '%s eliminată';
+$lang['revstart'] = 'Procesul de revenire a început. Acesta poate dura mult timp.Dacă scriptul expiră înainte de finalizare, trebuie să reveniţi în paşi mai mici.';
+$lang['revstop'] = 'Procesul de revenire s-a finalizat cu succes.';
+$lang['note1'] = 'Notă: această căutare este sensibilă la majuscule.';
+$lang['note2'] = 'Notă: pagina va reveni la ultima versiune ce nu conţine termenul de spam <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/ru/intro.txt b/lib/plugins/revert/lang/ru/intro.txt
new file mode 100644
index 000000000..52d1f8d3d
--- /dev/null
+++ b/lib/plugins/revert/lang/ru/intro.txt
@@ -0,0 +1,3 @@
+====== Менеджер откаток ======
+
+Эта страница поможет вам в автоматической откатке изменений после спам-атаки. Для того, чтобы найти спам-страницы, введите ключевые слова и произведите поиск (например, по URL спамера). Затем убедитесь, что найденные страницы действительно содержат спам и сделайте откатку изменений.
diff --git a/lib/plugins/revert/lang/ru/lang.php b/lib/plugins/revert/lang/ru/lang.php
new file mode 100644
index 000000000..9624d8fd6
--- /dev/null
+++ b/lib/plugins/revert/lang/ru/lang.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * russian language file
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Andrew Pleshakov <beotiger@mail.ru>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['menu'] = 'Менеджер откаток';
+$lang['filter'] = 'Поиск спам-страниц';
+$lang['revert'] = 'Откатить изменения для выбранных страниц';
+$lang['reverted'] = '%s откачена к версии %s';
+$lang['removed'] = '%s удалена';
+$lang['revstart'] = 'Начат процесс откатки. Он может занять много времени. Если скрипт не успевает завершить работу и выдаёт ошибку, необходимо произвести откатку более маленькими частями.';
+$lang['revstop'] = 'Процесс откатки успешно завершён.';
+$lang['note1'] = 'Замечание: поиск с учётом регистра';
+$lang['note2'] = 'Замечание: страница будет восстановлена до последней версии, не содержащей спам-термин <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sk/intro.txt b/lib/plugins/revert/lang/sk/intro.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/lib/plugins/revert/lang/sk/intro.txt
diff --git a/lib/plugins/revert/lang/sk/lang.php b/lib/plugins/revert/lang/sk/lang.php
new file mode 100644
index 000000000..368d2d929
--- /dev/null
+++ b/lib/plugins/revert/lang/sk/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Slovaklanguage file
+ *
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['menu'] = 'Reverzný manažér';
+$lang['filter'] = 'Hľadať spamerské stránky';
+$lang['revert'] = 'Vrátiť vybrané stránky';
+$lang['reverted'] = '%s vrátená na revíziu %s';
+$lang['removed'] = '%s odstránená';
+$lang['revstart'] = 'Proces reverzie bol spustený. Toto môže trvať dlhý čas. Ak skript prekročí daný maximálny časový interval pred tým, ako skončí, musíte urobiť reverziu v menších dávkach.';
+$lang['revstop'] = 'Proces reverzie sa úspešne skončil.';
+$lang['note1'] = 'Poznámka: vyhľadávanie rozlišuje medzi veľkými a malými písmenami';
+$lang['note2'] = 'Poznámka: táto stránka bude vrátená do poslednej verzie, ktorá neobsahuje spamový výraz <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sl/intro.txt b/lib/plugins/revert/lang/sl/intro.txt
new file mode 100644
index 000000000..4e2cabf96
--- /dev/null
+++ b/lib/plugins/revert/lang/sl/intro.txt
@@ -0,0 +1,3 @@
+====== Povrnitev okvarjene vsebine ======
+
+Na tej strani je mogoče povrniti vsebino wiki strani na izvorne vrednosti po napadu na stran in vpisu neželenih vsebin. Za iskanje strani z neželeno vsebino, uporabite iskalnik z ustreznim nizom (npr. naslov URL), potem pa potrdite, da so najdene strani res z neželeno vsebino in nato povrnite stanje na zadnjo pravo različico.
diff --git a/lib/plugins/revert/lang/sl/lang.php b/lib/plugins/revert/lang/sl/lang.php
new file mode 100644
index 000000000..92b0427ce
--- /dev/null
+++ b/lib/plugins/revert/lang/sl/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['menu'] = 'Povrnitev okvarjene vsebine';
+$lang['filter'] = 'Iskanje strani z neželeno vsebino';
+$lang['revert'] = 'Povrni izbrane strani';
+$lang['reverted'] = 'stran %s je povrnjena na različico %s';
+$lang['removed'] = 'stran %s je odstranjena';
+$lang['revstart'] = 'Postopek povrnitve vsebine je začet. Opravilo je lahko dolgotrajno. V kolikor opravilo časovno poteče prek končanjem povrnitve, bo treba postopek ponoviti na manjših odsekih.';
+$lang['revstop'] = 'Postopek povrnitve vsebine je uspešno končan.';
+$lang['note1'] = 'Opomba: iskanje upošteva velikost črk';
+$lang['note2'] = 'Opomba: stran bo povrnjena na zadnjo različico brez neželenega pojma <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sq/intro.txt b/lib/plugins/revert/lang/sq/intro.txt
new file mode 100644
index 000000000..25e16b6eb
--- /dev/null
+++ b/lib/plugins/revert/lang/sq/intro.txt
@@ -0,0 +1,3 @@
+====== Menaxhuesi Rikthimit ======
+
+Kjo faqe ndihmon për rikthimin automatik në rast të një sulmi spam. Për të gjetur një listë me faqe spam në fillim fut një varg kërkimi (psh një URL spam), dhe pastaj konfirmo që faqet e gjetura janë me të vërtetë spam dhe rikthe redaktimet. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/sq/lang.php b/lib/plugins/revert/lang/sq/lang.php
new file mode 100644
index 000000000..45ae4997c
--- /dev/null
+++ b/lib/plugins/revert/lang/sq/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['menu'] = 'Menaxhuesi Rikthimit';
+$lang['filter'] = 'Kërko faqe me spam';
+$lang['revert'] = 'Rikthe faqet e përzgjedhura';
+$lang['reverted'] = '%s u rikthye në rishikimin %s';
+$lang['removed'] = '%s u hoq';
+$lang['revstart'] = 'Proçesi i rikthimit filloi. Kjo mund të zgjasë për një kohë të gjatë. Nëse koha e skriptit mbaron para përfundimit, atëherë rikthimi duhet të bëhet me copa të vogla.';
+$lang['revstop'] = 'Proçesi i rikthimit mbaroi me sukses.';
+$lang['note1'] = 'Shënim: në këtë kërkim bëhet dallim midis gërmave kapitale dhe gërmave të vogla.';
+$lang['note2'] = 'Shënim: faqja do të rikthehet në versionin e fundit që nuk përmban term-in spam të dhënë <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sr/intro.txt b/lib/plugins/revert/lang/sr/intro.txt
new file mode 100644
index 000000000..8c288e7f1
--- /dev/null
+++ b/lib/plugins/revert/lang/sr/intro.txt
@@ -0,0 +1,3 @@
+====== Управљач за враћање ======
+
+Ова страна вам помаже од напада спама аутоматским враћањем на старе верзије страница. Да бисте пронашли спамоване странице откуцајте реч за претрагу (тј. реч која се појављује у спаму), затим потврдите да се на пронађеним страницама стварно налази спам и онда вратите на стање пре промена. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/sr/lang.php b/lib/plugins/revert/lang/sr/lang.php
new file mode 100644
index 000000000..62c712ad1
--- /dev/null
+++ b/lib/plugins/revert/lang/sr/lang.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['menu'] = 'Управљач за враћање';
+$lang['filter'] = 'Претрага спам страница';
+$lang['revert'] = 'Врати одабране странице';
+$lang['reverted'] = '%s враћена на ревизију %s';
+$lang['removed'] = '%s је уклоњена';
+$lang['revstart'] = 'Процес враћања је покренут. Може потрајати дуже време. Ако истекне време пре завршетка потребно је да покренете у мањим деловима.';
+$lang['revstop'] = 'Процес враћања је успешно завршен.';
+$lang['note1'] = 'Напомена: ова претрага разликује велика и мала слова';
+$lang['note2'] = 'Напомена: страница ће бити враћена на последњу верзију која не садржи спам израз <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/sv/intro.txt b/lib/plugins/revert/lang/sv/intro.txt
new file mode 100644
index 000000000..cd7f322a3
--- /dev/null
+++ b/lib/plugins/revert/lang/sv/intro.txt
@@ -0,0 +1,3 @@
+====== Hantera återställningar ======
+
+Den här sidan hjälper till med automatiskt återställning efter en spamattack. För att hitta spammade sidor, ange först en söksträng (till exempel en webbadress). Kontrollera sedan att sidorna som hittades verkligen är spam, och återställ sedan redigeringarna.
diff --git a/lib/plugins/revert/lang/sv/lang.php b/lib/plugins/revert/lang/sv/lang.php
new file mode 100644
index 000000000..29c6702eb
--- /dev/null
+++ b/lib/plugins/revert/lang/sv/lang.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Swedish language file
+ *
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['menu'] = 'Hantera återställningar';
+$lang['filter'] = 'Sök efter spamsidor';
+$lang['revert'] = 'Återställ markerade redigeringar';
+$lang['reverted'] = '%s återställd till version %s';
+$lang['removed'] = '%s borttagen';
+$lang['revstart'] = 'Återställningen startad. Detta kan ta lång tid. Om
+ skriptet får en timeout innan det är färdigt måste du köra återställningen
+ med färre sidor åt gången.';
+$lang['revstop'] = 'Återställningen avslutades utan problem.';
+$lang['note1'] = 'OBS: sökningen skiljer på stora och små bokstäver';
+$lang['note2'] = 'OBS: sidan kommer att återställas till den senaste versionen som inte innehåller den angivna söksträngen <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/th/intro.txt b/lib/plugins/revert/lang/th/intro.txt
new file mode 100644
index 000000000..2bfd27e59
--- /dev/null
+++ b/lib/plugins/revert/lang/th/intro.txt
@@ -0,0 +1,3 @@
+====== ตัวจัดการกู้คืนสภาพเอกสาร ======
+
+หน้านี้จะช่วยคุณด้วยการกู้คืนหน้าที่ถูกแสปมโดยอัตโนมัติ เพื่อที่จะค้นหารายการหน้าที่ถูกสแปม อันดับแรกให้กรอกข้อความสืบค้น (เช่น URL เว็บโฆษณาที่มาสแปมไว้), จากนั้นให้ยืนยันว่าเพจที่พบนั้นถูกสแปมจริงๆ แล้วจึงสั่งคืนสภาพต้นฉบับ \ No newline at end of file
diff --git a/lib/plugins/revert/lang/th/lang.php b/lib/plugins/revert/lang/th/lang.php
new file mode 100644
index 000000000..86e4f9ca4
--- /dev/null
+++ b/lib/plugins/revert/lang/th/lang.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Arthit Suriyawongkul <arthit@gmail.com>
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['menu'] = 'ตัวจัดการคืนสภาพเอกสารฉบับเดิม';
+$lang['filter'] = 'ค้นหาเพจที่ถูกแสปม';
+$lang['revert'] = 'คืนสภาพเพจที่เลือกไว้';
+$lang['reverted'] = 'คืนสภาพ %s กลับไปเป็นฉบับ %s';
+$lang['removed'] = 'ถอดทิ้ง %s';
+$lang['revstart'] = 'กระบวนการคืนสภาพได้เริ่มต้นแล้ว นี่อาจต้องใช้เวลานาน ถ้าหมดเวลาที่กำหนดสำหรับสคริปต์ก่อนที่จะสำเร็จ คุณต้องไปทำการแบ่งข้อมูลให้เล็กลงเพื่อการคืนสภาพทีละส่วน';
+$lang['revstop'] = 'กระบวนการคืนสภาพสำเร็จเรียบร้อย';
+$lang['note1'] = 'คำเตือน: การค้นนี้นับตัวพิมพ์ใหญ่เล็ก (case sensitive)';
+$lang['note2'] = 'คำเตือน: เพจจะถูกคืนสภาพไปยังรุ่นล่าสุดที่ไม่มีประโยคสแปมนี้ <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/tr/intro.txt b/lib/plugins/revert/lang/tr/intro.txt
new file mode 100644
index 000000000..ff123995a
--- /dev/null
+++ b/lib/plugins/revert/lang/tr/intro.txt
@@ -0,0 +1,3 @@
+====== Eskiye Döndürme Yöneticisi ======
+
+Bu sayfa spam saldırılarına karşı otomatik eski haline çevirim yapmanızı sağlar. Spam içerikli sayfayı bulmak için bir anahtar kelime girin (mesela spam URLsi), daha sonra spame maruz kalan sayfalar olduğundan emin olup eski haline çevirin. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/tr/lang.php b/lib/plugins/revert/lang/tr/lang.php
new file mode 100644
index 000000000..aa1458a95
--- /dev/null
+++ b/lib/plugins/revert/lang/tr/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['menu'] = 'Eskiye Döndürme';
+$lang['filter'] = 'Spam bulunan sayfaları ara';
+$lang['revert'] = 'Seçili sayfaları eskiye döndür';
+$lang['reverted'] = '%s %s sürümüne geri çevrildi. ';
+$lang['removed'] = '%s kaldırıldı';
+$lang['revstart'] = 'Eskiye döndürme işlemi başlatıldı. Bu işlem uzun sürebilir. Eğer script işlemi tamamlayamadan zaman aşımına uğrarsa küçük parçalar halinde işlemi uygulayın.';
+$lang['revstop'] = 'Eskiye döndürme işlemi başarıyla tamamlandı.';
+$lang['note1'] = 'Not: bu aramada küçük harf büyük harf ayrımı vardır.';
+$lang['note2'] = 'Not: bu sayfa <i>%s</i> spam kelimelerini içermeyen son haline geri çevirilecektir.';
diff --git a/lib/plugins/revert/lang/uk/intro.txt b/lib/plugins/revert/lang/uk/intro.txt
new file mode 100644
index 000000000..7bf5dfcb9
--- /dev/null
+++ b/lib/plugins/revert/lang/uk/intro.txt
@@ -0,0 +1,3 @@
+====== Менеджер відновлення ======
+
+Ця сторінка дозволяє вам автоматично відновлюватися після спамерських атак. Для створення списку зіпсутих сторінок спочатку введіть рядок (напр. спамерське посилання), а потім підтвердіть, що знайдена сторінка дійсно є спамом і відновіть редагування. \ No newline at end of file
diff --git a/lib/plugins/revert/lang/uk/lang.php b/lib/plugins/revert/lang/uk/lang.php
new file mode 100644
index 000000000..310f8e8da
--- /dev/null
+++ b/lib/plugins/revert/lang/uk/lang.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Ukrainian language file
+ *
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ * @author Kate Arzamastseva pshns@ukr.net
+ */
+$lang['menu'] = 'Менеджер відновлення';
+$lang['filter'] = 'Пошук спамних сторінок';
+$lang['revert'] = 'Відновити обрані сторінки';
+$lang['reverted'] = '%s відновлено до версії %s';
+$lang['removed'] = '%s вилучено';
+$lang['revstart'] = 'Розпочато процес відновлення. Це може зайняти багато часу. Якщо скрипт не закінчує роботу до таймауту, необхідно відновлювати меншими частинами.';
+$lang['revstop'] = 'Процес відновлення успішно закінчено.';
+$lang['note1'] = 'Увага: пошук залежить від регістру символів';
+$lang['note2'] = 'Увага: сторінку буде відновлено до останньої версії, яка не містить спамерського терміну <i>%s</i>.';
diff --git a/lib/plugins/revert/lang/zh-tw/intro.txt b/lib/plugins/revert/lang/zh-tw/intro.txt
new file mode 100644
index 000000000..17632b1dd
--- /dev/null
+++ b/lib/plugins/revert/lang/zh-tw/intro.txt
@@ -0,0 +1,3 @@
+====== 還原管理器 ======
+
+本頁面能幫助您自動還原被垃圾訊息攻擊的頁面過來。先輸入關鍵字詞搜尋包含垃圾訊息的頁面(如垃圾訊息的 URL),確認找到的頁面確實包含垃圾訊息,再將它們還原。
diff --git a/lib/plugins/revert/lang/zh-tw/lang.php b/lib/plugins/revert/lang/zh-tw/lang.php
new file mode 100644
index 000000000..a853ccd2e
--- /dev/null
+++ b/lib/plugins/revert/lang/zh-tw/lang.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Chinese Traditional language file
+ *
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin <danny0838@pchome.com.tw>
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '還原管理';
+$lang['filter'] = '搜索包含垃圾訊息的頁面';
+$lang['revert'] = '還原選取的頁面';
+$lang['reverted'] = '%s 已還原為版本 %s';
+$lang['removed'] = '%s 已移除';
+$lang['revstart'] = '已開始還原操作。有可能需要很長時間。如果程式執行逾時,請嘗試分次還原少量內容。';
+$lang['revstop'] = '還原程序已成功完成。';
+$lang['note1'] = '注意:搜尋區分大小寫';
+$lang['note2'] = '注意:此頁面將被還原為最後一個不含垃圾訊息 <i>%s</i> 的版本。';
diff --git a/lib/plugins/revert/lang/zh/intro.txt b/lib/plugins/revert/lang/zh/intro.txt
new file mode 100644
index 000000000..c697f8aea
--- /dev/null
+++ b/lib/plugins/revert/lang/zh/intro.txt
@@ -0,0 +1,3 @@
+====== 还原管理器 ======
+
+该页面能帮助您的页面从垃圾信息的攻击中自动还原过来。 请先输入关键词搜索包含垃圾信息的页面(如某个垃圾信息的 URL),然后请确定搜索结果的确包含垃圾信息,并将其还原至先前的修订版。
diff --git a/lib/plugins/revert/lang/zh/lang.php b/lib/plugins/revert/lang/zh/lang.php
new file mode 100644
index 000000000..d4d010f29
--- /dev/null
+++ b/lib/plugins/revert/lang/zh/lang.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Chinese(Simplified) language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '还原管理器';
+$lang['filter'] = '搜索包含垃圾信息的页面';
+$lang['revert'] = '还原选中的页面';
+$lang['reverted'] = '%s 还原至修订版 %s';
+$lang['removed'] = '%s 已移除';
+$lang['revstart'] = '已开始还原操作。有可能需要很长时间。如果计时器在还原操作完成前停止了,请尝试还原较少的内容。';
+$lang['revstop'] = '还原操作成功完成。';
+$lang['note1'] = '请注意:本次搜索区分大小写';
+$lang['note2'] = '请注意:本页面将被还原至不包含给定垃圾信息 <i>%s</i> 的最近的修订版。';
diff --git a/lib/plugins/revert/plugin.info.txt b/lib/plugins/revert/plugin.info.txt
new file mode 100644
index 000000000..5bb6f3413
--- /dev/null
+++ b/lib/plugins/revert/plugin.info.txt
@@ -0,0 +1,6 @@
+author Andreas Gohr
+email andi@splitbrain.org
+date 2008-12-10
+name Revert Manager
+desc Allows you to mass revert recent edits
+url http://dokuwiki.org/plugin:revert
diff --git a/lib/plugins/safefnrecode/action.php b/lib/plugins/safefnrecode/action.php
new file mode 100644
index 000000000..5d3eaae3a
--- /dev/null
+++ b/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>
+ */
+
+// must be run within Dokuwiki
+if (!defined('DOKU_INC')) die();
+
+require_once DOKU_PLUGIN.'action.php';
+
+class action_plugin_safefnrecode extends DokuWiki_Action_Plugin {
+
+ public function register(Doku_Event_Handler &$controller) {
+
+ $controller->register_hook('INDEXER_TASKS_RUN', 'BEFORE', $this, 'handle_indexer_tasks_run');
+
+ }
+
+ public function handle_indexer_tasks_run(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);
+ }
+
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/lib/plugins/safefnrecode/plugin.info.txt b/lib/plugins/safefnrecode/plugin.info.txt
new file mode 100644
index 000000000..b1600060c
--- /dev/null
+++ b/lib/plugins/safefnrecode/plugin.info.txt
@@ -0,0 +1,7 @@
+base safefnrecode
+author Andreas Gohr
+email andi@splitbrain.org
+date 2011-04-03
+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/lib/plugins/syntax.php b/lib/plugins/syntax.php
new file mode 100644
index 000000000..12451f636
--- /dev/null
+++ b/lib/plugins/syntax.php
@@ -0,0 +1,282 @@
+<?php
+/**
+ * Syntax Plugin Prototype
+ *
+ * @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();
+
+/**
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ */
+class DokuWiki_Syntax_Plugin extends Doku_Parser_Mode {
+
+ var $allowedModesSetup = false;
+ var $localised = false; // set to true by setupLocale() after loading language dependent strings
+ var $lang = array(); // array to hold language dependent strings, best accessed via ->getLang()
+ var $configloaded = false; // set to true by loadConfig() after loading plugin configuration variables
+ var $conf = array(); // array to hold plugin settings, best accessed via ->getConf()
+
+ /**
+ * General Info
+ *
+ * Needs to return a associative array with the following values:
+ *
+ * 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)
+ */
+ function getInfo(){
+ $parts = explode('_',get_class($this));
+ $info = DOKU_PLUGIN.'/'.$parts[2].'/plugin.info.txt';
+ if(@file_exists($info)) return confToHash($info);
+ trigger_error('getInfo() not implemented in '.get_class($this).' and '.$info.' not found', E_USER_WARNING);
+ }
+
+ /**
+ * Syntax Type
+ *
+ * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
+ */
+ function getType(){
+ trigger_error('getType() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ /**
+ * 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
+ */
+ 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
+ */
+ 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 $match string The text matched by the patterns
+ * @param $state int The lexer state for the match
+ * @param $pos int The character position of the matched text
+ * @param $handler ref Reference to the Doku_Handler object
+ * @return array Return an array with all data you want to use in render
+ */
+ function handle($match, $state, $pos, &$handler){
+ trigger_error('handle() not implemented in '.get_class($this), E_USER_WARNING);
+ }
+
+ /**
+ * 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 $format string output format being rendered
+ * @param $renderer ref reference to the current renderer object
+ * @param $data array data created by handler()
+ * @return boolean rendered correctly?
+ */
+ function render($format, &$renderer, $data) {
+ trigger_error('render() not implemented in '.get_class($this), E_USER_WARNING);
+
+ }
+
+ /**
+ * There should be no need to override these functions
+ */
+ 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);
+ }
+
+ // plugin introspection methods
+ // extract from class name, format = <plugin type>_plugin_<name>[_<component name>]
+ function getPluginType() { list($t) = explode('_', get_class($this), 2); return $t; }
+ function getPluginName() { list($t, $p, $n) = explode('_', get_class($this), 4); return $n; }
+ function getPluginComponent() { list($t, $p, $n, $c) = explode('_', get_class($this), 4); return (isset($c)?$c:''); }
+
+ // localisation methods
+ /**
+ * getLang($id)
+ *
+ * use this function to 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 $id id of the string to be retrieved
+ * @return string string in appropriate language or english if not available
+ */
+ function getLang($id) {
+ if (!$this->localised) $this->setupLocale();
+
+ return (isset($this->lang[$id]) ? $this->lang[$id] : '');
+ }
+
+ /**
+ * locale_xhtml($id)
+ *
+ * retrieve a language dependent wiki page and pass to xhtml renderer for display
+ * plugin equivalent of p_locale_xhtml()
+ *
+ * @param $id id of language dependent wiki page
+ * @return string parsed contents of the wiki page in xhtml format
+ */
+ function locale_xhtml($id) {
+ return p_cached_output($this->localFN($id));
+ }
+
+ /**
+ * localFN($id)
+ * prepends appropriate path for a language dependent filename
+ * plugin equivalent of localFN()
+ */
+ function localFN($id) {
+ global $conf;
+ $plugin = $this->getPluginName();
+ $file = DOKU_CONF.'/plugin_lang/'.$plugin.'/'.$conf['lang'].'/'.$id.'.txt';
+ if (!@file_exists($file)){
+ $file = DOKU_PLUGIN.$plugin.'/lang/'.$conf['lang'].'/'.$id.'.txt';
+ if(!@file_exists($file)){
+ //fall back to english
+ $file = DOKU_PLUGIN.$plugin.'/lang/en/'.$id.'.txt';
+ }
+ }
+ return $file;
+ }
+
+ /**
+ * setupLocale()
+ * reads all the plugins language dependent strings into $this->lang
+ * this function is automatically called by getLang()
+ */
+ function setupLocale() {
+ if ($this->localised) return;
+
+ global $conf; // definitely don't invoke "global $lang"
+ $path = DOKU_PLUGIN.$this->getPluginName().'/lang/';
+
+ // don't include once, in case several plugin components require the same language file
+ @include($path.'en/lang.php');
+ if ($conf['lang'] != 'en') @include($path.$conf['lang'].'/lang.php');
+
+ $this->lang = $lang;
+ $this->localised = true;
+ }
+
+ // configuration methods
+ /**
+ * getConf($setting)
+ *
+ * use this function to access plugin configuration variables
+ */
+ function getConf($setting){
+
+ if (!$this->configloaded){ $this->loadConfig(); }
+
+ return $this->conf[$setting];
+ }
+
+ /**
+ * loadConfig()
+ * merges the plugin's default settings with any local settings
+ * this function is automatically called through getConf()
+ */
+ 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
+ */
+ function readDefaultSettings() {
+
+ $path = DOKU_PLUGIN.$this->getPluginName().'/conf/';
+ $conf = array();
+
+ if (@file_exists($path.'default.php')) {
+ include($path.'default.php');
+ }
+
+ return $conf;
+ }
+
+ /**
+ * Allow the plugin to prevent DokuWiki from reusing an instance
+ *
+ * @return bool false if the plugin has to be instantiated
+ */
+ function isSingleton() {
+ return true;
+ }
+
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/lib/plugins/usermanager/admin.php b/lib/plugins/usermanager/admin.php
new file mode 100644
index 000000000..8b646b426
--- /dev/null
+++ b/lib/plugins/usermanager/admin.php
@@ -0,0 +1,630 @@
+<?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>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+if(!defined('DOKU_PLUGIN_IMAGES')) define('DOKU_PLUGIN_IMAGES',DOKU_BASE.'lib/plugins/usermanager/images/');
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
+
+ var $_auth = null; // auth object
+ var $_user_total = 0; // number of registered users
+ var $_filter = array(); // user selection filter(s)
+ var $_start = 0; // index of first user to be displayed
+ var $_last = 0; // index of the last user to be displayed
+ var $_pagesize = 20; // number of users to list on one page
+ var $_edit_user = ''; // set to user selected for editing
+ var $_edit_userdata = array();
+ var $_disabled = ''; // if disabled set to explanatory string
+
+ /**
+ * Constructor
+ */
+ function admin_plugin_usermanager(){
+ global $auth;
+
+ $this->setupLocale();
+
+ if (!isset($auth)) {
+ $this->disabled = $this->lang['noauth'];
+ } else if (!$auth->canDo('getUsers')) {
+ $this->disabled = $this->lang['nosupport'];
+ } else {
+
+ // we're good to go
+ $this->_auth = & $auth;
+
+ }
+ }
+
+ /**
+ * return prompt for admin menu
+ */
+ 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
+ */
+ function getMenuSort() {
+ return 2;
+ }
+
+ /**
+ * handle user request
+ */
+ function handle() {
+ global $ID;
+
+ 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 = $_REQUEST['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") {
+ if (!empty($_REQUEST['start']))
+ $this->_start = $_REQUEST['start'];
+ $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;
+ }
+
+ $this->_user_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->_user_total; break;
+ }
+ $this->_validatePagination();
+ }
+
+ /**
+ * output appropriate html
+ */
+ 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);
+ $users = array_keys($user_list);
+
+ $page_buttons = $this->_pagination();
+ $delete_disable = $this->_auth->canDo('delUser') ? '' : 'disabled="disabled"';
+
+ $editable = $this->_auth->canDo('UserMod');
+
+ print $this->locale_xhtml('intro');
+ print $this->locale_xhtml('list');
+
+ ptln("<div id=\"user__manager\">");
+ ptln("<div class=\"level2\">");
+
+ if ($this->_user_total > 0) {
+ ptln("<p>".sprintf($this->lang['summary'],$this->_start+1,$this->_last,$this->_user_total,$this->_auth->getUserCount())."</p>");
+ } else {
+ ptln("<p>".sprintf($this->lang['nonefound'],$this->_auth->getUserCount())."</p>");
+ }
+ ptln("<form action=\"".wl($ID)."\" method=\"post\">");
+ formSecurityToken();
+ ptln(" <div class=\"table\">");
+ ptln(" <table class=\"inline\">");
+ ptln(" <thead>");
+ ptln(" <tr>");
+ ptln(" <th>&nbsp;</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=\"".DOKU_PLUGIN_IMAGES."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->_user_total) {
+ ptln(" <tbody>");
+ foreach ($user_list as $user => $userinfo) {
+ extract($userinfo);
+ $groups = join(', ',$grps);
+ ptln(" <tr class=\"user_info\">");
+ ptln(" <td class=\"centeralign\"><input type=\"checkbox\" name=\"delete[".$user."]\" ".$delete_disable." /></td>");
+ if ($editable) {
+ ptln(" <td><a href=\"".wl($ID,array('fn[edit]['.hsc($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(" <input type=\"submit\" name=\"fn[delete]\" ".$delete_disable." class=\"button\" value=\"".$this->lang['delete_selected']."\" id=\"usrmgr__del\" />");
+ ptln(" </span>");
+ ptln(" <span class=\"mediaright\">");
+ ptln(" <input type=\"submit\" name=\"fn[start]\" ".$page_buttons['start']." class=\"button\" value=\"".$this->lang['start']."\" />");
+ ptln(" <input type=\"submit\" name=\"fn[prev]\" ".$page_buttons['prev']." class=\"button\" value=\"".$this->lang['prev']."\" />");
+ ptln(" <input type=\"submit\" name=\"fn[next]\" ".$page_buttons['next']." class=\"button\" value=\"".$this->lang['next']."\" />");
+ ptln(" <input type=\"submit\" name=\"fn[last]\" ".$page_buttons['last']." class=\"button\" value=\"".$this->lang['last']."\" />");
+ ptln(" </span>");
+ ptln(" <input type=\"submit\" name=\"fn[search][clear]\" class=\"button\" value=\"".$this->lang['clear']."\" />");
+ 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>");
+ }
+ ptln("</div>");
+ }
+
+
+ /**
+ * @todo disable fields which the backend can't change
+ */
+ function _htmlUserForm($cmd,$user='',$userdata=array(),$indent=0) {
+ global $conf;
+ global $ID;
+
+ $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"), $indent+6);
+ $this->_htmlInputField($cmd."_userpass", "userpass", $this->lang["user_pass"], "", $this->_auth->canDo("modPass"), $indent+6);
+ $this->_htmlInputField($cmd."_username", "username", $this->lang["user_name"], $name, $this->_auth->canDo("modName"), $indent+6);
+ $this->_htmlInputField($cmd."_usermail", "usermail", $this->lang["user_mail"], $mail, $this->_auth->canDo("modMail"), $indent+6);
+ $this->_htmlInputField($cmd."_usergroups","usergroups",$this->lang["user_groups"],$groups,$this->_auth->canDo("modGroups"),$indent+6);
+
+ if ($this->_auth->canDo("modPass")) {
+ $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=\"".$user."\" />",$indent);
+
+ $this->_htmlFilterSettings($indent+10);
+
+ ptln(" <input type=\"submit\" name=\"fn[".$cmd."]\" class=\"button\" value=\"".$this->lang[$cmd]."\" />",$indent);
+ ptln(" </td>",$indent);
+ ptln(" </tr>",$indent);
+ ptln(" </tbody>",$indent);
+ ptln(" </table>",$indent);
+ ptln(" </div>",$indent);
+
+ foreach ($notes as $note)
+ ptln("<div class=\"fn\">".$note."</div>",$indent);
+
+ ptln("</form>",$indent);
+ }
+
+ function _htmlInputField($id, $name, $label, $value, $cando, $indent=0) {
+ $class = $cando ? '' : ' class="disabled"';
+ $disabled = $cando ? '' : ' disabled="disabled"';
+ echo str_pad('',$indent);
+
+ if($name == 'userpass'){
+ $fieldtype = 'password';
+ $autocomp = 'autocomplete="off"';
+ }else{
+ $fieldtype = 'text';
+ $autocomp = '';
+ }
+
+
+ echo "<tr $class>";
+ echo "<td><label for=\"$id\" >$label: </label></td>";
+ echo "<td>";
+ if($cando){
+ echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\" value=\"$value\" class=\"edit\" $autocomp />";
+ }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>";
+ }
+
+ function _htmlFilter($key) {
+ if (empty($this->_filter)) return '';
+ return (isset($this->_filter[$key]) ? hsc($this->_filter[$key]) : '');
+ }
+
+ 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);
+ }
+ }
+
+ function _addUser(){
+ if (!checkSecurityToken()) return false;
+ if (!$this->_auth->canDo('addUser')) return false;
+
+ list($user,$pass,$name,$mail,$grps) = $this->_retrieveUser();
+ if (empty($user)) return false;
+
+ if ($this->_auth->canDo('modPass')){
+ if (empty($pass)){
+ if(!empty($_REQUEST['usernotify'])){
+ $pass = auth_pwgen();
+ } else {
+ msg($this->lang['add_fail'], -1);
+ return false;
+ }
+ }
+ } else {
+ if (!empty($pass)){
+ msg($this->lang['add_fail'], -1);
+ return false;
+ }
+ }
+
+ if ($this->_auth->canDo('modName')){
+ if (empty($name)){
+ msg($this->lang['add_fail'], -1);
+ return false;
+ }
+ } else {
+ if (!empty($name)){
+ return false;
+ }
+ }
+
+ if ($this->_auth->canDo('modMail')){
+ if (empty($mail)){
+ msg($this->lang['add_fail'], -1);
+ return false;
+ }
+ } else {
+ if (!empty($mail)){
+ return false;
+ }
+ }
+
+ if ($ok = $this->_auth->triggerUserMod('create', array($user,$pass,$name,$mail,$grps))) {
+
+ msg($this->lang['add_ok'], 1);
+
+ if (!empty($_REQUEST['usernotify']) && $pass) {
+ $this->_notifyUser($user,$pass);
+ }
+ } else {
+ msg($this->lang['add_fail'], -1);
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Delete user
+ */
+ function _deleteUser(){
+ global $conf;
+
+ if (!checkSecurityToken()) return false;
+ if (!$this->_auth->canDo('delUser')) return false;
+
+ $selected = $_REQUEST['delete'];
+ if (!is_array($selected) || 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)
+ */
+ function _editUser($param) {
+ if (!checkSecurityToken()) return false;
+ if (!$this->_auth->canDo('UserMod')) return false;
+
+ $user = cleanID(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 (modified user data has been recieved)
+ */
+ function _modifyUser(){
+ global $conf;
+
+ if (!checkSecurityToken()) return false;
+ if (!$this->_auth->canDo('UserMod')) return false;
+
+ // get currently valid user data
+ $olduser = cleanID(preg_replace('/.*:/','',$_REQUEST['userid_old']));
+ $oldinfo = $this->_auth->getUserData($olduser);
+
+ // get new user data subject to change
+ list($newuser,$newpass,$newname,$newmail,$newgrps) = $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;
+ }
+ }
+
+ // generate password if left empty and notification is on
+ if(!empty($_REQUEST['usernotify']) && empty($newpass)){
+ $newpass = auth_pwgen();
+ }
+
+ if (!empty($newpass) && $this->_auth->canDo('modPass'))
+ $changes['pass'] = $newpass;
+ 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 (!empty($_REQUEST['usernotify']) && $newpass) {
+ $notify = empty($changes['user']) ? $olduser : $newuser;
+ $this->_notifyUser($notify,$newpass);
+ }
+
+ // 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
+ */
+ function _notifyUser($user, $password) {
+
+ if ($sent = auth_sendPassword($user,$password)) {
+ msg($this->lang['notify_ok'], 1);
+ } else {
+ msg($this->lang['notify_fail'], -1);
+ }
+
+ return $sent;
+ }
+
+ /**
+ * retrieve & clean user data from the form
+ *
+ * @return array(user, password, full name, email, array(groups))
+ */
+ function _retrieveUser($clean=true) {
+ global $auth;
+
+ $user[0] = ($clean) ? $auth->cleanUser($_REQUEST['userid']) : $_REQUEST['userid'];
+ $user[1] = $_REQUEST['userpass'];
+ $user[2] = $_REQUEST['username'];
+ $user[3] = $_REQUEST['usermail'];
+ $user[4] = explode(',',$_REQUEST['usergroups']);
+
+ $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;
+ }
+
+ 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);
+ }
+ }
+
+ function _retrieveFilter() {
+
+ $t_filter = $_REQUEST['filter'];
+ if (!is_array($t_filter)) return array();
+
+ // 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;
+ }
+
+ function _validatePagination() {
+
+ if ($this->_start >= $this->_user_total) {
+ $this->_start = $this->_user_total - $this->_pagesize;
+ }
+ if ($this->_start < 0) $this->_start = 0;
+
+ $this->_last = min($this->_user_total, $this->_start + $this->_pagesize);
+ }
+
+ /*
+ * return an array of strings to enable/disable pagination buttons
+ */
+ function _pagination() {
+
+ $disabled = 'disabled="disabled"';
+
+ $buttons['start'] = $buttons['prev'] = ($this->_start == 0) ? $disabled : '';
+
+ if ($this->_user_total == -1) {
+ $buttons['last'] = $disabled;
+ $buttons['next'] = '';
+ } else {
+ $buttons['last'] = $buttons['next'] = (($this->_start + $this->_pagesize) >= $this->_user_total) ? $disabled : '';
+ }
+
+ return $buttons;
+ }
+}
diff --git a/lib/plugins/usermanager/images/search.png b/lib/plugins/usermanager/images/search.png
new file mode 100644
index 000000000..e9dabc11e
--- /dev/null
+++ b/lib/plugins/usermanager/images/search.png
Binary files differ
diff --git a/lib/plugins/usermanager/lang/af/lang.php b/lib/plugins/usermanager/lang/af/lang.php
new file mode 100644
index 000000000..9a6c5666d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/af/lang.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Afrikaans language file
+ *
+ */
+$lang['user_pass'] = 'Wagwoord';
+$lang['user_name'] = 'Regte Naam';
+$lang['user_mail'] = 'E-pos';
+$lang['edit'] = 'Verander';
+$lang['search'] = 'Soek';
+$lang['start'] = 'begin';
+$lang['prev'] = 'voorigste';
+$lang['next'] = 'volgende';
+$lang['last'] = 'einde';
diff --git a/lib/plugins/usermanager/lang/ar/add.txt b/lib/plugins/usermanager/lang/ar/add.txt
new file mode 100644
index 000000000..14a10a27d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/add.txt
@@ -0,0 +1 @@
+==== إضافة حساب ==== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ar/delete.txt b/lib/plugins/usermanager/lang/ar/delete.txt
new file mode 100644
index 000000000..d44bb9fda
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/delete.txt
@@ -0,0 +1 @@
+==== حذف الحساب ==== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ar/edit.txt b/lib/plugins/usermanager/lang/ar/edit.txt
new file mode 100644
index 000000000..bd9876d82
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/edit.txt
@@ -0,0 +1 @@
+==== تعديل المستخدم ==== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ar/intro.txt b/lib/plugins/usermanager/lang/ar/intro.txt
new file mode 100644
index 000000000..1cfb841fa
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/intro.txt
@@ -0,0 +1 @@
+====== مدير المستخدمين ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ar/lang.php b/lib/plugins/usermanager/lang/ar/lang.php
new file mode 100644
index 000000000..d4b891320
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Arabic language file
+ *
+ * @author Yaman Hokan <always.smile.yh@hotmail.com>
+ * @author Usama Akkad <uahello@gmail.com>
+ * @author uahello@gmail.com
+ */
+$lang['menu'] = 'مدير المستخدمين';
+$lang['noauth'] = '(مصادقة المستخدمين غير متوفرة)';
+$lang['nosupport'] = '(إدارة المستخدمين غير متوفرة)';
+$lang['badauth'] = 'آلية مصادقة غير صالحة';
+$lang['user_id'] = 'اسم المستخدم';
+$lang['user_pass'] = 'كلمة السر';
+$lang['user_name'] = 'الاسم الحقيقي';
+$lang['user_mail'] = 'البريد الالكتروني';
+$lang['user_groups'] = 'المجموعات';
+$lang['field'] = 'حقل';
+$lang['value'] = 'القيمة';
+$lang['add'] = 'إضافة';
+$lang['delete'] = 'حذف';
+$lang['delete_selected'] = 'حذف المختار';
+$lang['edit'] = 'تحرير';
+$lang['edit_prompt'] = 'حرر هذا المستخدم';
+$lang['modify'] = 'حفظ التعديلات';
+$lang['search'] = 'بحث';
+$lang['search_prompt'] = 'ابدأ البحث';
+$lang['clear'] = 'صفّر مرشح البحث';
+$lang['filter'] = 'المرشّح';
+$lang['summary'] = 'عرض المستخدمين %1$d-%2$d of %3$d وجد. %4$d مستخدم كلي.';
+$lang['nonefound'] = 'لم يوجد مستخدمين. %d مستخدم كليا.';
+$lang['delete_ok'] = '%d مستخدم حذفوا';
+$lang['delete_fail'] = '%d فشل حذفهم.';
+$lang['update_ok'] = 'حُدث المستخدم بنجاح';
+$lang['update_fail'] = 'فشل تحديث المستخدم';
+$lang['update_exists'] = 'لقد فشل تغيير اسم المستخدم , اسم المستخدم المحدد (%s) غير متاح . ( سيتم تطبيق أي تغييرات أخرى )';
+$lang['start'] = 'ابدأ';
+$lang['prev'] = 'السابق';
+$lang['next'] = 'التالي';
+$lang['last'] = 'الأخير';
+$lang['edit_usermissing'] = 'لم يعثر على المستخدم المحدد، يحتمل أن اسم المستخدم قد حذف أو غُير في مكان آخر.';
+$lang['user_notify'] = 'أشعر المستخدم';
+$lang['note_notify'] = 'بريد الاشعار يرسل فقط إن اعطي المستخدم كلمة سر جديدة.';
+$lang['note_group'] = 'المستخدمون الجدد سيضافون للمجموعة الافتراضية (%s) إن لم تُحدد لهم مجموعة.';
+$lang['note_pass'] = 'ستولد كلمة المرور تلقائيا إن تُرك الحقل فارغا مع تمكين إشعار المستخدم.';
+$lang['add_ok'] = 'اضيف المستخدم بنجاح';
+$lang['add_fail'] = 'فشلت إضافة المستخدم';
+$lang['notify_ok'] = 'ارسلت رسالة الاشعار';
+$lang['notify_fail'] = 'تعذر ارسال بريد الاشعار';
diff --git a/lib/plugins/usermanager/lang/ar/list.txt b/lib/plugins/usermanager/lang/ar/list.txt
new file mode 100644
index 000000000..02e9a0363
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ar/list.txt
@@ -0,0 +1 @@
+===== قائمة المستخدمين ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/bg/add.txt b/lib/plugins/usermanager/lang/bg/add.txt
new file mode 100644
index 000000000..e0678198b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/add.txt
@@ -0,0 +1 @@
+===== Добавяне на потребител =====
diff --git a/lib/plugins/usermanager/lang/bg/delete.txt b/lib/plugins/usermanager/lang/bg/delete.txt
new file mode 100644
index 000000000..aa60fc3df
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/delete.txt
@@ -0,0 +1 @@
+===== Изтриване на потребител =====
diff --git a/lib/plugins/usermanager/lang/bg/edit.txt b/lib/plugins/usermanager/lang/bg/edit.txt
new file mode 100644
index 000000000..652d03617
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/edit.txt
@@ -0,0 +1 @@
+===== Редактиране на потребител =====
diff --git a/lib/plugins/usermanager/lang/bg/intro.txt b/lib/plugins/usermanager/lang/bg/intro.txt
new file mode 100644
index 000000000..0a9afd513
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/intro.txt
@@ -0,0 +1 @@
+====== Управление на потребителите ======
diff --git a/lib/plugins/usermanager/lang/bg/lang.php b/lib/plugins/usermanager/lang/bg/lang.php
new file mode 100644
index 000000000..9ed27f42a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * bulgarian language file
+ *
+ * @author Nikolay Vladimirov <nikolay@vladimiroff.com>
+ * @author Viktor Usunov <usun0v@mail.bg>
+ * @author Kiril <neohidra@gmail.com>
+ */
+$lang['menu'] = 'Диспечер на потребителите';
+$lang['noauth'] = '(удостоверяването на потребители не е налично)';
+$lang['nosupport'] = '(управлението на потребители не се поддържа)';
+$lang['badauth'] = 'невалиден механизъм за удостоверяване';
+$lang['user_id'] = 'Потребител';
+$lang['user_pass'] = 'Парола';
+$lang['user_name'] = 'Истинско име';
+$lang['user_mail'] = 'Електронна поща';
+$lang['user_groups'] = 'Групи';
+$lang['field'] = 'Поле';
+$lang['value'] = 'Стойност';
+$lang['add'] = 'Добави';
+$lang['delete'] = 'Изтрий';
+$lang['delete_selected'] = 'Изтрий избраните';
+$lang['edit'] = 'Редактирай';
+$lang['edit_prompt'] = 'Редактиране на потребителя';
+$lang['modify'] = 'Запиши промените';
+$lang['search'] = 'Търсене';
+$lang['search_prompt'] = 'Търси';
+$lang['clear'] = 'Обновяване на търсенето';
+$lang['filter'] = 'Филтър';
+$lang['summary'] = 'Показване на потребители %1$d-%2$d от %3$d намерени. Общо %4$d потребителя.';
+$lang['nonefound'] = 'Не са намерени потребители. Общо %d потребителя.';
+$lang['delete_ok'] = '%d изтрити потребителя';
+$lang['delete_fail'] = 'изтриването на %d се провали.';
+$lang['update_ok'] = 'Обновяването на потребителя е успешно';
+$lang['update_fail'] = 'Обновяването на потребителя се провали';
+$lang['update_exists'] = 'Смяната на потребителското име се провали, въведеното потребителско име (%s) вече съществува (всички други промени ще бъдат приложени).';
+$lang['start'] = 'начало';
+$lang['prev'] = 'назад';
+$lang['next'] = 'напред';
+$lang['last'] = 'край';
+$lang['edit_usermissing'] = 'Избраният потребител не е намерен, въведеното потребителско име може да е изтрито или променено другаде.';
+$lang['user_notify'] = 'Уведомяване на потребителя';
+$lang['note_notify'] = 'Ел. писмо се изпраща само ако бъде променена паролата на потребителя.';
+$lang['note_group'] = 'Новите потребители биват добавяни към стандартната групата (%s) ако не е посочена друга.';
+$lang['note_pass'] = 'Паролата ще бъде генерирана автоматично, ако оставите полето празно и функцията за уведомяване на потребителя е включена.';
+$lang['add_ok'] = 'Добавянето на потребителя е успешно';
+$lang['add_fail'] = 'Добавянето на потребителя се провали';
+$lang['notify_ok'] = 'Изпратено е осведомително ел. писмо';
+$lang['notify_fail'] = 'Изпращането на осведомително ел. писмо не е възможно';
diff --git a/lib/plugins/usermanager/lang/bg/list.txt b/lib/plugins/usermanager/lang/bg/list.txt
new file mode 100644
index 000000000..106856c0e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/bg/list.txt
@@ -0,0 +1 @@
+===== Списък на потребителите =====
diff --git a/lib/plugins/usermanager/lang/ca-valencia/add.txt b/lib/plugins/usermanager/lang/ca-valencia/add.txt
new file mode 100644
index 000000000..df5ba9235
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/add.txt
@@ -0,0 +1 @@
+===== Afegir usuari =====
diff --git a/lib/plugins/usermanager/lang/ca-valencia/delete.txt b/lib/plugins/usermanager/lang/ca-valencia/delete.txt
new file mode 100644
index 000000000..f386b589a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/delete.txt
@@ -0,0 +1 @@
+===== Borrar usuari =====
diff --git a/lib/plugins/usermanager/lang/ca-valencia/edit.txt b/lib/plugins/usermanager/lang/ca-valencia/edit.txt
new file mode 100644
index 000000000..6b78c127f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/edit.txt
@@ -0,0 +1 @@
+===== Editar usuari =====
diff --git a/lib/plugins/usermanager/lang/ca-valencia/intro.txt b/lib/plugins/usermanager/lang/ca-valencia/intro.txt
new file mode 100644
index 000000000..540a0702e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/intro.txt
@@ -0,0 +1 @@
+====== Gestor d'usuaris ======
diff --git a/lib/plugins/usermanager/lang/ca-valencia/lang.php b/lib/plugins/usermanager/lang/ca-valencia/lang.php
new file mode 100644
index 000000000..5b0c628ed
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Valencian language file
+ *
+ * @author Bernat Arlandis i Mañó <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@ya.com>
+ * @author Bernat Arlandis <berarma@llenguaitecnologia.com>
+ */
+$lang['menu'] = 'Gestor d\'usuaris';
+$lang['noauth'] = '(autenticació d\'usuaris no disponible)';
+$lang['nosupport'] = '(gestió d\'usuaris no admesa)';
+$lang['badauth'] = 'mecanisme d\'autenticació no vàlit';
+$lang['user_id'] = 'Usuari';
+$lang['user_pass'] = 'Contrasenya';
+$lang['user_name'] = 'Nom real';
+$lang['user_mail'] = 'Correu electrònic';
+$lang['user_groups'] = 'Grups';
+$lang['field'] = 'Camp';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Afegir';
+$lang['delete'] = 'Borrar';
+$lang['delete_selected'] = 'Borrar seleccionats';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar est usuari';
+$lang['modify'] = 'Guardar canvis';
+$lang['search'] = 'Buscar';
+$lang['search_prompt'] = 'Començar busca';
+$lang['clear'] = 'Reiniciar filtre de busques';
+$lang['filter'] = 'Filtre';
+$lang['summary'] = 'Mostrant usuaris %1$d-%2$d de %3$d trobats. %4$d usuaris totals.';
+$lang['nonefound'] = 'No s\'han trobat usuaris. %d usuaris totals.';
+$lang['delete_ok'] = '%d usuaris borrats';
+$lang['delete_fail'] = 'Erro borrant %d.';
+$lang['update_ok'] = 'Usuari actualisat correctament';
+$lang['update_fail'] = 'Erro actualisant usuari';
+$lang['update_exists'] = 'Erro canviant el nom de l\'usuari, el nom d\'usuari que ha donat ya existix (els demés canvis s\'aplicaran).';
+$lang['start'] = 'primera';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'següent';
+$lang['last'] = 'última';
+$lang['edit_usermissing'] = 'L\'usuari seleccionat no existix, pot haver segut borrat o modificat des d\'un atre lloc.';
+$lang['user_notify'] = 'Notificar a l\'usuari';
+$lang['note_notify'] = 'Els correus de notificació només s\'envien si a l\'usuari se li assigna una contrasenya nova.';
+$lang['note_group'] = 'Els usuaris nous s\'afegiran al grup predeterminat (%s) si no se n\'especifica atre.';
+$lang['note_pass'] = 'Si es deixa el camp buit i la notificació a l\'usuari està desactivada s\'autogenerarà la contrasenya.';
+$lang['add_ok'] = 'Usuari afegit correctament';
+$lang['add_fail'] = 'Erro afegint usuari';
+$lang['notify_ok'] = 'Correu de notificació enviat';
+$lang['notify_fail'] = 'Erro enviant el correu de notificació';
diff --git a/lib/plugins/usermanager/lang/ca-valencia/list.txt b/lib/plugins/usermanager/lang/ca-valencia/list.txt
new file mode 100644
index 000000000..15af2d56f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca-valencia/list.txt
@@ -0,0 +1 @@
+===== Llista d'usuaris =====
diff --git a/lib/plugins/usermanager/lang/ca/add.txt b/lib/plugins/usermanager/lang/ca/add.txt
new file mode 100644
index 000000000..07c599476
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/add.txt
@@ -0,0 +1 @@
+===== Nou usuari ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ca/delete.txt b/lib/plugins/usermanager/lang/ca/delete.txt
new file mode 100644
index 000000000..90878e563
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/delete.txt
@@ -0,0 +1 @@
+===== Supressió d'usuari ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ca/edit.txt b/lib/plugins/usermanager/lang/ca/edit.txt
new file mode 100644
index 000000000..f7dc8cb8e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/edit.txt
@@ -0,0 +1 @@
+===== Edició d'usuari ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ca/intro.txt b/lib/plugins/usermanager/lang/ca/intro.txt
new file mode 100644
index 000000000..864aa1008
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/intro.txt
@@ -0,0 +1 @@
+======= Gestió d'usuaris ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ca/lang.php b/lib/plugins/usermanager/lang/ca/lang.php
new file mode 100644
index 000000000..445556973
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Catalan language file
+ *
+ * @author Carles Bellver <carles.bellver@gmail.com>
+ * @author carles.bellver@gmail.com
+ * @author carles.bellver@cent.uji.es
+ * @author Carles Bellver <carles.bellver@cent.uji.es>
+ */
+$lang['menu'] = 'Gestió d\'usuaris';
+$lang['noauth'] = '(l\'autenticació d\'usuaris no està disponible)';
+$lang['nosupport'] = '(la gestió d\'usuaris no funciona)';
+$lang['badauth'] = 'el mecanisme d\'autenticació no és vàlid';
+$lang['user_id'] = 'Usuari';
+$lang['user_pass'] = 'Contrasenya';
+$lang['user_name'] = 'Nom real';
+$lang['user_mail'] = 'Correu electrònic';
+$lang['user_groups'] = 'Grups';
+$lang['field'] = 'Camp';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Afegeix';
+$lang['delete'] = 'Suprimeix';
+$lang['delete_selected'] = 'Suprimeix els seleccionats';
+$lang['edit'] = 'Edita';
+$lang['edit_prompt'] = 'Edita aquest usuari';
+$lang['modify'] = 'Desa els canvis';
+$lang['search'] = 'Cerca';
+$lang['search_prompt'] = 'Fes la cerca';
+$lang['clear'] = 'Reinicia el filtre de cerca';
+$lang['filter'] = 'Filtre';
+$lang['summary'] = 'Visualització d\'usuaris %1$d-%2$d de %3$d trobats. %4$d usuaris en total.';
+$lang['nonefound'] = 'No s\'han trobat usuaris. %d usuaris en total.';
+$lang['delete_ok'] = 'S\'han suprimit %d usuaris';
+$lang['delete_fail'] = 'No s\'han pogut suprimir %d.';
+$lang['update_ok'] = 'L\'usuari ha estat actualitzat amb èxit';
+$lang['update_fail'] = 'Ha fallat l\'actualització de l\'usuari';
+$lang['update_exists'] = 'No s\'ha pogut canviar el nom de l\'usuari. El nom d\'usuari especificat (%s) ja existeix (qualsevol altre canvi sí que serà efectiu).';
+$lang['start'] = 'inici';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'següent';
+$lang['last'] = 'final';
+$lang['edit_usermissing'] = 'L\'usuari seleccionat no s\'ha pogut trobar. Potser el nom d\'usuari especificat s\'ha suprimit o modificat des d\'un altre lloc.';
+$lang['user_notify'] = 'Notificació a l\'usuari';
+$lang['note_notify'] = 'Els correus de notificació només s\'envien si es canvia la contrasenya de l\'usuari.';
+$lang['note_group'] = 'Els nous usuaris s\'afegeixen al grup per defecte (%s) si no s\'especifica un altre grup.';
+$lang['note_pass'] = 'La contrasenya es generarà automàticament si el camp es deixa en blanc i les notificacions estan habilitades per a aquest usuari.';
+$lang['add_ok'] = 'L\'usuari s\'ha afegit amb èxit';
+$lang['add_fail'] = 'No s\'ha pogut afegir l\'usuari';
+$lang['notify_ok'] = 'S\'ha enviat el correu de notificació';
+$lang['notify_fail'] = 'No s\'ha pogut enviar el correu de notificació';
diff --git a/lib/plugins/usermanager/lang/ca/list.txt b/lib/plugins/usermanager/lang/ca/list.txt
new file mode 100644
index 000000000..22e1587f4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ca/list.txt
@@ -0,0 +1 @@
+===== Llista d'usuaris ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/cs/add.txt b/lib/plugins/usermanager/lang/cs/add.txt
new file mode 100644
index 000000000..39b14d554
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/add.txt
@@ -0,0 +1 @@
+===== Přidat uživatele =====
diff --git a/lib/plugins/usermanager/lang/cs/delete.txt b/lib/plugins/usermanager/lang/cs/delete.txt
new file mode 100644
index 000000000..a8790d87d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/delete.txt
@@ -0,0 +1 @@
+===== Smazat uživatele =====
diff --git a/lib/plugins/usermanager/lang/cs/edit.txt b/lib/plugins/usermanager/lang/cs/edit.txt
new file mode 100644
index 000000000..d8ba38605
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/edit.txt
@@ -0,0 +1 @@
+===== Upravit uživatele =====
diff --git a/lib/plugins/usermanager/lang/cs/intro.txt b/lib/plugins/usermanager/lang/cs/intro.txt
new file mode 100644
index 000000000..5b8f6e90b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/intro.txt
@@ -0,0 +1 @@
+====== Správa uživatelů ======
diff --git a/lib/plugins/usermanager/lang/cs/lang.php b/lib/plugins/usermanager/lang/cs/lang.php
new file mode 100644
index 000000000..fe54d4cce
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Czech language file
+ *
+ * @author Tomas Valenta <t.valenta@sh.cvut.cz>
+ * @author Zbynek Krivka <zbynek.krivka@seznam.cz>
+ * @author Bohumir Zamecnik <bohumir@zamecnik.org>
+ * @author tomas@valenta.cz
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @author Lefty <lefty@multihost.cz>
+ * @author Vojta Beran <xmamut@email.cz>
+ * @author zbynek.krivka@seznam.cz
+ */
+$lang['menu'] = 'Správa uživatelů';
+$lang['noauth'] = '(autentizace uživatelů není k dispozici)';
+$lang['nosupport'] = '(správa uživatelů není podporována)';
+$lang['badauth'] = 'chybná metoda autentizace';
+$lang['user_id'] = 'Uživatel';
+$lang['user_pass'] = 'Heslo';
+$lang['user_name'] = 'Celé jméno';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Skupiny';
+$lang['field'] = 'Položka';
+$lang['value'] = 'Hodnota';
+$lang['add'] = 'Přidat';
+$lang['delete'] = 'Smazat';
+$lang['delete_selected'] = 'Smazat vybrané';
+$lang['edit'] = 'Upravit';
+$lang['edit_prompt'] = 'Upravit uživatele';
+$lang['modify'] = 'Uložit změny';
+$lang['search'] = 'Hledání';
+$lang['search_prompt'] = 'Prohledat';
+$lang['clear'] = 'Zrušit vyhledávací filtr';
+$lang['filter'] = 'Filtr';
+$lang['summary'] = 'Zobrazuji uživatele %1$d-%2$d z %3$d nalezených. Celkem %4$d uživatelů.';
+$lang['nonefound'] = 'Žadný uživatel nenalezen. Celkem %d uživatelů.';
+$lang['delete_ok'] = '%d uživatelů smazáno';
+$lang['delete_fail'] = '%d uživatelů nelze smazat.';
+$lang['update_ok'] = 'Uživatel upraven';
+$lang['update_fail'] = 'Úprava uživatele selhala';
+$lang['update_exists'] = 'Jméno nelze změnit, jelikož zadané uživatelské jméno (%s) již existuje (ostatní změny ale budou provedeny).';
+$lang['start'] = 'první';
+$lang['prev'] = 'předchozí';
+$lang['next'] = 'další';
+$lang['last'] = 'poslední';
+$lang['edit_usermissing'] = 'Vybraný uživatel nebyl nalezen, zadané uživatelského mohlo být smazáno nebo změněno.';
+$lang['user_notify'] = 'Upozornit uživatele';
+$lang['note_notify'] = 'Maily s upozorněním se budou posílat pouze, když uživatel dostává nové heslo.';
+$lang['note_group'] = 'Noví uživatelé budou přidáváni do této výchozí skupiny (%s), pokud pro ně není uvedena žádná skupina.';
+$lang['note_pass'] = 'Heslo bude automaticky vygenerováno pokud je pole ponecháno prázdné a je zapnutá notifikace uživatele.';
+$lang['add_ok'] = 'Uživatel úspěšně vytvořen';
+$lang['add_fail'] = 'Vytvoření uživatele selhalo';
+$lang['notify_ok'] = 'Odeslán mail s upozorněním';
+$lang['notify_fail'] = 'Mail s upozorněním nebylo možno odeslat';
diff --git a/lib/plugins/usermanager/lang/cs/list.txt b/lib/plugins/usermanager/lang/cs/list.txt
new file mode 100644
index 000000000..36b87fed9
--- /dev/null
+++ b/lib/plugins/usermanager/lang/cs/list.txt
@@ -0,0 +1 @@
+===== Seznam uživatelů =====
diff --git a/lib/plugins/usermanager/lang/da/add.txt b/lib/plugins/usermanager/lang/da/add.txt
new file mode 100644
index 000000000..d97de4248
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/add.txt
@@ -0,0 +1 @@
+===== Tilføj bruger =====
diff --git a/lib/plugins/usermanager/lang/da/delete.txt b/lib/plugins/usermanager/lang/da/delete.txt
new file mode 100644
index 000000000..dff05454c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/delete.txt
@@ -0,0 +1 @@
+===== Slet bruger =====
diff --git a/lib/plugins/usermanager/lang/da/edit.txt b/lib/plugins/usermanager/lang/da/edit.txt
new file mode 100644
index 000000000..05d63b7b0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/edit.txt
@@ -0,0 +1 @@
+===== Rediger bruger =====
diff --git a/lib/plugins/usermanager/lang/da/intro.txt b/lib/plugins/usermanager/lang/da/intro.txt
new file mode 100644
index 000000000..3f597a243
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/intro.txt
@@ -0,0 +1 @@
+====== Brugerstyring ======
diff --git a/lib/plugins/usermanager/lang/da/lang.php b/lib/plugins/usermanager/lang/da/lang.php
new file mode 100644
index 000000000..ea3109374
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Danish language file
+ *
+ * @author Lars Næsbye Christensen <larsnaesbye@stud.ku.dk>
+ * @author Kalle Sommer Nielsen <kalle@php.net>
+ * @author Esben Laursen <hyber@hyber.dk>
+ * @author Harith <haj@berlingske.dk>
+ * @author Daniel Ejsing-Duun <dokuwiki@zilvador.dk>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author rasmus@kinnerup.com
+ * @author Michael Pedersen subben@gmail.com
+ */
+$lang['menu'] = 'Brugerstyring';
+$lang['noauth'] = '(Brugervalidering er ikke tilgængelig)';
+$lang['nosupport'] = '(Brugerstyring er ikke understøttet)';
+$lang['badauth'] = 'Ugyldig brugerbekræftelsesfunktion';
+$lang['user_id'] = 'Bruger';
+$lang['user_pass'] = 'Adgangskode';
+$lang['user_name'] = 'Navn';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Grupper';
+$lang['field'] = 'Felt';
+$lang['value'] = 'Værdi';
+$lang['add'] = 'Tilføj';
+$lang['delete'] = 'Slet';
+$lang['delete_selected'] = 'Slet valgte';
+$lang['edit'] = 'Rediger';
+$lang['edit_prompt'] = 'Rediger denne bruger';
+$lang['modify'] = 'Gem ændringer';
+$lang['search'] = 'Søg';
+$lang['search_prompt'] = 'Udfør søgning';
+$lang['clear'] = 'Nulstil søgefilter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Viser brugerne %1$d-%2$d ud af %3$d fundne. %4$d brugere totalt.';
+$lang['nonefound'] = 'Ingen brugere fundet. %d brugere totalt.';
+$lang['delete_ok'] = '%d brugere slettet';
+$lang['delete_fail'] = '%d kunne ikke slettes.';
+$lang['update_ok'] = 'Bruger opdateret korrekt';
+$lang['update_fail'] = 'Brugeropdatering mislykkedes';
+$lang['update_exists'] = 'Ændring af brugernavn mislykkedes, det valgte brugernavn (%s) er allerede optaget (andre ændringer vil blive udført).';
+$lang['start'] = 'begynde';
+$lang['prev'] = 'forrige';
+$lang['next'] = 'næste';
+$lang['last'] = 'sidste';
+$lang['edit_usermissing'] = 'Den valgte bruger blev ikke fundet. Brugernavnet kan være slettet eller ændret andetsteds.';
+$lang['user_notify'] = 'Meddel bruger';
+$lang['note_notify'] = 'Meddelelser bliver kun sendt, hvis brugeren får givet et nyt adgangskode.';
+$lang['note_group'] = 'Nye brugere vil blive tilføjet til standardgruppen (%s), hvis ingen gruppe er opgivet.';
+$lang['note_pass'] = 'Adgangskoden vil blive dannet automatisk, hvis feltet er tomt og underretning af brugeren er aktiveret.';
+$lang['add_ok'] = 'Bruger tilføjet uden fejl.';
+$lang['add_fail'] = 'Tilføjelse af bruger mislykkedes';
+$lang['notify_ok'] = 'Meddelelse sendt';
+$lang['notify_fail'] = 'Meddelelse kunne ikke sendes';
diff --git a/lib/plugins/usermanager/lang/da/list.txt b/lib/plugins/usermanager/lang/da/list.txt
new file mode 100644
index 000000000..11d1710a0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/da/list.txt
@@ -0,0 +1 @@
+===== Brugerliste =====
diff --git a/lib/plugins/usermanager/lang/de-informal/add.txt b/lib/plugins/usermanager/lang/de-informal/add.txt
new file mode 100644
index 000000000..1fc34c968
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/add.txt
@@ -0,0 +1 @@
+===== Benutzer hinzufügen ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de-informal/delete.txt b/lib/plugins/usermanager/lang/de-informal/delete.txt
new file mode 100644
index 000000000..778396aa0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/delete.txt
@@ -0,0 +1 @@
+===== Benutzer gelöscht ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de-informal/edit.txt b/lib/plugins/usermanager/lang/de-informal/edit.txt
new file mode 100644
index 000000000..291b0f19d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/edit.txt
@@ -0,0 +1 @@
+===== Benutzer bearbeiten ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de-informal/intro.txt b/lib/plugins/usermanager/lang/de-informal/intro.txt
new file mode 100644
index 000000000..a5927a89d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/intro.txt
@@ -0,0 +1 @@
+===== Benutzerverwaltung ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de-informal/lang.php b/lib/plugins/usermanager/lang/de-informal/lang.php
new file mode 100644
index 000000000..dbdce1fbf
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * German (informal) language file
+ *
+ * @author Alexander Fischer <tbanus@os-forge.net>
+ * @author Juergen Schwarzer <jschwarzer@freenet.de>
+ * @author Marcel Metz <marcel_metz@gmx.de>
+ * @author Matthias Schulte <post@lupo49.de>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Benutzerverwalter';
+$lang['noauth'] = '(Benutzeranmeldung ist nicht verfügbar)';
+$lang['nosupport'] = '(Benutzerverwaltung wird nicht unterstützt)';
+$lang['badauth'] = 'Ungültige Authentifizierung';
+$lang['user_id'] = 'Benutzer';
+$lang['user_pass'] = 'Passwort';
+$lang['user_name'] = 'Echter Name';
+$lang['user_mail'] = 'E-Mail';
+$lang['user_groups'] = 'Gruppen';
+$lang['field'] = 'Feld';
+$lang['value'] = 'Wert';
+$lang['add'] = 'Zufügen';
+$lang['delete'] = 'Löschen';
+$lang['delete_selected'] = 'Lösche ausgewähltes';
+$lang['edit'] = 'Bearbeiten';
+$lang['edit_prompt'] = 'Bearbeite diesen Benutzer';
+$lang['modify'] = 'Änderungen speichern';
+$lang['search'] = 'Suchen';
+$lang['search_prompt'] = 'Suche ausführen';
+$lang['clear'] = 'Suchfilter zurücksetzen';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Zeige Benutzer %1$d-%2$d von %3$d gefundenen. %4$d Benutzer insgesamt.';
+$lang['nonefound'] = 'Keinen Benutzer gefunden. Insgesamt %d Benutzer.';
+$lang['delete_ok'] = '%d Benutzer wurden gelöscht';
+$lang['delete_fail'] = '%d konnte nicht gelöscht werden';
+$lang['update_ok'] = 'Benutzer wurde erfolgreich aktualisiert';
+$lang['update_fail'] = 'Aktualisierung des Benutzers ist fehlgeschlagen';
+$lang['update_exists'] = 'Benutzername konnte nicht geändert werden, der angegebene Benutzername (%s) existiert bereits (alle anderen Änderungen werden angewandt).';
+$lang['start'] = 'Start';
+$lang['prev'] = 'vorige';
+$lang['next'] = 'nächste';
+$lang['last'] = 'letzte';
+$lang['edit_usermissing'] = 'Der gewählte Benutzer wurde nicht gefunden. Der angegebene Benutzername könnte gelöscht oder an anderer Stelle geändert worden sein.';
+$lang['user_notify'] = 'Benutzer benachrichtigen';
+$lang['note_notify'] = 'Benachrichtigungsemails werden nur versandt, wenn der Benutzer ein neues Kennwort erhält.';
+$lang['note_group'] = 'Neue Benutzer werden zur Standardgruppe (%s) hinzugefügt, wenn keine Gruppe angegeben wird.';
+$lang['note_pass'] = 'Das Passwort wird automatisch erzeugt, wenn das Feld freigelassen wird und der Benutzer Benachrichtigungen aktiviert hat.';
+$lang['add_ok'] = 'Benutzer erfolgreich hinzugefügt';
+$lang['add_fail'] = 'Hinzufügen des Benutzers fehlgeschlagen';
+$lang['notify_ok'] = 'Benachrichtigungs-Mail wurde versendet';
+$lang['notify_fail'] = 'Benachrichtigungse-Mail konnte nicht gesendet werden';
diff --git a/lib/plugins/usermanager/lang/de-informal/list.txt b/lib/plugins/usermanager/lang/de-informal/list.txt
new file mode 100644
index 000000000..0a62012e5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de-informal/list.txt
@@ -0,0 +1 @@
+===== Benutzerliste ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/de/add.txt b/lib/plugins/usermanager/lang/de/add.txt
new file mode 100644
index 000000000..925fa5042
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/add.txt
@@ -0,0 +1 @@
+===== Benutzer hinzufügen =====
diff --git a/lib/plugins/usermanager/lang/de/delete.txt b/lib/plugins/usermanager/lang/de/delete.txt
new file mode 100644
index 000000000..4f3bbbd03
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/delete.txt
@@ -0,0 +1 @@
+===== Benutzer löschen =====
diff --git a/lib/plugins/usermanager/lang/de/edit.txt b/lib/plugins/usermanager/lang/de/edit.txt
new file mode 100644
index 000000000..9419200dd
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/edit.txt
@@ -0,0 +1 @@
+===== Benutzer ändern =====
diff --git a/lib/plugins/usermanager/lang/de/intro.txt b/lib/plugins/usermanager/lang/de/intro.txt
new file mode 100644
index 000000000..a5837b8c7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/intro.txt
@@ -0,0 +1 @@
+====== Benutzer-Manager ======
diff --git a/lib/plugins/usermanager/lang/de/lang.php b/lib/plugins/usermanager/lang/de/lang.php
new file mode 100644
index 000000000..507fe1f7c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/lang.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * German language file
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Leo Moll <leo@yeasoft.com>
+ * @author Florian Anderiasch <fa@art-core.org>
+ * @author Robin Kluth <commi1993@gmail.com>
+ * @author Arne Pelka <mail@arnepelka.de>
+ * @author Dirk Einecke <dirk@dirkeinecke.de>
+ * @author Blitzi94@gmx.de
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Niels Lange <niels@boldencursief.nl>
+ * @author Christian Wichmann <nospam@zone0.de>
+ * @author Paul Lachewsky <kaeptn.haddock@gmail.com>
+ * @author Pierre Corell <info@joomla-praxis.de>
+ */
+$lang['menu'] = 'Benutzerverwaltung';
+$lang['noauth'] = '(Authentifizierungssystem nicht verfügbar)';
+$lang['nosupport'] = '(Benutzerverwaltung nicht unterstützt)';
+$lang['badauth'] = 'Ungültige Methode zur Authentifizierung';
+$lang['user_id'] = 'Benutzername';
+$lang['user_pass'] = 'Passwort';
+$lang['user_name'] = 'Voller Name';
+$lang['user_mail'] = 'E-Mail';
+$lang['user_groups'] = 'Gruppen';
+$lang['field'] = 'Feld';
+$lang['value'] = 'Wert';
+$lang['add'] = 'Hinzufügen';
+$lang['delete'] = 'Löschen';
+$lang['delete_selected'] = 'Ausgewählte löschen';
+$lang['edit'] = 'Ändern';
+$lang['edit_prompt'] = 'Benutzerdaten ändern';
+$lang['modify'] = 'Speichern';
+$lang['search'] = 'Suchen';
+$lang['search_prompt'] = 'Benutzerdaten filtern';
+$lang['clear'] = 'Filter zurücksetzen';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Zeige Benutzer %1$d-%2$d von %3$d gefundenen. %4$d Benutzer insgesamt.';
+$lang['nonefound'] = 'Keine Benutzer gefunden. %d Benutzer insgesamt.';
+$lang['delete_ok'] = '%d Benutzer gelöscht';
+$lang['delete_fail'] = '%d konnten nicht gelöscht werden.';
+$lang['update_ok'] = 'Benutzerdaten erfolgreich geändert.';
+$lang['update_fail'] = 'Änderung der Benutzerdaten fehlgeschlagen.';
+$lang['update_exists'] = 'Nutzername konnte nicht geändert werden, weil der angegebene Nutzer (%s) bereits existiert (alle anderen Änderungen wurden durchgeführt).';
+$lang['start'] = 'Anfang';
+$lang['prev'] = 'Vorherige';
+$lang['next'] = 'Nächste';
+$lang['last'] = 'Ende';
+$lang['edit_usermissing'] = 'Der ausgewählte Nutzer wurde nicht gefunden. Möglicherweise wurde er gelöscht oder der Nutzer wurde anderswo geändert.';
+$lang['user_notify'] = 'Nutzer benachrichtigen';
+$lang['note_notify'] = 'Benachrichtigungs-E-Mails werden nur versandt, wenn ein neues Passwort vergeben wurde.';
+$lang['note_group'] = 'Neue Nutzer werden der Standard-Gruppe (%s) hinzugefügt, wenn keine Gruppe angegeben wurde.';
+$lang['note_pass'] = 'Das Passwort wird automatisch generiert, wenn das entsprechende Feld leergelassen wird und die Benachrichtigung des Nutzers aktiviert ist.';
+$lang['add_ok'] = 'Nutzer erfolgreich angelegt';
+$lang['add_fail'] = 'Nutzer konnte nicht angelegt werden';
+$lang['notify_ok'] = 'Benachrichtigungs-Mail wurde versandt';
+$lang['notify_fail'] = 'Benachrichtigungs-Mail konnte nicht versandt werden';
diff --git a/lib/plugins/usermanager/lang/de/list.txt b/lib/plugins/usermanager/lang/de/list.txt
new file mode 100644
index 000000000..8d6d5fb46
--- /dev/null
+++ b/lib/plugins/usermanager/lang/de/list.txt
@@ -0,0 +1 @@
+===== Benutzerliste =====
diff --git a/lib/plugins/usermanager/lang/el/add.txt b/lib/plugins/usermanager/lang/el/add.txt
new file mode 100644
index 000000000..0616f8c53
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/add.txt
@@ -0,0 +1 @@
+===== Προσθήκη Χρήστη =====
diff --git a/lib/plugins/usermanager/lang/el/delete.txt b/lib/plugins/usermanager/lang/el/delete.txt
new file mode 100644
index 000000000..baf9bc054
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/delete.txt
@@ -0,0 +1 @@
+===== Διαγραφή Χρήστη =====
diff --git a/lib/plugins/usermanager/lang/el/edit.txt b/lib/plugins/usermanager/lang/el/edit.txt
new file mode 100644
index 000000000..dec59efd7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/edit.txt
@@ -0,0 +1 @@
+===== Τροποποίηση Χρήστη =====
diff --git a/lib/plugins/usermanager/lang/el/intro.txt b/lib/plugins/usermanager/lang/el/intro.txt
new file mode 100644
index 000000000..874c13b57
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/intro.txt
@@ -0,0 +1 @@
+====== Διαχείριση Χρηστών ======
diff --git a/lib/plugins/usermanager/lang/el/lang.php b/lib/plugins/usermanager/lang/el/lang.php
new file mode 100644
index 000000000..4b4d95379
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/lang.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Greek language file
+ *
+ * Based on DokuWiki Version rc2007-05-24 english language file
+ * Original english language file contents included for reference
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Thanos Massias <tm@thriasio.gr>
+ * @author Αθανάσιος Νταής <homunculus@wana.gr>
+ * @author Konstantinos Koryllos <koryllos@gmail.com>
+ * @author George Petsagourakis <petsagouris@gmail.com>
+ * @author Petros Vidalis <pvidalis@gmail.com>
+ */
+$lang['menu'] = 'Διαχείριση Χρηστών';
+$lang['noauth'] = '(η είσοδος χρηστών δεν είναι δυνατή)';
+$lang['nosupport'] = '(δεν υποστηρίζεται η διαχείριση χρηστών)';
+$lang['badauth'] = 'μη επιτρεπτός μηχανισμός πιστοποίησης';
+$lang['user_id'] = 'Χρήστης';
+$lang['user_pass'] = 'Κωδικός';
+$lang['user_name'] = 'Πλήρες όνομα';
+$lang['user_mail'] = 'e-mail';
+$lang['user_groups'] = 'Ομάδες';
+$lang['field'] = 'Πεδίο';
+$lang['value'] = 'Τιμή';
+$lang['add'] = 'Προσθήκη';
+$lang['delete'] = 'Διαγραφή';
+$lang['delete_selected'] = 'Διαγραφή επιλεγμένων χρηστών';
+$lang['edit'] = 'Τροποποίηση';
+$lang['edit_prompt'] = 'Τροποποίηση χρήστη';
+$lang['modify'] = 'Αποθήκευση αλλαγών';
+$lang['search'] = 'Αναζήτηση';
+$lang['search_prompt'] = 'Εκκίνηση αναζήτησης';
+$lang['clear'] = 'Καθαρισμός φίλτρων';
+$lang['filter'] = 'Φίλτρο';
+$lang['summary'] = 'Εμφάνιση χρηστών %1$d-%2$d από %3$d σχετικούς. %4$d χρήστες συνολικά.';
+$lang['nonefound'] = 'Δεν βρέθηκαν σχετικοί χρήστες. %d χρήστες συνολικά.';
+$lang['delete_ok'] = '%d χρήστες διεγράφησαν';
+$lang['delete_fail'] = '%d χρήστες δεν διεγράφησαν.';
+$lang['update_ok'] = 'Επιτυχημένη τροποποίηση προφίλ χρήστη';
+$lang['update_fail'] = 'Αποτυχημένη τροποποίηση προφίλ χρήστη';
+$lang['update_exists'] = 'Η αλλαγή ονόματος χρήστη απέτυχε -- το νέο όνομα χρήστη (%s) ήδη υπάρχει (τυχόν άλλες αλλαγές θα εφαρμοστούν).';
+$lang['start'] = 'αρχή';
+$lang['prev'] = 'προηγούμενα';
+$lang['next'] = 'επόμενα';
+$lang['last'] = 'τέλος';
+$lang['edit_usermissing'] = 'Ο επιλεγμένος χρήστης δεν βρέθηκε. Πιθανόν να διαγράφηκε στο μεταξύ.';
+$lang['user_notify'] = 'Ειδοποίηση χρήστη';
+$lang['note_notify'] = 'Τα ενημερωτικά e-mails στέλνονται μόνο όταν δίνεται νέος κωδικός στον χρήστη.';
+$lang['note_group'] = 'Οι νέοι χρήστες θα ανήκουν στην ομάδα (%s) αν δεν οριστεί άλλη ομάδα.';
+$lang['note_pass'] = 'Ο κωδικός θα δημιουργηθεί αυτόματα εάν το πεδίο μείνει κενό και έχει επιλεγεί η αποστολή ειδοποίησης χρήστη.';
+$lang['add_ok'] = 'Επιτυχημένη εγγραφή χρήστη';
+$lang['add_fail'] = 'Η εγγραφή του χρήστη απέτυχε';
+$lang['notify_ok'] = 'Εστάλη ενημερωτικό e-mail';
+$lang['notify_fail'] = 'Δεν ήταν δυνατή η αποστολή του ενημερωτικού e-mail';
diff --git a/lib/plugins/usermanager/lang/el/list.txt b/lib/plugins/usermanager/lang/el/list.txt
new file mode 100644
index 000000000..adb5c210b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/el/list.txt
@@ -0,0 +1 @@
+===== Κατάλογος Χρηστών =====
diff --git a/lib/plugins/usermanager/lang/en/add.txt b/lib/plugins/usermanager/lang/en/add.txt
new file mode 100644
index 000000000..9afecb5cd
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/add.txt
@@ -0,0 +1 @@
+===== Add user =====
diff --git a/lib/plugins/usermanager/lang/en/delete.txt b/lib/plugins/usermanager/lang/en/delete.txt
new file mode 100644
index 000000000..c3ca90dbb
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/delete.txt
@@ -0,0 +1 @@
+===== Delete user =====
diff --git a/lib/plugins/usermanager/lang/en/edit.txt b/lib/plugins/usermanager/lang/en/edit.txt
new file mode 100644
index 000000000..4d02dfddc
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/edit.txt
@@ -0,0 +1 @@
+===== Edit user =====
diff --git a/lib/plugins/usermanager/lang/en/intro.txt b/lib/plugins/usermanager/lang/en/intro.txt
new file mode 100644
index 000000000..73bf55613
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/intro.txt
@@ -0,0 +1 @@
+====== User Manager ======
diff --git a/lib/plugins/usermanager/lang/en/lang.php b/lib/plugins/usermanager/lang/en/lang.php
new file mode 100644
index 000000000..189a1db20
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/lang.php
@@ -0,0 +1,58 @@
+<?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['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';
+
diff --git a/lib/plugins/usermanager/lang/en/list.txt b/lib/plugins/usermanager/lang/en/list.txt
new file mode 100644
index 000000000..54c45caf7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/en/list.txt
@@ -0,0 +1 @@
+===== User List =====
diff --git a/lib/plugins/usermanager/lang/eo/add.txt b/lib/plugins/usermanager/lang/eo/add.txt
new file mode 100644
index 000000000..8775ff85d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/add.txt
@@ -0,0 +1 @@
+===== Aldoni uzanton ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eo/delete.txt b/lib/plugins/usermanager/lang/eo/delete.txt
new file mode 100644
index 000000000..0d94f8122
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/delete.txt
@@ -0,0 +1 @@
+===== Forigi uzanton ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eo/edit.txt b/lib/plugins/usermanager/lang/eo/edit.txt
new file mode 100644
index 000000000..2ced16e7c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/edit.txt
@@ -0,0 +1 @@
+===== Modifi uzanton ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eo/intro.txt b/lib/plugins/usermanager/lang/eo/intro.txt
new file mode 100644
index 000000000..2ef373f66
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/intro.txt
@@ -0,0 +1 @@
+====== Administrado de Uzantoj ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eo/lang.php b/lib/plugins/usermanager/lang/eo/lang.php
new file mode 100644
index 000000000..b5f1abc0e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Esperantolanguage file
+ *
+ * @author Felipe Castro <fefcas@uol.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Felipe Castro <fefcas (cxe) gmail (punkto) com>
+ * @author Felipo Kastro <fefcas@gmail.com>
+ * @author Robert Bogenschneider <robog@gmx.de>
+ * @author Erik Pedersen <erik pedersen@shaw.ca>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Robert Bogenschneider <robog@GMX.de>
+ * @author Robert BOGENSCHNEIDER <robog@gmx.de>
+ * @author Robert BOGENSCHNEIDER <bogi@UEA.org>
+ */
+$lang['menu'] = 'Administrado de uzantoj';
+$lang['noauth'] = '(identiĝo de uzantoj ne disponeblas)';
+$lang['nosupport'] = '(administro de uzantoj ne estas subtenata)';
+$lang['badauth'] = 'tiu identiĝa procezo ne validas';
+$lang['user_id'] = 'Uzanto';
+$lang['user_pass'] = 'Pasvorto';
+$lang['user_name'] = 'Vera nomo';
+$lang['user_mail'] = 'Retadreso';
+$lang['user_groups'] = 'Grupoj';
+$lang['field'] = 'Kampo';
+$lang['value'] = 'Valoro';
+$lang['add'] = 'Aldoni';
+$lang['delete'] = 'Forigi';
+$lang['delete_selected'] = 'Forigi elektitan';
+$lang['edit'] = 'Modifi';
+$lang['edit_prompt'] = 'Modifi tiun ĉi uzanton';
+$lang['modify'] = 'Registri modifojn';
+$lang['search'] = 'Serĉi';
+$lang['search_prompt'] = 'Fari serĉon';
+$lang['clear'] = 'Refari serĉan filtron';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Montriĝas uzantoj %1$d-%2$d el %3$d trovitaj. %4$d uzantoj entute.';
+$lang['nonefound'] = 'Neniu uzantoj troviĝas. %d uzantoj entute.';
+$lang['delete_ok'] = '%d uzantoj estis forigitaj';
+$lang['delete_fail'] = '%d malsukcesis esti forigitaj.';
+$lang['update_ok'] = 'Tiu uzanto estis sukcese ĝisdatigita';
+$lang['update_fail'] = 'Malsukceso okazis por ĝisdatigi tiun uzanton';
+$lang['update_exists'] = 'Malsukceso okazis por ŝanĝi la nomon de tiu uzanto: la enmetita nomo (%s) jam ekzistas (ĉiuj aliaj ŝanĝoj estos aplikitaj)';
+$lang['start'] = 'Ekigi';
+$lang['prev'] = 'antaŭe';
+$lang['next'] = 'sekve';
+$lang['last'] = 'laste';
+$lang['edit_usermissing'] = 'La elektita uzanto ne estis trovita: tiu nomo povis esti forigita aŭ ŝanĝita aliloke.';
+$lang['user_notify'] = 'Avizi uzanton';
+$lang['note_notify'] = 'Avizantaj mesaĝoj estos sendataj nur se la uzanto ekhavos novan pasvorton.';
+$lang['note_group'] = 'Novaj uzantoj estos aldonitaj al la komuna grupo (%s) se neniu alia estos specifita.';
+$lang['note_pass'] = 'La pasvorto estos aŭtomate kreita se la kampo estos lasita malplena kaj \'aviso al uzantoj\' estos ebligita.';
+$lang['add_ok'] = 'La uzanto estis sukcese aldonita';
+$lang['add_fail'] = 'Malsukceso okazis por aldoni uzulon';
+$lang['notify_ok'] = 'Avizanta mesaĝo estis sendita';
+$lang['notify_fail'] = 'La avizanta mesaĝo ne povis esti sendita';
diff --git a/lib/plugins/usermanager/lang/eo/list.txt b/lib/plugins/usermanager/lang/eo/list.txt
new file mode 100644
index 000000000..714671afb
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eo/list.txt
@@ -0,0 +1 @@
+===== Listo de Uzantoj ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/es/add.txt b/lib/plugins/usermanager/lang/es/add.txt
new file mode 100644
index 000000000..90c56e31d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/add.txt
@@ -0,0 +1 @@
+===== Agregar un usuario =====
diff --git a/lib/plugins/usermanager/lang/es/delete.txt b/lib/plugins/usermanager/lang/es/delete.txt
new file mode 100644
index 000000000..4c552a9c1
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/delete.txt
@@ -0,0 +1 @@
+===== Eliminar un usuario =====
diff --git a/lib/plugins/usermanager/lang/es/edit.txt b/lib/plugins/usermanager/lang/es/edit.txt
new file mode 100644
index 000000000..ccdd26f86
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/edit.txt
@@ -0,0 +1 @@
+===== Editar datos del usuario =====
diff --git a/lib/plugins/usermanager/lang/es/intro.txt b/lib/plugins/usermanager/lang/es/intro.txt
new file mode 100644
index 000000000..e558d3a28
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/intro.txt
@@ -0,0 +1 @@
+====== Administración de usuarios ======
diff --git a/lib/plugins/usermanager/lang/es/lang.php b/lib/plugins/usermanager/lang/es/lang.php
new file mode 100644
index 000000000..c12b77b3d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/lang.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Spanish language file
+ *
+ * @author Miguel Pagano <miguel.pagano>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ * @author Gabriel Castillo <gch@pumas.ii.unam.mx>
+ * @author oliver@samera.com.py
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Manuel Meco <manuel.meco@gmail.com>
+ * @author VictorCastelan <victorcastelan@gmail.com>
+ * @author Jordan Mero hack.jord@gmail.com
+ * @author Felipe Martinez <metalmartinez@gmail.com>
+ * @author Javier Aranda <internet@javierav.com>
+ * @author Zerial <fernando@zerial.org>
+ * @author Marvin Ortega <maty1206@maryanlinux.com>
+ * @author Daniel Castro Alvarado <dancas2@gmail.com>
+ * @author Fernando J. Gómez <fjgomez@gmail.com>
+ * @author Victor Castelan <victorcastelan@gmail.com>
+ * @author Mauro Javier Giamberardino <mgiamberardino@gmail.com>
+ * @author emezeta <emezeta@infoprimo.com>
+ * @author Oscar Ciudad <oscar@jacho.net>
+ * @author Ruben Figols <ruben.figols@gmail.com>
+ */
+$lang['menu'] = 'Administración de usuarios';
+$lang['noauth'] = '(la autenticación de usuarios no está disponible)';
+$lang['nosupport'] = '(la administración de usuarios no está habilitada)';
+$lang['badauth'] = 'Mecanismo de autenticación inválido';
+$lang['user_id'] = 'Usuario';
+$lang['user_pass'] = 'Contraseña';
+$lang['user_name'] = 'Nombre';
+$lang['user_mail'] = 'Correo electrónico';
+$lang['user_groups'] = 'Grupos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Agregar';
+$lang['delete'] = 'Eliminar';
+$lang['delete_selected'] = 'Eliminar seleccionados';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar datos de este usuario';
+$lang['modify'] = 'Guardar los cambios';
+$lang['search'] = 'Buscar';
+$lang['search_prompt'] = 'Realizar la búsqueda';
+$lang['clear'] = 'Limpiar los filtros de la búsqueda';
+$lang['filter'] = 'Filtrar';
+$lang['summary'] = 'Mostrando los usuarios %1$d-%2$d de %3$d encontrados. Cantidad total de usuarios %4$d.';
+$lang['nonefound'] = 'No se encontraron usuarios que coincidan con los párametros de la búsqueda. Cantidad total de usuarios %d.';
+$lang['delete_ok'] = '%d usuarios eliminados';
+$lang['delete_fail'] = '%d no se pudieron eliminar.';
+$lang['update_ok'] = 'Los datos del usuario se actualizaron exitosamente ';
+$lang['update_fail'] = 'Los datos del usuario no se actualizaron';
+$lang['update_exists'] = 'El cambio de nombre de usuario falló, el nombre especificado (%s) ya está en uso (los otros cambios se aplicaron).';
+$lang['start'] = 'primera';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'siguiente';
+$lang['last'] = 'última';
+$lang['edit_usermissing'] = 'El usuario seleccionado no ha sido encontrado; el usuario especificado puede haber sido eliminado o cambiado en algún otro lugar.';
+$lang['user_notify'] = 'Notificar al usuario';
+$lang['note_notify'] = 'El correo electrónico de notificación sólo será enviado si se actualizo la contraseña del usuario.';
+$lang['note_group'] = 'Si no se especifica ningún grupo, los nuevos usuarios serán agregados al grupo por defecto (%s).';
+$lang['note_pass'] = 'Se generará una clave automáticamente si el campo izquierdo es vacío y se esta activo la notificación de usuario. ';
+$lang['add_ok'] = 'El usuario fue creado exitosamente';
+$lang['add_fail'] = 'Falló la creación del usuario';
+$lang['notify_ok'] = 'Se envió la notificación por correo electrónico';
+$lang['notify_fail'] = 'No se pudo enviar la notificación por correo electrónico';
diff --git a/lib/plugins/usermanager/lang/es/list.txt b/lib/plugins/usermanager/lang/es/list.txt
new file mode 100644
index 000000000..d0d32b913
--- /dev/null
+++ b/lib/plugins/usermanager/lang/es/list.txt
@@ -0,0 +1 @@
+===== Lista de usuarios =====
diff --git a/lib/plugins/usermanager/lang/et/lang.php b/lib/plugins/usermanager/lang/et/lang.php
new file mode 100644
index 000000000..2161df918
--- /dev/null
+++ b/lib/plugins/usermanager/lang/et/lang.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Estonian language file
+ *
+ * @author kristian.kankainen@kuu.la
+ * @author Rivo Zängov <eraser@eraser.ee>
+ */
+$lang['menu'] = 'Kasutajate haldamine';
+$lang['user_id'] = 'Kasutaja';
+$lang['user_pass'] = 'Parool';
+$lang['user_name'] = 'Tegelik nimi';
+$lang['user_mail'] = 'E-post';
+$lang['user_groups'] = 'Grupid';
+$lang['field'] = 'Väli';
+$lang['value'] = 'Väärtus';
+$lang['add'] = 'Lisa';
+$lang['delete'] = 'Kustuta';
+$lang['delete_selected'] = 'Kustuta valitud';
+$lang['edit'] = 'Muuda';
+$lang['edit_prompt'] = 'Muuda seda kasutajat';
+$lang['modify'] = 'Salvesta muudatused';
+$lang['search'] = 'Otsi';
+$lang['search_prompt'] = 'Soorita otsing';
+$lang['filter'] = 'Filtreeri';
+$lang['update_fail'] = 'Kasutaja uuendamine ebaõnnestus';
+$lang['start'] = 'esimesed';
+$lang['prev'] = 'eelmine';
+$lang['next'] = 'järgmine';
+$lang['last'] = 'viimased';
+$lang['user_notify'] = 'Teavita kasutajat';
diff --git a/lib/plugins/usermanager/lang/eu/add.txt b/lib/plugins/usermanager/lang/eu/add.txt
new file mode 100644
index 000000000..855c43218
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/add.txt
@@ -0,0 +1 @@
+===== Erabiltzailea gehitu ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eu/delete.txt b/lib/plugins/usermanager/lang/eu/delete.txt
new file mode 100644
index 000000000..987b98f20
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/delete.txt
@@ -0,0 +1 @@
+===== Erabiltzailea ezabatu ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eu/edit.txt b/lib/plugins/usermanager/lang/eu/edit.txt
new file mode 100644
index 000000000..82b92afe7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/edit.txt
@@ -0,0 +1 @@
+====== Editatu erabiltzailea ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eu/intro.txt b/lib/plugins/usermanager/lang/eu/intro.txt
new file mode 100644
index 000000000..848b3da05
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/intro.txt
@@ -0,0 +1 @@
+====== Erabiltzaile Kudeatzailea ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/eu/lang.php b/lib/plugins/usermanager/lang/eu/lang.php
new file mode 100644
index 000000000..b6e04f7c4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Basque language file
+ *
+ * @author Inko Illarramendi <inko.i.a@gmail.com>
+ */
+$lang['menu'] = 'Erabiltzaile Kudeatzailea';
+$lang['noauth'] = '(erabiltzaile kautotzea ez dago erabilgarri)';
+$lang['nosupport'] = '(erabiltzaile kudeaketa ez dago erabilgarri)';
+$lang['badauth'] = 'kautotze mekanismo baliogabea';
+$lang['user_id'] = 'Erabiltzailea';
+$lang['user_pass'] = 'Pasahitza';
+$lang['user_name'] = 'Benetako Izena';
+$lang['user_mail'] = 'Posta-e';
+$lang['user_groups'] = 'Taldeak';
+$lang['field'] = 'Eremu';
+$lang['value'] = 'Balioa';
+$lang['add'] = 'Gehitu';
+$lang['delete'] = 'Ezabatu';
+$lang['delete_selected'] = 'Ezabatu Hautatutakoak';
+$lang['edit'] = 'Editatu';
+$lang['edit_prompt'] = 'Editatu erabiltzaile hau';
+$lang['modify'] = 'Gorde Aldaketak';
+$lang['search'] = 'Bilatu';
+$lang['search_prompt'] = 'Egin bilaketa';
+$lang['clear'] = 'Berrasieratu Bilaketa Iragazkia';
+$lang['filter'] = 'Iragazi';
+$lang['summary'] = 'Erakusten diren erabiltzaileak %1$d-%2$d bilatutako %3$d erabiltzailetatik. %4$d erabiltzaile guztira.';
+$lang['nonefound'] = 'Ez da erabiltzailerik aurkitu. %d erabiltzaile guztira.';
+$lang['delete_ok'] = '%d erabiltzaile ezabatuak';
+$lang['delete_fail'] = '%d huts ezabatzean.';
+$lang['update_ok'] = 'Erabiltzailea arrakastaz eguneratuak';
+$lang['update_fail'] = 'Erabiltzaile eguneratzeak huts egin du ';
+$lang['update_exists'] = 'Erabiltzaile izen aldaketak huts egin du, zehaztutako erabiltzaile izena (%s) lehendik existitzen zen (beste edozein aldaketa ezarri egingo da).';
+$lang['start'] = 'hasi';
+$lang['prev'] = 'aurrekoa';
+$lang['next'] = 'hurrengoa';
+$lang['last'] = 'azkena';
+$lang['edit_usermissing'] = 'Aukeratutako erabiltzailea ez da aurkitu, zehaztutako erabiltzaile izena beste nonbait ezabatua edo aldatua izana gerta zitekeen.';
+$lang['user_notify'] = 'Erabiltzailea jakinarazi';
+$lang['note_notify'] = 'Jakinarazpen postak erabiltzaileari pasahitz berria ematen bazaio bakarrik bidaltzen dira.';
+$lang['note_group'] = 'Erabiltzaile berriak (%s) talde lehenetsira gehituko dira ez bada talderik zehazten.';
+$lang['note_pass'] = 'Pasahitza automatikoki sortuko da eremua hutsik uzten bada eta erabiltzailearen jakinarazpena gaitua badago.';
+$lang['add_ok'] = 'Erabiltzailea arrakastaz gehitua';
+$lang['add_fail'] = 'Erabiltzaile gehitzeak huts egin du';
+$lang['notify_ok'] = 'Jakinarazpen posta-e bidalia';
+$lang['notify_fail'] = 'Jakinarazpen posta-e ezin izan da bidali';
diff --git a/lib/plugins/usermanager/lang/eu/list.txt b/lib/plugins/usermanager/lang/eu/list.txt
new file mode 100644
index 000000000..fb80b14be
--- /dev/null
+++ b/lib/plugins/usermanager/lang/eu/list.txt
@@ -0,0 +1 @@
+====== Erabiltzaile zerrenda ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/add.txt b/lib/plugins/usermanager/lang/fa/add.txt
new file mode 100644
index 000000000..32d604e43
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/add.txt
@@ -0,0 +1 @@
+===== افزودن کاربر ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/delete.txt b/lib/plugins/usermanager/lang/fa/delete.txt
new file mode 100644
index 000000000..f8a59ff10
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/delete.txt
@@ -0,0 +1 @@
+===== حذف کاربر ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/edit.txt b/lib/plugins/usermanager/lang/fa/edit.txt
new file mode 100644
index 000000000..33fe5b517
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/edit.txt
@@ -0,0 +1 @@
+===== ویرایش کاربر ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/intro.txt b/lib/plugins/usermanager/lang/fa/intro.txt
new file mode 100644
index 000000000..ffb850109
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/intro.txt
@@ -0,0 +1 @@
+===== مدیریت کاربران ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fa/lang.php b/lib/plugins/usermanager/lang/fa/lang.php
new file mode 100644
index 000000000..f9e973b9c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Persian language file
+ *
+ * @author behrad eslamifar <behrad_es@yahoo.com)
+ * @author Mohsen Firoozmandan <info@mambolearn.com>
+ * @author omidmr@gmail.com
+ * @author Omid Mottaghi <omidmr@gmail.com>
+ * @author Mohammad Reza Shoaei <shoaei@gmail.com>
+ */
+$lang['menu'] = 'مدیریت کاربر';
+$lang['noauth'] = '(معتبرسازی کاربر ممکن نیست)';
+$lang['nosupport'] = '(مدیریت کاربر پشتیبانی نمی‌شود)';
+$lang['badauth'] = 'روش معتبرسازی اشتباه است';
+$lang['user_id'] = 'کاربر';
+$lang['user_pass'] = 'گذرواژه';
+$lang['user_name'] = 'نام حقیقی';
+$lang['user_mail'] = 'ایمیل';
+$lang['user_groups'] = 'گروه‌ها';
+$lang['field'] = 'فیلد';
+$lang['value'] = 'ارزش';
+$lang['add'] = 'اضافه کردن';
+$lang['delete'] = 'حذف';
+$lang['delete_selected'] = 'حذف انتخاب شده‌ها';
+$lang['edit'] = 'ویرایش';
+$lang['edit_prompt'] = 'ویرایش این کاربر';
+$lang['modify'] = 'ذخیره تغییرات';
+$lang['search'] = 'جستجو';
+$lang['search_prompt'] = 'انجام جستجو';
+$lang['clear'] = 'بازنویسی فیلترهای جستجو';
+$lang['filter'] = 'فیلتر';
+$lang['summary'] = 'نمایش کاربر %1$d-%2$d از %3$d. در کل %4$d کاربر.';
+$lang['nonefound'] = 'هیچ کاربری یافت نشد. در کل %d کاربر.';
+$lang['delete_ok'] = '%d کاربر حذف شد';
+$lang['delete_fail'] = 'حذف %d کاربر با مشکل مواجه شد.';
+$lang['update_ok'] = 'کاربر با موفقیت به روز رسانی شد.';
+$lang['update_fail'] = 'به روز رسانی کاربر با مشکل مواجه شد';
+$lang['update_exists'] = 'تغییر نام کاربری ممکن نیست، نام کاربری مورد نظر (%s) قبلن وجود داشته (مابقی تغییرات اعمال شده است)';
+$lang['start'] = 'شروع';
+$lang['prev'] = 'قبلی';
+$lang['next'] = 'بعدی';
+$lang['last'] = 'آخرین';
+$lang['edit_usermissing'] = 'کاربر انتخاب شده یافت نشد، نام کاربری مورد نظر در جایی دیگر حذف شده یا تغییر کرده.';
+$lang['user_notify'] = 'آگاه کردن کاربر';
+$lang['note_notify'] = 'ایمیلی برای آگاهی، فقط در زمان تغییر گذرواژه‌ ارسال می‌شود.';
+$lang['note_group'] = 'اگر گروهی انتخاب نشود، کاربران جدید به گروه پیش‌فرض (%s) افزوده خواهند شد.';
+$lang['note_pass'] = 'اگر فیلد گذرواژه خالی گذاشته شود، گذرواژه به طور خودکار تولید و ایمیلی برای کاربر ارسال خواهد شد.';
+$lang['add_ok'] = 'کاربر با موفقیت افزوده شد';
+$lang['add_fail'] = 'افزودن کاربر با مشکل مواجه شد';
+$lang['notify_ok'] = 'ایمیل آگاهی دهنده ارسال شد';
+$lang['notify_fail'] = 'ارسال ایمیل آگاهی دهنده با مشکل مواجه شد';
diff --git a/lib/plugins/usermanager/lang/fa/list.txt b/lib/plugins/usermanager/lang/fa/list.txt
new file mode 100644
index 000000000..b539bf18a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fa/list.txt
@@ -0,0 +1 @@
+===== لیست کاربران ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/add.txt b/lib/plugins/usermanager/lang/fi/add.txt
new file mode 100644
index 000000000..5c4ee0a41
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/add.txt
@@ -0,0 +1 @@
+===== Lisää käyttäjä ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/delete.txt b/lib/plugins/usermanager/lang/fi/delete.txt
new file mode 100644
index 000000000..2203a20f8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/delete.txt
@@ -0,0 +1 @@
+===== Poista käyttäjä ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/edit.txt b/lib/plugins/usermanager/lang/fi/edit.txt
new file mode 100644
index 000000000..53e0b41ab
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/edit.txt
@@ -0,0 +1 @@
+===== Muokkaa käyttäjää ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/intro.txt b/lib/plugins/usermanager/lang/fi/intro.txt
new file mode 100644
index 000000000..2ef0bb509
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/intro.txt
@@ -0,0 +1 @@
+====== Käyttäjähallinta ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fi/lang.php b/lib/plugins/usermanager/lang/fi/lang.php
new file mode 100644
index 000000000..1db4bd7fb
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Finnish language file
+ *
+ * @author otto@valjakko.net
+ * @author Otto Vainio <otto@valjakko.net>
+ * @author Teemu Mattila <ghcsystems@gmail.com>
+ * @author Sami Olmari <sami@olmari.fi>
+ */
+$lang['menu'] = 'Käyttäjähallinta';
+$lang['noauth'] = '(autentikointi ei ole käytössä)';
+$lang['nosupport'] = '(käyttäjähallinta ei ole tuettu)';
+$lang['badauth'] = 'Viallinen autentikointimenetelmä';
+$lang['user_id'] = 'Käyttäjä';
+$lang['user_pass'] = 'Salasana';
+$lang['user_name'] = 'Oikea nimi';
+$lang['user_mail'] = 'Sähköposti';
+$lang['user_groups'] = 'Ryhmät';
+$lang['field'] = 'Kenttä';
+$lang['value'] = 'Arvo';
+$lang['add'] = 'Lisää';
+$lang['delete'] = 'Poista';
+$lang['delete_selected'] = 'Poista valittu';
+$lang['edit'] = 'Muokkaa';
+$lang['edit_prompt'] = 'Muokkaa ryhmää';
+$lang['modify'] = 'Tallenna muutokset';
+$lang['search'] = 'Hae';
+$lang['search_prompt'] = 'Tee haku';
+$lang['clear'] = 'Tyhjennä hakusuodatin';
+$lang['filter'] = 'Suodatin';
+$lang['summary'] = 'Näytetään käyttäjät %1$d-%2$d / %3$d löytynyttä. %4$d käyttäjää yhteensä.';
+$lang['nonefound'] = 'Ei löytynyt käyttäjiä. %d käyttäjää yhteensä.';
+$lang['delete_ok'] = '%d käyttäjää poistettu';
+$lang['delete_fail'] = '%d poistoa epäonnistui';
+$lang['update_ok'] = 'Käyttäjän päivitys onnistui';
+$lang['update_fail'] = 'Käyttäjän päivitys epäonnistui';
+$lang['update_exists'] = 'Käyttäjän nimen vaihto epäonnistui. Nimi (%s) on jo olemassa (muut muutokset onnistuivat)';
+$lang['start'] = 'alku';
+$lang['prev'] = 'edellinen';
+$lang['next'] = 'seuraava';
+$lang['last'] = 'viimeinen';
+$lang['edit_usermissing'] = 'Valittua käyttäjää ei löytynyt. Käyttäjä on voitu päivittää tai poistaa muualta.';
+$lang['user_notify'] = 'Tiedota käyttäjälle';
+$lang['note_notify'] = 'Tiedotus lähetetään vain, jos käyttäjälle on määritelty uusi salasana.';
+$lang['note_group'] = 'Uudelle käyttäjälle määritellään oletusryhmä (%s), jos ryhmää ei erikseen määritellä.';
+$lang['note_pass'] = 'Salasana luodaan automaattisesti, mikäli kenttä jätetään tyhjäksi ja jos käyttäjän tiedotus on päällä.';
+$lang['add_ok'] = 'Käyttäjä lisätty onnistuneesti';
+$lang['add_fail'] = 'Käyttäjän lisäys epäonnistui';
+$lang['notify_ok'] = 'Ilmoitus sähköpostilla lähetetty';
+$lang['notify_fail'] = 'Ilmoitusta sähköpostilla ei voitu lähettää';
diff --git a/lib/plugins/usermanager/lang/fi/list.txt b/lib/plugins/usermanager/lang/fi/list.txt
new file mode 100644
index 000000000..5ecf2ff7b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fi/list.txt
@@ -0,0 +1 @@
+===== Käyttäjälista ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/fr/add.txt b/lib/plugins/usermanager/lang/fr/add.txt
new file mode 100644
index 000000000..e60b8b894
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/add.txt
@@ -0,0 +1 @@
+===== Ajouter un utilisateur =====
diff --git a/lib/plugins/usermanager/lang/fr/delete.txt b/lib/plugins/usermanager/lang/fr/delete.txt
new file mode 100644
index 000000000..778f44192
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/delete.txt
@@ -0,0 +1 @@
+===== Supprimer un utilisateur =====
diff --git a/lib/plugins/usermanager/lang/fr/edit.txt b/lib/plugins/usermanager/lang/fr/edit.txt
new file mode 100644
index 000000000..ec193eb5a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/edit.txt
@@ -0,0 +1 @@
+===== Modifier les informations d'un utilisateur =====
diff --git a/lib/plugins/usermanager/lang/fr/intro.txt b/lib/plugins/usermanager/lang/fr/intro.txt
new file mode 100644
index 000000000..84987b0bf
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/intro.txt
@@ -0,0 +1 @@
+====== Gestion des utilisateurs ======
diff --git a/lib/plugins/usermanager/lang/fr/lang.php b/lib/plugins/usermanager/lang/fr/lang.php
new file mode 100644
index 000000000..948262a8f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * french language file
+ *
+ * @author Guy Brand <gb@unistra.fr>
+ * @author Delassaux Julien <julien@delassaux.fr>
+ * @author Maurice A. LeBlanc <leblancma@cooptel.qc.ca>
+ * @author stephane.gully@gmail.com
+ * @author Guillaume Turri <guillaume.turri@gmail.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author olivier duperray <duperray.olivier@laposte.net>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author Philippe Bajoit <philippe.bajoit@gmail.com>
+ * @author Florian Gaub <floriang@floriang.net>
+ * @author Samuel Dorsaz samuel.dorsaz@novelion.net
+ * @author Johan Guilbaud <guilbaud.johan@gmail.com>
+ * @author schplurtz@laposte.net
+ * @author skimpax@gmail.com
+ */
+$lang['menu'] = 'Gestion des utilisateurs';
+$lang['noauth'] = '(authentification utilisateur non disponible)';
+$lang['nosupport'] = '(gestion utilisateur non supportée)';
+$lang['badauth'] = 'mécanisme d\'authentification invalide';
+$lang['user_id'] = 'Identifiant ';
+$lang['user_pass'] = 'Mot de passe ';
+$lang['user_name'] = 'Nom ';
+$lang['user_mail'] = 'Courriel ';
+$lang['user_groups'] = 'Groupes ';
+$lang['field'] = 'Champ';
+$lang['value'] = 'Valeur';
+$lang['add'] = 'Ajouter';
+$lang['delete'] = 'Supprimer';
+$lang['delete_selected'] = 'Supprimer la sélection';
+$lang['edit'] = 'Modifier';
+$lang['edit_prompt'] = 'Modifier cet utilisateur';
+$lang['modify'] = 'Enregistrer les modifications';
+$lang['search'] = 'Rechercher';
+$lang['search_prompt'] = 'Effectuer la recherche';
+$lang['clear'] = 'Réinitialiser la recherche';
+$lang['filter'] = 'Filtre';
+$lang['summary'] = 'Affichage des utilisateurs %1$d-%2$d parmi %3$d trouvé(s). %4$d utilisateur(s) au total.';
+$lang['nonefound'] = 'Aucun utilisateur trouvé. %d utilisateur(s) au total.';
+$lang['delete_ok'] = '%d utilisateurs effacés';
+$lang['delete_fail'] = '%d effacement échoué.';
+$lang['update_ok'] = 'Utilisateur mis à jour avec succès';
+$lang['update_fail'] = 'Échec de la mise à jour utilisateur';
+$lang['update_exists'] = 'Échec du changement de nom d\'utilisateur, le nom spécifié (%s) existe déjà (toutes les autres modifications seront effectuées).';
+$lang['start'] = 'Démarrage';
+$lang['prev'] = 'Précédent';
+$lang['next'] = 'Suivant';
+$lang['last'] = 'Dernier';
+$lang['edit_usermissing'] = 'Utilisateur sélectionné non trouvé, cet utilisateur a peut-être été supprimé ou modifié ailleurs.';
+$lang['user_notify'] = 'Notifier l\'utilisateur ';
+$lang['note_notify'] = 'Envoi de notification par courriel uniquement lorsqu\'un nouveau mot de passe est attribué à l\'utilisateur.';
+$lang['note_group'] = 'Les nouveaux utilisateurs seront ajoutés au groupe par défaut (%s) si aucun groupe n\'est spécifié.';
+$lang['note_pass'] = 'Le mot de passe sera généré automatiquement si le champ est laissé vide et si la notification de l\'utilisateur est activée.';
+$lang['add_ok'] = 'Utilisateur ajouté avec succès';
+$lang['add_fail'] = 'Échec de l\'ajout de l\'utilisateur';
+$lang['notify_ok'] = 'Courriel de notification expédié';
+$lang['notify_fail'] = 'Échec de l\'expédition du courriel de notification';
diff --git a/lib/plugins/usermanager/lang/fr/list.txt b/lib/plugins/usermanager/lang/fr/list.txt
new file mode 100644
index 000000000..2d708fe43
--- /dev/null
+++ b/lib/plugins/usermanager/lang/fr/list.txt
@@ -0,0 +1 @@
+===== Liste des utilisateurs =====
diff --git a/lib/plugins/usermanager/lang/gl/add.txt b/lib/plugins/usermanager/lang/gl/add.txt
new file mode 100644
index 000000000..7602c36ec
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/add.txt
@@ -0,0 +1 @@
+===== Engadir usuario ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/gl/delete.txt b/lib/plugins/usermanager/lang/gl/delete.txt
new file mode 100644
index 000000000..4262a0c05
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/delete.txt
@@ -0,0 +1 @@
+===== Eliminar usuario ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/gl/edit.txt b/lib/plugins/usermanager/lang/gl/edit.txt
new file mode 100644
index 000000000..11ef62cce
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/edit.txt
@@ -0,0 +1 @@
+===== Editar usuario ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/gl/intro.txt b/lib/plugins/usermanager/lang/gl/intro.txt
new file mode 100644
index 000000000..77675e9d6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/intro.txt
@@ -0,0 +1 @@
+====== Xestor de Usuarios ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/gl/lang.php b/lib/plugins/usermanager/lang/gl/lang.php
new file mode 100644
index 000000000..c9c633b39
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/lang.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Galicianlanguage file
+ *
+ * @author Medúlio <medulio@ciberirmandade.org>
+ * @author Oscar M. Lage <r0sk10@gmail.com>
+ */
+$lang['menu'] = 'Xestor de Usuarios';
+$lang['noauth'] = '(autenticación de usuarios non dispoñible)';
+$lang['nosupport'] = '(xestión de usuarios non soportada)';
+$lang['badauth'] = 'mecanismo de autenticación non válido';
+$lang['user_id'] = 'Usuario';
+$lang['user_pass'] = 'Contrasinal';
+$lang['user_name'] = 'Nome Real';
+$lang['user_mail'] = 'Correo-e';
+$lang['user_groups'] = 'Grupos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Engadir';
+$lang['delete'] = 'Eliminar';
+$lang['delete_selected'] = 'Eliminar Seleccionados';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar este usuario';
+$lang['modify'] = 'Gardar Trocos';
+$lang['search'] = 'Procurar';
+$lang['search_prompt'] = 'Facer procura';
+$lang['clear'] = 'Reiniciar Filtro de Procura';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Amosando usuarios %1$d-%2$d de %3$d atopados. %4$d usuarios en total.';
+$lang['nonefound'] = 'Non se atoparon usuarios. %d usuarios en total.';
+$lang['delete_ok'] = '%d usuarios eliminados';
+$lang['delete_fail'] = '%d non puideron ser eliminados.';
+$lang['update_ok'] = 'Usuario actualizado correctamente';
+$lang['update_fail'] = 'Non se puido actualizar o usuario';
+$lang['update_exists'] = 'Non se puido mudar o nome do usuario, xa que o nome especificado (%s) xa existe (o resto de trocos aplicaranse sen problemas).';
+$lang['start'] = 'comezo';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'seguinte';
+$lang['last'] = 'derradeiro';
+$lang['edit_usermissing'] = 'Non se atopou o usuario seleccionado, pode que o nome de usuario fose eliminado ou mudado nalgún intre.';
+$lang['user_notify'] = 'Notificar ao usuario';
+$lang['note_notify'] = 'Os correos-e de notificación envíanse só se o usuario obtén un novo contrasinal.';
+$lang['note_group'] = 'Os novos usuarios serán engadidos ao grupo por defecto (%s) se non se especifica outro.';
+$lang['note_pass'] = 'Se deixas o campo baleiro e a notificación ao usuario está activada xerarase automaticamente o contrasinal.';
+$lang['add_ok'] = 'Usuario engadido correctamente';
+$lang['add_fail'] = 'Non se puido engadir o usuario';
+$lang['notify_ok'] = 'Correo-e de notificación enviado';
+$lang['notify_fail'] = 'Non se puido enviar o correo-e de notificación';
diff --git a/lib/plugins/usermanager/lang/gl/list.txt b/lib/plugins/usermanager/lang/gl/list.txt
new file mode 100644
index 000000000..013b2d7d8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/gl/list.txt
@@ -0,0 +1 @@
+===== Lista de Usuarios ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/he/add.txt b/lib/plugins/usermanager/lang/he/add.txt
new file mode 100644
index 000000000..e2d1cb775
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/add.txt
@@ -0,0 +1 @@
+===== הוספת משתמש =====
diff --git a/lib/plugins/usermanager/lang/he/delete.txt b/lib/plugins/usermanager/lang/he/delete.txt
new file mode 100644
index 000000000..42d738b1d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/delete.txt
@@ -0,0 +1 @@
+===== מחיקת משתמש =====
diff --git a/lib/plugins/usermanager/lang/he/edit.txt b/lib/plugins/usermanager/lang/he/edit.txt
new file mode 100644
index 000000000..af90af359
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/edit.txt
@@ -0,0 +1 @@
+===== עריכת משתמש =====
diff --git a/lib/plugins/usermanager/lang/he/intro.txt b/lib/plugins/usermanager/lang/he/intro.txt
new file mode 100644
index 000000000..232c5153b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/intro.txt
@@ -0,0 +1 @@
+====== מנהל משתמשים ======
diff --git a/lib/plugins/usermanager/lang/he/lang.php b/lib/plugins/usermanager/lang/he/lang.php
new file mode 100644
index 000000000..601163013
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * hebrew language file
+ *
+ * @author DoK <kamberd@yahoo.com>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ * @author Moshe Kaplan <mokplan@gmail.com>
+ * @author Yaron Yogev <yaronyogev@gmail.com>
+ * @author Yaron Shahrabani <sh.yaron@gmail.com>
+ */
+$lang['menu'] = 'מנהל משתמשים';
+$lang['noauth'] = '(אימות משתמשים אינו זמין)';
+$lang['nosupport'] = '(ניהול משתמשים אינו נתמך)';
+$lang['badauth'] = 'מנגנון אימות לא תקף';
+$lang['user_id'] = 'שם משתמש';
+$lang['user_pass'] = 'סיסמה';
+$lang['user_name'] = 'שם אמיתי';
+$lang['user_mail'] = 'דוא"ל';
+$lang['user_groups'] = 'קבוצות';
+$lang['field'] = 'שדה';
+$lang['value'] = 'ערך';
+$lang['add'] = 'הוספה';
+$lang['delete'] = 'מחיקה';
+$lang['delete_selected'] = 'מחיקת הבחירה';
+$lang['edit'] = 'עריכה';
+$lang['edit_prompt'] = 'עריכת משתמש זה';
+$lang['modify'] = 'שמירת שינוים';
+$lang['search'] = 'חיפוש';
+$lang['search_prompt'] = 'בצע חיפוש';
+$lang['clear'] = 'אתחל סינון חיפוש';
+$lang['filter'] = 'סינון';
+$lang['summary'] = 'מציג משתמשים %1$d-%2$d מתוך %3$d שנמצאו. %4$d בסך הכל.';
+$lang['nonefound'] = 'לא נמצאו משתמשים. סך כל המשתמשים %d.';
+$lang['delete_ok'] = '%d משתמשים נמחקו';
+$lang['delete_fail'] = '%d כשל במחיקה.';
+$lang['update_ok'] = 'משתמש עודכן בהצלחה';
+$lang['update_fail'] = 'עידכון המשתמש כשל';
+$lang['update_exists'] = 'שינוי שם המשתמש כשל, שם השמתמש שצויין (%s) כבר נמצא (כל השינויים האחרים יוחלו).';
+$lang['start'] = 'התחלה';
+$lang['prev'] = 'קודם';
+$lang['next'] = 'הבא';
+$lang['last'] = 'סוף';
+$lang['edit_usermissing'] = 'המשתמש שנבחר לא נמצא, ייתכן כי שם המשתמש שצויין נמחק או השתנה במקום אחר.';
+$lang['user_notify'] = 'הודע למשתמש';
+$lang['note_notify'] = 'הודעות בדוא"ל נשלחות רק במקרה שהמשתמש מקבל סיסמה חדשה.';
+$lang['note_group'] = 'משתמשים חדשים יוספו לקבוצת ברירת המחדל (%s) אם לא צוינה קבוצה אחרת.';
+$lang['add_ok'] = 'משתמש הוסף בהצלחה';
+$lang['add_fail'] = 'הוספת המשתמש כשלה';
+$lang['notify_ok'] = 'הודעה נשלחה';
+$lang['notify_fail'] = 'לא ניתן היה לשלוח הודעה';
diff --git a/lib/plugins/usermanager/lang/he/list.txt b/lib/plugins/usermanager/lang/he/list.txt
new file mode 100644
index 000000000..9308fbebb
--- /dev/null
+++ b/lib/plugins/usermanager/lang/he/list.txt
@@ -0,0 +1 @@
+===== רשימת משתמשים =====
diff --git a/lib/plugins/usermanager/lang/hi/lang.php b/lib/plugins/usermanager/lang/hi/lang.php
new file mode 100644
index 000000000..d6f78ffd6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hi/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * Hindi language file
+ *
+ * @author Abhinav Tyagi <abhinavtyagi11@gmail.com>
+ * @author yndesai@gmail.com
+ */
diff --git a/lib/plugins/usermanager/lang/hr/lang.php b/lib/plugins/usermanager/lang/hr/lang.php
new file mode 100644
index 000000000..96f1d6afe
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hr/lang.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Croatian language file
+ *
+ * @author Branko Rihtman <theney@gmail.com>
+ * @author Dražen Odobašić <dodobasic@gmail.com>
+ * @author Dejan Igrec dejan.igrec@gmail.com
+ */
diff --git a/lib/plugins/usermanager/lang/hu/add.txt b/lib/plugins/usermanager/lang/hu/add.txt
new file mode 100644
index 000000000..70a44c41d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/add.txt
@@ -0,0 +1,2 @@
+===== Felhasználó hozzáadása =====
+
diff --git a/lib/plugins/usermanager/lang/hu/delete.txt b/lib/plugins/usermanager/lang/hu/delete.txt
new file mode 100644
index 000000000..963d2e7b3
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/delete.txt
@@ -0,0 +1,2 @@
+===== Felhasználó törlése =====
+
diff --git a/lib/plugins/usermanager/lang/hu/edit.txt b/lib/plugins/usermanager/lang/hu/edit.txt
new file mode 100644
index 000000000..f82746094
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/edit.txt
@@ -0,0 +1,2 @@
+===== Felhasználó szerkesztése =====
+
diff --git a/lib/plugins/usermanager/lang/hu/intro.txt b/lib/plugins/usermanager/lang/hu/intro.txt
new file mode 100644
index 000000000..150aff848
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/intro.txt
@@ -0,0 +1,2 @@
+====== Felhasználók kezelése ======
+
diff --git a/lib/plugins/usermanager/lang/hu/lang.php b/lib/plugins/usermanager/lang/hu/lang.php
new file mode 100644
index 000000000..9b9740cb0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/lang.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Hungarian language file
+ *
+ * @author Sandor TIHANYI <stihanyi+dw@gmail.com>
+ * @author Siaynoq Mage <siaynoqmage@gmail.com>
+ * @author schilling.janos@gmail.com
+ * @author Szabó Dávid <szabo.david@gyumolcstarhely.hu>
+ * @author Sándor TIHANYI <stihanyi+dw@gmail.com>
+ * @author David Szabo <szabo.david@gyumolcstarhely.hu>
+ */
+$lang['menu'] = 'Felhasználók kezelése';
+$lang['noauth'] = '(A felhasználói azonosítás nem működik.)';
+$lang['nosupport'] = '(A felhasználók kezelése nem támogatott.)';
+$lang['badauth'] = 'nem érvényes autentikációs technika';
+$lang['user_id'] = 'Felhasználó azonosító';
+$lang['user_pass'] = 'Jelszó';
+$lang['user_name'] = 'Név';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Csoportok';
+$lang['field'] = 'Mező';
+$lang['value'] = 'Érték';
+$lang['add'] = 'Hozzáadás';
+$lang['delete'] = 'Törlés';
+$lang['delete_selected'] = 'Kiválasztottak törlése';
+$lang['edit'] = 'Szerkesztés';
+$lang['edit_prompt'] = 'A felhasználó szerkesztése';
+$lang['modify'] = 'Változások mentése';
+$lang['search'] = 'Keresés';
+$lang['search_prompt'] = 'Keresés';
+$lang['clear'] = 'Keresési szűrés törlése';
+$lang['filter'] = 'Szűrés';
+$lang['summary'] = '%1$d-%2$d. felhasználókat mutatom a(z) %3$d megtalált felhasználóból. %4$d felhasználó van összesen.';
+$lang['nonefound'] = 'Nem találtam ilyen felhasználót. %d felhasználó van összesen.';
+$lang['delete_ok'] = '%d felhasználó törölve.';
+$lang['delete_fail'] = '%d felhasználót nem sikerült törölni.';
+$lang['update_ok'] = 'A felhasználó adatait sikeresen elmentettem.';
+$lang['update_fail'] = 'A felhasználó adatainak mentése nem sikerült.';
+$lang['update_exists'] = 'A felhasználói azonosító változtatása nem sikerült, a megadott azonosító (%s) már létezik. (A többi változtatás mentve.)';
+$lang['start'] = 'első';
+$lang['prev'] = 'előző';
+$lang['next'] = 'következő';
+$lang['last'] = 'utolsó';
+$lang['edit_usermissing'] = 'A kiválasztott felhasználót nem találom, a felhasználói nevét törölték vagy megváltoztatták.';
+$lang['user_notify'] = 'Felhasználó értesítése';
+$lang['note_notify'] = 'Csak akkor küld értesítő e-mailt, ha a felhasználó új jelszót kapott.';
+$lang['note_group'] = 'Ha nincs csoport meghatározva, az új felhasználó az alapértelmezett csoportba (%s) kerül.';
+$lang['note_pass'] = 'Ha a baloldali mező üres, és a felhasználó értesítés aktív, akkor generált jelszó lesz.';
+$lang['add_ok'] = 'A felhasználó sikeresen hozzáadva.';
+$lang['add_fail'] = 'A felhasználó hozzáadása nem sikerült.';
+$lang['notify_ok'] = 'Értesítő levél elküldve.';
+$lang['notify_fail'] = 'Nem sikerült az értesítő levelet elküldeni.';
diff --git a/lib/plugins/usermanager/lang/hu/list.txt b/lib/plugins/usermanager/lang/hu/list.txt
new file mode 100644
index 000000000..9da7320c6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/hu/list.txt
@@ -0,0 +1,2 @@
+===== Felhasználók listája =====
+
diff --git a/lib/plugins/usermanager/lang/ia/add.txt b/lib/plugins/usermanager/lang/ia/add.txt
new file mode 100644
index 000000000..4695834f4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/add.txt
@@ -0,0 +1 @@
+===== Adder usator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ia/delete.txt b/lib/plugins/usermanager/lang/ia/delete.txt
new file mode 100644
index 000000000..db1b4c077
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/delete.txt
@@ -0,0 +1 @@
+===== Deler usator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ia/edit.txt b/lib/plugins/usermanager/lang/ia/edit.txt
new file mode 100644
index 000000000..2fcf02378
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/edit.txt
@@ -0,0 +1 @@
+===== Modificar usator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ia/intro.txt b/lib/plugins/usermanager/lang/ia/intro.txt
new file mode 100644
index 000000000..f4fafcb9b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/intro.txt
@@ -0,0 +1 @@
+====== Gestion de usatores ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ia/lang.php b/lib/plugins/usermanager/lang/ia/lang.php
new file mode 100644
index 000000000..a8b8f45c0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Interlingua language file
+ *
+ * @author robocap <robocap1@gmail.com>
+ * @author Martijn Dekker <martijn@inlv.org>
+ */
+$lang['menu'] = 'Gestion de usatores';
+$lang['noauth'] = '(authentication de usatores non disponibile)';
+$lang['nosupport'] = '(gestion de usatores non supportate)';
+$lang['badauth'] = 'mechanismo de authentication invalide';
+$lang['user_id'] = 'Usator';
+$lang['user_pass'] = 'Contrasigno';
+$lang['user_name'] = 'Nomine real';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Gruppos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Adder';
+$lang['delete'] = 'Deler';
+$lang['delete_selected'] = 'Deler seligite';
+$lang['edit'] = 'Modificar';
+$lang['edit_prompt'] = 'Modificar iste usator';
+$lang['modify'] = 'Salveguardar cambios';
+$lang['search'] = 'Cercar';
+$lang['search_prompt'] = 'Executar recerca';
+$lang['clear'] = 'Reinitialisar filtro de recerca';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Presentation del usatores %1$d-%2$d de %3$d trovate. %4$d usatores in total.';
+$lang['nonefound'] = 'Nulle usator trovate. %d usatores in total.';
+$lang['delete_ok'] = '%d usatores delite';
+$lang['delete_fail'] = 'Deletion de %d usatores fallite.';
+$lang['update_ok'] = 'Actualisation del usator succedite';
+$lang['update_fail'] = 'Actualisation del usator fallite';
+$lang['update_exists'] = 'Le modification del nomine del usator ha fallite; le usator specificate (%s) ja existe. (Omne altere modificationes essera applicate.)
+';
+$lang['start'] = 'initio';
+$lang['prev'] = 'precedente';
+$lang['next'] = 'sequente';
+$lang['last'] = 'fin';
+$lang['edit_usermissing'] = 'Le usator seligite non ha essite trovate. Es possibile que le nomine de usator specificate ha essite delite o cambiate alterubi.';
+$lang['user_notify'] = 'Notificar usator';
+$lang['note_notify'] = 'Le messages de notification es solmente inviate un nove contrasigno es date al usator.';
+$lang['note_group'] = 'Nove usatores essera addite al gruppo predefinite (%s) si nulle gruppo es specificate.';
+$lang['note_pass'] = 'Le contrasigno essera automaticamente generate si le campo es lassate vacue e le notification del usator es activate.';
+$lang['add_ok'] = 'Addition del usator succedite';
+$lang['add_fail'] = 'Addition del usator fallite';
+$lang['notify_ok'] = 'Message de notification inviate';
+$lang['notify_fail'] = 'Le message de notification non poteva esser inviate';
diff --git a/lib/plugins/usermanager/lang/ia/list.txt b/lib/plugins/usermanager/lang/ia/list.txt
new file mode 100644
index 000000000..f545f06df
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ia/list.txt
@@ -0,0 +1 @@
+===== Lista de usatores ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id-ni/lang.php b/lib/plugins/usermanager/lang/id-ni/lang.php
new file mode 100644
index 000000000..d367340b7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id-ni/lang.php
@@ -0,0 +1,7 @@
+<?php
+/**
+ * idni language file
+ *
+ * @author Harefa <fidelis@harefa.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
diff --git a/lib/plugins/usermanager/lang/id/add.txt b/lib/plugins/usermanager/lang/id/add.txt
new file mode 100644
index 000000000..eae407c04
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/add.txt
@@ -0,0 +1 @@
+===== Tambah User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id/delete.txt b/lib/plugins/usermanager/lang/id/delete.txt
new file mode 100644
index 000000000..99e53c9ef
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/delete.txt
@@ -0,0 +1 @@
+===== Hapus User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id/edit.txt b/lib/plugins/usermanager/lang/id/edit.txt
new file mode 100644
index 000000000..6d14f4fde
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/edit.txt
@@ -0,0 +1 @@
+===== Edit User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id/intro.txt b/lib/plugins/usermanager/lang/id/intro.txt
new file mode 100644
index 000000000..de053f2ae
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/intro.txt
@@ -0,0 +1 @@
+===== Manajemen User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/id/lang.php b/lib/plugins/usermanager/lang/id/lang.php
new file mode 100644
index 000000000..457ad4963
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Indonesian language file
+ *
+ * @author Irwan Butar Butar <irwansah.putra@gmail.com>
+ * @author Yustinus Waruwu <juswaruwu@gmail.com>
+ */
+$lang['menu'] = 'Manajemen User';
+$lang['noauth'] = '(autentikasi tidak tersedia)';
+$lang['nosupport'] = '(manajemen user tidak didukung)';
+$lang['badauth'] = 'mekanisme autentikasi invali';
+$lang['user_id'] = 'User';
+$lang['user_pass'] = 'Password';
+$lang['user_name'] = 'Nama Lengkap';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Grup';
+$lang['field'] = 'Field';
+$lang['value'] = 'Nilai';
+$lang['add'] = 'Tambah';
+$lang['delete'] = 'Hapus';
+$lang['delete_selected'] = 'Hapus pilihan';
+$lang['edit'] = 'Edit';
+$lang['edit_prompt'] = 'Edit user ini';
+$lang['modify'] = 'Simpan Perubahan';
+$lang['search'] = 'Pencarian';
+$lang['search_prompt'] = 'Lakukan pencarian';
+$lang['clear'] = 'Reset Filter Pencarian';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Menampilkan user %1$d-%2$d dari %3$d user yang ditemukan. Total semua user %4$d.';
+$lang['nonefound'] = 'User tidak ditemukan. Total semua user %d. ';
+$lang['delete_ok'] = 'User %d dihapus';
+$lang['delete_fail'] = 'User %d tidak berhasil dihapus';
+$lang['update_ok'] = 'User berhasil diubah';
+$lang['update_fail'] = 'Perubahan user tidak berhasil';
+$lang['update_exists'] = 'Perubahan username tidak berhasil, Username (%s) sudah ada (perubahan lain tetap dilakukan)';
+$lang['start'] = 'awal';
+$lang['prev'] = 'sebelumnya';
+$lang['next'] = 'berikutnya';
+$lang['last'] = 'terakhir';
+$lang['edit_usermissing'] = 'User yang dipilih tida ditemukan, username tersebut mungkin sudah dihapus atau diubah ditempat lain.';
+$lang['user_notify'] = 'Beritahu user';
+$lang['note_notify'] = 'Email notifikasi hanya dikirim jika user diberikan password baru';
+$lang['note_group'] = 'User baru akan ditambahkan ke grup default (%s) jika tidak ada grup yang diisi.';
+$lang['add_ok'] = 'User telah berhasil ditambahkan';
+$lang['add_fail'] = 'Penambahan user tidak berhasil.';
+$lang['notify_ok'] = 'Email notifikasi berhasil terkirim.';
+$lang['notify_fail'] = 'Email notifikasi tidak berhasil terkirim.';
diff --git a/lib/plugins/usermanager/lang/id/list.txt b/lib/plugins/usermanager/lang/id/list.txt
new file mode 100644
index 000000000..9b70bc157
--- /dev/null
+++ b/lib/plugins/usermanager/lang/id/list.txt
@@ -0,0 +1 @@
+===== Daftar User ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/is/delete.txt b/lib/plugins/usermanager/lang/is/delete.txt
new file mode 100644
index 000000000..564006584
--- /dev/null
+++ b/lib/plugins/usermanager/lang/is/delete.txt
@@ -0,0 +1 @@
+===== Eyða notanda ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/is/lang.php b/lib/plugins/usermanager/lang/is/lang.php
new file mode 100644
index 000000000..cabf83d64
--- /dev/null
+++ b/lib/plugins/usermanager/lang/is/lang.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Icelandic language file
+ *
+ * @author Hrannar Baldursson <hrannar.baldursson@gmail.com>
+ * @author Ólafur Gunnlaugsson <oli@audiotools.com>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ */
+$lang['user_id'] = 'Notandi';
+$lang['user_pass'] = 'Aðgangsorð';
+$lang['user_name'] = 'Raunnafn';
+$lang['user_groups'] = 'Hópar';
+$lang['field'] = 'Svæði';
+$lang['delete'] = 'Eyða';
+$lang['add_ok'] = 'Notandinn var bætt við';
+$lang['add_fail'] = 'Bæta við nýjum notanda mistókst';
+$lang['notify_ok'] = 'Tilkynning var sendast með tölvupósti';
+$lang['notify_fail'] = 'Ekki hægt að senda tilkynning með tölvupósti';
diff --git a/lib/plugins/usermanager/lang/it/add.txt b/lib/plugins/usermanager/lang/it/add.txt
new file mode 100644
index 000000000..9ce4c6e38
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/add.txt
@@ -0,0 +1 @@
+===== Aggiungi utente =====
diff --git a/lib/plugins/usermanager/lang/it/delete.txt b/lib/plugins/usermanager/lang/it/delete.txt
new file mode 100644
index 000000000..270061f0d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/delete.txt
@@ -0,0 +1 @@
+===== Elimina utente =====
diff --git a/lib/plugins/usermanager/lang/it/edit.txt b/lib/plugins/usermanager/lang/it/edit.txt
new file mode 100644
index 000000000..39767bfdc
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/edit.txt
@@ -0,0 +1 @@
+===== Modifica utente =====
diff --git a/lib/plugins/usermanager/lang/it/intro.txt b/lib/plugins/usermanager/lang/it/intro.txt
new file mode 100644
index 000000000..3421709d6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/intro.txt
@@ -0,0 +1 @@
+====== Gestione Utenti ======
diff --git a/lib/plugins/usermanager/lang/it/lang.php b/lib/plugins/usermanager/lang/it/lang.php
new file mode 100644
index 000000000..34c510def
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Italian language file
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Silvia Sargentoni <polinnia@tin.it>
+ * @author Pietro Battiston toobaz@email.it
+ * @author Diego Pierotto ita.translations@tiscali.it
+ * @author ita.translations@tiscali.it
+ * @author Lorenzo Breda <lbreda@gmail.com>
+ * @author snarchio@alice.it
+ * @author robocap <robocap1@gmail.com>
+ * @author Osman Tekin osman.tekin93@hotmail.it
+ * @author Jacopo Corbetta <jacopo.corbetta@gmail.com>
+ */
+$lang['menu'] = 'Gestione Utenti';
+$lang['noauth'] = '(autenticazione non disponibile)';
+$lang['nosupport'] = '(gestione utenti non supportata)';
+$lang['badauth'] = 'sistema di autenticazione non valido';
+$lang['user_id'] = 'ID utente';
+$lang['user_pass'] = 'Password';
+$lang['user_name'] = 'Nome completo';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Gruppi';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valore';
+$lang['add'] = 'Aggiungi';
+$lang['delete'] = 'Elimina';
+$lang['delete_selected'] = 'Elimina selezionati';
+$lang['edit'] = 'Modifica';
+$lang['edit_prompt'] = 'Modifica questo utente';
+$lang['modify'] = 'Salva modifiche';
+$lang['search'] = 'Cerca';
+$lang['search_prompt'] = 'Esegui ricerca';
+$lang['clear'] = 'Azzera filtro di ricerca';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Visualizzazione utenti %1$d-%2$d di %3$d trovati. %4$d utenti totali.';
+$lang['nonefound'] = 'Nessun utente trovato. %d utenti totali.';
+$lang['delete_ok'] = '%d utenti eliminati';
+$lang['delete_fail'] = 'Eliminazione %d fallita.';
+$lang['update_ok'] = 'Aggiornamento utente riuscito';
+$lang['update_fail'] = 'Aggiornamento utente fallito';
+$lang['update_exists'] = 'Modifica nome utente fallita, il nome utente specificato (%s) esiste già (qualunque altra modifica sarà applicata).';
+$lang['start'] = 'primo';
+$lang['prev'] = 'precedente';
+$lang['next'] = 'successivo';
+$lang['last'] = 'ultimo';
+$lang['edit_usermissing'] = 'Utente selezionato non trovato, il nome utente specificato potrebbe essere stato eliminato o modificato altrove.';
+$lang['user_notify'] = 'Notifica utente';
+$lang['note_notify'] = 'Le email di notifica sono inviate soltanto se all\'utente è stata assegnata una nuova password.';
+$lang['note_group'] = 'Se non si specifica alcun gruppo, i nuovi utenti saranno aggiunti al gruppo predefinito (%s).';
+$lang['note_pass'] = 'La password verrà generata automaticamente qualora il campo di inserimento relativo venisse lasciato vuoto e le notifiche all\'utente fossero abilitate.';
+$lang['add_ok'] = 'Utente aggiunto correttamente';
+$lang['add_fail'] = 'Aggiunta utente fallita';
+$lang['notify_ok'] = 'Email di notifica inviata';
+$lang['notify_fail'] = 'L\'email di notifica non può essere inviata';
diff --git a/lib/plugins/usermanager/lang/it/list.txt b/lib/plugins/usermanager/lang/it/list.txt
new file mode 100644
index 000000000..91e27a9de
--- /dev/null
+++ b/lib/plugins/usermanager/lang/it/list.txt
@@ -0,0 +1 @@
+===== Elenco Utenti =====
diff --git a/lib/plugins/usermanager/lang/ja/add.txt b/lib/plugins/usermanager/lang/ja/add.txt
new file mode 100644
index 000000000..87b30e0a0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/add.txt
@@ -0,0 +1 @@
+===== ユーザー作成 =====
diff --git a/lib/plugins/usermanager/lang/ja/delete.txt b/lib/plugins/usermanager/lang/ja/delete.txt
new file mode 100644
index 000000000..67ef23e23
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/delete.txt
@@ -0,0 +1 @@
+===== ユーザー削除 =====
diff --git a/lib/plugins/usermanager/lang/ja/edit.txt b/lib/plugins/usermanager/lang/ja/edit.txt
new file mode 100644
index 000000000..e7695e307
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/edit.txt
@@ -0,0 +1 @@
+===== ユーザー編集 =====
diff --git a/lib/plugins/usermanager/lang/ja/intro.txt b/lib/plugins/usermanager/lang/ja/intro.txt
new file mode 100644
index 000000000..5dbe51c8c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/intro.txt
@@ -0,0 +1 @@
+====== ユーザー管理 ======
diff --git a/lib/plugins/usermanager/lang/ja/lang.php b/lib/plugins/usermanager/lang/ja/lang.php
new file mode 100644
index 000000000..321bbafe8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * japanese language file
+ * @author Yuji Takenaka <webmaster@davilin.com>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Ikuo Obataya <i.obataya@gmail.com>
+ * @author Daniel Dupriest <kououken@gmail.com>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+$lang['menu'] = 'ユーザー管理';
+$lang['noauth'] = '(ユーザー認証が無効です)';
+$lang['nosupport'] = '(ユーザー管理はサポートされていません)';
+$lang['badauth'] = '認証のメカニズムが無効です';
+$lang['user_id'] = 'ユーザー';
+$lang['user_pass'] = 'パスワード';
+$lang['user_name'] = '氏名';
+$lang['user_mail'] = 'メールアドレス';
+$lang['user_groups'] = 'グループ';
+$lang['field'] = '項目';
+$lang['value'] = '値';
+$lang['add'] = '追加';
+$lang['delete'] = '削除';
+$lang['delete_selected'] = '選択したユーザーを削除';
+$lang['edit'] = '編集';
+$lang['edit_prompt'] = 'このユーザーを編集';
+$lang['modify'] = '変更を保存';
+$lang['search'] = '検索';
+$lang['search_prompt'] = '検索を実行';
+$lang['clear'] = '検索フィルターをリセット';
+$lang['filter'] = 'フィルター';
+$lang['summary'] = 'ユーザー %1$d-%2$d / %3$d, 総ユーザー数 %4$d';
+$lang['nonefound'] = 'ユーザーが見つかりません, 総ユーザー数 %d';
+$lang['delete_ok'] = '%d ユーザーが削除されました';
+$lang['delete_fail'] = '%d ユーザーの削除に失敗しました';
+$lang['update_ok'] = 'ユーザーは更新されました';
+$lang['update_fail'] = 'ユーザーの更新に失敗しました';
+$lang['update_exists'] = 'ユーザー名(%s)は既に存在するため、ユーザー名の変更に失敗しました(その他の項目は変更されました)。';
+$lang['start'] = '最初';
+$lang['prev'] = '前へ';
+$lang['next'] = '次へ';
+$lang['last'] = '最後';
+$lang['edit_usermissing'] = '選択したユーザーは見つかりません。削除もしくは変更された可能性があります。';
+$lang['user_notify'] = '通知するユーザー';
+$lang['note_notify'] = 'ユーザーが新しいパスワードを設定した場合のみ、通知メールが送信されます。';
+$lang['note_group'] = 'グループを指定しない場合は、既定のグループ(%s)に登録されいます。';
+$lang['note_pass'] = 'パスワードを空欄とした場合は、パスワードを自動的に生成します。この場合、ユーザーへの通知が有効となります。';
+$lang['add_ok'] = 'ユーザーを登録しました';
+$lang['add_fail'] = 'ユーザーの登録に失敗しました';
+$lang['notify_ok'] = '通知メールを送信しました';
+$lang['notify_fail'] = '通知メールを送信できませんでした';
diff --git a/lib/plugins/usermanager/lang/ja/list.txt b/lib/plugins/usermanager/lang/ja/list.txt
new file mode 100644
index 000000000..182cc198c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ja/list.txt
@@ -0,0 +1 @@
+===== ユーザーリスト =====
diff --git a/lib/plugins/usermanager/lang/kk/lang.php b/lib/plugins/usermanager/lang/kk/lang.php
new file mode 100644
index 000000000..dde5b9577
--- /dev/null
+++ b/lib/plugins/usermanager/lang/kk/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * kazakh language file
+ *
+ * @author Nurgozha Kaliaskarov astana08@gmail.com
+ */
diff --git a/lib/plugins/usermanager/lang/ko/add.txt b/lib/plugins/usermanager/lang/ko/add.txt
new file mode 100644
index 000000000..578ba5636
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/add.txt
@@ -0,0 +1 @@
+===== 사용자 추가 =====
diff --git a/lib/plugins/usermanager/lang/ko/delete.txt b/lib/plugins/usermanager/lang/ko/delete.txt
new file mode 100644
index 000000000..1e9c0ba73
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/delete.txt
@@ -0,0 +1 @@
+===== 사용자 삭제 =====
diff --git a/lib/plugins/usermanager/lang/ko/edit.txt b/lib/plugins/usermanager/lang/ko/edit.txt
new file mode 100644
index 000000000..b8b13c5c8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/edit.txt
@@ -0,0 +1 @@
+===== 사용자 정보 수정 =====
diff --git a/lib/plugins/usermanager/lang/ko/intro.txt b/lib/plugins/usermanager/lang/ko/intro.txt
new file mode 100644
index 000000000..8c8bfa5b9
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/intro.txt
@@ -0,0 +1 @@
+====== 사용자 관리 ======
diff --git a/lib/plugins/usermanager/lang/ko/lang.php b/lib/plugins/usermanager/lang/ko/lang.php
new file mode 100644
index 000000000..f2322414a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * korean language file
+ *
+ * @author jk Lee
+ * @author dongnak@gmail.com
+ * @author Song Younghwan <purluno@gmail.com>
+ * @author SONG Younghwan <purluno@gmail.com>
+ * @author Seung-Chul Yoo <dryoo@live.com>
+ */
+$lang['menu'] = '사용자 관리자';
+$lang['noauth'] = '(사용자 인증이 불가능합니다.)';
+$lang['nosupport'] = '(사용자 관리가 지원되지 않습니다.)';
+$lang['badauth'] = '유효하지 않은 인증 메카니즘입니다.';
+$lang['user_id'] = '사용자';
+$lang['user_pass'] = '패스워드';
+$lang['user_name'] = '실제 이름';
+$lang['user_mail'] = '이메일 ';
+$lang['user_groups'] = '그룹들';
+$lang['field'] = '항목';
+$lang['value'] = '값';
+$lang['add'] = '추가';
+$lang['delete'] = '삭제';
+$lang['delete_selected'] = '삭제 선택';
+$lang['edit'] = '수정';
+$lang['edit_prompt'] = '이 사용자 수정';
+$lang['modify'] = '변경 저장';
+$lang['search'] = '검색';
+$lang['search_prompt'] = '검색 실행';
+$lang['clear'] = '검색 필터 초기화';
+$lang['filter'] = '필터';
+$lang['summary'] = '검색된 사용자들 보기(%1$d-%2$d 중 %3$d). 전체 사용자 %4$d 명.';
+$lang['nonefound'] = '검색된 사용자가 없습니다. 전체 사용자 %d 명.';
+$lang['delete_ok'] = '%d 명의 사용자가 삭제되었습니다.';
+$lang['delete_fail'] = '%d 명의 사용자의 삭제가 실패했습니다.';
+$lang['update_ok'] = '사용자 갱신이 성공했습니다.';
+$lang['update_fail'] = '사용자 갱신이 실패했습니다.';
+$lang['update_exists'] = '사용자 이름 변경이 실패했습니다. 사용자 이름(%s)이 이미 존재합니다. (다른 항목들의 변경은 적용됩니다.)';
+$lang['start'] = '시작';
+$lang['prev'] = '이전';
+$lang['next'] = '다음';
+$lang['last'] = '마지막';
+$lang['edit_usermissing'] = '선택된 사용자를 찾을 수 없습니다, 사용자 이름이 삭제되거나 변경됐을 수도 있습니다.';
+$lang['user_notify'] = '사용자에게 알림';
+$lang['note_notify'] = '사용자에게 새로운 암호를 준 경우에만 알림 이메일이 보내집니다.';
+$lang['note_group'] = '새로운 사용자들은 어떤 그룹도 설정하지 않은 경우에 기본 그룹(%s)에 추가됩니다.';
+$lang['note_pass'] = '사용자 통지가 지정되어 있을때, 필드에 아무값도 입력하지 않으면 암호가 자동 생성 됩니다.';
+$lang['add_ok'] = '사용자가 성공적으로 추가되었습니다.';
+$lang['add_fail'] = '사용자 추가가 실패했습니다.';
+$lang['notify_ok'] = '알림 이메일이 성공적으로 발송되었습니다. ';
+$lang['notify_fail'] = '알림 이메일 발송이 실패했습니다.';
diff --git a/lib/plugins/usermanager/lang/ko/list.txt b/lib/plugins/usermanager/lang/ko/list.txt
new file mode 100644
index 000000000..93fa3d6f2
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ko/list.txt
@@ -0,0 +1 @@
+===== 사용자 목록 =====
diff --git a/lib/plugins/usermanager/lang/la/add.txt b/lib/plugins/usermanager/lang/la/add.txt
new file mode 100644
index 000000000..beb797c4a
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/add.txt
@@ -0,0 +1 @@
+===== Sodalem addere ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/la/delete.txt b/lib/plugins/usermanager/lang/la/delete.txt
new file mode 100644
index 000000000..1eb5e1f14
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/delete.txt
@@ -0,0 +1 @@
+===== Sodalem delere ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/la/edit.txt b/lib/plugins/usermanager/lang/la/edit.txt
new file mode 100644
index 000000000..4e3d3b2ae
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/edit.txt
@@ -0,0 +1 @@
+===== Sodalem recensere ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/la/intro.txt b/lib/plugins/usermanager/lang/la/intro.txt
new file mode 100644
index 000000000..7f5c011a8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/intro.txt
@@ -0,0 +1 @@
+====== Sodalis Tabella ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/la/lang.php b/lib/plugins/usermanager/lang/la/lang.php
new file mode 100644
index 000000000..52c848754
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Latin language file
+ *
+ * @author Massimiliano Vassalli <vassalli.max@gmail.com>
+ */
+$lang['menu'] = 'Sodalis Tabella';
+$lang['noauth'] = '(Sodalis confirmatio deest)';
+$lang['nosupport'] = '(Sodalis administratio deest)';
+$lang['badauth'] = 'Confirmatio fieri non potest.';
+$lang['user_id'] = 'Sodalis';
+$lang['user_pass'] = 'Tessera';
+$lang['user_name'] = 'Nomen uerum';
+$lang['user_mail'] = 'Cursus Interretialis';
+$lang['user_groups'] = 'Grex';
+$lang['field'] = 'Campus';
+$lang['value'] = 'Vis';
+$lang['add'] = 'Addere';
+$lang['delete'] = 'Delere';
+$lang['delete_selected'] = 'Electa delere';
+$lang['edit'] = 'Recensere';
+$lang['edit_prompt'] = 'Sodalem recensere';
+$lang['modify'] = 'Mutata seruare';
+$lang['search'] = 'Quaerere';
+$lang['search_prompt'] = 'Agentem quaerere';
+$lang['clear'] = 'Colum quaerendi abrogare';
+$lang['filter'] = 'Colum';
+$lang['summary'] = 'Sodales %1$d-%2$d inter %3$d ostenduntur. Numerus Sodalium. %4$d.';
+$lang['nonefound'] = 'Sodalis non repertus. Numerus sodalium: %d';
+$lang['delete_ok'] = '%d Sodales delentur.';
+$lang['delete_fail'] = '%d non deleri possunt.';
+$lang['update_ok'] = 'Sodalis feliciter nouatus\a';
+$lang['update_fail'] = 'Sodalis infeliciter nouatus\a';
+$lang['update_exists'] = 'Nomen Sodalis non mutatur, eo quod hoc nomen (%s) iam electum est.';
+$lang['start'] = 'in primis';
+$lang['prev'] = 'antea';
+$lang['next'] = 'postea';
+$lang['last'] = 'in extremis';
+$lang['edit_usermissing'] = 'Hic Sodalis non inuenitur, eo quod nomen iam deletum uel mutatum est.';
+$lang['user_notify'] = 'Sodalem adnotare';
+$lang['note_notify'] = 'Adnotationes cursu interretiali missae solum si noua tessera petitur.';
+$lang['note_group'] = 'Noui\ae Sodales communi Gregi adduntur (%s) si Grex non elegitur.';
+$lang['note_pass'] = 'Tessera non generata nisi campus uacuos est et Sodalis adnotationes aptae faciuntur.';
+$lang['add_ok'] = 'Sodalis feliciter additur.';
+$lang['add_fail'] = 'Sodalis infeliciter additur.';
+$lang['notify_ok'] = 'Adnotationes cursu interretiali missae';
+$lang['notify_fail'] = 'Adnotationes cursu interretiali non missae';
diff --git a/lib/plugins/usermanager/lang/la/list.txt b/lib/plugins/usermanager/lang/la/list.txt
new file mode 100644
index 000000000..b470d2ea4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/la/list.txt
@@ -0,0 +1 @@
+===== Sodalis index ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/lb/lang.php b/lib/plugins/usermanager/lang/lb/lang.php
new file mode 100644
index 000000000..59acdf7a8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lb/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * lb language file
+ *
+ * @author joel@schintgen.net
+ */
diff --git a/lib/plugins/usermanager/lang/lb/list.txt b/lib/plugins/usermanager/lang/lb/list.txt
new file mode 100644
index 000000000..022afe831
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lb/list.txt
@@ -0,0 +1 @@
+===== Benotzerlëscht ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/lt/add.txt b/lib/plugins/usermanager/lang/lt/add.txt
new file mode 100644
index 000000000..32681ade7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/add.txt
@@ -0,0 +1,2 @@
+===== Pridėti vartotoją =====
+
diff --git a/lib/plugins/usermanager/lang/lt/delete.txt b/lib/plugins/usermanager/lang/lt/delete.txt
new file mode 100644
index 000000000..262713c98
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/delete.txt
@@ -0,0 +1,2 @@
+===== Ištrinti vartotoją =====
+
diff --git a/lib/plugins/usermanager/lang/lt/edit.txt b/lib/plugins/usermanager/lang/lt/edit.txt
new file mode 100644
index 000000000..da57ea380
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/edit.txt
@@ -0,0 +1,2 @@
+===== Redaguoti vartotoją =====
+
diff --git a/lib/plugins/usermanager/lang/lt/intro.txt b/lib/plugins/usermanager/lang/lt/intro.txt
new file mode 100644
index 000000000..61f80d52e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/intro.txt
@@ -0,0 +1,2 @@
+====== Vartotojų administravimas ======
+
diff --git a/lib/plugins/usermanager/lang/lt/lang.php b/lib/plugins/usermanager/lang/lt/lang.php
new file mode 100644
index 000000000..db3cf2d32
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/lang.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Lithuanian language file
+ *
+ * @author grawity <grawity@gmail.com>
+ * @author audrius.klevas@gmail.com
+ * @author Arunas Vaitekunas <aras@fan.lt>
+ */
+$lang['menu'] = 'Vartotojų administravimas';
+$lang['noauth'] = '(vartotojų autentifikacija neprieinama)';
+$lang['nosupport'] = '(vartotojų administravimas nepalaikomas)';
+$lang['badauth'] = 'neteisingas autentifikacijos būdas';
+$lang['user_id'] = 'Vartotojas';
+$lang['user_pass'] = 'Slaptažodis';
+$lang['user_name'] = 'Vardas';
+$lang['user_mail'] = 'El.paštas';
+$lang['user_groups'] = 'Grupės';
+$lang['field'] = 'Laukas';
+$lang['value'] = 'Turinys';
+$lang['add'] = 'Pridėti';
+$lang['delete'] = 'Pašalinti';
+$lang['delete_selected'] = 'Pašalinti pažymėtus';
+$lang['edit'] = 'Redaguoti';
+$lang['edit_prompt'] = 'Redaguoti šį vartotoją';
+$lang['modify'] = 'Išsaugoti';
+$lang['search'] = 'Paieška';
+$lang['search_prompt'] = 'Ieškoti';
+$lang['clear'] = 'Panaikinti filtrą';
+$lang['filter'] = 'Filtras';
+$lang['summary'] = 'Rodomi vartotojai %1$d-%2$d iš %3$d rastų. Iš viso %4$d vartotojų.';
+$lang['nonefound'] = 'Vartotojų nerasta. Iš viso %d vartotojų.';
+$lang['delete_ok'] = 'Pašalinta %d vartotojų';
+$lang['delete_fail'] = '%d nepavyko pašalinti.';
+$lang['update_ok'] = 'Vartotojas sėkmingai pakeistas';
+$lang['update_fail'] = 'Vartotojo pakeitimas nepavyko';
+$lang['update_exists'] = 'Vartotojo vardo pakeitimas nepavyko, nes nurodytas vartotojo vardas (%s) jau yra (kiti pakeitimai įvykdyti).';
+$lang['start'] = 'pradžia';
+$lang['prev'] = 'atgal';
+$lang['next'] = 'pirmyn';
+$lang['last'] = 'pabaiga';
+$lang['edit_usermissing'] = 'Pasirinktas vartotojas nerastas, nurodytas vartotojo vardas galėjo būti pašalintas ar pakeistas kitur.';
+$lang['user_notify'] = 'Įspėti vartotoją';
+$lang['note_notify'] = 'Įspėjimas siunčiamas tik tada, kai vartotojui priskiriamas naujas slaptažodis.';
+$lang['note_group'] = 'Jei grupė nenurodyta, nauji vartotojai pridedami į pagrindinę grupę (%s).';
+$lang['add_ok'] = 'Vartotojas sėkmingai pridėtas';
+$lang['add_fail'] = 'Vartotojo pridėjimas nepavyko';
+$lang['notify_ok'] = 'Įspėjimo el.laiškas išsiųstas';
+$lang['notify_fail'] = 'Įspėjimo el.laiško išsiųsti nepavyko';
diff --git a/lib/plugins/usermanager/lang/lt/list.txt b/lib/plugins/usermanager/lang/lt/list.txt
new file mode 100644
index 000000000..87be62843
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lt/list.txt
@@ -0,0 +1,2 @@
+===== Vartotojų sąrašas =====
+
diff --git a/lib/plugins/usermanager/lang/lv/add.txt b/lib/plugins/usermanager/lang/lv/add.txt
new file mode 100644
index 000000000..06fd70002
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/add.txt
@@ -0,0 +1 @@
+===== Pievienot lietotāju =====
diff --git a/lib/plugins/usermanager/lang/lv/delete.txt b/lib/plugins/usermanager/lang/lv/delete.txt
new file mode 100644
index 000000000..5f59af7b8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/delete.txt
@@ -0,0 +1 @@
+===== Dzēst lietotāju =====
diff --git a/lib/plugins/usermanager/lang/lv/edit.txt b/lib/plugins/usermanager/lang/lv/edit.txt
new file mode 100644
index 000000000..efb0b04d7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/edit.txt
@@ -0,0 +1 @@
+===== Labot lietotāju =====
diff --git a/lib/plugins/usermanager/lang/lv/intro.txt b/lib/plugins/usermanager/lang/lv/intro.txt
new file mode 100644
index 000000000..b248ddcb7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/intro.txt
@@ -0,0 +1 @@
+====== Lietotāju pārvaldnieks ======
diff --git a/lib/plugins/usermanager/lang/lv/lang.php b/lib/plugins/usermanager/lang/lv/lang.php
new file mode 100644
index 000000000..620678ff5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/lang.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Latvian language file
+ *
+ * @author Aivars Miška <allefm@gmail.lv>
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['menu'] = 'Lietotāju pārvaldnieks';
+$lang['noauth'] = '(lietotāju autentifikācijas nav)';
+$lang['nosupport'] = '(lietotāju pārvaldība netiek uzturēta)';
+$lang['badauth'] = 'nederīgs autentifikācijas mehānisms';
+$lang['user_id'] = 'Lietotājs';
+$lang['user_pass'] = 'Parole';
+$lang['user_name'] = 'Vārds/uzvārds';
+$lang['user_mail'] = 'Epasts';
+$lang['user_groups'] = 'Grupas';
+$lang['field'] = 'Lauks';
+$lang['value'] = 'Vērtība';
+$lang['add'] = 'Pielikt';
+$lang['delete'] = 'Dzēst';
+$lang['delete_selected'] = 'Dzēst izvēlēto';
+$lang['edit'] = 'Labot';
+$lang['edit_prompt'] = 'Labot šo lietotāju';
+$lang['modify'] = 'Saglabāt izmaiņas';
+$lang['search'] = 'Meklēšana';
+$lang['search_prompt'] = 'Meklēt';
+$lang['clear'] = 'Noņemt meklēšanas filtru';
+$lang['filter'] = 'Filtrs';
+$lang['summary'] = 'Lietotāji %1$d.- %2$d. no %3$d atrastajiem. Pavisam %4$d lietotāji.';
+$lang['nonefound'] = 'Neviens nav atrasts. Pavisam %d lietotāju.';
+$lang['delete_ok'] = 'Dzēsti %d lietotāji';
+$lang['delete_fail'] = '%d neizdevās izdzēst.';
+$lang['update_ok'] = 'Lietotāja dati saglabāti';
+$lang['update_fail'] = 'Lietotāja dati nav saglabāti';
+$lang['update_exists'] = 'Lietotāja vārds nav nomainīts, norādīto vārdu (%s) kāds jau izmanto (pārējās izmaiņas tiks saglabātas).';
+$lang['start'] = 'sākums';
+$lang['prev'] = 'iepriekšējais';
+$lang['next'] = 'nākamais';
+$lang['last'] = 'pēdējais';
+$lang['edit_usermissing'] = 'Norādītais lietotājs nav atrasts, varbūt tas ir dzēst vai mainīts citur.';
+$lang['user_notify'] = 'Paziņot lietotājam';
+$lang['note_notify'] = 'Paziņojumus izsūta tikai tad, ja lietotājam dod jaunu paroli.';
+$lang['note_group'] = 'Ja nenorāda grupu, lietotāju pievieno noklusētajai grupai (%s).';
+$lang['note_pass'] = 'Ja paroles lauku atstāj tukšu un atzīmē paziņošanu lietotājam, parole tiks ģenerēta automātiski.';
+$lang['add_ok'] = 'Lietotājs veiksmīgi pievienots';
+$lang['add_fail'] = 'Lietotājs nav pievienots.';
+$lang['notify_ok'] = 'Paziņojums izsūtīts.';
+$lang['notify_fail'] = 'Nevar izsūtīt paziņojumu.';
diff --git a/lib/plugins/usermanager/lang/lv/list.txt b/lib/plugins/usermanager/lang/lv/list.txt
new file mode 100644
index 000000000..44a10d94c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/lv/list.txt
@@ -0,0 +1 @@
+===== Lietotāju saraksts =====
diff --git a/lib/plugins/usermanager/lang/mk/add.txt b/lib/plugins/usermanager/lang/mk/add.txt
new file mode 100644
index 000000000..c90121d1b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/add.txt
@@ -0,0 +1 @@
+===== Додај корисник ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mk/delete.txt b/lib/plugins/usermanager/lang/mk/delete.txt
new file mode 100644
index 000000000..8a6b5e9b5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/delete.txt
@@ -0,0 +1 @@
+===== Избриши корисник ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mk/edit.txt b/lib/plugins/usermanager/lang/mk/edit.txt
new file mode 100644
index 000000000..da6306141
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/edit.txt
@@ -0,0 +1 @@
+===== Уреди корисник ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mk/intro.txt b/lib/plugins/usermanager/lang/mk/intro.txt
new file mode 100644
index 000000000..747d00921
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/intro.txt
@@ -0,0 +1 @@
+===== Менаџер за корисник ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mk/lang.php b/lib/plugins/usermanager/lang/mk/lang.php
new file mode 100644
index 000000000..97ef51369
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/lang.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Macedonian language file
+ *
+ * @author Dimitar Talevski <dimi3.14@gmail.com>
+ */
+$lang['menu'] = 'Менаџер за корисник';
+$lang['noauth'] = '(автентикација на корисник не е достапна)';
+$lang['nosupport'] = '(менаџирање на корисник не е поддржано)';
+$lang['badauth'] = 'невалиден механизам за автентикација';
+$lang['user_id'] = 'Корисник';
+$lang['user_pass'] = 'Лозинка';
+$lang['user_name'] = 'Вистинско име';
+$lang['user_mail'] = 'Е-пошта';
+$lang['user_groups'] = 'Групи';
+$lang['field'] = 'Поле';
+$lang['value'] = 'Вредност';
+$lang['add'] = 'Додај';
+$lang['delete'] = 'Избриши';
+$lang['delete_selected'] = 'Избриши ги избраните';
+$lang['edit'] = 'Уреди';
+$lang['edit_prompt'] = 'Уреди го овој корисник';
+$lang['modify'] = 'Зачувај промени';
+$lang['search'] = 'Барај';
+$lang['search_prompt'] = 'Изврши пребарување';
+$lang['clear'] = 'Ресетирај го филтерот за пребарување';
+$lang['filter'] = 'Филтер';
+$lang['delete_ok'] = '%d корисници се избришани';
+$lang['delete_fail'] = '%d не успееја да се избришат.';
+$lang['update_ok'] = 'Корисникот е успешно ажуриран';
+$lang['update_fail'] = 'Корисникот не е успешно ажуриран';
+$lang['start'] = 'почеток';
+$lang['prev'] = 'претходна';
+$lang['next'] = 'следна';
+$lang['last'] = 'последна';
+$lang['user_notify'] = 'Извести го корисникот';
+$lang['add_ok'] = 'Корисникот е успешно додаден';
+$lang['add_fail'] = 'Додавањето на корисникот не е успешно';
diff --git a/lib/plugins/usermanager/lang/mk/list.txt b/lib/plugins/usermanager/lang/mk/list.txt
new file mode 100644
index 000000000..651462e9d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mk/list.txt
@@ -0,0 +1 @@
+===== Листа со корисници ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/add.txt b/lib/plugins/usermanager/lang/mr/add.txt
new file mode 100644
index 000000000..fc3a87737
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/add.txt
@@ -0,0 +1 @@
+====== सदस्य नोंद करा ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/delete.txt b/lib/plugins/usermanager/lang/mr/delete.txt
new file mode 100644
index 000000000..cf0e48551
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/delete.txt
@@ -0,0 +1 @@
+====== सदस्य डिलीट करा ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/edit.txt b/lib/plugins/usermanager/lang/mr/edit.txt
new file mode 100644
index 000000000..2d3d64915
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/edit.txt
@@ -0,0 +1 @@
+====== सदस्य बदला ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/intro.txt b/lib/plugins/usermanager/lang/mr/intro.txt
new file mode 100644
index 000000000..9253b323e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/intro.txt
@@ -0,0 +1 @@
+====== सदस्य व्यवस्थापक ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/mr/lang.php b/lib/plugins/usermanager/lang/mr/lang.php
new file mode 100644
index 000000000..8915678cc
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Marathi language file
+ *
+ * @author ghatothkach@hotmail.com
+ * @author Padmanabh Kulkarni <kulkarnipadmanabh@gmail.com>
+ * @author Padmanabh Kulkarni<kulkarnipadmanabh@gmail.com>
+ * @author shantanoo@gmail.com
+ */
+$lang['menu'] = 'सदस्य व्यवस्थापक';
+$lang['noauth'] = '( सदस्य अधिकृत करण्याची सुविधा नाही )';
+$lang['nosupport'] = '( सदस्य व्यवस्थापन उपलब्ध नाही )';
+$lang['badauth'] = 'अधिकृत करण्याची व्यवस्था अवैध';
+$lang['user_id'] = 'सदस्य';
+$lang['user_pass'] = 'पासवर्ड';
+$lang['user_name'] = 'खरे नाव';
+$lang['user_mail'] = 'ईमेल';
+$lang['user_groups'] = 'गट';
+$lang['field'] = 'रकाना';
+$lang['value'] = 'किम्मत';
+$lang['add'] = 'जोड़ा';
+$lang['delete'] = 'डिलीट';
+$lang['delete_selected'] = 'निवडलेले डिलीट करा';
+$lang['edit'] = 'संपादन';
+$lang['edit_prompt'] = 'या सदस्याची माहिती बदला';
+$lang['modify'] = 'बदल सुरक्षित करा';
+$lang['search'] = 'शोध';
+$lang['search_prompt'] = 'शोध करा';
+$lang['clear'] = 'शोधाचे निकष बदला';
+$lang['filter'] = 'निकष';
+$lang['summary'] = 'सापडलेल्या %3$d सदस्यापैकी %1$d ते %2$d दाखवले आहेत. एकूण सदस्या %4$d.';
+$lang['nonefound'] = 'एकही सदस्य मिळाला नाही. एकूण सदस्य %d.';
+$lang['delete_ok'] = '%d सदस्य डिलीट केले.';
+$lang['delete_fail'] = '%d डिलीट करू शकलो नाही.';
+$lang['update_ok'] = 'सदस्याची माहिती यशस्वीरीत्या बदलली आहे';
+$lang['update_fail'] = 'सदस्याची माहिती बदलता आली नाही';
+$lang['update_exists'] = 'सदस्याचे नाव बदलू शकलो नाही. %s हे नाव आधीच अस्तित्वात आहे. ( इतर सर्व बदल केले जातील )';
+$lang['start'] = 'सुरुवात';
+$lang['prev'] = 'आधीचं';
+$lang['next'] = 'पुढचं';
+$lang['last'] = 'शेवटचं';
+$lang['edit_usermissing'] = 'दिलेला सदस्य सापडला नाही. तो कदाचित डिलीट झाला असेल किंवा बदलला गेला असेल.';
+$lang['user_notify'] = 'सदस्याला सूचित करा.';
+$lang['note_notify'] = 'सदस्याला नवीन पासवर्ड दिला तरच सूचनेचे ईमेल पाठवले जातात.';
+$lang['note_group'] = 'नवीन सदस्य जर गट निवडला नसेल तर %s या गटात टाकले जातील.';
+$lang['note_pass'] = 'पासवर्डचा रकाना रिकामा ठेवल्यास व सदस्य सूचना व्यवस्था चालू असल्यास पासवर्ड आपोआप तयार केला जाईल.';
+$lang['add_ok'] = 'सदस्य यशस्वीरीत्या नोंद झाला';
+$lang['add_fail'] = 'सदस्याची नोंद झाली नाही';
+$lang['notify_ok'] = 'सूचनेचा ईमेल पाठवला';
+$lang['notify_fail'] = 'सूचनेचा ईमेल पाठवला गेला नाही';
diff --git a/lib/plugins/usermanager/lang/mr/list.txt b/lib/plugins/usermanager/lang/mr/list.txt
new file mode 100644
index 000000000..ab6906771
--- /dev/null
+++ b/lib/plugins/usermanager/lang/mr/list.txt
@@ -0,0 +1 @@
+====== सदस्य यादी ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ms/lang.php b/lib/plugins/usermanager/lang/ms/lang.php
new file mode 100644
index 000000000..77ad2a1c1
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ms/lang.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Malay language file
+ *
+ * @author Markos
+ */
diff --git a/lib/plugins/usermanager/lang/ne/add.txt b/lib/plugins/usermanager/lang/ne/add.txt
new file mode 100644
index 000000000..868b12ab1
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/add.txt
@@ -0,0 +1 @@
+=====प्रयोगकर्ता थप्नुहोस् ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ne/delete.txt b/lib/plugins/usermanager/lang/ne/delete.txt
new file mode 100644
index 000000000..4441c8349
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/delete.txt
@@ -0,0 +1 @@
+===== प्रयोगकर्ता मेट्नुहोस ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ne/edit.txt b/lib/plugins/usermanager/lang/ne/edit.txt
new file mode 100644
index 000000000..040d2697d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/edit.txt
@@ -0,0 +1 @@
+===== प्रयोगकर्ता सम्पादन गर्नुहोस===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ne/intro.txt b/lib/plugins/usermanager/lang/ne/intro.txt
new file mode 100644
index 000000000..de08e483d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/intro.txt
@@ -0,0 +1 @@
+====== प्रयोगकर्ता व्यवस्थापक ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ne/lang.php b/lib/plugins/usermanager/lang/ne/lang.php
new file mode 100644
index 000000000..f68ed2074
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Nepali language file
+ *
+ * @author Saroj Kumar Dhakal <lotusnagarkot@gmail.com>
+ * @author SarojKumar Dhakal <lotusnagarkot@yahoo.com>
+ * @author Saroj Dhakal<lotusnagarkot@yahoo.com>
+ */
+$lang['menu'] = 'प्रयोगकर्ता व्यवस्थापक';
+$lang['noauth'] = '(प्रयोगकर्ता प्रमाणिकरण उपलब्ध छैन)';
+$lang['nosupport'] = '(प्रयोगकर्ता व्यवस्थापन समर्थित छैन)';
+$lang['badauth'] = 'अमान्य प्रमाणिकरण विधि';
+$lang['user_id'] = 'प्रयोगकर्ता';
+$lang['user_pass'] = 'प्रवेशशब्द';
+$lang['user_name'] = 'वास्तविक नाम';
+$lang['user_mail'] = 'इमेल';
+$lang['user_groups'] = 'समूह ';
+$lang['field'] = 'क्षेत्र';
+$lang['value'] = 'मान ';
+$lang['add'] = 'थप्नुहोस्';
+$lang['delete'] = 'मेट्नुहोस्';
+$lang['delete_selected'] = 'सेलेक्ट गरिएको मेट्नुहोस्';
+$lang['edit'] = 'सम्पादन गर्नुहोस्';
+$lang['edit_prompt'] = 'यो प्रयोगकर्ता सम्पादन गर्नुहोस् ';
+$lang['modify'] = 'परिवर्तन वचत गर्नुहोस्';
+$lang['search'] = 'खोज';
+$lang['search_prompt'] = 'खोज्नुहोस्';
+$lang['clear'] = 'खोज फिल्टर पूर्वरुपमा फर्काउनुहोस्';
+$lang['filter'] = 'फिल्टर ';
+$lang['summary'] = 'देखाउदै %1$d-%2$d of %3$d भेटिएका %4$d कुल प्रयोगकर्ता मध्येबाट ।';
+$lang['nonefound'] = '%d कुल प्रयोगकर्ता। कुनै पनि प्रयोगकर्ता भेटिएन ।';
+$lang['delete_ok'] = '%d प्रयोगकर्ता मेटिए';
+$lang['delete_fail'] = '%d प्रयोगकर्ता हटाउन सकिएन ';
+$lang['update_ok'] = 'प्रयोगकर्ता सफलतापूर्वक अध्यावधिक गरियो ';
+$lang['update_fail'] = 'प्रयोगकर्ता अध्यावधिक कार्य असफल';
+$lang['update_exists'] = 'पर्ययोगकर्ताको नाम परिवर्तन असफल, दिइएको प्रयोगकर्ता नाम( %s) पहिले देखि रहेको छ। ( यसबाहेकका परिवर्रनहरू गरिएका छन्)';
+$lang['start'] = 'सुरु गर्नुहोस्';
+$lang['prev'] = 'पहिलेको ';
+$lang['next'] = 'पछिको';
+$lang['last'] = 'अन्तिम';
+$lang['edit_usermissing'] = 'छानिएको प्रयोगकर्ता भेटिएन, खुलाइएको प्रयोगकर्ता मेटिएको या कतै परिवर्तन गरिएको हुनसक्छ।';
+$lang['user_notify'] = 'प्रयोगकर्तालाई जानकारी दिनुहोस् ';
+$lang['note_notify'] = 'जानकारी इमेल तब मात्र पठाइन्छ जब प्रयोगकर्तालाई नयाँ प्रवेश शब्द दिइन्छ।';
+$lang['note_group'] = 'नयाँ प्रयोगकर्तालाई पूर्वनिर्धारित समूह नखुलाएमा (%s) मा समावेश गराइनेछ ।';
+$lang['note_pass'] = 'प्रवेश शव्द क्षेत्र खाली राखेमा प्रवेश शव्द स्वत: निर्माण हुनेछ र प्रयोगकर्तालाई जानकारी पठइने छ ।';
+$lang['add_ok'] = 'प्रोगकर्ता सफलतापूर्वक थपियो';
+$lang['add_fail'] = 'प्रयोगकर्ता थप्ने कार्य असफल';
+$lang['notify_ok'] = 'जानकारी पत्र पठाइयो';
+$lang['notify_fail'] = 'जानकारी पत्र पठाउन सकिएन ';
diff --git a/lib/plugins/usermanager/lang/ne/list.txt b/lib/plugins/usermanager/lang/ne/list.txt
new file mode 100644
index 000000000..ece94b388
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ne/list.txt
@@ -0,0 +1 @@
+===== प्रयोगकर्ता सुची ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/add.txt b/lib/plugins/usermanager/lang/nl/add.txt
new file mode 100644
index 000000000..992d9f300
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/add.txt
@@ -0,0 +1 @@
+===== Nieuwe gebruiker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/delete.txt b/lib/plugins/usermanager/lang/nl/delete.txt
new file mode 100644
index 000000000..ad26e058f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/delete.txt
@@ -0,0 +1 @@
+===== Verwijder gebruiker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/edit.txt b/lib/plugins/usermanager/lang/nl/edit.txt
new file mode 100644
index 000000000..0d58e48f3
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/edit.txt
@@ -0,0 +1 @@
+===== Gebruiker wijzigen ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/intro.txt b/lib/plugins/usermanager/lang/nl/intro.txt
new file mode 100644
index 000000000..7df09dbab
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/intro.txt
@@ -0,0 +1 @@
+==== Gebruikersmanager ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/nl/lang.php b/lib/plugins/usermanager/lang/nl/lang.php
new file mode 100644
index 000000000..b00ab22e0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/lang.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Dutch language file
+ *
+ * @author Wouter Schoot <wouter@schoot.org>
+ * @author John de Graaff <john@de-graaff.net>
+ * @author Niels Schoot <niels.schoot@quintiq.com>
+ * @author Dion Nicolaas <dion@nicolaas.net>
+ * @author Danny Rotsaert <danny.rotsaert@edpnet.be>
+ * @author Marijn Hofstra hofstra.m@gmail.com
+ * @author Matthias Carchon webmaster@c-mattic.be
+ * @author Marijn Hofstra <hofstra.m@gmail.com>
+ * @author Timon Van Overveldt <timonvo@gmail.com>
+ * @author Jeroen
+ * @author Ricardo Guijt <ricardoguijt@gmail.com>
+ */
+$lang['menu'] = 'Gebruikersmanager';
+$lang['noauth'] = '(gebruikersauthenticatie niet beschikbaar)';
+$lang['nosupport'] = '(gebruikersmanagement niet ondersteund)';
+$lang['badauth'] = 'ongeldige authenticatiemethode';
+$lang['user_id'] = 'Gebruiker';
+$lang['user_pass'] = 'Wachtwoord';
+$lang['user_name'] = 'Volledige naam';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Groepen';
+$lang['field'] = 'Veld';
+$lang['value'] = 'Waarde';
+$lang['add'] = 'Toevoegen';
+$lang['delete'] = 'Verwijder';
+$lang['delete_selected'] = 'Verwijder geselecteerden';
+$lang['edit'] = 'Wijzigen';
+$lang['edit_prompt'] = 'Wijzig deze gebruiker';
+$lang['modify'] = 'Wijzigingen opslaan';
+$lang['search'] = 'Zoek';
+$lang['search_prompt'] = 'Voer zoekopdracht uit';
+$lang['clear'] = 'Verwijder zoekfilter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Weergegeven gebruikers %1$d-%2$d van %3$d gevonden. %4$d gebruikers in totaal.';
+$lang['nonefound'] = 'Geen gebruikers gevonden. %d gebruikers in totaal.';
+$lang['delete_ok'] = '%d gebruikers verwijderd';
+$lang['delete_fail'] = '%d kon niet worden verwijderd.';
+$lang['update_ok'] = 'Gebruiker succesvol gewijzigd';
+$lang['update_fail'] = 'Gebruiker wijzigen mislukt';
+$lang['update_exists'] = 'Gebruikersnaam veranderen mislukt, de opgegeven gebruikersnaam (%s) bestaat reeds (overige aanpassingen worden wel doorgevoerd).';
+$lang['start'] = 'start';
+$lang['prev'] = 'vorige';
+$lang['next'] = 'volgende';
+$lang['last'] = 'laatste';
+$lang['edit_usermissing'] = 'Geselecteerde gebruiker niet gevonden, de opgegeven gebruikersnaam kan verwijderd zijn of elders aangepast.';
+$lang['user_notify'] = 'Gebruiker notificeren';
+$lang['note_notify'] = 'Notificatie-e-mails worden alleen verstuurd wanneer de gebruiker een nieuw wachtwoord wordt toegekend.';
+$lang['note_group'] = 'Nieuwe gebruikers zullen aan de standaard groep (%s) worden toegevoegd als er geen groep opgegeven is.';
+$lang['note_pass'] = 'Het wachtwoord wordt automatisch gegenereerd als het veld wordt leeggelaten en gebruikersnotificaties aanstaan.';
+$lang['add_ok'] = 'Gebruiker succesvol toegevoegd';
+$lang['add_fail'] = 'Gebruiker kon niet worden toegevoegd';
+$lang['notify_ok'] = 'Notificatie-e-mail verzonden';
+$lang['notify_fail'] = 'Notificatie-e-mail kon niet worden verzonden';
diff --git a/lib/plugins/usermanager/lang/nl/list.txt b/lib/plugins/usermanager/lang/nl/list.txt
new file mode 100644
index 000000000..a9aac845d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/nl/list.txt
@@ -0,0 +1 @@
+===== Gebruikerslijst ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/add.txt b/lib/plugins/usermanager/lang/no/add.txt
new file mode 100644
index 000000000..4fb9cf271
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/add.txt
@@ -0,0 +1 @@
+===== Legg til bruker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/delete.txt b/lib/plugins/usermanager/lang/no/delete.txt
new file mode 100644
index 000000000..55010182f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/delete.txt
@@ -0,0 +1 @@
+===== Slett bruker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/edit.txt b/lib/plugins/usermanager/lang/no/edit.txt
new file mode 100644
index 000000000..3dff0c92e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/edit.txt
@@ -0,0 +1 @@
+===== Rediger bruker ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/intro.txt b/lib/plugins/usermanager/lang/no/intro.txt
new file mode 100644
index 000000000..c9e1e5b8c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/intro.txt
@@ -0,0 +1 @@
+===== Behandle brukere ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/no/lang.php b/lib/plugins/usermanager/lang/no/lang.php
new file mode 100644
index 000000000..7124e4811
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/lang.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Norwegianlanguage file
+ *
+ * @author Thomas Nygreen <nygreen@gmail.com>
+ * @author Arild Burud <arildb@met.no>
+ * @author Torkill Bruland <torkar-b@online.no>
+ * @author Rune M. Andersen <rune.andersen@gmail.com>
+ * @author Jakob Vad Nielsen (me@jakobnielsen.net)
+ * @author Kjell Tore Næsgaard <kjell.t.nasgaard@ntnu.no>
+ * @author Knut Staring <knutst@gmail.com>
+ * @author Lisa Ditlefsen <lisa@vervesearch.com>
+ * @author Erik Pedersen <erik.pedersen@shaw.ca>
+ * @author Erik Bjørn Pedersen <erik.pedersen@shaw.ca>
+ * @author Rune Rasmussen syntaxerror.no@gmail.com
+ * @author Jon Bøe <jonmagneboe@hotmail.com>
+ * @author Egil Hansen <egil@rosetta.no>
+ */
+$lang['menu'] = 'Behandle brukere';
+$lang['noauth'] = '(autentisering av brukere ikke tilgjengelig)';
+$lang['nosupport'] = '(behandling av brukere støttes ikke)';
+$lang['badauth'] = 'ugyldig autentiseringsmekanisme';
+$lang['user_id'] = 'Bruker';
+$lang['user_pass'] = 'Passord';
+$lang['user_name'] = 'Fullt navn';
+$lang['user_mail'] = 'E-post';
+$lang['user_groups'] = 'Grupper';
+$lang['field'] = 'Felt';
+$lang['value'] = 'Verdi';
+$lang['add'] = 'Legg til';
+$lang['delete'] = 'Slett';
+$lang['delete_selected'] = 'Slett valgte';
+$lang['edit'] = 'Rediger';
+$lang['edit_prompt'] = 'Rediger denne brukeren';
+$lang['modify'] = 'Lagre endringer';
+$lang['search'] = 'Søk';
+$lang['search_prompt'] = 'Start søk';
+$lang['clear'] = 'Tilbakestill søkefilter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Viser brukere %1$d-%2$d av %3$d. %4$d users total.';
+$lang['nonefound'] = 'Ingen brukere funnet. %d brukere totalt.';
+$lang['delete_ok'] = '%d brukere slettet.';
+$lang['delete_fail'] = '%d kunne ikke slettes.';
+$lang['update_ok'] = 'Brukeren ble oppdatert';
+$lang['update_fail'] = 'Oppdatering av brukeren feilet';
+$lang['update_exists'] = 'Endring av brukernavn feilet. Det oppgitte brukernavnet (%s) eksisterer allerede (alle andre endringer vil bli gjort).';
+$lang['start'] = 'første';
+$lang['prev'] = 'forrige';
+$lang['next'] = 'neste';
+$lang['last'] = 'siste';
+$lang['edit_usermissing'] = 'Fant ikke valgte brukere. Det oppgitte brukernavnet kan ha blitt slettet eller endret et annet sted.';
+$lang['user_notify'] = 'Varsle bruker';
+$lang['note_notify'] = 'E-post med varsling blir bare sendt hvis brukeren blir gitt nytt passord.';
+$lang['note_group'] = 'Nye brukere vil bli lagt til standardgruppen (%s) hvis ingen gruppe oppgis.';
+$lang['note_pass'] = 'Passordet vil bli autogenerert dersom feltet er tomt og varsle bruker er valgt.';
+$lang['add_ok'] = 'Brukeren ble lagt til';
+$lang['add_fail'] = 'Brukeren kunne ikke legges til';
+$lang['notify_ok'] = 'Varsling sendt';
+$lang['notify_fail'] = 'Varsling kunne ikke sendes';
diff --git a/lib/plugins/usermanager/lang/no/list.txt b/lib/plugins/usermanager/lang/no/list.txt
new file mode 100644
index 000000000..40de64b01
--- /dev/null
+++ b/lib/plugins/usermanager/lang/no/list.txt
@@ -0,0 +1 @@
+===== Brukerliste ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pl/add.txt b/lib/plugins/usermanager/lang/pl/add.txt
new file mode 100644
index 000000000..a33f3baa7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/add.txt
@@ -0,0 +1 @@
+===== Dodawanie użytkownika =====
diff --git a/lib/plugins/usermanager/lang/pl/delete.txt b/lib/plugins/usermanager/lang/pl/delete.txt
new file mode 100644
index 000000000..72dd338f3
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/delete.txt
@@ -0,0 +1 @@
+===== Usuwanie użytkownika =====
diff --git a/lib/plugins/usermanager/lang/pl/edit.txt b/lib/plugins/usermanager/lang/pl/edit.txt
new file mode 100644
index 000000000..3c9d89835
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/edit.txt
@@ -0,0 +1 @@
+===== Edycja użytkownika =====
diff --git a/lib/plugins/usermanager/lang/pl/intro.txt b/lib/plugins/usermanager/lang/pl/intro.txt
new file mode 100644
index 000000000..da1cfeac0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/intro.txt
@@ -0,0 +1 @@
+====== Menadżer użytkowników ======
diff --git a/lib/plugins/usermanager/lang/pl/lang.php b/lib/plugins/usermanager/lang/pl/lang.php
new file mode 100644
index 000000000..5bbf84370
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/lang.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * polish language file
+ *
+ * @author Grzegorz Żur <grzegorz.zur@gmail.com>
+ * @author Mariusz Kujawski <marinespl@gmail.com>
+ * @author Maciej Kurczewski <pipijajko@gmail.com>
+ * @author Sławomir Boczek <slawkens@gmail.com>
+ * @author sleshek@wp.pl
+ * @author Leszek Stachowski <shazarre@gmail.com>
+ * @author maros <dobrimaros@yahoo.pl>
+ * @author Grzegorz Widła <dzesdzes@gmail.com>
+ * @author Łukasz Chmaj <teachmeter@gmail.com>
+ * @author Begina Felicysym <begina.felicysym@wp.eu>
+ */
+$lang['menu'] = 'Menadżer użytkowników';
+$lang['noauth'] = '(uwierzytelnienie użytkownika niemożliwe)';
+$lang['nosupport'] = '(zarządzanie użytkownikami niemożliwe)';
+$lang['badauth'] = 'błędny mechanizm uwierzytelniania';
+$lang['user_id'] = 'Nazwa użytkownika';
+$lang['user_pass'] = 'Hasło';
+$lang['user_name'] = 'Użytkownik';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Grupy';
+$lang['field'] = 'Pole';
+$lang['value'] = 'Wartość';
+$lang['add'] = 'Dodaj';
+$lang['delete'] = 'Usuń';
+$lang['delete_selected'] = 'Usuń zaznaczone';
+$lang['edit'] = 'Edytuj';
+$lang['edit_prompt'] = 'Edytuj użytkownika';
+$lang['modify'] = 'Zapisz zmiany';
+$lang['search'] = 'Szukaj';
+$lang['search_prompt'] = 'Rozpocznij przeszukiwanie';
+$lang['clear'] = 'Resetuj filtr przeszukiwania';
+$lang['filter'] = 'Filtr';
+$lang['summary'] = 'Użytkownicy %1$d-%2$d z %3$d znalezionych. Całkowita ilość użytkowników %4$d.';
+$lang['nonefound'] = 'Nie znaleziono użytkowników. Całkowita ilość użytkowników %d.';
+$lang['delete_ok'] = 'Usunięto %d użytkowników.';
+$lang['delete_fail'] = 'Błąd przy usuwaniu %d użytkowników.';
+$lang['update_ok'] = 'Dane użytkownika zostały zmienione!';
+$lang['update_fail'] = 'Błąd przy zmianie danych użytkownika!';
+$lang['update_exists'] = 'Błąd przy zmianie nazwy użytkownika, użytkownik o tej nazwie (%s) już istnieje (inne zmiany zostały wprowadzone).';
+$lang['start'] = 'początek';
+$lang['prev'] = 'poprzedni';
+$lang['next'] = 'następny';
+$lang['last'] = 'ostatni';
+$lang['edit_usermissing'] = 'Nie znaleziono wybranego użytkownika, nazwa użytkownika mogła zostać zmieniona lub usunięta.';
+$lang['user_notify'] = 'Powiadamianie użytkownika';
+$lang['note_notify'] = 'Powiadomienia wysyłane są tylko jeżeli zmieniono hasło użytkownika.';
+$lang['note_group'] = 'Nowy użytkownik zostanie dodany do grupy domyślnej (%s) jeśli nie podano innej grupy.';
+$lang['note_pass'] = 'Jeśli pole będzie puste i powiadamianie użytkownika jest włączone, hasło zostanie automatyczne wygenerowane.';
+$lang['add_ok'] = 'Dodano użytkownika';
+$lang['add_fail'] = 'Dodawanie użytkownika nie powiodło się';
+$lang['notify_ok'] = 'Powiadomienie zostało wysłane';
+$lang['notify_fail'] = 'Wysyłanie powiadomienia nie powiodło się';
diff --git a/lib/plugins/usermanager/lang/pl/list.txt b/lib/plugins/usermanager/lang/pl/list.txt
new file mode 100644
index 000000000..57da2e605
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pl/list.txt
@@ -0,0 +1 @@
+===== Lista użytkowników =====
diff --git a/lib/plugins/usermanager/lang/pt-br/add.txt b/lib/plugins/usermanager/lang/pt-br/add.txt
new file mode 100644
index 000000000..759ed688b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/add.txt
@@ -0,0 +1 @@
+===== Adicionar usuário ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt-br/delete.txt b/lib/plugins/usermanager/lang/pt-br/delete.txt
new file mode 100644
index 000000000..9d18d58ff
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/delete.txt
@@ -0,0 +1 @@
+===== Excluir usuário ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt-br/edit.txt b/lib/plugins/usermanager/lang/pt-br/edit.txt
new file mode 100644
index 000000000..a1be1c8b7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/edit.txt
@@ -0,0 +1 @@
+===== Editar usuário ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt-br/intro.txt b/lib/plugins/usermanager/lang/pt-br/intro.txt
new file mode 100644
index 000000000..5f3399653
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/intro.txt
@@ -0,0 +1 @@
+====== Gerenciamento de Usuários ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt-br/lang.php b/lib/plugins/usermanager/lang/pt-br/lang.php
new file mode 100644
index 000000000..285231f35
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Portuguese language file
+ *
+ * @author Frederico Gonçalves Guimarães <frederico@teia.bio.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Lucien Raven <lucienraven@yahoo.com.br>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Flávio Veras <flaviove@gmail.com>
+ * @author Jeferson Propheta <jeferson.propheta@gmail.com>
+ * @author jair.henrique@gmail.com
+ * @author Luis Dantas <luis@dantas.com>
+ * @author Frederico Guimarães <frederico@teia.bio.br>
+ * @author Jair Henrique <jair.henrique@gmail.com>
+ * @author Luis Dantas <luisdantas@gmail.com>
+ * @author Sergio Motta sergio@cisne.com.br
+ * @author Isaias Masiero Filho <masiero@masiero.org>
+ * @author Balaco Baco <balacobaco@imap.cc>
+ */
+$lang['menu'] = 'Gerenciamento de Usuários';
+$lang['noauth'] = '(o gerenciamento de usuários não está disponível)';
+$lang['nosupport'] = '(o gerenciamento de usuários não é suportado)';
+$lang['badauth'] = 'mecanismo de autenticação inválido';
+$lang['user_id'] = 'Usuário';
+$lang['user_pass'] = 'Senha';
+$lang['user_name'] = 'Nome real';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Grupos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Adicionar';
+$lang['delete'] = 'Excluir';
+$lang['delete_selected'] = 'Excluir a seleção';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar esse usuário';
+$lang['modify'] = 'Salvar as alterações';
+$lang['search'] = 'Pesquisar';
+$lang['search_prompt'] = 'Executar a pesquisa';
+$lang['clear'] = 'Limpar o filtro de pesquisa';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Exibindo usuários %1$d-%2$d de %3$d encontrados. %4$d usuários no total.';
+$lang['nonefound'] = 'Nenhum usuário encontrado. %d usuários no total.';
+$lang['delete_ok'] = '%d usuários excluídos';
+$lang['delete_fail'] = 'Erro na exclusão de %d usuários.';
+$lang['update_ok'] = 'Usuário atualizado com sucesso';
+$lang['update_fail'] = 'Não foi possível atualizar o usuário';
+$lang['update_exists'] = 'Não foi possível mudar o nome do usuário. O nome especificado (%s) já existe (as outras mudanças serão aplicadas).';
+$lang['start'] = 'primeira';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'próxima';
+$lang['last'] = 'última';
+$lang['edit_usermissing'] = 'O usuário selecionado não foi encontrado, ele foi excluído ou teve o seu nome modificado.';
+$lang['user_notify'] = 'Notificar o usuário';
+$lang['note_notify'] = 'E-mails de notificação são enviados apenas se o usuário digitar uma nova senha.';
+$lang['note_group'] = 'Novos usuários serão adicionados ao grupo padrão (%s), caso nenhum grupo seja especificado.';
+$lang['note_pass'] = 'A senha será gerada automaticamente se o campo for deixado em branco e a notificação de usuário estiver habilitada.';
+$lang['add_ok'] = 'O usuário foi adicionado com sucesso';
+$lang['add_fail'] = 'O usuário não foi adicionado';
+$lang['notify_ok'] = 'O e-mail de notificação foi enviado';
+$lang['notify_fail'] = 'Não foi possível enviar o e-mail de notificação';
diff --git a/lib/plugins/usermanager/lang/pt-br/list.txt b/lib/plugins/usermanager/lang/pt-br/list.txt
new file mode 100644
index 000000000..e5f79fb8d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt-br/list.txt
@@ -0,0 +1 @@
+===== Lista de usuários ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/add.txt b/lib/plugins/usermanager/lang/pt/add.txt
new file mode 100644
index 000000000..a4c2672c7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/add.txt
@@ -0,0 +1 @@
+===== Adicionar Utilizador ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/delete.txt b/lib/plugins/usermanager/lang/pt/delete.txt
new file mode 100644
index 000000000..95bffc1e3
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/delete.txt
@@ -0,0 +1 @@
+===== Remover Utilizador ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/edit.txt b/lib/plugins/usermanager/lang/pt/edit.txt
new file mode 100644
index 000000000..176798454
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/edit.txt
@@ -0,0 +1 @@
+===== Editar Utilizador ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/intro.txt b/lib/plugins/usermanager/lang/pt/intro.txt
new file mode 100644
index 000000000..27985ded6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/intro.txt
@@ -0,0 +1 @@
+===== Gerir Utilizadores ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/pt/lang.php b/lib/plugins/usermanager/lang/pt/lang.php
new file mode 100644
index 000000000..6d0d85e38
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/lang.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Portugueselanguage file
+ *
+ * @author José Monteiro <Jose.Monteiro@DoWeDo-IT.com>
+ * @author Enrico Nicoletto <liverig@gmail.com>
+ * @author Fil <fil@meteopt.com>
+ * @author André Neves <drakferion@gmail.com>
+ * @author José Campos zecarlosdecampos@gmail.com
+ */
+$lang['menu'] = 'Gestor de Perfis';
+$lang['noauth'] = '(autenticação indisponível)';
+$lang['nosupport'] = '(gestão de utilizadores não suportada)';
+$lang['badauth'] = 'Mecanismo de autenticação inválido';
+$lang['user_id'] = 'Utilizador';
+$lang['user_pass'] = 'Senha';
+$lang['user_name'] = 'Nome Real';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Grupos';
+$lang['field'] = 'Campo';
+$lang['value'] = 'Valor';
+$lang['add'] = 'Adicionar';
+$lang['delete'] = 'Remover';
+$lang['delete_selected'] = 'Remover Seleccionado(s)';
+$lang['edit'] = 'Editar';
+$lang['edit_prompt'] = 'Editar utilizador';
+$lang['modify'] = 'Gravar Alterações';
+$lang['search'] = 'Pesquisar';
+$lang['search_prompt'] = 'Pesquisar';
+$lang['clear'] = 'Limpar Filtro de Pesquisa';
+$lang['filter'] = 'Filtro';
+$lang['summary'] = 'Apresentar utilizadores %1$d-%2$d de %3$d encontrados. %4$d inscritos.';
+$lang['nonefound'] = 'Nenhum utilizador encontrado. %d inscritos.';
+$lang['delete_ok'] = '%d utilizadores removidos';
+$lang['delete_fail'] = '%d remoções falhadas.';
+$lang['update_ok'] = 'Utilizador actualizado';
+$lang['update_fail'] = 'Utilizador não actualizado';
+$lang['update_exists'] = 'Falhou a alteração do nome, porque o utilizador (%s) já existe (as restantes alterações serão aplicadas).';
+$lang['start'] = 'primeiro';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'seguinte';
+$lang['last'] = 'último';
+$lang['edit_usermissing'] = 'Utilizador seleccionado não encontrado. Terá já sido removido ou alterado entretanto?';
+$lang['user_notify'] = 'Notificar utilizador';
+$lang['note_notify'] = 'Notificações só são enviadas se for atribuída uma nova senha ao utilizador.';
+$lang['note_group'] = 'Os novos utilizadores são adicionados ao grupo por omissão (%s) se não for especificado nenhum grupo.';
+$lang['note_pass'] = 'A password será automáticamente gerada se o campo esquerdo estiver vazio e a notificação de utilizador estiver activada.';
+$lang['add_ok'] = 'Utilizador adicionado.';
+$lang['add_fail'] = 'Utilizador não adicionado.';
+$lang['notify_ok'] = 'Mensagem de notificação enviada.';
+$lang['notify_fail'] = 'Não foi possível enviar mensagem de notificação';
diff --git a/lib/plugins/usermanager/lang/pt/list.txt b/lib/plugins/usermanager/lang/pt/list.txt
new file mode 100644
index 000000000..01a0460aa
--- /dev/null
+++ b/lib/plugins/usermanager/lang/pt/list.txt
@@ -0,0 +1 @@
+===== Lista de Utilizadores ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/add.txt b/lib/plugins/usermanager/lang/ro/add.txt
new file mode 100644
index 000000000..9a5c45eef
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/add.txt
@@ -0,0 +1 @@
+===== Adaugă utilizator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/delete.txt b/lib/plugins/usermanager/lang/ro/delete.txt
new file mode 100644
index 000000000..ea65fa984
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/delete.txt
@@ -0,0 +1 @@
+===== Şterge utilizator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/edit.txt b/lib/plugins/usermanager/lang/ro/edit.txt
new file mode 100644
index 000000000..b7f8a4213
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/edit.txt
@@ -0,0 +1 @@
+===== Editează utilizator ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/intro.txt b/lib/plugins/usermanager/lang/ro/intro.txt
new file mode 100644
index 000000000..f3c66266d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/intro.txt
@@ -0,0 +1 @@
+===== Manager Utilizatori ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ro/lang.php b/lib/plugins/usermanager/lang/ro/lang.php
new file mode 100644
index 000000000..b8c1f24fc
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Romanian language file
+ *
+ * @author Sergiu Baltariu <s_baltariu@yahoo.com>
+ * @author s_baltariu@yahoo.com
+ * @author Emanuel-Emeric Andrasi <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrași <n30@mandrivausers.ro>
+ * @author Emanuel-Emeric Andraşi <em.andrasi@mandrivausers.ro>
+ * @author Emanuel-Emeric Andrasi <em.andrasi@mandrivausers.ro>
+ * @author Marius OLAR <olarmariusalex@gmail.com>
+ * @author Emanuel-Emeric Andrași <em.andrasi@mandrivausers.ro>
+ */
+$lang['menu'] = 'Manager Utilizatori';
+$lang['noauth'] = '(autentificarea utilizatorilor nu este disponibilă)';
+$lang['nosupport'] = '(menegementul utilizatorilor nu e suportat)';
+$lang['badauth'] = 'mecanism de autentificare invalid';
+$lang['user_id'] = 'Utilizator';
+$lang['user_pass'] = 'Parolă';
+$lang['user_name'] = 'Nume Real';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Grupuri';
+$lang['field'] = 'Câmp';
+$lang['value'] = 'Valoare';
+$lang['add'] = 'Adaugă';
+$lang['delete'] = 'Şterge';
+$lang['delete_selected'] = 'Şterge selecţia';
+$lang['edit'] = 'Editează';
+$lang['edit_prompt'] = 'Editează acest utilizator';
+$lang['modify'] = 'Salvează Modificările';
+$lang['search'] = 'Caută';
+$lang['search_prompt'] = 'Se caută';
+$lang['clear'] = 'Resetează Filtrul de Căutare';
+$lang['filter'] = 'Filtru';
+$lang['summary'] = 'Afişarea utilizatorilor %1$d-%2$d din %3$d găsită. %4$d utilizatori în total.';
+$lang['nonefound'] = 'Nici un utilizator nu a fost găsit. %d utilizatori în total.';
+$lang['delete_ok'] = '%d utilizatori şterşi';
+$lang['delete_fail'] = '%d eşuat la ştergere.';
+$lang['update_ok'] = 'Utilizatorul a fost actualizat cu succes';
+$lang['update_fail'] = 'Actualizarea utilizatorului a eşuat';
+$lang['update_exists'] = 'Modificarea numelui de utilizator a eşuat. Numele de utilizator specificat (%s) există deja (orice altă modificare se va aplica)';
+$lang['start'] = 'început';
+$lang['prev'] = 'anterior';
+$lang['next'] = 'urmator';
+$lang['last'] = 'sfârşit';
+$lang['edit_usermissing'] = 'Utilizatorul selectat nu a fost găsit. E posibil ca numele de utilizator specificat să fi fost şters sau modificat în altă parte.';
+$lang['user_notify'] = 'Notificare utilizator';
+$lang['note_notify'] = 'Emailurile de notificare sunt trimise numai dacă utilizatorului îi este dată o nouă parolă.';
+$lang['note_group'] = 'Noii utilizatori vor fi adăugaţi la grupul implicit (%s) dacă nu se specifică grupul.';
+$lang['note_pass'] = 'Parola va fi regenerată automat dacă câmpul este lăsat gol şi notificarea utilizatorului este activată.';
+$lang['add_ok'] = 'Utilizator adăugat cu succes';
+$lang['add_fail'] = 'Adăugarea utilizatorului a eşuat';
+$lang['notify_ok'] = 'Emailul de notificare a fost trimis';
+$lang['notify_fail'] = 'Emailul de notificare nu a putut fi trimis';
diff --git a/lib/plugins/usermanager/lang/ro/list.txt b/lib/plugins/usermanager/lang/ro/list.txt
new file mode 100644
index 000000000..6c0563444
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ro/list.txt
@@ -0,0 +1 @@
+===== Listă utilizatori ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/ru/add.txt b/lib/plugins/usermanager/lang/ru/add.txt
new file mode 100644
index 000000000..3cb4264e7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/add.txt
@@ -0,0 +1 @@
+===== Добавить пользователя =====
diff --git a/lib/plugins/usermanager/lang/ru/delete.txt b/lib/plugins/usermanager/lang/ru/delete.txt
new file mode 100644
index 000000000..80f874e05
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/delete.txt
@@ -0,0 +1 @@
+===== Удалить пользователя =====
diff --git a/lib/plugins/usermanager/lang/ru/edit.txt b/lib/plugins/usermanager/lang/ru/edit.txt
new file mode 100644
index 000000000..d447c4005
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/edit.txt
@@ -0,0 +1 @@
+===== Редактировать пользователя =====
diff --git a/lib/plugins/usermanager/lang/ru/intro.txt b/lib/plugins/usermanager/lang/ru/intro.txt
new file mode 100644
index 000000000..3a3e2607d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/intro.txt
@@ -0,0 +1 @@
+====== Управление пользователями ======
diff --git a/lib/plugins/usermanager/lang/ru/lang.php b/lib/plugins/usermanager/lang/ru/lang.php
new file mode 100644
index 000000000..456ba5b29
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/lang.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Russian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Denis Simakov <akinoame1@gmail.com>
+ * @author Andrew Pleshakov <beotiger@mail.ru>
+ * @author Змей Этерийский evil_snake@eternion.ru
+ * @author Hikaru Nakajima <jisatsu@mail.ru>
+ * @author Alexei Tereschenko <alexeitlex@yahoo.com>
+ * @author Irina Ponomareva irinaponomareva@webperfectionist.com
+ * @author Alexander Sorkin <kibizoid@gmail.com>
+ * @author Kirill Krasnov <krasnovforum@gmail.com>
+ * @author Vlad Tsybenko <vlad.development@gmail.com>
+ * @author Aleksey Osadchiy <rfc@nm.ru>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Ladyko Andrey <fylh@succexy.spb.ru>
+ * @author Eugene <windy.wanderer@gmail.com>
+ */
+$lang['menu'] = 'Управление пользователями';
+$lang['noauth'] = '(авторизация пользователей недоступна)';
+$lang['nosupport'] = '(управление пользователями не поддерживается)';
+$lang['badauth'] = 'некорректный механизм аутентификации';
+$lang['user_id'] = 'Логин';
+$lang['user_pass'] = 'Пароль';
+$lang['user_name'] = 'Полное имя';
+$lang['user_mail'] = 'Эл. адрес';
+$lang['user_groups'] = 'Группы';
+$lang['field'] = 'Поле';
+$lang['value'] = 'Значение';
+$lang['add'] = 'Добавить';
+$lang['delete'] = 'Удалить';
+$lang['delete_selected'] = 'Удалить выбранные';
+$lang['edit'] = 'Редактировать';
+$lang['edit_prompt'] = 'Редактировать этого пользователя';
+$lang['modify'] = 'Сохранить изменения';
+$lang['search'] = 'Поиск';
+$lang['search_prompt'] = 'Искать';
+$lang['clear'] = 'Сброс фильтра поиска';
+$lang['filter'] = 'Фильтр';
+$lang['summary'] = 'Показаны пользователи %1$d-%2$d из %3$d найденных. Всего пользователей: %4$d.';
+$lang['nonefound'] = 'Не найдено ни одного пользователя. Всего пользователей: %d.';
+$lang['delete_ok'] = 'Удалено пользователей: %d';
+$lang['delete_fail'] = 'Не удалось удалить %d.';
+$lang['update_ok'] = 'Пользователь успешно обновлён';
+$lang['update_fail'] = 'Не удалось обновить пользователя';
+$lang['update_exists'] = 'Не удалось изменить имя пользователя, такой пользователь (%s) уже существует (все остальные изменения будут применены).';
+$lang['start'] = 'в начало';
+$lang['prev'] = 'назад';
+$lang['next'] = 'вперёд';
+$lang['last'] = 'в конец';
+$lang['edit_usermissing'] = 'Выбранный пользователь не найден. Возможно, указанный логин был удалён или изменён извне.';
+$lang['user_notify'] = 'Сообщить пользователю';
+$lang['note_notify'] = 'Письма с уведомлением высылаются только в случае получения нового пароля.';
+$lang['note_group'] = 'Если группа не указана, новые пользователи будут добавлены в группу по умолчанию (%s).';
+$lang['note_pass'] = 'Пароль будет сгенерирован автоматически, если поле оставлено пустым и включено уведомление пользователя.';
+$lang['add_ok'] = 'Пользователь успешно добавлен';
+$lang['add_fail'] = 'Не удалось добавить пользователя';
+$lang['notify_ok'] = 'Письмо с уведомлением отправлено';
+$lang['notify_fail'] = 'Не удалось отправить письмо с уведомлением';
diff --git a/lib/plugins/usermanager/lang/ru/list.txt b/lib/plugins/usermanager/lang/ru/list.txt
new file mode 100644
index 000000000..26c0cbead
--- /dev/null
+++ b/lib/plugins/usermanager/lang/ru/list.txt
@@ -0,0 +1 @@
+===== Список пользователей =====
diff --git a/lib/plugins/usermanager/lang/sk/add.txt b/lib/plugins/usermanager/lang/sk/add.txt
new file mode 100644
index 000000000..e2e106089
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/add.txt
@@ -0,0 +1,2 @@
+===== Pridanie užívateľa =====
+
diff --git a/lib/plugins/usermanager/lang/sk/delete.txt b/lib/plugins/usermanager/lang/sk/delete.txt
new file mode 100644
index 000000000..c7d6a3cc2
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/delete.txt
@@ -0,0 +1,2 @@
+===== Zmazanie užívateľa =====
+
diff --git a/lib/plugins/usermanager/lang/sk/edit.txt b/lib/plugins/usermanager/lang/sk/edit.txt
new file mode 100644
index 000000000..28af5b53c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/edit.txt
@@ -0,0 +1,2 @@
+===== Zmena užívateľa =====
+
diff --git a/lib/plugins/usermanager/lang/sk/intro.txt b/lib/plugins/usermanager/lang/sk/intro.txt
new file mode 100644
index 000000000..0a626de52
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/intro.txt
@@ -0,0 +1,2 @@
+====== Správa používateľov ======
+
diff --git a/lib/plugins/usermanager/lang/sk/lang.php b/lib/plugins/usermanager/lang/sk/lang.php
new file mode 100644
index 000000000..54ed374c6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Slovak language file
+ *
+ * @author Ondrej Végh <ov@vsieti.sk>
+ * @author Michal Mesko <michal.mesko@gmail.com>
+ * @author exusik@gmail.com
+ * @author Martin Michalek <michalek.dev@gmail.com>
+ */
+$lang['menu'] = 'Správa používateľov';
+$lang['noauth'] = '(autentifikácia užívateľov nie je dostupná)';
+$lang['nosupport'] = '(správa užívateľov nie je podporovaná)';
+$lang['badauth'] = 'neplatný autorizačný mechanizmus';
+$lang['user_id'] = 'Užívateľ';
+$lang['user_pass'] = 'Heslo';
+$lang['user_name'] = 'Skutočné meno';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Skupiny';
+$lang['field'] = 'Pole';
+$lang['value'] = 'Hodnota';
+$lang['add'] = 'Pridať';
+$lang['delete'] = 'Zmazať';
+$lang['delete_selected'] = 'Zmazať vybrané';
+$lang['edit'] = 'Zmeniť';
+$lang['edit_prompt'] = 'Zmeniť tohoto užívateľa';
+$lang['modify'] = 'Uložiť zmeny';
+$lang['search'] = 'Hľadať';
+$lang['search_prompt'] = 'Vykonať vyhľadávanie';
+$lang['clear'] = 'Vynulovať vyhľadávací filter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Zobrazenie užívateľov %1$d-%2$d z %3$d nájdených. %4$d užívateľov celkom.';
+$lang['nonefound'] = 'Žiadni užívatelia nenájdení. %d užívateľov celkom.';
+$lang['delete_ok'] = '%d užívateľov zmazaných';
+$lang['delete_fail'] = '%d chýb vymazania.';
+$lang['update_ok'] = 'Užívateľ úspešne zmenený';
+$lang['update_fail'] = 'Chyba zmeny užívateľa';
+$lang['update_exists'] = 'Chyba zmeny užívateľa, užívateľské meno (%s) už existuje (iné zmeny budú zaznamenané).';
+$lang['start'] = 'prvé';
+$lang['prev'] = 'predošlé';
+$lang['next'] = 'ďalšie';
+$lang['last'] = 'posledné';
+$lang['edit_usermissing'] = 'Vybraný užívateľ nebol nájdený, mohol byť zmazaný alebo zmenený iným spôsobom.';
+$lang['user_notify'] = 'Upozorniť užívateľa';
+$lang['note_notify'] = 'Notifikačné e-maily iba vtedy, ak dostane užívateľ nové heslo';
+$lang['note_group'] = 'Noví užívatelia budú pridaní do východzej skupiny (%s), ak nie je pre nich špecifikovaná iná skupina.';
+$lang['note_pass'] = 'Heslo bude vygenerované automaticky, ak bude pole prázdne a je zapnutá notifikácia používateľa.';
+$lang['add_ok'] = 'Používateľ úspešne pridaný';
+$lang['add_fail'] = 'Pridávanie užívateľa nebolo úspešné';
+$lang['notify_ok'] = 'Notifikačný e-mail bol poslaný';
+$lang['notify_fail'] = 'Notifikačný e-mail nemohol byť poslaný';
diff --git a/lib/plugins/usermanager/lang/sk/list.txt b/lib/plugins/usermanager/lang/sk/list.txt
new file mode 100644
index 000000000..6f15331e9
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sk/list.txt
@@ -0,0 +1,2 @@
+===== Zoznam užívateľov =====
+
diff --git a/lib/plugins/usermanager/lang/sl/add.txt b/lib/plugins/usermanager/lang/sl/add.txt
new file mode 100644
index 000000000..c1d8913b4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/add.txt
@@ -0,0 +1 @@
+===== Dodajanje uporabnika ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sl/delete.txt b/lib/plugins/usermanager/lang/sl/delete.txt
new file mode 100644
index 000000000..1fd4fffe1
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/delete.txt
@@ -0,0 +1 @@
+===== Izbris uporabnika ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sl/edit.txt b/lib/plugins/usermanager/lang/sl/edit.txt
new file mode 100644
index 000000000..e80bc8585
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/edit.txt
@@ -0,0 +1 @@
+===== Urejanje uporabnikov ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sl/intro.txt b/lib/plugins/usermanager/lang/sl/intro.txt
new file mode 100644
index 000000000..a4729a8a5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/intro.txt
@@ -0,0 +1 @@
+====== Upravljanje uporabnikov ======
diff --git a/lib/plugins/usermanager/lang/sl/lang.php b/lib/plugins/usermanager/lang/sl/lang.php
new file mode 100644
index 000000000..96acfd0af
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Slovenian language file
+ *
+ * @author Dejan Levec <webphp@gmail.com>
+ * @author Boštjan Seničar <senicar@gmail.com>
+ * @author Gregor Skumavc (grega.skumavc@gmail.com)
+ * @author Matej Urbančič (mateju@svn.gnome.org)
+ */
+$lang['menu'] = 'Upravljanje uporabnikov';
+$lang['noauth'] = '(overjanje istovetnosti uporabnikov ni na voljo)';
+$lang['nosupport'] = '(upravljanje računov uporabnikov ni podprto)';
+$lang['badauth'] = 'neveljaven način overjanja';
+$lang['user_id'] = 'Uporabnik';
+$lang['user_pass'] = 'Geslo';
+$lang['user_name'] = 'Pravo ime';
+$lang['user_mail'] = 'Elektronski naslov';
+$lang['user_groups'] = 'Skupine';
+$lang['field'] = 'Polje';
+$lang['value'] = 'Vrednost';
+$lang['add'] = 'Dodaj';
+$lang['delete'] = 'Izbriši';
+$lang['delete_selected'] = 'Izbriši izbrano';
+$lang['edit'] = 'Uredi';
+$lang['edit_prompt'] = 'Uredi tega uporabnika';
+$lang['modify'] = 'Shrani spremembe';
+$lang['search'] = 'Iskanje';
+$lang['search_prompt'] = 'Poišči';
+$lang['clear'] = 'Počisti filter iskanja';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Izpisani so uporabniki %1$d-%2$d od skupno %3$d. Vseh uporabnikov je %4$d.';
+$lang['nonefound'] = 'Ni najdenih uporabnikov. Vseh uporabnikov je %d.';
+$lang['delete_ok'] = '%d uporabnikov je izbrisanih';
+$lang['delete_fail'] = '%d ni bilo mogoče izbrisati';
+$lang['update_ok'] = 'Uporabniški račun je uspešno posodobljen';
+$lang['update_fail'] = 'Posodobitev uporabniškega računa je spodletela';
+$lang['update_exists'] = 'Spreminjanje imena uporabnika je spodletelo. Navedeno uporabniško ime (%s) že obstaja (vse ostale spremembe bodo uveljavljene).';
+$lang['start'] = 'Začetni';
+$lang['prev'] = 'Predhodni';
+$lang['next'] = 'Naslednji';
+$lang['last'] = 'Končni';
+$lang['edit_usermissing'] = 'Izbranega uporabnika ni mogoče najti. Navedeno uporabniško ime je morda izbrisano ali spremenjeno.';
+$lang['user_notify'] = 'Obvesti uporabnika';
+$lang['note_notify'] = 'Obvestilna sporočila so poslana le, če uporabnik prejme novo geslo za dostop do strani.';
+$lang['note_group'] = 'Nov uporabnik bo dodan k privzeti skupini (%s), v kolikor ni navedene druge skupine.';
+$lang['note_pass'] = 'Geslo bo ustvarjeno samodejno, v kolikor je polje izpuščeno in je omogočeno obveščanje uporabnika.';
+$lang['add_ok'] = 'Uporabnik je uspešno dodan';
+$lang['add_fail'] = 'Dodajanje uporabnika je spodletelo';
+$lang['notify_ok'] = 'Obvestilno sporočilo je poslano.';
+$lang['notify_fail'] = 'Obvestilnega sporočila ni mogoče poslati.';
diff --git a/lib/plugins/usermanager/lang/sl/list.txt b/lib/plugins/usermanager/lang/sl/list.txt
new file mode 100644
index 000000000..1aa8b7a7c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sl/list.txt
@@ -0,0 +1 @@
+===== Seznam uporabnikov ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/add.txt b/lib/plugins/usermanager/lang/sq/add.txt
new file mode 100644
index 000000000..4c66aaf3e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/add.txt
@@ -0,0 +1 @@
+===== Shto Përdorues ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/delete.txt b/lib/plugins/usermanager/lang/sq/delete.txt
new file mode 100644
index 000000000..34cb49173
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/delete.txt
@@ -0,0 +1 @@
+===== Fshi përdorues ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/edit.txt b/lib/plugins/usermanager/lang/sq/edit.txt
new file mode 100644
index 000000000..63131038f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/edit.txt
@@ -0,0 +1 @@
+===== Redakto Përdorues ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/intro.txt b/lib/plugins/usermanager/lang/sq/intro.txt
new file mode 100644
index 000000000..e1ebea60c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/intro.txt
@@ -0,0 +1 @@
+===== Menaxhuesi i Përdoruesit ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sq/lang.php b/lib/plugins/usermanager/lang/sq/lang.php
new file mode 100644
index 000000000..bddf54d5b
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/lang.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Albanian language file
+ *
+ * @author Leonard Elezi leonard.elezi@depinfo.info
+ */
+$lang['menu'] = 'Menaxhuesi Përdoruesve';
+$lang['noauth'] = '(autentikimi i përdoruesve nuk është i disponueshëm)';
+$lang['nosupport'] = '(menaxhimi i përdoruesve nuk suportohet)';
+$lang['badauth'] = '(mekanizëm i pavlefshëm autentikimi)';
+$lang['user_id'] = 'Përdoruesi';
+$lang['user_pass'] = 'Fjalëkalimi
+';
+$lang['user_name'] = 'Emri i Vërtetë';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Grupe';
+$lang['field'] = 'Fusha';
+$lang['value'] = 'Vlera';
+$lang['add'] = 'Shto';
+$lang['delete'] = 'Fshi';
+$lang['delete_selected'] = 'Fshi të Përzgjedhurën';
+$lang['edit'] = 'Redakto';
+$lang['edit_prompt'] = 'Redakto këtë përdorues';
+$lang['modify'] = 'Ruaj Ndryshimet';
+$lang['search'] = 'Kërko';
+$lang['search_prompt'] = 'Kryej kërkim';
+$lang['clear'] = 'Rivendos Filter Kërkimi';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Duke treguar përdoruesit %1$d-%2$d nga %3$d të gjetur. %4$d përdorues në total.';
+$lang['nonefound'] = 'Asnjë përdorues nuk u gjet. %d përdorues në total.';
+$lang['delete_ok'] = '%d përdorues u fshinë.';
+$lang['delete_fail'] = '%d dështuan të fshihen.';
+$lang['update_ok'] = 'Përdoruesi u përditësia me sukses.';
+$lang['update_fail'] = 'Përditësimi i përdoruesit dështoi.';
+$lang['update_exists'] = 'Ndryshimi i emrit të përdoruesit dështoi, emri i përdoruesit i specifikuar (%s) ekziston tashmë (çdo ndryshim tjetër do të zbatohet).';
+$lang['start'] = 'Fillim';
+$lang['prev'] = 'Mëpara';
+$lang['next'] = 'Tjetra';
+$lang['last'] = 'Fundi';
+$lang['edit_usermissing'] = 'Përdoruesi i përzgjedhur nuk u gjet, emri i specifikuar i përdoruesit mund të jetë fshirë ose ndryshuar diku tjetër.';
+$lang['user_notify'] = 'Lajmëro përdoruesin';
+$lang['note_notify'] = 'Email-et e lajmërimit dërgohen vetëm nëse përdoruesit i jepet një fjalëkalim i ri.';
+$lang['note_group'] = 'Përdorues të rinj do të shtohen në grupin default (%s) nëse asnjë grup nuk specifikohet.';
+$lang['note_pass'] = 'Fjalëkalimi do të autogjenerohet nëse fusha lihet bosh dhe lajmërimi i përdoruesit është i aktivizuar.';
+$lang['add_ok'] = 'Përdoruesi u shtua me sukses.';
+$lang['add_fail'] = 'Shtimi i përdoruesit dështoi.';
+$lang['notify_ok'] = 'Email-i lajmërimit u dërgua.';
+$lang['notify_fail'] = 'Email-i lajmërimit nuk mundi të dërgohej.';
diff --git a/lib/plugins/usermanager/lang/sq/list.txt b/lib/plugins/usermanager/lang/sq/list.txt
new file mode 100644
index 000000000..68fc2e7c6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sq/list.txt
@@ -0,0 +1 @@
+===== Lista Përdoruesve ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/add.txt b/lib/plugins/usermanager/lang/sr/add.txt
new file mode 100644
index 000000000..1de9a50e4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/add.txt
@@ -0,0 +1 @@
+===== Додај корисника ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/delete.txt b/lib/plugins/usermanager/lang/sr/delete.txt
new file mode 100644
index 000000000..9b50365be
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/delete.txt
@@ -0,0 +1 @@
+===== Обриши корисника ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/edit.txt b/lib/plugins/usermanager/lang/sr/edit.txt
new file mode 100644
index 000000000..11e22e2f5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/edit.txt
@@ -0,0 +1 @@
+===== Измени корисника ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/intro.txt b/lib/plugins/usermanager/lang/sr/intro.txt
new file mode 100644
index 000000000..6c6ac9a5c
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/intro.txt
@@ -0,0 +1 @@
+====== Управљач корисницима ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sr/lang.php b/lib/plugins/usermanager/lang/sr/lang.php
new file mode 100644
index 000000000..5f2669b58
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/lang.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Serbian language file
+ *
+ * @author Иван Петровић petrovicivan@ubuntusrbija.org
+ * @author Ivan Petrovic <petrovicivan@ubuntusrbija.org>
+ * @author Miroslav Šolti <solti.miroslav@gmail.com>
+ */
+$lang['menu'] = 'Управљач корисницима';
+$lang['noauth'] = '(корисничка провера није доступна)';
+$lang['nosupport'] = '(уптављање корисницима није подржано)';
+$lang['badauth'] = 'неисправан механизам провере';
+$lang['user_id'] = 'Корисник';
+$lang['user_pass'] = 'Лозинка';
+$lang['user_name'] = 'Име и презиме';
+$lang['user_mail'] = 'Е-адреса';
+$lang['user_groups'] = 'Групе';
+$lang['field'] = 'Поље';
+$lang['value'] = 'Вредност';
+$lang['add'] = 'Додај';
+$lang['delete'] = 'Обриши';
+$lang['delete_selected'] = 'Обриши одабране';
+$lang['edit'] = 'Измени';
+$lang['edit_prompt'] = 'Измени корисника';
+$lang['modify'] = 'Сачувај измене';
+$lang['search'] = 'Претрага';
+$lang['search_prompt'] = 'Изведи претрагу';
+$lang['clear'] = 'Поништи филтер претраге';
+$lang['filter'] = 'Филтер';
+$lang['summary'] = 'Приказ %1$d-%2$d од %3$d пронађена корисника. Укупно има %4$d корисника.';
+$lang['nonefound'] = 'Није пронађен корисник. Укупно има %d корисника.';
+$lang['delete_ok'] = '%d корисника је обрисано';
+$lang['delete_fail'] = '%d брисања није успело.';
+$lang['update_ok'] = 'Кориснички налог је ажуриран';
+$lang['update_fail'] = 'Кориснички налог није ажуриран';
+$lang['update_exists'] = 'Измена корисничког имена није успела, наведени корисник (%s) већ постоји (остале измене ће бити примењене).';
+$lang['start'] = 'почетак';
+$lang['prev'] = 'претходна';
+$lang['next'] = 'следећа';
+$lang['last'] = 'крај';
+$lang['edit_usermissing'] = 'Одабрани корисник не постоји, наведено корисничко име је можда обрисано или је измењено негде другде.';
+$lang['user_notify'] = 'Обавести корисника';
+$lang['note_notify'] = 'Потврдна порука ће бити послата једино ако је кориснику додељена нова лозинка.';
+$lang['note_group'] = 'Нови корисници ће бити додељени подразумеваној групи (%s) ако није другачије назначено.';
+$lang['note_pass'] = 'Ако сте оставили поље празно и укључили обавештавање корисника лозинка ће бити аутоматски генерисана.';
+$lang['add_ok'] = 'Корисник је успешно додат';
+$lang['add_fail'] = 'Додавање корисника није успело';
+$lang['notify_ok'] = 'Порука са обавештењен је послата';
+$lang['notify_fail'] = 'Порука са обавештењен није послата';
diff --git a/lib/plugins/usermanager/lang/sr/list.txt b/lib/plugins/usermanager/lang/sr/list.txt
new file mode 100644
index 000000000..948444245
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sr/list.txt
@@ -0,0 +1 @@
+===== Списак корисника ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/sv/add.txt b/lib/plugins/usermanager/lang/sv/add.txt
new file mode 100644
index 000000000..2ff1ee640
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/add.txt
@@ -0,0 +1 @@
+===== Lägg till användare =====
diff --git a/lib/plugins/usermanager/lang/sv/delete.txt b/lib/plugins/usermanager/lang/sv/delete.txt
new file mode 100644
index 000000000..5664a5906
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/delete.txt
@@ -0,0 +1 @@
+===== Radera användare =====
diff --git a/lib/plugins/usermanager/lang/sv/edit.txt b/lib/plugins/usermanager/lang/sv/edit.txt
new file mode 100644
index 000000000..f1a7f4a22
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/edit.txt
@@ -0,0 +1 @@
+===== Redigera användare =====
diff --git a/lib/plugins/usermanager/lang/sv/intro.txt b/lib/plugins/usermanager/lang/sv/intro.txt
new file mode 100644
index 000000000..bd13b8157
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/intro.txt
@@ -0,0 +1 @@
+====== Hantera användare ======
diff --git a/lib/plugins/usermanager/lang/sv/lang.php b/lib/plugins/usermanager/lang/sv/lang.php
new file mode 100644
index 000000000..bd747927e
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/lang.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Swedish language file
+ *
+ * @author Per Foreby <per@foreby.se>
+ * @author Nicklas Henriksson <nicklas[at]nihe.se>
+ * @author Håkan Sandell <hakan.sandell[at]mydata.se>
+ * @author Dennis Karlsson
+ * @author Tormod Otter Johansson <tormod@latast.se>
+ * @author emil@sys.nu
+ * @author Pontus Bergendahl <pontus.bergendahl@gmail.com>
+ * @author Tormod Johansson tormod.otter.johansson@gmail.com
+ * @author Emil Lind <emil@sys.nu>
+ * @author Bogge Bogge <bogge@bogge.com>
+ * @author Peter Åström <eaustreum@gmail.com>
+ * @author Håkan Sandell <hakan.sandell@home.se>
+ * @author mikael@mallander.net
+ */
+$lang['menu'] = 'Hantera användare';
+$lang['noauth'] = '(användarautentisering ej tillgänlig)';
+$lang['nosupport'] = '(användarhantering stödjs ej)';
+$lang['badauth'] = 'ogiltig autentiseringsmekanism';
+$lang['user_id'] = 'Användare';
+$lang['user_pass'] = 'Lösenord';
+$lang['user_name'] = 'Namn';
+$lang['user_mail'] = 'E-post';
+$lang['user_groups'] = 'Grupper';
+$lang['field'] = 'Fält';
+$lang['value'] = 'Värde';
+$lang['add'] = 'Lägg till';
+$lang['delete'] = 'Radera';
+$lang['delete_selected'] = 'Radera markerade';
+$lang['edit'] = 'Redigera';
+$lang['edit_prompt'] = 'Redigera användaren';
+$lang['modify'] = 'Spara ändringar';
+$lang['search'] = 'Sök';
+$lang['search_prompt'] = 'Utför sökning';
+$lang['clear'] = 'Återställ sökfilter';
+$lang['filter'] = 'Filter';
+$lang['summary'] = 'Visar användare %1$d-%2$d av %3$d funna. %4$d användare totalt.';
+$lang['nonefound'] = 'Inga användare hittades. %d användare totalt.';
+$lang['delete_ok'] = '%d användare raderade';
+$lang['delete_fail'] = '%d kunde inte raderas.';
+$lang['update_ok'] = 'Användaren uppdaterad';
+$lang['update_fail'] = 'Användaruppdatering misslyckades';
+$lang['update_exists'] = 'Kunde inte ändra användarnamn,, det angivna användarnamnet (%s) finns redan (andra ändringar kommer att utföras).';
+$lang['start'] = 'start';
+$lang['prev'] = 'föregående';
+$lang['next'] = 'nästa';
+$lang['last'] = 'sista';
+$lang['edit_usermissing'] = 'Vald användare hittades inte. Den angivna användaren kan ha blivit raderad, eller ändrats någon annanstans.';
+$lang['user_notify'] = 'Meddela användaren';
+$lang['note_notify'] = 'E-postmeddelanden skickas bara om användaren har fått ett nytt lösenord.';
+$lang['note_group'] = 'Nya användare läggs till i standardgruppen (%s) om inga grupper anges.';
+$lang['note_pass'] = 'Lösenordet kommer att autogenereras om fältet är tomt och e-postmeddelanden till användaren är påslaget.';
+$lang['add_ok'] = 'Användaren tillagd';
+$lang['add_fail'] = 'Användare kunde inte läggas till';
+$lang['notify_ok'] = 'E-postmeddelande skickat';
+$lang['notify_fail'] = 'E-postmeddelande kunde inte skickas';
diff --git a/lib/plugins/usermanager/lang/sv/list.txt b/lib/plugins/usermanager/lang/sv/list.txt
new file mode 100644
index 000000000..e07c45277
--- /dev/null
+++ b/lib/plugins/usermanager/lang/sv/list.txt
@@ -0,0 +1 @@
+===== Användarlista =====
diff --git a/lib/plugins/usermanager/lang/th/add.txt b/lib/plugins/usermanager/lang/th/add.txt
new file mode 100644
index 000000000..6a5f09855
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/add.txt
@@ -0,0 +1 @@
+====== เพิ่มผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/th/delete.txt b/lib/plugins/usermanager/lang/th/delete.txt
new file mode 100644
index 000000000..4dbc82bf9
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/delete.txt
@@ -0,0 +1 @@
+====== ลบผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/th/edit.txt b/lib/plugins/usermanager/lang/th/edit.txt
new file mode 100644
index 000000000..c36e8ddf8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/edit.txt
@@ -0,0 +1 @@
+====== แก้ไขผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/th/intro.txt b/lib/plugins/usermanager/lang/th/intro.txt
new file mode 100644
index 000000000..0f6a0c3b6
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/intro.txt
@@ -0,0 +1 @@
+====== ตัวจัดการผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/th/lang.php b/lib/plugins/usermanager/lang/th/lang.php
new file mode 100644
index 000000000..eb88d7b91
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/lang.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Thai language file
+ *
+ * @author Komgrit Niyomrath <n.komgrit@gmail.com>
+ * @author Kittithat Arnontavilas mrtomyum@gmail.com
+ * @author Kittithat Arnontavilas <mrtomyum@gmail.com>
+ * @author Thanasak Sompaisansin <jombthep@gmail.com>
+ */
+$lang['menu'] = 'ตัวจัดการบัญชีผู้ใช้';
+$lang['user_id'] = 'ผู้ใช้';
+$lang['user_pass'] = 'รหัสผ่าน';
+$lang['user_name'] = 'ชื่อจริง';
+$lang['user_mail'] = 'อีเมล';
+$lang['user_groups'] = 'กลุ่ม';
+$lang['field'] = 'ฟิลด์';
+$lang['value'] = 'ค่า';
+$lang['add'] = 'เพิ่ม';
+$lang['delete'] = 'ลบ';
+$lang['delete_selected'] = 'ลบที่เลือก';
+$lang['edit'] = 'แก้ไข';
+$lang['edit_prompt'] = 'แก้ไขผู้ใช้คนนี้';
+$lang['modify'] = 'บันทึกการแก้ไข';
+$lang['search'] = 'สืบค้น';
+$lang['search_prompt'] = 'ทำการสืบค้น';
+$lang['clear'] = 'รีเซ็ทตัวกรองคำค้น';
+$lang['filter'] = 'ตัวกรอง';
+$lang['summary'] = 'แสดงผู้ใช้ %1$d-%2$d จากที่พบ %3$d คน, จากทั้งหมด %4$d คน';
+$lang['nonefound'] = 'ไม่พบผู้ใช้ จากทั้งหมด %d คน';
+$lang['delete_ok'] = 'ลบชื่อผู้ใช้ %d คน';
+$lang['delete_fail'] = 'ไม่สามารถลบได้ %d คน';
+$lang['update_ok'] = 'ปรับปรุงข้อมูลผู้ใช้ สำเร็จ';
+$lang['update_fail'] = 'ปรับปรุงข้อมูลผู้ใช้ **ไม่สำเร็จ**';
+$lang['update_exists'] = 'ไม่สามารถเปลี่นชื่อผู้ใช้ได้ ชื่อผู้ใช้ที่ระบุ (%s) มีอยู่แล้ว (การเปลี่นนแปลงอื่นๆ ยังคงทำได้)';
+$lang['start'] = 'เริ่ม';
+$lang['prev'] = 'ก่อนหน้า';
+$lang['next'] = 'ถัดไป';
+$lang['last'] = 'สุดท้าย';
+$lang['edit_usermissing'] = 'หาผู้ใช้ที่เลือกไม่พบ, ชื่อผุ้ใช้ที่ระบุอาจจะถูกลบ หรือเปลี่ยนเป็นอย่างอื่น';
+$lang['user_notify'] = 'แจ้งเตือนผู้ใช้';
+$lang['note_notify'] = 'จดหมายแจ้งเตือนถูกส่งก็ต่อเมื่อผู้ใช้ได้รับมอบรหัสผ่านใหม่';
+$lang['note_group'] = 'ผู้ใช้ใหม่จะถูกเพิ่มเข้าไปยังกลุ่มปริยาย (%s) หากมิได้ระบุกลุ่มเอาไว้';
+$lang['note_pass'] = 'รหัสผ่านจะถูกสร้างโดยอัตโนมัติ ถ้าเว้นว่างช่องกรอก และเปิดการแจ้งเตือนผู้ใช้เอาไว้';
+$lang['add_ok'] = 'การเพิ่มผู้ใช้สำเร็จ';
+$lang['add_fail'] = 'การเพิ่มผู้ใช้ล้มเหลว';
+$lang['notify_ok'] = 'ส่งจดหมายแจ้งเตือนไปแล้ว';
+$lang['notify_fail'] = 'ไม่สามารถส่งจดหมายแจ้งเตือน';
diff --git a/lib/plugins/usermanager/lang/th/list.txt b/lib/plugins/usermanager/lang/th/list.txt
new file mode 100644
index 000000000..fdf65b555
--- /dev/null
+++ b/lib/plugins/usermanager/lang/th/list.txt
@@ -0,0 +1 @@
+====== รายชื่อผู้ใช้ ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/add.txt b/lib/plugins/usermanager/lang/tr/add.txt
new file mode 100644
index 000000000..beedc0be0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/add.txt
@@ -0,0 +1 @@
+===== Kullanıcı ekleme ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/delete.txt b/lib/plugins/usermanager/lang/tr/delete.txt
new file mode 100644
index 000000000..adb8e91e4
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/delete.txt
@@ -0,0 +1 @@
+===== Kullanıcı silme ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/edit.txt b/lib/plugins/usermanager/lang/tr/edit.txt
new file mode 100644
index 000000000..d9f3b7125
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/edit.txt
@@ -0,0 +1 @@
+===== Kullanıcı Düzenleme ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/intro.txt b/lib/plugins/usermanager/lang/tr/intro.txt
new file mode 100644
index 000000000..1edcb2ce0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/intro.txt
@@ -0,0 +1 @@
+====== Kullanıcı Yöneticisi ====== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/tr/lang.php b/lib/plugins/usermanager/lang/tr/lang.php
new file mode 100644
index 000000000..b9c9cfc52
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/lang.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Turkish language file
+ *
+ * @author Aydın Coşkuner <aydinweb@gmail.com>
+ * @author Cihan Kahveci <kahvecicihan@gmail.com>
+ * @author Yavuz Selim <yavuzselim@gmail.com>
+ * @author Caleb Maclennan <caleb@alerque.com>
+ */
+$lang['menu'] = 'Kullanıcı Yönetimi';
+$lang['noauth'] = '(kullanıcı onaylaması yoktur)';
+$lang['nosupport'] = '(kullanıcı yönetimi desteklenmemektedir)';
+$lang['badauth'] = 'yanlış onaylama metodu';
+$lang['user_id'] = 'Kullanıcı';
+$lang['user_pass'] = 'Şifre';
+$lang['user_name'] = 'Gerçek İsim';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Gruplar';
+$lang['field'] = 'Alan';
+$lang['value'] = 'Değer';
+$lang['add'] = 'Ekle';
+$lang['delete'] = 'Sil';
+$lang['delete_selected'] = 'Seçilenleri Sil';
+$lang['edit'] = 'Düzenle';
+$lang['edit_prompt'] = 'Bu kullanıcıyı düzenle';
+$lang['modify'] = 'Değişiklikleri kaydet';
+$lang['search'] = 'Arama';
+$lang['search_prompt'] = 'Aramayı Gerçekleştir';
+$lang['clear'] = 'Arama ayarlarını sıfırla';
+$lang['filter'] = 'Filtre';
+$lang['summary'] = 'Bulunan %3$d kullanıcının %1$d-%2$d gösterilmektedir. Toplam %4$d kullanıcı bulunmaktadır.';
+$lang['nonefound'] = 'Hiç kullanıcı bulunamadı. Toplam %d kullanıcı bulunmaktadır.';
+$lang['delete_ok'] = '%d kullanıcılar silindi';
+$lang['delete_fail'] = '%d silinemedi.';
+$lang['update_ok'] = 'Kullanıcı başarı ile güncelleştirildi';
+$lang['update_fail'] = 'Kullanıcı güncelleştirilemedi';
+$lang['update_exists'] = 'Kullanıcı adı değiştirilemedi. Belirtilen kullanıcı adı (%s) zaten bulunmaktadır (yapılan diğer değişiklikler uygulanacaktır).';
+$lang['start'] = 'başla';
+$lang['prev'] = 'önceki';
+$lang['next'] = 'sonraki';
+$lang['last'] = 'sonuncu';
+$lang['edit_usermissing'] = 'Seçili kullanıcılar bulunamadı, belirtilen kullanıcı silinmiş ya da değiştirilmiş olabilir.';
+$lang['user_notify'] = 'Kullanıcıyı bilgilendir';
+$lang['note_notify'] = 'Bilgilendirme e-postaları sadece kullanıcıya yeni bir parola verildiğinde gönderilmektedir.';
+$lang['note_group'] = 'Yeni kullanıcılar bir grup belirtilmezse varsayılan (%s) gruba eklenecektir.';
+$lang['note_pass'] = 'Eğer alan boş bırakılırsa parola otomatik oluşturulacaktır ve kullanıcı bilgilendirme etkinleştirilecektir. ';
+$lang['add_ok'] = 'Kullanıcı başarı ile eklendi';
+$lang['add_fail'] = 'Kullanıcı ekleme başarısız';
+$lang['notify_ok'] = 'Bildirim emaili gönderildi';
+$lang['notify_fail'] = 'Bildirim emaili gönderilemedi';
diff --git a/lib/plugins/usermanager/lang/tr/list.txt b/lib/plugins/usermanager/lang/tr/list.txt
new file mode 100644
index 000000000..2314eb22f
--- /dev/null
+++ b/lib/plugins/usermanager/lang/tr/list.txt
@@ -0,0 +1 @@
+===== Kullanıcı Listesi ===== \ No newline at end of file
diff --git a/lib/plugins/usermanager/lang/uk/add.txt b/lib/plugins/usermanager/lang/uk/add.txt
new file mode 100644
index 000000000..bc3469714
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/add.txt
@@ -0,0 +1 @@
+===== Додати користувача =====
diff --git a/lib/plugins/usermanager/lang/uk/delete.txt b/lib/plugins/usermanager/lang/uk/delete.txt
new file mode 100644
index 000000000..739340b19
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/delete.txt
@@ -0,0 +1 @@
+===== Видалення користувача =====
diff --git a/lib/plugins/usermanager/lang/uk/edit.txt b/lib/plugins/usermanager/lang/uk/edit.txt
new file mode 100644
index 000000000..efc84be89
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/edit.txt
@@ -0,0 +1 @@
+===== Редагувати користувача =====
diff --git a/lib/plugins/usermanager/lang/uk/intro.txt b/lib/plugins/usermanager/lang/uk/intro.txt
new file mode 100644
index 000000000..b658affe5
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/intro.txt
@@ -0,0 +1 @@
+====== Керування користувачами ======
diff --git a/lib/plugins/usermanager/lang/uk/lang.php b/lib/plugins/usermanager/lang/uk/lang.php
new file mode 100644
index 000000000..027c94b44
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/lang.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * ukrainian language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Oleksiy Voronin <ovoronin@gmail.com>
+ * @author serg_stetsuk@ukr.net
+ * @author okunia@gmail.com
+ * @author Oleksandr Kunytsia <okunia@gmail.com>
+ * @author Uko uko@uar.net
+ * @author Ulrikhe Lukoie <lukoie@gmail>.com
+ */
+$lang['menu'] = 'Керування користувачами';
+$lang['noauth'] = '(автентифікація користувачів не доступна)';
+$lang['nosupport'] = '(керування користувачами не підтримується)';
+$lang['badauth'] = 'невірний механізм автентифікації';
+$lang['user_id'] = 'Ім’я користувача';
+$lang['user_pass'] = 'Пароль';
+$lang['user_name'] = 'Повне ім’я';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = 'Групи';
+$lang['field'] = 'Поле';
+$lang['value'] = 'Значення';
+$lang['add'] = 'Додати';
+$lang['delete'] = 'Видалити';
+$lang['delete_selected'] = 'Видалити вибраних';
+$lang['edit'] = 'Змінити';
+$lang['edit_prompt'] = 'Змінити цього користувача';
+$lang['modify'] = 'Зберегти зміни';
+$lang['search'] = 'Пошук';
+$lang['search_prompt'] = 'Шукати';
+$lang['clear'] = 'Очистити фільтр пошуку';
+$lang['filter'] = 'Фільтр';
+$lang['summary'] = 'Показано користувачі %1$d-%2$d з %3$d знайдених. Всього користувачів: %4$d.';
+$lang['nonefound'] = 'Не знайдено жодного користувача. Всього користувачів: %d.';
+$lang['delete_ok'] = 'Видалено користувачів: %d';
+$lang['delete_fail'] = 'Не вдалося видалити %d.';
+$lang['update_ok'] = 'Дані користувача оновлено';
+$lang['update_fail'] = 'Не вдалося оновити дані користувача';
+$lang['update_exists'] = 'Не вдалося змінити ім’я користувача, такий користувач (%s) вже існує (всі інші зміни будуть застосовані).';
+$lang['start'] = 'на початок';
+$lang['prev'] = 'назад';
+$lang['next'] = 'вперед';
+$lang['last'] = 'в кінець';
+$lang['edit_usermissing'] = 'Обраного користувача не знайдено, можливо його було вилучено або змінено ще десь.';
+$lang['user_notify'] = 'Повідомити користувача';
+$lang['note_notify'] = 'Листи з повідомленнями відсилаються лише у випадку видачі нового пароля користувачу.';
+$lang['note_group'] = 'Якщо не визначено групи, то нові користувачі будуть автоматично додані до групи за замовчуванням (%s).';
+$lang['note_pass'] = 'Пароль буде згенеровано автоматично, якщо поле пароля не заповнено і увімкнено прапорець "повідомити користувача".';
+$lang['add_ok'] = 'Користувача додано';
+$lang['add_fail'] = 'Неможливо додати користувача';
+$lang['notify_ok'] = 'Листа з повідомленням надіслано';
+$lang['notify_fail'] = 'Неможливо вислати листа з повідомленням';
diff --git a/lib/plugins/usermanager/lang/uk/list.txt b/lib/plugins/usermanager/lang/uk/list.txt
new file mode 100644
index 000000000..76013a9b7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/uk/list.txt
@@ -0,0 +1 @@
+===== Список користувачів =====
diff --git a/lib/plugins/usermanager/lang/zh-tw/add.txt b/lib/plugins/usermanager/lang/zh-tw/add.txt
new file mode 100644
index 000000000..6e25f1719
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/add.txt
@@ -0,0 +1 @@
+===== 增加帳號 =====
diff --git a/lib/plugins/usermanager/lang/zh-tw/delete.txt b/lib/plugins/usermanager/lang/zh-tw/delete.txt
new file mode 100644
index 000000000..1a29ba349
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/delete.txt
@@ -0,0 +1 @@
+===== 刪除帳號 =====
diff --git a/lib/plugins/usermanager/lang/zh-tw/edit.txt b/lib/plugins/usermanager/lang/zh-tw/edit.txt
new file mode 100644
index 000000000..ec1c5d5ec
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/edit.txt
@@ -0,0 +1 @@
+===== 修改帳號 =====
diff --git a/lib/plugins/usermanager/lang/zh-tw/intro.txt b/lib/plugins/usermanager/lang/zh-tw/intro.txt
new file mode 100644
index 000000000..8f9488d7d
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/intro.txt
@@ -0,0 +1 @@
+====== 帳號管理員 ======
diff --git a/lib/plugins/usermanager/lang/zh-tw/lang.php b/lib/plugins/usermanager/lang/zh-tw/lang.php
new file mode 100644
index 000000000..5cb20aae8
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/lang.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * English language file
+ *
+ * @author chinsan <chinsan.tw@gmail.com>
+ * @author Li-Jiun Huang <ljhuang.tw@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-simptrad.html
+ * @author Wayne San <waynesan@zerozone.tw>
+ * @author Li-Jiun Huang <ljhuang.tw@gmai.com>
+ * @author Cheng-Wei Chien <e.cwchien@gmail.com>
+ * @author Danny Lin <danny0838@pchome.com.tw>
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '帳號管理員';
+$lang['noauth'] = '(帳號認證尚未開放)';
+$lang['nosupport'] = '(尚不支援帳號管理)';
+$lang['badauth'] = '錯誤的認證機制';
+$lang['user_id'] = '帳號';
+$lang['user_pass'] = '密碼';
+$lang['user_name'] = '真實姓名';
+$lang['user_mail'] = 'E-mail';
+$lang['user_groups'] = '群組';
+$lang['field'] = '欄位';
+$lang['value'] = '設定值';
+$lang['add'] = '增加';
+$lang['delete'] = '刪除';
+$lang['delete_selected'] = '刪除所選的';
+$lang['edit'] = '修改';
+$lang['edit_prompt'] = '修改該帳號';
+$lang['modify'] = '儲存變更';
+$lang['search'] = '搜尋';
+$lang['search_prompt'] = '開始搜尋';
+$lang['clear'] = '重設篩選條件';
+$lang['filter'] = '篩選條件(Filter)';
+$lang['summary'] = '顯示帳號 %1$d-%2$d,共 %3$d 筆符合。共有 %4$d 個帳號。';
+$lang['nonefound'] = '找不到帳號。共有 %d 個帳號。';
+$lang['delete_ok'] = '已刪除 %d 個帳號';
+$lang['delete_fail'] = '%d 個帳號刪除失敗';
+$lang['update_ok'] = '成功更新該帳號';
+$lang['update_fail'] = '更新該帳號時失敗';
+$lang['update_exists'] = '變更帳號名稱 (%s) 失敗,因為有同名帳號存在(其他修改已套用)。';
+$lang['start'] = '開始';
+$lang['prev'] = '上一頁';
+$lang['next'] = '下一頁';
+$lang['last'] = '最後一頁';
+$lang['edit_usermissing'] = '找不到選取的帳號,可能已被刪除或改為其他名稱。';
+$lang['user_notify'] = '通知使用者';
+$lang['note_notify'] = '通知信只會在指定使用者新密碼時寄送。';
+$lang['note_group'] = '如果沒有指定群組,新使用者將會被加入到預設群組(%s)當中。';
+$lang['note_pass'] = '如果沒有輸入這個欄位而且有勾選通知使用者,則會自動產生一組密碼。';
+$lang['add_ok'] = '新增使用者成功';
+$lang['add_fail'] = '新增使用者失敗';
+$lang['notify_ok'] = '通知信已寄出';
+$lang['notify_fail'] = '通知信無法寄出';
diff --git a/lib/plugins/usermanager/lang/zh-tw/list.txt b/lib/plugins/usermanager/lang/zh-tw/list.txt
new file mode 100644
index 000000000..1e539bd41
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh-tw/list.txt
@@ -0,0 +1 @@
+===== 帳號清單 =====
diff --git a/lib/plugins/usermanager/lang/zh/add.txt b/lib/plugins/usermanager/lang/zh/add.txt
new file mode 100644
index 000000000..fd3b1e581
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/add.txt
@@ -0,0 +1 @@
+===== 添加用户 =====
diff --git a/lib/plugins/usermanager/lang/zh/delete.txt b/lib/plugins/usermanager/lang/zh/delete.txt
new file mode 100644
index 000000000..dc6b7fcc7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/delete.txt
@@ -0,0 +1 @@
+===== 删除用户 =====
diff --git a/lib/plugins/usermanager/lang/zh/edit.txt b/lib/plugins/usermanager/lang/zh/edit.txt
new file mode 100644
index 000000000..83b72dff7
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/edit.txt
@@ -0,0 +1 @@
+===== 编辑用户 =====
diff --git a/lib/plugins/usermanager/lang/zh/intro.txt b/lib/plugins/usermanager/lang/zh/intro.txt
new file mode 100644
index 000000000..5f254be72
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/intro.txt
@@ -0,0 +1 @@
+====== 用户管理器 ======
diff --git a/lib/plugins/usermanager/lang/zh/lang.php b/lib/plugins/usermanager/lang/zh/lang.php
new file mode 100644
index 000000000..e7a228229
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/lang.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * English language file
+ *
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author http://www.chinese-tools.com/tools/converter-tradsimp.html
+ * @author George Sheraton guxd@163.com
+ * @author Simon zhan <simonzhan@21cn.com>
+ * @author mr.jinyi@gmail.com
+ * @author ben <ben@livetom.com>
+ * @author lainme <lainme993@gmail.com>
+ * @author caii <zhoucaiqi@gmail.com>
+ * @author Hiphen Lee <jacob.b.leung@gmail.com>
+ * @author caii, patent agent in China <zhoucaiqi@gmail.com>
+ * @author lainme993@gmail.com
+ * @author Shuo-Ting Jian <shoting@gmail.com>
+ */
+$lang['menu'] = '用户管理器';
+$lang['noauth'] = '(用户认证不可用)';
+$lang['nosupport'] = '(用户管理不支持)';
+$lang['badauth'] = '非法的认证结构';
+$lang['user_id'] = '用户名';
+$lang['user_pass'] = '密码';
+$lang['user_name'] = '真实姓名';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = '组 *';
+$lang['field'] = '栏目';
+$lang['value'] = '值';
+$lang['add'] = '添加';
+$lang['delete'] = '删除';
+$lang['delete_selected'] = '删除选中的';
+$lang['edit'] = '编辑';
+$lang['edit_prompt'] = '编辑该用户';
+$lang['modify'] = '保存更改';
+$lang['search'] = '搜索';
+$lang['search_prompt'] = '进行搜索';
+$lang['clear'] = '重置搜索过滤器';
+$lang['filter'] = '过滤器';
+$lang['summary'] = '找到 %3$d 名用户,显示其中第 %1$d 至 %2$d 位用户。数据库中共有 %4$d 名用户。';
+$lang['nonefound'] = '没有找到用户。数据库中共有 %d 名用户。';
+$lang['delete_ok'] = '用户 %d 已删除';
+$lang['delete_fail'] = '用户 %d 删除失败。';
+$lang['update_ok'] = '用户更新成功';
+$lang['update_fail'] = '用户更新失败';
+$lang['update_exists'] = '用户名更改失败,您指定的用户名(%s)已存在(其他更改将立即生效)。';
+$lang['start'] = '第一页';
+$lang['prev'] = '前一页';
+$lang['next'] = '后一页';
+$lang['last'] = '最后一页';
+$lang['edit_usermissing'] = '您指定的用户没有找到,可能用户已被删除或用户名已更改。';
+$lang['user_notify'] = '通知用户';
+$lang['note_notify'] = '通知邮件只有在用户获得新密码时才会发送。';
+$lang['note_group'] = '* 如果没有指定组,新用户将被添加到默认的组(%s)中。';
+$lang['note_pass'] = '如果输入框留空则自动生成口令,并会通知用户。';
+$lang['add_ok'] = '用户添加成功';
+$lang['add_fail'] = '用户添加失败';
+$lang['notify_ok'] = '通知邮件已发送';
+$lang['notify_fail'] = '通知邮件无法发送';
diff --git a/lib/plugins/usermanager/lang/zh/list.txt b/lib/plugins/usermanager/lang/zh/list.txt
new file mode 100644
index 000000000..e62a85bd0
--- /dev/null
+++ b/lib/plugins/usermanager/lang/zh/list.txt
@@ -0,0 +1 @@
+===== 用户列表 =====
diff --git a/lib/plugins/usermanager/plugin.info.txt b/lib/plugins/usermanager/plugin.info.txt
new file mode 100644
index 000000000..7ec5fafd5
--- /dev/null
+++ b/lib/plugins/usermanager/plugin.info.txt
@@ -0,0 +1,6 @@
+author Chris Smith
+email chris@jalakai.co.uk
+date 2008-09-17
+name User Manager
+desc Manage users
+url http://dokuwiki.org/plugin:usermanager
diff --git a/lib/plugins/usermanager/script.js b/lib/plugins/usermanager/script.js
new file mode 100644
index 000000000..de013242b
--- /dev/null
+++ b/lib/plugins/usermanager/script.js
@@ -0,0 +1,8 @@
+/**
+ * Add JavaScript confirmation to the User Delete button
+ */
+jQuery(function(){
+ jQuery('#usrmgr__del').click(function(){
+ return confirm(LANG.del_confirm);
+ });
+});
diff --git a/lib/plugins/usermanager/style.css b/lib/plugins/usermanager/style.css
new file mode 100644
index 000000000..ff8e5d9d1
--- /dev/null
+++ b/lib/plugins/usermanager/style.css
@@ -0,0 +1,20 @@
+/* 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 input.button[disabled] {
+ color: #ccc!important;
+ border-color: #ccc!important;
+}
+/* IE won't understand but doesn't require it */
diff --git a/lib/scripts/behaviour.js b/lib/scripts/behaviour.js
new file mode 100644
index 000000000..cffdde042
--- /dev/null
+++ b/lib/scripts/behaviour.js
@@ -0,0 +1,180 @@
+/**
+ * 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('#page__revisions input[type=checkbox]').live('click',
+ dw_behaviour.revisionBoxHandler
+ );
+ },
+
+ /**
+ * Looks for an element with the ID scroll__here at scrolls to it
+ */
+ scrollToMarker: function(){
+ var $obj = jQuery('#scroll__here');
+ if($obj.length) {
+ $obj[0].scrollIntoView();
+ }
+ },
+
+ /**
+ * Looks for an element with the ID focus__this at sets focus to it
+ */
+ focusMarker: function(){
+ jQuery('#focus__this').focus();
+ },
+
+ /**
+ * Remove all search highlighting when clicking on a highlighted term
+ *
+ * @FIXME would be nice to have it fade out
+ */
+ removeHighlightOnClick: function(){
+ jQuery('span.search_hit').click(
+ function(e){
+ jQuery(e.target).removeClass('search_hit');
+ }
+ );
+ },
+
+ /**
+ * 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')
+ .change(function(e){ e.target.form.submit(); })
+ .closest('form').find('input[type=submit]').not('.show').hide();
+ },
+
+ /**
+ * Display error for Windows Shares on browsers other than IE
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ checkWindowsShares: function() {
+ if(!LANG.nosmblinks || typeof(document.all) !== 'undefined') {
+ // No warning requested or none necessary
+ return;
+ }
+
+ jQuery('a.windows').live('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']")
+ .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')
+ .click();
+ },
+
+ /**
+ * disable multiple revisions checkboxes if two are checked
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ revisionBoxHandler: function(){
+ var $checked = jQuery('#page__revisions input[type=checkbox]:checked');
+ var $all = jQuery('#page__revisions input[type=checkbox]');
+
+ if($checked.length < 2){
+ $all.attr('disabled',false);
+ jQuery('#page__revisions input[type=submit]').attr('disabled',true);
+ }else{
+ $all.attr('disabled',true);
+ jQuery('#page__revisions input[type=submit]').attr('disabled',false);
+ for(var i=0; i<$checked.length; i++){
+ $checked[i].disabled = false;
+ if(i>1){
+ $checked[i].checked = false;
+ }
+ }
+ }
+ }
+
+};
+
+/**
+ * Hides elements with a slide animation
+ *
+ * @param fn optional callback to run after hiding
+ * @author Adrian Lang <mail@adrianlang.de>
+ */
+jQuery.fn.dw_hide = function(fn) {
+ return this.slideUp('fast', fn);
+};
+
+/**
+ * Unhides elements with a slide animation
+ *
+ * @param fn optional callback to run after hiding
+ * @author Adrian Lang <mail@adrianlang.de>
+ */
+jQuery.fn.dw_show = function(fn) {
+ return this.slideDown('fast', fn);
+};
+
+/**
+ * Toggles visibility of an element using a slide element
+ *
+ * @param bool the current state of the element (optional)
+ */
+jQuery.fn.dw_toggle = function(bool, fn) {
+ return this.each(function() {
+ var $this = jQuery(this);
+ if (typeof bool === 'undefined') {
+ bool = $this.is(':hidden');
+ }
+ $this[bool ? "dw_show" : "dw_hide" ](fn);
+ });
+};
+
+jQuery(dw_behaviour.init);
diff --git a/lib/scripts/compatibility.js b/lib/scripts/compatibility.js
new file mode 100644
index 000000000..385e45854
--- /dev/null
+++ b/lib/scripts/compatibility.js
@@ -0,0 +1,414 @@
+/**
+ * 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);
+ };
+}
+
+/**
+ * Handy shortcut to document.getElementById
+ *
+ * This function was taken from the prototype library
+ *
+ * @link http://prototype.conio.net/
+ */
+function $() {
+ DEPRECATED('Please use the jQuery() function instead.');
+
+ var elements = new Array();
+
+ for (var i = 0; i < arguments.length; i++) {
+ var element = arguments[i];
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+
+ if (arguments.length == 1)
+ return element;
+
+ elements.push(element);
+ }
+
+ return elements;
+}
+
+
+
+
+var index = {
+ throbber_delay: dw_index.throbber_delay,
+ toggle: DEPRECATED_WRAP(dw_index.toggle, dw_index),
+ treeattach: DEPRECATED_WRAP(dw_index.treeattach, dw_index)
+};
+
+var ajax_quicksearch = {
+ init: DEPRECATED_WRAP(dw_qsearch.init, dw_qsearch),
+ clear_results: DEPRECATED_WRAP(dw_qsearch.clear_results, dw_qsearch),
+ onCompletion: DEPRECATED_WRAP(dw_qsearch.onCompletion, dw_qsearch)
+};
+
+var linkwiz = {
+ init: DEPRECATED_WRAP(dw_linkwiz.init, dw_linkwiz),
+ onEntry: DEPRECATED_WRAP(dw_linkwiz.onEntry, dw_linkwiz),
+ getResult: DEPRECATED_WRAP(dw_linkwiz.getResult, dw_linkwiz),
+ select: DEPRECATED_WRAP(dw_linkwiz.select, dw_linkwiz),
+ deselect: DEPRECATED_WRAP(dw_linkwiz.deselect, dw_linkwiz),
+ onResultClick: DEPRECATED_WRAP(dw_linkwiz.onResultClick, dw_linkwiz),
+ resultClick: DEPRECATED_WRAP(dw_linkwiz.resultClick, dw_linkwiz),
+ insertLink: DEPRECATED_WRAP(dw_linkwiz.insertLink, dw_linkwiz),
+ autocomplete: DEPRECATED_WRAP(dw_linkwiz.autocomplete, dw_linkwiz),
+ autocomplete_exec: DEPRECATED_WRAP(dw_linkwiz.autocomplete_exec, dw_linkwiz),
+ show: DEPRECATED_WRAP(dw_linkwiz.show, dw_linkwiz),
+ hide: DEPRECATED_WRAP(dw_linkwiz.hide, dw_linkwiz),
+ toggle: DEPRECATED_WRAP(dw_linkwiz.toggle, dw_linkwiz)
+};
+
+var locktimer = {
+ init: DEPRECATED_WRAP(dw_locktimer.init, dw_locktimer),
+ reset: DEPRECATED_WRAP(dw_locktimer.reset, dw_locktimer),
+ warning: DEPRECATED_WRAP(dw_locktimer.warning, dw_locktimer),
+ clear: DEPRECATED_WRAP(dw_locktimer.clear, dw_locktimer),
+ refresh: DEPRECATED_WRAP(dw_locktimer.refresh, dw_locktimer),
+ refreshed: DEPRECATED_WRAP(dw_locktimer.refreshed, dw_locktimer)
+};
+
+var media_manager = {
+ // treeattach, selectorattach, confirmattach are munched together into
+ // dw_mediamanager.init
+ attachoptions: DEPRECATED_WRAP(dw_mediamanager.attachoptions, dw_mediamanager),
+ togglekeepopen: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.toggleOption instead');
+ return dw_mediamanager.toggleOption.call(cb, 'keepopen');
+ },
+ togglehide: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.toggleOption instead');
+ return dw_mediamanager.toggleOption.call(cb, 'hide');
+ },
+ updatehide: DEPRECATED_WRAP(dw_mediamanager.updatehide, dw_mediamanager),
+ select: function (event, link) {
+ DEPRECATED('Use dw_mediamanager.select instead');
+ return dw_mediamanager.select.call(link, event);
+ },
+ initpopup: DEPRECATED_WRAP(dw_mediamanager.initpopup, dw_mediamanager),
+ insert: DEPRECATED_WRAP(dw_mediamanager.insert, dw_mediamanager),
+ list: function (event, link) {
+ DEPRECATED('Use dw_mediamanager.list instead');
+ return dw_mediamanager.list.call(link, event);
+ },
+ // toggle is handled by dw_tree
+ suggest: DEPRECATED_WRAP(dw_mediamanager.suggest, dw_mediamanager),
+ initFlashUpload: DEPRECATED_WRAP(dw_mediamanager.initFlashUpload, dw_mediamanager),
+ closePopup: function () {
+ DEPRECATED();
+ dw_mediamanager.$popup.dialog('close');
+ },
+ setalign: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.setOpt instead');
+ return dw_mediamanager.setOpt.call(this, 'align', event);
+ },
+ setlink: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.setOpt instead');
+ return dw_mediamanager.setOpt.call(this, 'link', event);
+ },
+ setsize: function (event, cb) {
+ DEPRECATED('Use dw_mediamanager.setOpt instead');
+ return dw_mediamanager.setOpt.call(this, 'size', event);
+ },
+ outSet: function (id) {
+ DEPRECATED();
+ return jQuery(id).removeClass('selected');
+ },
+ inSet: function (id) {
+ DEPRECATED();
+ return jQuery(id).addClass('selected');
+ }
+};
+
+initSizeCtl = DEPRECATED_WRAP(dw_editor.initSizeCtl);
+sizeCtl = DEPRECATED_WRAP(dw_editor.sizeCtl);
+toggleWrap = DEPRECATED_WRAP(dw_editor.toggleWrap);
+setWrap = DEPRECATED_WRAP(dw_editor.setWrap);
+
+function findPosX(object){
+ DEPRECATED('Use jQuery.position() instead');
+ return jQuery(object).position().left;
+}
+
+function findPosY(object){
+ DEPRECATED('Use jQuery.position() instead');
+ return jQuery(object).position().top;
+}
+
+function getElementsByClass(searchClass,node,tag){
+ DEPRECATED('Use jQuery() instead');
+ if(node == null) node = document;
+ if(typeof tag === 'undefined') tag = '';
+ return jQuery(node).find(tag+'.'+searchClass).toArray();
+}
+
+function prependChild(parent,element) {
+ DEPRECATED('Use jQuery.prepend() instead');
+ jQuery(parent).prepend(element);
+}
+
+function addEvent(element, type, handler) {
+ DEPRECATED('Use jQuery.bind() instead. Note that jQuery’s behaviour' +
+ ' when a handler returns false differs from addEvent’s');
+ jQuery(element).bind(type,{},function (e) {
+ // returning false in an addEvent event handler did not prevent
+ // bubbling but just canceled handlers on this node and prevented
+ // default behavior, so wrap the handler call and mimic that behavior.
+ //
+ // Refer to jQuery.event.handle().
+ var ret = handler.apply(this, Array.prototype.slice.call(arguments, 0));
+ if (typeof ret !== 'undefined') {
+ if ( ret !== false ) {
+ return ret;
+ }
+ // What jQuery does.
+ e.result = ret;
+ e.preventDefault();
+ // Not what jQuery does. This would be: event.stopPropagation();
+ // Hack it so that immediate propagation (other event handlers on
+ // this element) appears stopped without stopping the actual
+ // propagation (bubbling)
+ e.isImmediatePropagationStopped = function () { return true; };
+ }
+ });
+}
+
+function removeEvent(element, type, handler) {
+ DEPRECATED('Use jQuery.unbind() instead.');
+ jQuery(element).unbind(type,handler);
+}
+
+function addInitEvent(func) {
+ DEPRECATED('Use jQuery(<function>) instead');
+ jQuery(func);
+}
+
+
+function jsEscape(text){
+ DEPRECATED('Insert text through jQuery.text() instead of escaping on your own');
+ var re=new RegExp("\\\\","g");
+ text=text.replace(re,"\\\\");
+ re=new RegExp("'","g");
+ text=text.replace(re,"\\'");
+ re=new RegExp('"',"g");
+ text=text.replace(re,'&quot;');
+ re=new RegExp("\\\\\\\\n","g");
+ text=text.replace(re,"\\n");
+ return text;
+}
+
+/**
+ * Simple function to check if a global var is defined
+ *
+ * @author Kae Verens
+ * @link http://verens.com/archives/2005/07/25/isset-for-javascript/#comment-2835
+ */
+function isset(varname){
+ DEPRECATED("Use `typeof var !== 'undefined'` instead");
+ return(typeof(window[varname])!='undefined');
+}
+
+/**
+ * Checks if property is undefined
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isUndefined (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'undefined'` instead");
+ return (typeof prop == 'undefined');
+}
+
+/**
+ * Checks if property is function
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isFunction (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'function'` instead");
+ return (typeof prop == 'function');
+}
+/**
+ * Checks if property is string
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isString (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'string'` instead");
+ return (typeof prop == 'string');
+}
+
+/**
+ * Checks if property is number
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isNumber (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'number'` instead");
+ return (typeof prop == 'number');
+}
+
+/**
+ * Checks if property is the calculable number
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isNumeric (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'number' && !isNaN(var) && isFinite(var)` instead");
+ return isNumber(prop)&&!isNaN(prop)&&isFinite(prop);
+}
+
+/**
+ * Checks if property is array
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isArray (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `var instanceof Array` instead");
+ return (prop instanceof Array);
+}
+
+/**
+ * Checks if property is regexp
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isRegExp (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `var instanceof RegExp` instead");
+ return (prop instanceof RegExp);
+}
+
+/**
+ * Checks if property is a boolean value
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isBoolean (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'boolean'` instead");
+ return ('boolean' == typeof prop);
+}
+
+/**
+ * Checks if property is a scalar value (value that could be used as the hash key)
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isScalar (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED("Use `typeof var === 'string' || (typeof var === 'number' &&" +
+ " !isNaN(var) && isFinite(var))` instead");
+ return isNumeric(prop)||isString(prop);
+}
+
+/**
+ * Checks if property is empty
+ *
+ * @param {Object} prop value to check
+ * @return {Boolean} true if matched
+ * @scope public
+ * @author Ilya Lebedev <ilya@lebedev.net>
+ */
+function isEmpty (prop /* :Object */) /* :Boolean */ {
+ DEPRECATED();
+ var i;
+ if (isBoolean(prop)) {
+ return false;
+ } else if (isRegExp(prop) && new RegExp("").toString() == prop.toString()) {
+ return true;
+ } else if (isString(prop) || isNumber(prop)) {
+ return !prop;
+ } else if (Boolean(prop) && false != prop) {
+ for (i in prop) {
+ if(prop.hasOwnProperty(i)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/**
+ * Get the computed style of a node.
+ *
+ * @link https://acidmartin.wordpress.com/2008/08/26/style-get-any-css-property-value-of-an-object/
+ * @link http://svn.dojotoolkit.org/src/dojo/trunk/_base/html.js
+ */
+function gcs(node){
+ DEPRECATED('Use jQuery(node).style() instead');
+ if(node.currentStyle){
+ return node.currentStyle;
+ }else{
+ return node.ownerDocument.defaultView.getComputedStyle(node, null);
+ }
+}
+
+/**
+ * Until 2011-05-25 "Rincewind", a code intended to fix some Safari issue
+ * always declared the global _timer. plugin:sortablejs relies on _timer
+ * being declared.
+ */
+var _timer;
diff --git a/lib/scripts/cookie.js b/lib/scripts/cookie.js
new file mode 100644
index 000000000..3ad67bfa4
--- /dev/null
+++ b/lib/scripts/cookie.js
@@ -0,0 +1,64 @@
+/**
+* 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();
+ 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_BASE});
+ },
+
+ /**
+ * Get a Value from the Cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ getValue: function(key){
+ this.init();
+ return this.data[key];
+ },
+
+ /**
+ * 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/lib/scripts/delay.js b/lib/scripts/delay.js
new file mode 100644
index 000000000..edd53def3
--- /dev/null
+++ b/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/lib/scripts/drag.js b/lib/scripts/drag.js
new file mode 100644
index 000000000..dd252d95d
--- /dev/null
+++ b/lib/scripts/drag.js
@@ -0,0 +1,87 @@
+/**
+ * Makes a DOM object draggable
+ *
+ * If you just want to move objects around, use drag.attach. For full
+ * customization, drag can be used as a javascript prototype, it is
+ * inheritance-aware.
+ *
+ * @deprecated
+ * @link http://nofunc.org/Drag_Drop/
+ */
+var drag = {
+ obj: null,
+ handle: null,
+ oX: 0, // object X position
+ oY: 0, // object Y position
+ eX: 0, // event X delta
+ eY: 0, // event Y delta
+
+ /**
+ * Attaches the needed handlers to the given object
+ *
+ * This can be called for multiple objects, the right one is later
+ * determined from the event itself. The handle is optional
+ *
+ * @param DOMObject obj The object that should be draggable
+ * @param DOMObject handle A handle on which the obj can be dragged
+ */
+ attach: function (obj,handle) {
+ DEPRECATED('Use jQuery.draggable() instead.');
+ if(handle){
+ handle.dragobject = obj;
+ }else{
+ handle = obj;
+ }
+ var _this = this;
+ addEvent($(handle),'mousedown',function (e) {return _this.start(e); });
+ },
+
+ /**
+ * Starts the dragging operation
+ */
+ start: function (e){
+ this.handle = e.target;
+ if(this.handle.dragobject){
+ this.obj = this.handle.dragobject;
+ }else{
+ this.obj = this.handle;
+ }
+
+ this.handle.className += ' ondrag';
+ this.obj.className += ' ondrag';
+
+ this.oX = parseInt(this.obj.style.left);
+ this.oY = parseInt(this.obj.style.top);
+ this.eX = e.pageX;
+ this.eY = e.pageY;
+
+ var _this = this;
+ this.mousehandlers = [function (e) {return _this.drag(e);}, function (e) {return _this.stop(e);}];
+ addEvent(document,'mousemove', this.mousehandlers[0]);
+ addEvent(document,'mouseup', this.mousehandlers[1]);
+
+ return false;
+ },
+
+ /**
+ * Ends the dragging operation
+ */
+ stop: function(){
+ this.handle.className = this.handle.className.replace(/ ?ondrag/,'');
+ this.obj.className = this.obj.className.replace(/ ?ondrag/,'');
+ removeEvent(document,'mousemove', this.mousehandlers[0]);
+ removeEvent(document,'mouseup', this.mousehandlers[1]);
+ this.obj = null;
+ this.handle = null;
+ },
+
+ /**
+ * Moves the object during the dragging operation
+ */
+ drag: function(e) {
+ if(this.obj) {
+ this.obj.style.top = (e.pageY+this.oY-this.eY+'px');
+ this.obj.style.left = (e.pageX+this.oX-this.eX+'px');
+ }
+ }
+};
diff --git a/lib/scripts/edit.js b/lib/scripts/edit.js
new file mode 100644
index 000000000..33a8f61b5
--- /dev/null
+++ b/lib/scripts/edit.js
@@ -0,0 +1,268 @@
+/**
+ * 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
+ *
+ * Style the buttons through the toolbutton class
+ *
+ * @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);
+ 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);
+ $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
+ * @rteurn 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)
+ .bind('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)
+ .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 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 Gabriel Birke <birke@d-scribe.de>
+ */
+function addBtnActionSignature($btn, props, edid) {
+ if(typeof SIG != 'undefined' && SIG != ''){
+ $btn.bind('click', bind(insertAtCarret,edid,SIG));
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Determine the current section level while editing
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+function currentHeadlineLevel(textboxId){
+ var field = jQuery('#' + textboxId)[0],
+ s = false,
+ opts = [field.value.substr(0,getSelection(field).start)];
+ if (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;
+
+/**
+ * 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
+ *
+ * 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 = getSelection($edit_text[0]);
+ sel.start = 0;
+ sel.end = 0;
+ setSelection(sel);
+ $edit_text.focus();
+ }
+
+ var checkfunc = function() {
+ textChanged = true; //global var
+ summaryCheck();
+ };
+
+ $editform.change(checkfunc);
+ $editform.keydown(checkfunc);
+
+ window.onbeforeunload = function(){
+ if(window.textChanged) {
+ return LANG.notsavedyet;
+ }
+ };
+ window.onunload = deleteDraft;
+
+ // reset change memory var on submit
+ jQuery('#edbtn__save').click(
+ function() {
+ window.onbeforeunload = '';
+ textChanged = false;
+ }
+ );
+ jQuery('#edbtn__preview').click(
+ function() {
+ window.onbeforeunload = '';
+ textChanged = false;
+ window.keepDraft = true; // needed to keep draft on page unload
+ }
+ );
+
+ var $summary = jQuery('#edit__summary');
+ $summary.change(summaryCheck);
+ $summary.keyup(summaryCheck);
+
+ if (textChanged) summaryCheck();
+});
+
+/**
+ * Checks if a summary was entered - if not the style is changed
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function summaryCheck(){
+ var $sum = jQuery('#edit__summary'),
+ missing = $sum.val() === '';
+ $sum.toggleClass('missing', missing).toggleClass('edit', !missing);
+}
diff --git a/lib/scripts/editor.js b/lib/scripts/editor.js
new file mode 100644
index 000000000..042e34608
--- /dev/null
+++ b/lib/scripts/editor.js
@@ -0,0 +1,204 @@
+/**
+ * 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;
+ }
+
+ // in Firefox, keypress doesn't send the correct keycodes,
+ // in Opera, the default of keydown can't be prevented
+ if (jQuery.browser.opera) {
+ $editor.keypress(dw_editor.keyHandler);
+ } else {
+ $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')
+ .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, backspce and 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, 13, 32]) === -1) {
+ return;
+ }
+ var selection = getSelection(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){ // 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;
+ setSelection(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;
+ }
+ setSelection(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;
+ setSelection(selection);
+ e.preventDefault(); // prevent space
+ return false;
+ }
+ }
+ }
+
+
+};
+
+jQuery(dw_editor.init);
diff --git a/lib/scripts/fileuploader.js b/lib/scripts/fileuploader.js
new file mode 100644
index 000000000..e75b8d3a5
--- /dev/null
+++ b/lib/scripts/fileuploader.js
@@ -0,0 +1,1247 @@
+/**
+ * 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){
+ 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/lib/scripts/fileuploaderextended.js b/lib/scripts/fileuploaderextended.js
new file mode 100644
index 000000000..4abd63bef
--- /dev/null
+++ b/lib/scripts/fileuploaderextended.js
@@ -0,0 +1,344 @@
+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">' +
+ ' <input class="qq-upload-action button" type="submit" value="' + LANG.media_upload_btn + '" id="mediamanager__upload_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).attr('disabled', 'disabled');
+ });
+ });
+ },
+
+ _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 + '" name="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 class="button" type="submit" value="' + LANG.media_done_btn + '"></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').attr('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').attr('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/lib/scripts/helpers.js b/lib/scripts/helpers.js
new file mode 100644
index 000000000..d6f36967d
--- /dev/null
+++ b/lib/scripts/helpers.js
@@ -0,0 +1,70 @@
+/**
+ * Various helper functions
+ */
+
+/**
+ * Very simplistic Flash plugin check, probably works for Flash 8 and higher only
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function hasFlash(version){
+ var ver = 0;
+ try{
+ if(navigator.plugins != null && navigator.plugins.length > 0){
+ ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0];
+ }else{
+ ver = (new ActiveXObject("ShockwaveFlash.ShockwaveFlash"))
+ .GetVariable("$version").split(' ')[1].split(',')[0];
+ }
+ }catch(e){ }
+
+ return ver >= version;
+}
+
+/**
+ * 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)));
+ };
+}
diff --git a/lib/scripts/hotkeys.js b/lib/scripts/hotkeys.js
new file mode 100644
index 000000000..bff28530d
--- /dev/null
+++ b/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 input 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 input [type="submit"] with accesskey and register event -
+ * perform "click" on a button.
+ */
+ var inputs = document.getElementsByTagName("input");
+ 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/lib/scripts/index.html b/lib/scripts/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/scripts/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<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/lib/scripts/index.js b/lib/scripts/index.js
new file mode 100644
index 000000000..4b67a0b12
--- /dev/null
+++ b/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/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_0_aaaaaa_40x100.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100644
index 000000000..5b5dab2ab
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_75_ffffff_40x100.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_75_ffffff_40x100.png
new file mode 100644
index 000000000..ac8b229af
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_75_ffffff_40x100.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644
index 000000000..ad3d6346e
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 000000000..42ccba269
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644
index 000000000..5a46b47cb
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644
index 000000000..86c2baa65
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644
index 000000000..4443fdc1a
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644
index 000000000..7c9fa6c6e
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.png
new file mode 100644
index 000000000..b273ff111
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 000000000..09d1cdc85
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.png
new file mode 100644
index 000000000..59bd45b90
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.png
new file mode 100644
index 000000000..6d02426c1
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.png b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 000000000..2ab019b73
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/lib/scripts/jquery/jquery-ui-theme/smoothness.css b/lib/scripts/jquery/jquery-ui-theme/smoothness.css
new file mode 100644
index 000000000..910d24b95
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui-theme/smoothness.css
@@ -0,0 +1,568 @@
+/*
+ * jQuery UI CSS Framework 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,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:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+ * jQuery UI CSS Framework 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+ */
+
+
+/* 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-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; 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 { 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 { 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 { 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 { color: #212121; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { 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-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
+.ui-widget :active { outline: 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-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); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }
+.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-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
+.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); }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-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 { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*
+ * jQuery UI Resizable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizable#theming
+ */
+.ui-resizable { position: relative;}
+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; }
+.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;}/*
+ * jQuery UI Selectable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectable#theming
+ */
+.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; }
+/*
+ * jQuery UI Accordion 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion#theming
+ */
+/* IE/Win - Fix animation bug - #4615 */
+.ui-accordion { width: 100%; }
+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }
+.ui-accordion .ui-accordion-li-fix { display: inline; }
+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }
+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
+.ui-accordion .ui-accordion-content-active { display: block; }
+/*
+ * jQuery UI Autocomplete 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete#theming
+ */
+.ui-autocomplete { position: absolute; cursor: default; }
+
+/* workarounds */
+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
+
+/*
+ * jQuery UI Menu 1.8.16
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu#theming
+ */
+.ui-menu {
+ list-style:none;
+ padding: 2px;
+ margin: 0;
+ display:block;
+ float: left;
+}
+.ui-menu .ui-menu {
+ margin-top: -3px;
+}
+.ui-menu .ui-menu-item {
+ margin:0;
+ padding: 0;
+ zoom: 1;
+ float: left;
+ clear: left;
+ width: 100%;
+}
+.ui-menu .ui-menu-item a {
+ text-decoration:none;
+ display:block;
+ padding:.2em .4em;
+ line-height:1.5;
+ zoom:1;
+}
+.ui-menu .ui-menu-item a.ui-state-hover,
+.ui-menu .ui-menu-item a.ui-state-active {
+ font-weight: normal;
+ margin: -1px;
+}
+/*
+ * jQuery UI Button 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button#theming
+ */
+.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
+.ui-button-icons-only { width: 3.4em; }
+button.ui-button-icons-only { width: 3.7em; }
+
+/*button text element */
+.ui-button .ui-button-text { display: block; line-height: 1.4; }
+.ui-button-text-only .ui-button-text { padding: .4em 1em; }
+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
+.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
+.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
+/* no icon support for input elements, provide padding by default */
+input.ui-button { padding: .4em 1em; }
+
+/*button icon element(s) */
+.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
+.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
+.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
+
+/*button sets*/
+.ui-buttonset { margin-right: 7px; }
+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
+
+/* workarounds */
+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
+/*
+ * jQuery UI Dialog 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog#theming
+ */
+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
+.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
+.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
+.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; 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-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
+.ui-draggable .ui-dialog-titlebar { cursor: move; }
+/*
+ * jQuery UI Slider 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.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; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.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; }/*
+ * jQuery UI Tabs 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs#theming
+ */
+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+.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: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
+/*
+ * jQuery UI Datepicker 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker#theming
+ */
+.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-year {width: 100%;}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year { width: 49%;}
+.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 { border-left-width:0; }
+.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:0em; }
+
+/* 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 { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group { float:right; }
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }
+
+/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */
+.ui-datepicker-cover {
+ display: none; /*sorry for IE5*/
+ display/**/: block; /*sorry for IE5*/
+ position: absolute; /*must have*/
+ z-index: -1; /*must have*/
+ filter: mask(); /*must have*/
+ top: -4px; /*must have*/
+ left: -4px; /*must have*/
+ width: 200px; /*must have*/
+ height: 200px; /*must have*/
+}/*
+ * jQuery UI Progressbar 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar#theming
+ */
+.ui-progressbar { height:2em; text-align: left; }
+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file
diff --git a/lib/scripts/jquery/jquery-ui.js b/lib/scripts/jquery/jquery-ui.js
new file mode 100644
index 000000000..cd515f361
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui.js
@@ -0,0 +1,11767 @@
+/*!
+ * jQuery UI 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function( $, undefined ) {
+
+// prevent duplicate loading
+// this is only a problem because we proxy existing functions
+// and we don't want to double proxy them
+$.ui = $.ui || {};
+if ( $.ui.version ) {
+ return;
+}
+
+$.extend( $.ui, {
+ version: "1.8.16",
+
+ keyCode: {
+ ALT: 18,
+ BACKSPACE: 8,
+ CAPS_LOCK: 20,
+ COMMA: 188,
+ COMMAND: 91,
+ COMMAND_LEFT: 91, // COMMAND
+ COMMAND_RIGHT: 93,
+ CONTROL: 17,
+ DELETE: 46,
+ DOWN: 40,
+ END: 35,
+ ENTER: 13,
+ ESCAPE: 27,
+ HOME: 36,
+ INSERT: 45,
+ LEFT: 37,
+ MENU: 93, // COMMAND_RIGHT
+ NUMPAD_ADD: 107,
+ NUMPAD_DECIMAL: 110,
+ NUMPAD_DIVIDE: 111,
+ NUMPAD_ENTER: 108,
+ NUMPAD_MULTIPLY: 106,
+ NUMPAD_SUBTRACT: 109,
+ PAGE_DOWN: 34,
+ PAGE_UP: 33,
+ PERIOD: 190,
+ RIGHT: 39,
+ SHIFT: 16,
+ SPACE: 32,
+ TAB: 9,
+ UP: 38,
+ WINDOWS: 91 // COMMAND
+ }
+});
+
+// plugins
+$.fn.extend({
+ propAttr: $.fn.prop || $.fn.attr,
+
+ _focus: $.fn.focus,
+ focus: function( delay, fn ) {
+ return typeof delay === "number" ?
+ this.each(function() {
+ var elem = this;
+ setTimeout(function() {
+ $( elem ).focus();
+ if ( fn ) {
+ fn.call( elem );
+ }
+ }, delay );
+ }) :
+ this._focus.apply( this, arguments );
+ },
+
+ scrollParent: function() {
+ var scrollParent;
+ if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
+ scrollParent = this.parents().filter(function() {
+ return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ } else {
+ scrollParent = this.parents().filter(function() {
+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ }
+
+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
+ },
+
+ zIndex: function( zIndex ) {
+ if ( zIndex !== undefined ) {
+ return this.css( "zIndex", zIndex );
+ }
+
+ if ( this.length ) {
+ var elem = $( this[ 0 ] ), position, value;
+ while ( elem.length && elem[ 0 ] !== document ) {
+ // Ignore z-index if position is set to a value where z-index is ignored by the browser
+ // This makes behavior of this function consistent across browsers
+ // WebKit always returns auto if the element is positioned
+ position = elem.css( "position" );
+ if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+ // IE returns 0 when zIndex is not specified
+ // other browsers return a string
+ // we ignore the case of nested elements with an explicit value of 0
+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+ value = parseInt( elem.css( "zIndex" ), 10 );
+ if ( !isNaN( value ) && value !== 0 ) {
+ return value;
+ }
+ }
+ elem = elem.parent();
+ }
+ }
+
+ return 0;
+ },
+
+ disableSelection: function() {
+ return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
+ ".ui-disableSelection", function( event ) {
+ event.preventDefault();
+ });
+ },
+
+ enableSelection: function() {
+ return this.unbind( ".ui-disableSelection" );
+ }
+});
+
+$.each( [ "Width", "Height" ], function( i, name ) {
+ var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+ type = name.toLowerCase(),
+ orig = {
+ innerWidth: $.fn.innerWidth,
+ innerHeight: $.fn.innerHeight,
+ outerWidth: $.fn.outerWidth,
+ outerHeight: $.fn.outerHeight
+ };
+
+ function reduce( elem, size, border, margin ) {
+ $.each( side, function() {
+ size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
+ if ( border ) {
+ size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
+ }
+ if ( margin ) {
+ size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
+ }
+ });
+ return size;
+ }
+
+ $.fn[ "inner" + name ] = function( size ) {
+ if ( size === undefined ) {
+ return orig[ "inner" + name ].call( this );
+ }
+
+ return this.each(function() {
+ $( this ).css( type, reduce( this, size ) + "px" );
+ });
+ };
+
+ $.fn[ "outer" + name] = function( size, margin ) {
+ if ( typeof size !== "number" ) {
+ return orig[ "outer" + name ].call( this, size );
+ }
+
+ return this.each(function() {
+ $( this).css( type, reduce( this, size, true, margin ) + "px" );
+ });
+ };
+});
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+ var nodeName = element.nodeName.toLowerCase();
+ if ( "area" === nodeName ) {
+ var map = element.parentNode,
+ mapName = map.name,
+ img;
+ if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+ return false;
+ }
+ img = $( "img[usemap=#" + mapName + "]" )[0];
+ return !!img && visible( img );
+ }
+ return ( /input|select|textarea|button|object/.test( nodeName )
+ ? !element.disabled
+ : "a" == nodeName
+ ? element.href || isTabIndexNotNaN
+ : isTabIndexNotNaN)
+ // the element and all of its ancestors must be visible
+ && visible( element );
+}
+
+function visible( element ) {
+ return !$( element ).parents().andSelf().filter(function() {
+ return $.curCSS( this, "visibility" ) === "hidden" ||
+ $.expr.filters.hidden( this );
+ }).length;
+}
+
+$.extend( $.expr[ ":" ], {
+ data: function( elem, i, match ) {
+ return !!$.data( elem, match[ 3 ] );
+ },
+
+ focusable: function( element ) {
+ return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+ },
+
+ tabbable: function( element ) {
+ var tabIndex = $.attr( element, "tabindex" ),
+ isTabIndexNaN = isNaN( tabIndex );
+ return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+ }
+});
+
+// support
+$(function() {
+ var body = document.body,
+ div = body.appendChild( div = document.createElement( "div" ) );
+
+ $.extend( div.style, {
+ minHeight: "100px",
+ height: "auto",
+ padding: 0,
+ borderWidth: 0
+ });
+
+ $.support.minHeight = div.offsetHeight === 100;
+ $.support.selectstart = "onselectstart" in div;
+
+ // set display to none to avoid a layout bug in IE
+ // http://dev.jquery.com/ticket/4014
+ body.removeChild( div ).style.display = "none";
+});
+
+
+
+
+
+// deprecated
+$.extend( $.ui, {
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
+ plugin: {
+ add: function( module, option, set ) {
+ var proto = $.ui[ module ].prototype;
+ for ( var i in set ) {
+ proto.plugins[ i ] = proto.plugins[ i ] || [];
+ proto.plugins[ i ].push( [ option, set[ i ] ] );
+ }
+ },
+ call: function( instance, name, args ) {
+ var set = instance.plugins[ name ];
+ if ( !set || !instance.element[ 0 ].parentNode ) {
+ return;
+ }
+
+ for ( var i = 0; i < set.length; i++ ) {
+ if ( instance.options[ set[ i ][ 0 ] ] ) {
+ set[ i ][ 1 ].apply( instance.element, args );
+ }
+ }
+ }
+ },
+
+ // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
+ contains: function( a, b ) {
+ return document.compareDocumentPosition ?
+ a.compareDocumentPosition( b ) & 16 :
+ a !== b && a.contains( b );
+ },
+
+ // only used by resizable
+ hasScroll: function( el, a ) {
+
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
+ if ( $( el ).css( "overflow" ) === "hidden") {
+ return false;
+ }
+
+ var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+ has = false;
+
+ if ( el[ scroll ] > 0 ) {
+ return true;
+ }
+
+ // TODO: determine which cases actually cause this to happen
+ // if the element doesn't have the scroll set, see if it's possible to
+ // set the scroll
+ el[ scroll ] = 1;
+ has = ( el[ scroll ] > 0 );
+ el[ scroll ] = 0;
+ return has;
+ },
+
+ // these are odd functions, fix the API or move into individual plugins
+ isOverAxis: function( x, reference, size ) {
+ //Determines when x coordinate is over "b" element axis
+ return ( x > reference ) && ( x < ( reference + size ) );
+ },
+ isOver: function( y, x, top, left, height, width ) {
+ //Determines when x, y coordinates is over "b" element
+ return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
+ }
+});
+
+})( jQuery );
+/*!
+ * jQuery UI Widget 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function( $, undefined ) {
+
+// jQuery 1.4+
+if ( $.cleanData ) {
+ var _cleanData = $.cleanData;
+ $.cleanData = function( elems ) {
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ try {
+ $( elem ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ }
+ _cleanData( elems );
+ };
+} else {
+ var _remove = $.fn.remove;
+ $.fn.remove = function( selector, keepData ) {
+ return this.each(function() {
+ if ( !keepData ) {
+ if ( !selector || $.filter( selector, [ this ] ).length ) {
+ $( "*", this ).add( [ this ] ).each(function() {
+ try {
+ $( this ).triggerHandler( "remove" );
+ // http://bugs.jquery.com/ticket/8235
+ } catch( e ) {}
+ });
+ }
+ }
+ return _remove.call( $(this), selector, keepData );
+ });
+ };
+}
+
+$.widget = function( name, base, prototype ) {
+ var namespace = name.split( "." )[ 0 ],
+ fullName;
+ name = name.split( "." )[ 1 ];
+ fullName = namespace + "-" + name;
+
+ if ( !prototype ) {
+ prototype = base;
+ base = $.Widget;
+ }
+
+ // create selector for plugin
+ $.expr[ ":" ][ fullName ] = function( elem ) {
+ return !!$.data( elem, name );
+ };
+
+ $[ namespace ] = $[ namespace ] || {};
+ $[ namespace ][ name ] = function( options, element ) {
+ // allow instantiation without initializing for simple inheritance
+ if ( arguments.length ) {
+ this._createWidget( options, element );
+ }
+ };
+
+ var basePrototype = new base();
+ // we need to make the options hash a property directly on the new instance
+ // otherwise we'll modify the options hash on the prototype that we're
+ // inheriting from
+// $.each( basePrototype, function( key, val ) {
+// if ( $.isPlainObject(val) ) {
+// basePrototype[ key ] = $.extend( {}, val );
+// }
+// });
+ basePrototype.options = $.extend( true, {}, basePrototype.options );
+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
+ namespace: namespace,
+ widgetName: name,
+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
+ widgetBaseClass: fullName
+ }, prototype );
+
+ $.widget.bridge( name, $[ namespace ][ name ] );
+};
+
+$.widget.bridge = function( name, object ) {
+ $.fn[ name ] = function( options ) {
+ var isMethodCall = typeof options === "string",
+ args = Array.prototype.slice.call( arguments, 1 ),
+ returnValue = this;
+
+ // allow multiple hashes to be passed on init
+ options = !isMethodCall && args.length ?
+ $.extend.apply( null, [ true, options ].concat(args) ) :
+ options;
+
+ // prevent calls to internal methods
+ if ( isMethodCall && options.charAt( 0 ) === "_" ) {
+ return returnValue;
+ }
+
+ if ( isMethodCall ) {
+ this.each(function() {
+ var instance = $.data( this, name ),
+ methodValue = instance && $.isFunction( instance[options] ) ?
+ instance[ options ].apply( instance, args ) :
+ instance;
+ // TODO: add this back in 1.9 and use $.error() (see #5972)
+// if ( !instance ) {
+// throw "cannot call methods on " + name + " prior to initialization; " +
+// "attempted to call method '" + options + "'";
+// }
+// if ( !$.isFunction( instance[options] ) ) {
+// throw "no such method '" + options + "' for " + name + " widget instance";
+// }
+// var methodValue = instance[ options ].apply( instance, args );
+ if ( methodValue !== instance && methodValue !== undefined ) {
+ returnValue = methodValue;
+ return false;
+ }
+ });
+ } else {
+ this.each(function() {
+ var instance = $.data( this, name );
+ if ( instance ) {
+ instance.option( options || {} )._init();
+ } else {
+ $.data( this, name, new object( options, this ) );
+ }
+ });
+ }
+
+ return returnValue;
+ };
+};
+
+$.Widget = function( options, element ) {
+ // allow instantiation without initializing for simple inheritance
+ if ( arguments.length ) {
+ this._createWidget( options, element );
+ }
+};
+
+$.Widget.prototype = {
+ widgetName: "widget",
+ widgetEventPrefix: "",
+ options: {
+ disabled: false
+ },
+ _createWidget: function( options, element ) {
+ // $.widget.bridge stores the plugin instance, but we do it anyway
+ // so that it's stored even before the _create function runs
+ $.data( element, this.widgetName, this );
+ this.element = $( element );
+ this.options = $.extend( true, {},
+ this.options,
+ this._getCreateOptions(),
+ options );
+
+ var self = this;
+ this.element.bind( "remove." + this.widgetName, function() {
+ self.destroy();
+ });
+
+ this._create();
+ this._trigger( "create" );
+ this._init();
+ },
+ _getCreateOptions: function() {
+ return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
+ },
+ _create: function() {},
+ _init: function() {},
+
+ destroy: function() {
+ this.element
+ .unbind( "." + this.widgetName )
+ .removeData( this.widgetName );
+ this.widget()
+ .unbind( "." + this.widgetName )
+ .removeAttr( "aria-disabled" )
+ .removeClass(
+ this.widgetBaseClass + "-disabled " +
+ "ui-state-disabled" );
+ },
+
+ widget: function() {
+ return this.element;
+ },
+
+ option: function( key, value ) {
+ var options = key;
+
+ if ( arguments.length === 0 ) {
+ // don't return a reference to the internal hash
+ return $.extend( {}, this.options );
+ }
+
+ if (typeof key === "string" ) {
+ if ( value === undefined ) {
+ return this.options[ key ];
+ }
+ options = {};
+ options[ key ] = value;
+ }
+
+ this._setOptions( options );
+
+ return this;
+ },
+ _setOptions: function( options ) {
+ var self = this;
+ $.each( options, function( key, value ) {
+ self._setOption( key, value );
+ });
+
+ return this;
+ },
+ _setOption: function( key, value ) {
+ this.options[ key ] = value;
+
+ if ( key === "disabled" ) {
+ this.widget()
+ [ value ? "addClass" : "removeClass"](
+ this.widgetBaseClass + "-disabled" + " " +
+ "ui-state-disabled" )
+ .attr( "aria-disabled", value );
+ }
+
+ return this;
+ },
+
+ enable: function() {
+ return this._setOption( "disabled", false );
+ },
+ disable: function() {
+ return this._setOption( "disabled", true );
+ },
+
+ _trigger: function( type, event, data ) {
+ var callback = this.options[ type ];
+
+ event = $.Event( event );
+ event.type = ( type === this.widgetEventPrefix ?
+ type :
+ this.widgetEventPrefix + type ).toLowerCase();
+ data = data || {};
+
+ // copy original event properties over to the new event
+ // this would happen if we could call $.event.fix instead of $.Event
+ // but we don't have a way to force an event to be fixed multiple times
+ if ( event.originalEvent ) {
+ for ( var i = $.event.props.length, prop; i; ) {
+ prop = $.event.props[ --i ];
+ event[ prop ] = event.originalEvent[ prop ];
+ }
+ }
+
+ this.element.trigger( event, data );
+
+ return !( $.isFunction(callback) &&
+ callback.call( this.element[0], event, data ) === false ||
+ event.isDefaultPrevented() );
+ }
+};
+
+})( jQuery );
+/*!
+ * jQuery UI Mouse 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+var mouseHandled = false;
+$( document ).mouseup( function( e ) {
+ mouseHandled = false;
+});
+
+$.widget("ui.mouse", {
+ options: {
+ cancel: ':input,option',
+ distance: 1,
+ delay: 0
+ },
+ _mouseInit: function() {
+ var self = this;
+
+ this.element
+ .bind('mousedown.'+this.widgetName, function(event) {
+ return self._mouseDown(event);
+ })
+ .bind('click.'+this.widgetName, function(event) {
+ if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
+ $.removeData(event.target, self.widgetName + '.preventClickEvent');
+ event.stopImmediatePropagation();
+ return false;
+ }
+ });
+
+ this.started = false;
+ },
+
+ // TODO: make sure destroying one instance of mouse doesn't mess with
+ // other instances of mouse
+ _mouseDestroy: function() {
+ this.element.unbind('.'+this.widgetName);
+ },
+
+ _mouseDown: function(event) {
+ // don't let more than one widget handle mouseStart
+ if( mouseHandled ) { return };
+
+ // we may have missed mouseup (out of window)
+ (this._mouseStarted && this._mouseUp(event));
+
+ this._mouseDownEvent = event;
+
+ var self = this,
+ btnIsLeft = (event.which == 1),
+ // event.target.nodeName works around a bug in IE 8 with
+ // disabled inputs (#7620)
+ elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+ return true;
+ }
+
+ this.mouseDelayMet = !this.options.delay;
+ if (!this.mouseDelayMet) {
+ this._mouseDelayTimer = setTimeout(function() {
+ self.mouseDelayMet = true;
+ }, this.options.delay);
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted = (this._mouseStart(event) !== false);
+ if (!this._mouseStarted) {
+ event.preventDefault();
+ return true;
+ }
+ }
+
+ // Click event may never have fired (Gecko & Opera)
+ if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
+ $.removeData(event.target, this.widgetName + '.preventClickEvent');
+ }
+
+ // these delegates are required to keep context
+ this._mouseMoveDelegate = function(event) {
+ return self._mouseMove(event);
+ };
+ this._mouseUpDelegate = function(event) {
+ return self._mouseUp(event);
+ };
+ $(document)
+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ event.preventDefault();
+
+ mouseHandled = true;
+ return true;
+ },
+
+ _mouseMove: function(event) {
+ // IE mouseup check - mouseup happened when mouse was out of window
+ if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
+ return this._mouseUp(event);
+ }
+
+ if (this._mouseStarted) {
+ this._mouseDrag(event);
+ return event.preventDefault();
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted =
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+ }
+
+ return !this._mouseStarted;
+ },
+
+ _mouseUp: function(event) {
+ $(document)
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ if (this._mouseStarted) {
+ this._mouseStarted = false;
+
+ if (event.target == this._mouseDownEvent.target) {
+ $.data(event.target, this.widgetName + '.preventClickEvent', true);
+ }
+
+ this._mouseStop(event);
+ }
+
+ return false;
+ },
+
+ _mouseDistanceMet: function(event) {
+ return (Math.max(
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
+ ) >= this.options.distance
+ );
+ },
+
+ _mouseDelayMet: function(event) {
+ return this.mouseDelayMet;
+ },
+
+ // These are placeholder methods, to be overriden by extending plugin
+ _mouseStart: function(event) {},
+ _mouseDrag: function(event) {},
+ _mouseStop: function(event) {},
+ _mouseCapture: function(event) { return true; }
+});
+
+})(jQuery);
+/*
+ * jQuery UI Draggable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.draggable", $.ui.mouse, {
+ widgetEventPrefix: "drag",
+ options: {
+ addClasses: true,
+ appendTo: "parent",
+ axis: false,
+ connectToSortable: false,
+ containment: false,
+ cursor: "auto",
+ cursorAt: false,
+ grid: false,
+ handle: false,
+ helper: "original",
+ iframeFix: false,
+ opacity: false,
+ refreshPositions: false,
+ revert: false,
+ revertDuration: 500,
+ scope: "default",
+ scroll: true,
+ scrollSensitivity: 20,
+ scrollSpeed: 20,
+ snap: false,
+ snapMode: "both",
+ snapTolerance: 20,
+ stack: false,
+ zIndex: false
+ },
+ _create: function() {
+
+ if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
+ this.element[0].style.position = 'relative';
+
+ (this.options.addClasses && this.element.addClass("ui-draggable"));
+ (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
+
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+ if(!this.element.data('draggable')) return;
+ this.element
+ .removeData("draggable")
+ .unbind(".draggable")
+ .removeClass("ui-draggable"
+ + " ui-draggable-dragging"
+ + " ui-draggable-disabled");
+ this._mouseDestroy();
+
+ return this;
+ },
+
+ _mouseCapture: function(event) {
+
+ var o = this.options;
+
+ // among others, prevent a drag on a resizable-handle
+ if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
+ return false;
+
+ //Quit if we're not on a valid handle
+ this.handle = this._getHandle(event);
+ if (!this.handle)
+ return false;
+
+ if ( o.iframeFix ) {
+ $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
+ $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
+ .css({
+ width: this.offsetWidth+"px", height: this.offsetHeight+"px",
+ position: "absolute", opacity: "0.001", zIndex: 1000
+ })
+ .css($(this).offset())
+ .appendTo("body");
+ });
+ }
+
+ return true;
+
+ },
+
+ _mouseStart: function(event) {
+
+ var o = this.options;
+
+ //Create and append the visible helper
+ this.helper = this._createHelper(event);
+
+ //Cache the helper size
+ this._cacheHelperProportions();
+
+ //If ddmanager is used for droppables, set the global draggable
+ if($.ui.ddmanager)
+ $.ui.ddmanager.current = this;
+
+ /*
+ * - Position generation -
+ * This block generates everything position related - it's the core of draggables.
+ */
+
+ //Cache the margins of the original element
+ this._cacheMargins();
+
+ //Store the helper's css position
+ this.cssPosition = this.helper.css("position");
+ this.scrollParent = this.helper.scrollParent();
+
+ //The element's absolute position on the page minus margins
+ this.offset = this.positionAbs = this.element.offset();
+ this.offset = {
+ top: this.offset.top - this.margins.top,
+ left: this.offset.left - this.margins.left
+ };
+
+ $.extend(this.offset, {
+ click: { //Where the click happened, relative to the element
+ left: event.pageX - this.offset.left,
+ top: event.pageY - this.offset.top
+ },
+ parent: this._getParentOffset(),
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+ });
+
+ //Generate the original position
+ this.originalPosition = this.position = this._generatePosition(event);
+ this.originalPageX = event.pageX;
+ this.originalPageY = event.pageY;
+
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+ //Set a containment if given in the options
+ if(o.containment)
+ this._setContainment();
+
+ //Trigger event + callbacks
+ if(this._trigger("start", event) === false) {
+ this._clear();
+ return false;
+ }
+
+ //Recache the helper size
+ this._cacheHelperProportions();
+
+ //Prepare the droppable offsets
+ if ($.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+
+ this.helper.addClass("ui-draggable-dragging");
+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+
+ //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
+ if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
+
+ return true;
+ },
+
+ _mouseDrag: function(event, noPropagation) {
+
+ //Compute the helpers position
+ this.position = this._generatePosition(event);
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ //Call plugins and callbacks and use the resulting position if something is returned
+ if (!noPropagation) {
+ var ui = this._uiHash();
+ if(this._trigger('drag', event, ui) === false) {
+ this._mouseUp({});
+ return false;
+ }
+ this.position = ui.position;
+ }
+
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+
+ //If we are using droppables, inform the manager about the drop
+ var dropped = false;
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
+ dropped = $.ui.ddmanager.drop(this, event);
+
+ //if a drop comes from outside (a sortable)
+ if(this.dropped) {
+ dropped = this.dropped;
+ this.dropped = false;
+ }
+
+ //if the original element is removed, don't bother to continue if helper is set to "original"
+ if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
+ return false;
+
+ if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
+ var self = this;
+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
+ if(self._trigger("stop", event) !== false) {
+ self._clear();
+ }
+ });
+ } else {
+ if(this._trigger("stop", event) !== false) {
+ this._clear();
+ }
+ }
+
+ return false;
+ },
+
+ _mouseUp: function(event) {
+ if (this.options.iframeFix === true) {
+ $("div.ui-draggable-iframeFix").each(function() {
+ this.parentNode.removeChild(this);
+ }); //Remove frame helpers
+ }
+
+ //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
+ if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
+
+ return $.ui.mouse.prototype._mouseUp.call(this, event);
+ },
+
+ cancel: function() {
+
+ if(this.helper.is(".ui-draggable-dragging")) {
+ this._mouseUp({});
+ } else {
+ this._clear();
+ }
+
+ return this;
+
+ },
+
+ _getHandle: function(event) {
+
+ var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
+ $(this.options.handle, this.element)
+ .find("*")
+ .andSelf()
+ .each(function() {
+ if(this == event.target) handle = true;
+ });
+
+ return handle;
+
+ },
+
+ _createHelper: function(event) {
+
+ var o = this.options;
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
+
+ if(!helper.parents('body').length)
+ helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
+
+ if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
+ helper.css("position", "absolute");
+
+ return helper;
+
+ },
+
+ _adjustOffsetFromHelper: function(obj) {
+ if (typeof obj == 'string') {
+ obj = obj.split(' ');
+ }
+ if ($.isArray(obj)) {
+ obj = {left: +obj[0], top: +obj[1] || 0};
+ }
+ if ('left' in obj) {
+ this.offset.click.left = obj.left + this.margins.left;
+ }
+ if ('right' in obj) {
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+ }
+ if ('top' in obj) {
+ this.offset.click.top = obj.top + this.margins.top;
+ }
+ if ('bottom' in obj) {
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+ }
+ },
+
+ _getParentOffset: function() {
+
+ //Get the offsetParent and cache its position
+ this.offsetParent = this.helper.offsetParent();
+ var po = this.offsetParent.offset();
+
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
+ po.left += this.scrollParent.scrollLeft();
+ po.top += this.scrollParent.scrollTop();
+ }
+
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
+ po = { top: 0, left: 0 };
+
+ return {
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+ };
+
+ },
+
+ _getRelativeOffset: function() {
+
+ if(this.cssPosition == "relative") {
+ var p = this.element.position();
+ return {
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+ };
+ } else {
+ return { top: 0, left: 0 };
+ }
+
+ },
+
+ _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 o = this.options;
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
+ o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
+ o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
+ (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
+ (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+ ];
+
+ if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
+ var c = $(o.containment);
+ var ce = c[0]; if(!ce) return;
+ var co = c.offset();
+ var over = ($(ce).css("overflow") != 'hidden');
+
+ this.containment = [
+ (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
+ (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
+ (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
+ (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom
+ ];
+ this.relative_container = c;
+
+ } else if(o.containment.constructor == Array) {
+ this.containment = o.containment;
+ }
+
+ },
+
+ _convertPositionTo: function(d, pos) {
+
+ if(!pos) pos = this.position;
+ var mod = d == "absolute" ? 1 : -1;
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ return {
+ top: (
+ pos.top // The absolute mouse position
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+ ),
+ left: (
+ pos.left // The absolute mouse position
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+ )
+ };
+
+ },
+
+ _generatePosition: function(event) {
+
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+ var pageX = event.pageX;
+ var pageY = event.pageY;
+
+ /*
+ * - Position constraining -
+ * Constrain the position to a mix of grid, containment.
+ */
+
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+ var containment;
+ if(this.containment) {
+ if (this.relative_container){
+ var co = this.relative_container.offset();
+ containment = [ this.containment[0] + co.left,
+ this.containment[1] + co.top,
+ this.containment[2] + co.left,
+ this.containment[3] + co.top ];
+ }
+ else {
+ containment = this.containment;
+ }
+
+ if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
+ if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
+ }
+
+ if(o.grid) {
+ //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
+ var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
+ pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+ var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
+ pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+ }
+
+ }
+
+ return {
+ top: (
+ pageY // The absolute mouse position
+ - this.offset.click.top // Click offset (relative to the element)
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+ ),
+ left: (
+ pageX // The absolute mouse position
+ - this.offset.click.left // Click offset (relative to the element)
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+ )
+ };
+
+ },
+
+ _clear: function() {
+ this.helper.removeClass("ui-draggable-dragging");
+ if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
+ //if($.ui.ddmanager) $.ui.ddmanager.current = null;
+ this.helper = null;
+ this.cancelHelperRemoval = false;
+ },
+
+ // From now on bulk stuff - mainly helpers
+
+ _trigger: function(type, event, ui) {
+ ui = ui || this._uiHash();
+ $.ui.plugin.call(this, type, [event, ui]);
+ if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
+ return $.Widget.prototype._trigger.call(this, type, event, ui);
+ },
+
+ plugins: {},
+
+ _uiHash: function(event) {
+ return {
+ helper: this.helper,
+ position: this.position,
+ originalPosition: this.originalPosition,
+ offset: this.positionAbs
+ };
+ }
+
+});
+
+$.extend($.ui.draggable, {
+ version: "1.8.16"
+});
+
+$.ui.plugin.add("draggable", "connectToSortable", {
+ start: function(event, ui) {
+
+ var inst = $(this).data("draggable"), o = inst.options,
+ uiSortable = $.extend({}, ui, { item: inst.element });
+ inst.sortables = [];
+ $(o.connectToSortable).each(function() {
+ var sortable = $.data(this, 'sortable');
+ if (sortable && !sortable.options.disabled) {
+ inst.sortables.push({
+ instance: sortable,
+ shouldRevert: sortable.options.revert
+ });
+ sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
+ sortable._trigger("activate", event, uiSortable);
+ }
+ });
+
+ },
+ stop: function(event, ui) {
+
+ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
+ var inst = $(this).data("draggable"),
+ uiSortable = $.extend({}, ui, { item: inst.element });
+
+ $.each(inst.sortables, function() {
+ if(this.instance.isOver) {
+
+ this.instance.isOver = 0;
+
+ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
+ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
+
+ //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
+ if(this.shouldRevert) this.instance.options.revert = true;
+
+ //Trigger the stop of the sortable
+ this.instance._mouseStop(event);
+
+ this.instance.options.helper = this.instance.options._helper;
+
+ //If the helper has been the original item, restore properties in the sortable
+ if(inst.options.helper == 'original')
+ this.instance.currentItem.css({ top: 'auto', left: 'auto' });
+
+ } else {
+ this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
+ this.instance._trigger("deactivate", event, uiSortable);
+ }
+
+ });
+
+ },
+ drag: function(event, ui) {
+
+ var inst = $(this).data("draggable"), self = this;
+
+ var checkPos = function(o) {
+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
+ var itemHeight = o.height, itemWidth = o.width;
+ var itemTop = o.top, itemLeft = o.left;
+
+ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
+ };
+
+ $.each(inst.sortables, function(i) {
+
+ //Copy over some variables to allow calling the sortable's native _intersectsWith
+ this.instance.positionAbs = inst.positionAbs;
+ this.instance.helperProportions = inst.helperProportions;
+ this.instance.offset.click = inst.offset.click;
+
+ if(this.instance._intersectsWith(this.instance.containerCache)) {
+
+ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
+ if(!this.instance.isOver) {
+
+ this.instance.isOver = 1;
+ //Now we fake the start of dragging for the sortable instance,
+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
+ //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
+ this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
+ this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
+ this.instance.options.helper = function() { return ui.helper[0]; };
+
+ event.target = this.instance.currentItem[0];
+ this.instance._mouseCapture(event, true);
+ this.instance._mouseStart(event, true, true);
+
+ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
+ this.instance.offset.click.top = inst.offset.click.top;
+ this.instance.offset.click.left = inst.offset.click.left;
+ this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
+ this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
+
+ inst._trigger("toSortable", event);
+ inst.dropped = this.instance.element; //draggable revert needs that
+ //hack so receive/update callbacks work (mostly)
+ inst.currentItem = inst.element;
+ this.instance.fromOutside = inst;
+
+ }
+
+ //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
+ if(this.instance.currentItem) this.instance._mouseDrag(event);
+
+ } else {
+
+ //If it doesn't intersect with the sortable, and it intersected before,
+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
+ if(this.instance.isOver) {
+
+ this.instance.isOver = 0;
+ this.instance.cancelHelperRemoval = true;
+
+ //Prevent reverting on this forced stop
+ this.instance.options.revert = false;
+
+ // The out event needs to be triggered independently
+ this.instance._trigger('out', event, this.instance._uiHash(this.instance));
+
+ this.instance._mouseStop(event, true);
+ this.instance.options.helper = this.instance.options._helper;
+
+ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
+ this.instance.currentItem.remove();
+ if(this.instance.placeholder) this.instance.placeholder.remove();
+
+ inst._trigger("fromSortable", event);
+ inst.dropped = false; //draggable revert needs that
+ }
+
+ };
+
+ });
+
+ }
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+ start: function(event, ui) {
+ var t = $('body'), o = $(this).data('draggable').options;
+ if (t.css("cursor")) o._cursor = t.css("cursor");
+ t.css("cursor", o.cursor);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ if (o._cursor) $('body').css("cursor", o._cursor);
+ }
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+ start: function(event, ui) {
+ var t = $(ui.helper), o = $(this).data('draggable').options;
+ if(t.css("opacity")) o._opacity = t.css("opacity");
+ t.css('opacity', o.opacity);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ if(o._opacity) $(ui.helper).css('opacity', o._opacity);
+ }
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+ start: function(event, ui) {
+ var i = $(this).data("draggable");
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
+ },
+ drag: function(event, ui) {
+
+ var i = $(this).data("draggable"), o = i.options, scrolled = false;
+
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
+
+ if(!o.axis || o.axis != 'x') {
+ if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
+ else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
+ }
+
+ if(!o.axis || o.axis != 'y') {
+ if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
+ else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
+ }
+
+ } else {
+
+ if(!o.axis || o.axis != 'x') {
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+ }
+
+ if(!o.axis || o.axis != 'y') {
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+ }
+
+ }
+
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(i, event);
+
+ }
+});
+
+$.ui.plugin.add("draggable", "snap", {
+ start: function(event, ui) {
+
+ var i = $(this).data("draggable"), o = i.options;
+ i.snapElements = [];
+
+ $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
+ var $t = $(this); var $o = $t.offset();
+ if(this != i.element[0]) i.snapElements.push({
+ item: this,
+ width: $t.outerWidth(), height: $t.outerHeight(),
+ top: $o.top, left: $o.left
+ });
+ });
+
+ },
+ drag: function(event, ui) {
+
+ var inst = $(this).data("draggable"), o = inst.options;
+ var d = o.snapTolerance;
+
+ var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
+
+ for (var i = inst.snapElements.length - 1; i >= 0; i--){
+
+ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
+ t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
+
+ //Yes, I know, this is insane ;)
+ if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
+ if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+ inst.snapElements[i].snapping = false;
+ continue;
+ }
+
+ if(o.snapMode != 'inner') {
+ var ts = Math.abs(t - y2) <= d;
+ var bs = Math.abs(b - y1) <= d;
+ var ls = Math.abs(l - x2) <= d;
+ var rs = Math.abs(r - x1) <= d;
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
+ }
+
+ var first = (ts || bs || ls || rs);
+
+ if(o.snapMode != 'outer') {
+ var ts = Math.abs(t - y1) <= d;
+ var bs = Math.abs(b - y2) <= d;
+ var ls = Math.abs(l - x1) <= d;
+ var rs = Math.abs(r - x2) <= d;
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
+ }
+
+ if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+
+ };
+
+ }
+});
+
+$.ui.plugin.add("draggable", "stack", {
+ start: function(event, ui) {
+
+ var o = $(this).data("draggable").options;
+
+ var group = $.makeArray($(o.stack)).sort(function(a,b) {
+ return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
+ });
+ if (!group.length) { return; }
+
+ var min = parseInt(group[0].style.zIndex) || 0;
+ $(group).each(function(i) {
+ this.style.zIndex = min + i;
+ });
+
+ this[0].style.zIndex = min + group.length;
+
+ }
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+ start: function(event, ui) {
+ var t = $(ui.helper), o = $(this).data("draggable").options;
+ if(t.css("zIndex")) o._zIndex = t.css("zIndex");
+ t.css('zIndex', o.zIndex);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data("draggable").options;
+ if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
+ }
+});
+
+})(jQuery);
+/*
+ * jQuery UI Droppable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Droppables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ * jquery.ui.mouse.js
+ * jquery.ui.draggable.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.droppable", {
+ widgetEventPrefix: "drop",
+ options: {
+ accept: '*',
+ activeClass: false,
+ addClasses: true,
+ greedy: false,
+ hoverClass: false,
+ scope: 'default',
+ tolerance: 'intersect'
+ },
+ _create: function() {
+
+ var o = this.options, accept = o.accept;
+ this.isover = 0; this.isout = 1;
+
+ this.accept = $.isFunction(accept) ? accept : function(d) {
+ return d.is(accept);
+ };
+
+ //Store the droppable's proportions
+ this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
+
+ // Add the reference and positions to the manager
+ $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
+ $.ui.ddmanager.droppables[o.scope].push(this);
+
+ (o.addClasses && this.element.addClass("ui-droppable"));
+
+ },
+
+ destroy: function() {
+ var drop = $.ui.ddmanager.droppables[this.options.scope];
+ for ( var i = 0; i < drop.length; i++ )
+ if ( drop[i] == this )
+ drop.splice(i, 1);
+
+ this.element
+ .removeClass("ui-droppable ui-droppable-disabled")
+ .removeData("droppable")
+ .unbind(".droppable");
+
+ return this;
+ },
+
+ _setOption: function(key, value) {
+
+ if(key == 'accept') {
+ this.accept = $.isFunction(value) ? value : function(d) {
+ return d.is(value);
+ };
+ }
+ $.Widget.prototype._setOption.apply(this, arguments);
+ },
+
+ _activate: function(event) {
+ var draggable = $.ui.ddmanager.current;
+ if(this.options.activeClass) this.element.addClass(this.options.activeClass);
+ (draggable && this._trigger('activate', event, this.ui(draggable)));
+ },
+
+ _deactivate: function(event) {
+ var draggable = $.ui.ddmanager.current;
+ if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
+ (draggable && this._trigger('deactivate', event, this.ui(draggable)));
+ },
+
+ _over: function(event) {
+
+ var draggable = $.ui.ddmanager.current;
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
+
+ if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+ if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
+ this._trigger('over', event, this.ui(draggable));
+ }
+
+ },
+
+ _out: function(event) {
+
+ var draggable = $.ui.ddmanager.current;
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
+
+ if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+ if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
+ this._trigger('out', event, this.ui(draggable));
+ }
+
+ },
+
+ _drop: function(event,custom) {
+
+ var draggable = custom || $.ui.ddmanager.current;
+ if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
+
+ var childrenIntersection = false;
+ this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
+ var inst = $.data(this, 'droppable');
+ if(
+ inst.options.greedy
+ && !inst.options.disabled
+ && inst.options.scope == draggable.options.scope
+ && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
+ && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
+ ) { childrenIntersection = true; return false; }
+ });
+ if(childrenIntersection) return false;
+
+ if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+ if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
+ if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
+ this._trigger('drop', event, this.ui(draggable));
+ return this.element;
+ }
+
+ return false;
+
+ },
+
+ ui: function(c) {
+ return {
+ draggable: (c.currentItem || c.element),
+ helper: c.helper,
+ position: c.position,
+ offset: c.positionAbs
+ };
+ }
+
+});
+
+$.extend($.ui.droppable, {
+ version: "1.8.16"
+});
+
+$.ui.intersect = function(draggable, droppable, toleranceMode) {
+
+ if (!droppable.offset) return false;
+
+ var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
+ y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
+ var l = droppable.offset.left, r = l + droppable.proportions.width,
+ t = droppable.offset.top, b = t + droppable.proportions.height;
+
+ switch (toleranceMode) {
+ case 'fit':
+ return (l <= x1 && x2 <= r
+ && t <= y1 && y2 <= b);
+ break;
+ case 'intersect':
+ return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
+ && x2 - (draggable.helperProportions.width / 2) < r // Left Half
+ && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
+ && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
+ break;
+ case 'pointer':
+ var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
+ draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
+ isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
+ return isOver;
+ break;
+ case 'touch':
+ return (
+ (y1 >= t && y1 <= b) || // Top edge touching
+ (y2 >= t && y2 <= b) || // Bottom edge touching
+ (y1 < t && y2 > b) // Surrounded vertically
+ ) && (
+ (x1 >= l && x1 <= r) || // Left edge touching
+ (x2 >= l && x2 <= r) || // Right edge touching
+ (x1 < l && x2 > r) // Surrounded horizontally
+ );
+ break;
+ default:
+ return false;
+ break;
+ }
+
+};
+
+/*
+ This manager tracks offsets of draggables and droppables
+*/
+$.ui.ddmanager = {
+ current: null,
+ droppables: { 'default': [] },
+ prepareOffsets: function(t, event) {
+
+ var m = $.ui.ddmanager.droppables[t.options.scope] || [];
+ var type = event ? event.type : null; // workaround for #2317
+ var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
+
+ droppablesLoop: for (var i = 0; i < m.length; i++) {
+
+ if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
+ for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
+ m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
+
+ if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
+
+ m[i].offset = m[i].element.offset();
+ m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
+
+ }
+
+ },
+ drop: function(draggable, event) {
+
+ var dropped = false;
+ $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
+
+ if(!this.options) return;
+ if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
+ dropped = dropped || this._drop.call(this, event);
+
+ if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
+ this.isout = 1; this.isover = 0;
+ this._deactivate.call(this, event);
+ }
+
+ });
+ return dropped;
+
+ },
+ dragStart: function( draggable, event ) {
+ //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
+ draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() {
+ if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
+ });
+ },
+ drag: function(draggable, event) {
+
+ //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
+ if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
+
+ //Run through all droppables and check their positions based on specific tolerance options
+ $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
+
+ if(this.options.disabled || this.greedyChild || !this.visible) return;
+ var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
+
+ var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
+ if(!c) return;
+
+ var parentInstance;
+ if (this.options.greedy) {
+ var parent = this.element.parents(':data(droppable):eq(0)');
+ if (parent.length) {
+ parentInstance = $.data(parent[0], 'droppable');
+ parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
+ }
+ }
+
+ // we just moved into a greedy child
+ if (parentInstance && c == 'isover') {
+ parentInstance['isover'] = 0;
+ parentInstance['isout'] = 1;
+ parentInstance._out.call(parentInstance, event);
+ }
+
+ this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
+ this[c == "isover" ? "_over" : "_out"].call(this, event);
+
+ // we just moved out of a greedy child
+ if (parentInstance && c == 'isout') {
+ parentInstance['isout'] = 0;
+ parentInstance['isover'] = 1;
+ parentInstance._over.call(parentInstance, event);
+ }
+ });
+
+ },
+ dragStop: function( draggable, event ) {
+ draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" );
+ //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
+ if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
+ }
+};
+
+})(jQuery);
+/*
+ * jQuery UI Resizable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.resizable", $.ui.mouse, {
+ widgetEventPrefix: "resize",
+ options: {
+ alsoResize: false,
+ animate: false,
+ animateDuration: "slow",
+ animateEasing: "swing",
+ aspectRatio: false,
+ autoHide: false,
+ containment: false,
+ ghost: false,
+ grid: false,
+ handles: "e,s,se",
+ helper: false,
+ maxHeight: null,
+ maxWidth: null,
+ minHeight: 10,
+ minWidth: 10,
+ zIndex: 1000
+ },
+ _create: function() {
+
+ var self = this, o = this.options;
+ this.element.addClass("ui-resizable");
+
+ $.extend(this, {
+ _aspectRatio: !!(o.aspectRatio),
+ aspectRatio: o.aspectRatio,
+ originalElement: this.element,
+ _proportionallyResizeElements: [],
+ _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
+ });
+
+ //Wrap the element if it cannot hold child nodes
+ if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+
+ //Opera fix for relative positioning
+ if (/relative/.test(this.element.css('position')) && $.browser.opera)
+ this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+ //Create a wrapper element and set the wrapper to the new current internal element
+ this.element.wrap(
+ $('<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')
+ })
+ );
+
+ //Overwrite the original this.element
+ this.element = this.element.parent().data(
+ "resizable", this.element.data('resizable')
+ );
+
+ this.elementIsWrapper = true;
+
+ //Move margins to the wrapper
+ this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
+ this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
+
+ //Prevent Safari textarea resize
+ this.originalResizeStyle = this.originalElement.css('resize');
+ this.originalElement.css('resize', 'none');
+
+ //Push the actual element to our proportionallyResize internal array
+ this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
+
+ // avoid IE jump (hard set the margin)
+ this.originalElement.css({ margin: this.originalElement.css('margin') });
+
+ // fix handlers offset
+ this._proportionallyResize();
+
+ }
+
+ this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { 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' });
+ if(this.handles.constructor == String) {
+
+ if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
+ var n = this.handles.split(","); this.handles = {};
+
+ for(var i = 0; i < n.length; i++) {
+
+ var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
+ var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
+
+ // increase zIndex of sw, se, ne, nw axis
+ //TODO : this modifies original option
+ if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
+
+ //TODO : What's going on here?
+ if ('se' == handle) {
+ axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
+ };
+
+ //Insert into internal handles object and append to element
+ this.handles[handle] = '.ui-resizable-'+handle;
+ this.element.append(axis);
+ }
+
+ }
+
+ this._renderAxis = function(target) {
+
+ target = target || this.element;
+
+ for(var i in this.handles) {
+
+ if(this.handles[i].constructor == String)
+ this.handles[i] = $(this.handles[i], this.element).show();
+
+ //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
+ if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
+
+ var axis = $(this.handles[i], this.element), padWrapper = 0;
+
+ //Checking the correct pad and border
+ padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+ //The padding type i have to apply...
+ var padPos = [ 'padding',
+ /ne|nw|n/.test(i) ? 'Top' :
+ /se|sw|s/.test(i) ? 'Bottom' :
+ /^e$/.test(i) ? 'Right' : 'Left' ].join("");
+
+ target.css(padPos, padWrapper);
+
+ this._proportionallyResize();
+
+ }
+
+ //TODO: What's that good for? There's not anything to be executed left
+ if(!$(this.handles[i]).length)
+ continue;
+
+ }
+ };
+
+ //TODO: make renderAxis a prototype function
+ this._renderAxis(this.element);
+
+ this._handles = $('.ui-resizable-handle', this.element)
+ .disableSelection();
+
+ //Matching axis name
+ this._handles.mouseover(function() {
+ if (!self.resizing) {
+ if (this.className)
+ var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+ //Axis, default = se
+ self.axis = axis && axis[1] ? axis[1] : 'se';
+ }
+ });
+
+ //If we want to auto hide the elements
+ if (o.autoHide) {
+ this._handles.hide();
+ $(this.element)
+ .addClass("ui-resizable-autohide")
+ .hover(function() {
+ if (o.disabled) return;
+ $(this).removeClass("ui-resizable-autohide");
+ self._handles.show();
+ },
+ function(){
+ if (o.disabled) return;
+ if (!self.resizing) {
+ $(this).addClass("ui-resizable-autohide");
+ self._handles.hide();
+ }
+ });
+ }
+
+ //Initialize the mouse interaction
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+
+ this._mouseDestroy();
+
+ var _destroy = function(exp) {
+ $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
+ .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
+ };
+
+ //TODO: Unwrap at same DOM position
+ if (this.elementIsWrapper) {
+ _destroy(this.element);
+ var wrapper = this.element;
+ wrapper.after(
+ this.originalElement.css({
+ position: wrapper.css('position'),
+ width: wrapper.outerWidth(),
+ height: wrapper.outerHeight(),
+ top: wrapper.css('top'),
+ left: wrapper.css('left')
+ })
+ ).remove();
+ }
+
+ this.originalElement.css('resize', this.originalResizeStyle);
+ _destroy(this.originalElement);
+
+ return this;
+ },
+
+ _mouseCapture: function(event) {
+ var handle = false;
+ for (var i in this.handles) {
+ if ($(this.handles[i])[0] == event.target) {
+ handle = true;
+ }
+ }
+
+ return !this.options.disabled && handle;
+ },
+
+ _mouseStart: function(event) {
+
+ var o = this.options, iniPos = this.element.position(), el = this.element;
+
+ this.resizing = true;
+ this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
+
+ // bugfix for http://dev.jquery.com/ticket/1749
+ if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
+ el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
+ }
+
+ //Opera fixing relative position
+ if ($.browser.opera && (/relative/).test(el.css('position')))
+ el.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+ this._renderProxy();
+
+ var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
+
+ if (o.containment) {
+ curleft += $(o.containment).scrollLeft() || 0;
+ curtop += $(o.containment).scrollTop() || 0;
+ }
+
+ //Store needed variables
+ this.offset = this.helper.offset();
+ this.position = { left: curleft, top: curtop };
+ this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalPosition = { left: curleft, top: curtop };
+ this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
+ this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+ //Aspect Ratio
+ this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
+
+ var cursor = $('.ui-resizable-' + this.axis).css('cursor');
+ $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
+
+ el.addClass("ui-resizable-resizing");
+ this._propagate("start", event);
+ return true;
+ },
+
+ _mouseDrag: function(event) {
+
+ //Increase performance, avoid regex
+ var el = this.helper, o = this.options, props = {},
+ self = this, smp = this.originalMousePosition, a = this.axis;
+
+ var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
+ var trigger = this._change[a];
+ if (!trigger) return false;
+
+ // Calculate the attrs that will be change
+ var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
+
+ // Put this in the mouseDrag handler since the user can start pressing shift while resizing
+ this._updateVirtualBoundaries(event.shiftKey);
+ if (this._aspectRatio || event.shiftKey)
+ data = this._updateRatio(data, event);
+
+ data = this._respectSize(data, event);
+
+ // plugins callbacks need to be called first
+ this._propagate("resize", event);
+
+ el.css({
+ top: this.position.top + "px", left: this.position.left + "px",
+ width: this.size.width + "px", height: this.size.height + "px"
+ });
+
+ if (!this._helper && this._proportionallyResizeElements.length)
+ this._proportionallyResize();
+
+ this._updateCache(data);
+
+ // calling the user callback at the end
+ this._trigger('resize', event, this.ui());
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+
+ this.resizing = false;
+ var o = this.options, self = this;
+
+ if(this._helper) {
+ var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ if (!o.animate)
+ this.element.css($.extend(s, { top: top, left: left }));
+
+ self.helper.height(self.size.height);
+ self.helper.width(self.size.width);
+
+ if (this._helper && !o.animate) this._proportionallyResize();
+ }
+
+ $('body').css('cursor', 'auto');
+
+ this.element.removeClass("ui-resizable-resizing");
+
+ this._propagate("stop", event);
+
+ if (this._helper) this.helper.remove();
+ return false;
+
+ },
+
+ _updateVirtualBoundaries: function(forceAspectRatio) {
+ var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
+
+ b = {
+ minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
+ maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
+ minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
+ maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
+ };
+
+ if(this._aspectRatio || forceAspectRatio) {
+ // We want to create an enclosing box whose aspect ration is the requested one
+ // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
+ pMinWidth = b.minHeight * this.aspectRatio;
+ pMinHeight = b.minWidth / this.aspectRatio;
+ pMaxWidth = b.maxHeight * this.aspectRatio;
+ pMaxHeight = b.maxWidth / this.aspectRatio;
+
+ if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
+ if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
+ if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
+ if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
+ }
+ this._vBoundaries = b;
+ },
+
+ _updateCache: function(data) {
+ var o = this.options;
+ this.offset = this.helper.offset();
+ if (isNumber(data.left)) this.position.left = data.left;
+ if (isNumber(data.top)) this.position.top = data.top;
+ if (isNumber(data.height)) this.size.height = data.height;
+ if (isNumber(data.width)) this.size.width = data.width;
+ },
+
+ _updateRatio: function(data, event) {
+
+ var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+
+ if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
+ else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
+
+ if (a == 'sw') {
+ data.left = cpos.left + (csize.width - data.width);
+ data.top = null;
+ }
+ if (a == 'nw') {
+ data.top = cpos.top + (csize.height - data.height);
+ data.left = cpos.left + (csize.width - data.width);
+ }
+
+ return data;
+ },
+
+ _respectSize: function(data, event) {
+
+ var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
+ ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+ isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
+
+ if (isminw) data.width = o.minWidth;
+ if (isminh) data.height = o.minHeight;
+ if (ismaxw) data.width = o.maxWidth;
+ if (ismaxh) data.height = o.maxHeight;
+
+ var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
+ var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+
+ if (isminw && cw) data.left = dw - o.minWidth;
+ if (ismaxw && cw) data.left = dw - o.maxWidth;
+ if (isminh && ch) data.top = dh - o.minHeight;
+ if (ismaxh && ch) data.top = dh - o.maxHeight;
+
+ // fixing jump error on top/left - bug #2330
+ var isNotwh = !data.width && !data.height;
+ if (isNotwh && !data.left && data.top) data.top = null;
+ else if (isNotwh && !data.top && data.left) data.left = null;
+
+ return data;
+ },
+
+ _proportionallyResize: function() {
+
+ var o = this.options;
+ if (!this._proportionallyResizeElements.length) return;
+ var element = this.helper || this.element;
+
+ for (var i=0; i < this._proportionallyResizeElements.length; i++) {
+
+ var prel = this._proportionallyResizeElements[i];
+
+ if (!this.borderDif) {
+ var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
+ p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
+
+ this.borderDif = $.map(b, function(v, i) {
+ var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
+ return border + padding;
+ });
+ }
+
+ if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
+ continue;
+
+ prel.css({
+ height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
+ width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
+ });
+
+ };
+
+ },
+
+ _renderProxy: function() {
+
+ var el = this.element, o = this.options;
+ this.elementOffset = el.offset();
+
+ if(this._helper) {
+
+ this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
+
+ // fix ie6 offset TODO: This seems broken
+ var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
+ pxyoffset = ( ie6 ? 2 : -1 );
+
+ this.helper.addClass(this._helper).css({
+ width: this.element.outerWidth() + pxyoffset,
+ height: this.element.outerHeight() + pxyoffset,
+ position: 'absolute',
+ left: this.elementOffset.left - ie6offset +'px',
+ top: this.elementOffset.top - ie6offset +'px',
+ zIndex: ++o.zIndex //TODO: Don't modify option
+ });
+
+ this.helper
+ .appendTo("body")
+ .disableSelection();
+
+ } else {
+ this.helper = this.element;
+ }
+
+ },
+
+ _change: {
+ e: function(event, dx, dy) {
+ return { width: this.originalSize.width + dx };
+ },
+ w: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { left: sp.left + dx, width: cs.width - dx };
+ },
+ n: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { top: sp.top + dy, height: cs.height - dy };
+ },
+ s: function(event, dx, dy) {
+ return { height: this.originalSize.height + dy };
+ },
+ se: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ sw: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ },
+ ne: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ nw: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ }
+ },
+
+ _propagate: function(n, event) {
+ $.ui.plugin.call(this, n, [event, this.ui()]);
+ (n != "resize" && this._trigger(n, event, 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
+ };
+ }
+
+});
+
+$.extend($.ui.resizable, {
+ version: "1.8.16"
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+ start: function (event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var _store = function (exp) {
+ $(exp).each(function() {
+ var el = $(this);
+ el.data("resizable-alsoresize", {
+ width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
+ left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10),
+ position: el.css('position') // to reset Opera on stop()
+ });
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
+ if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
+ else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
+ }else{
+ _store(o.alsoResize);
+ }
+ },
+
+ resize: function (event, ui) {
+ var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
+
+ var delta = {
+ height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
+ top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
+ },
+
+ _alsoResize = function (exp, c) {
+ $(exp).each(function() {
+ var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
+ css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
+
+ $.each(css, function (i, prop) {
+ var sum = (start[prop]||0) + (delta[prop]||0);
+ if (sum && sum >= 0)
+ style[prop] = sum || null;
+ });
+
+ // Opera fixing relative position
+ if ($.browser.opera && /relative/.test(el.css('position'))) {
+ self._revertToRelativePosition = true;
+ el.css({ position: 'absolute', top: 'auto', left: 'auto' });
+ }
+
+ el.css(style);
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+ $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
+ }else{
+ _alsoResize(o.alsoResize);
+ }
+ },
+
+ stop: function (event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var _reset = function (exp) {
+ $(exp).each(function() {
+ var el = $(this);
+ // reset position for Opera - no need to verify it was changed
+ el.css({ position: el.data("resizable-alsoresize").position });
+ });
+ };
+
+ if (self._revertToRelativePosition) {
+ self._revertToRelativePosition = false;
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+ $.each(o.alsoResize, function (exp) { _reset(exp); });
+ }else{
+ _reset(o.alsoResize);
+ }
+ }
+
+ $(this).removeData("resizable-alsoresize");
+ }
+});
+
+$.ui.plugin.add("resizable", "animate", {
+
+ stop: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ self.element.animate(
+ $.extend(style, top && left ? { top: top, left: left } : {}), {
+ duration: o.animateDuration,
+ easing: o.animateEasing,
+ step: function() {
+
+ var data = {
+ width: parseInt(self.element.css('width'), 10),
+ height: parseInt(self.element.css('height'), 10),
+ top: parseInt(self.element.css('top'), 10),
+ left: parseInt(self.element.css('left'), 10)
+ };
+
+ if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
+
+ // propagating resize, and updating values for each animation step
+ self._updateCache(data);
+ self._propagate("resize", event);
+
+ }
+ }
+ );
+ }
+
+});
+
+$.ui.plugin.add("resizable", "containment", {
+
+ start: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options, el = self.element;
+ var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
+ if (!ce) return;
+
+ self.containerElement = $(ce);
+
+ if (/document/.test(oc) || oc == document) {
+ self.containerOffset = { left: 0, top: 0 };
+ self.containerPosition = { left: 0, top: 0 };
+
+ self.parentData = {
+ element: $(document), left: 0, top: 0,
+ width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
+ };
+ }
+
+ // i'm a node, so compute top, left, right, bottom
+ else {
+ var element = $(ce), p = [];
+ $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
+
+ self.containerOffset = element.offset();
+ self.containerPosition = element.position();
+ self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
+
+ var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
+ width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
+
+ self.parentData = {
+ element: ce, left: co.left, top: co.top, width: width, height: height
+ };
+ }
+ },
+
+ resize: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options,
+ ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
+ pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
+
+ if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
+
+ if (cp.left < (self._helper ? co.left : 0)) {
+ self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
+ if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+ self.position.left = o.helper ? co.left : 0;
+ }
+
+ if (cp.top < (self._helper ? co.top : 0)) {
+ self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
+ if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+ self.position.top = self._helper ? co.top : 0;
+ }
+
+ self.offset.left = self.parentData.left+self.position.left;
+ self.offset.top = self.parentData.top+self.position.top;
+
+ var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
+ hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
+
+ var isParent = self.containerElement.get(0) == self.element.parent().get(0),
+ isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
+
+ if(isParent && isOffsetRelative) woset -= self.parentData.left;
+
+ if (woset + self.size.width >= self.parentData.width) {
+ self.size.width = self.parentData.width - woset;
+ if (pRatio) self.size.height = self.size.width / self.aspectRatio;
+ }
+
+ if (hoset + self.size.height >= self.parentData.height) {
+ self.size.height = self.parentData.height - hoset;
+ if (pRatio) self.size.width = self.size.height * self.aspectRatio;
+ }
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options, cp = self.position,
+ co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
+
+ var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
+
+ if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ if (self._helper && !o.animate && (/static/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ }
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+ start: function(event, ui) {
+
+ var self = $(this).data("resizable"), o = self.options, cs = self.size;
+
+ self.ghost = self.originalElement.clone();
+ self.ghost
+ .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
+ .addClass('ui-resizable-ghost')
+ .addClass(typeof o.ghost == 'string' ? o.ghost : '');
+
+ self.ghost.appendTo(self.helper);
+
+ },
+
+ resize: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
+ }
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+ resize: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
+ o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
+ var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+
+ if (/^(se|s|e)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ }
+ else if (/^(ne)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ }
+ else if (/^(sw)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.left = op.left - ox;
+ }
+ else {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ self.position.left = op.left - ox;
+ }
+ }
+
+});
+
+var num = function(v) {
+ return parseInt(v, 10) || 0;
+};
+
+var isNumber = function(value) {
+ return !isNaN(parseInt(value, 10));
+};
+
+})(jQuery);
+/*
+ * jQuery UI Selectable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.selectable", $.ui.mouse, {
+ options: {
+ appendTo: 'body',
+ autoRefresh: true,
+ distance: 0,
+ filter: '*',
+ tolerance: 'touch'
+ },
+ _create: function() {
+ var self = this;
+
+ this.element.addClass("ui-selectable");
+
+ this.dragged = false;
+
+ // cache selectee children based on filter
+ var selectees;
+ this.refresh = function() {
+ selectees = $(self.options.filter, self.element[0]);
+ selectees.each(function() {
+ var $this = $(this);
+ var pos = $this.offset();
+ $.data(this, "selectable-item", {
+ element: this,
+ $element: $this,
+ left: pos.left,
+ top: pos.top,
+ right: pos.left + $this.outerWidth(),
+ bottom: pos.top + $this.outerHeight(),
+ startselected: false,
+ selected: $this.hasClass('ui-selected'),
+ selecting: $this.hasClass('ui-selecting'),
+ unselecting: $this.hasClass('ui-unselecting')
+ });
+ });
+ };
+ this.refresh();
+
+ this.selectees = selectees.addClass("ui-selectee");
+
+ this._mouseInit();
+
+ this.helper = $("<div class='ui-selectable-helper'></div>");
+ },
+
+ destroy: function() {
+ this.selectees
+ .removeClass("ui-selectee")
+ .removeData("selectable-item");
+ this.element
+ .removeClass("ui-selectable ui-selectable-disabled")
+ .removeData("selectable")
+ .unbind(".selectable");
+ this._mouseDestroy();
+
+ return this;
+ },
+
+ _mouseStart: function(event) {
+ var self = this;
+
+ this.opos = [event.pageX, event.pageY];
+
+ if (this.options.disabled)
+ return;
+
+ var options = this.options;
+
+ this.selectees = $(options.filter, this.element[0]);
+
+ this._trigger("start", event);
+
+ $(options.appendTo).append(this.helper);
+ // position helper (lasso)
+ this.helper.css({
+ "left": event.clientX,
+ "top": event.clientY,
+ "width": 0,
+ "height": 0
+ });
+
+ if (options.autoRefresh) {
+ this.refresh();
+ }
+
+ this.selectees.filter('.ui-selected').each(function() {
+ var selectee = $.data(this, "selectable-item");
+ selectee.startselected = true;
+ if (!event.metaKey) {
+ selectee.$element.removeClass('ui-selected');
+ selectee.selected = false;
+ selectee.$element.addClass('ui-unselecting');
+ selectee.unselecting = true;
+ // selectable UNSELECTING callback
+ self._trigger("unselecting", event, {
+ unselecting: selectee.element
+ });
+ }
+ });
+
+ $(event.target).parents().andSelf().each(function() {
+ var selectee = $.data(this, "selectable-item");
+ if (selectee) {
+ var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
+ selectee.$element
+ .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
+ .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
+ selectee.unselecting = !doSelect;
+ selectee.selecting = doSelect;
+ selectee.selected = doSelect;
+ // selectable (UN)SELECTING callback
+ if (doSelect) {
+ self._trigger("selecting", event, {
+ selecting: selectee.element
+ });
+ } else {
+ self._trigger("unselecting", event, {
+ unselecting: selectee.element
+ });
+ }
+ return false;
+ }
+ });
+
+ },
+
+ _mouseDrag: function(event) {
+ var self = this;
+ this.dragged = true;
+
+ if (this.options.disabled)
+ return;
+
+ var options = this.options;
+
+ var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
+ if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
+ if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
+ this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
+
+ this.selectees.each(function() {
+ var selectee = $.data(this, "selectable-item");
+ //prevent helper from being selected if appendTo: selectable
+ if (!selectee || selectee.element == self.element[0])
+ return;
+ var hit = false;
+ if (options.tolerance == 'touch') {
+ hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
+ } else if (options.tolerance == 'fit') {
+ hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
+ }
+
+ if (hit) {
+ // SELECT
+ if (selectee.selected) {
+ selectee.$element.removeClass('ui-selected');
+ selectee.selected = false;
+ }
+ if (selectee.unselecting) {
+ selectee.$element.removeClass('ui-unselecting');
+ selectee.unselecting = false;
+ }
+ if (!selectee.selecting) {
+ selectee.$element.addClass('ui-selecting');
+ selectee.selecting = true;
+ // selectable SELECTING callback
+ self._trigger("selecting", event, {
+ selecting: selectee.element
+ });
+ }
+ } else {
+ // UNSELECT
+ if (selectee.selecting) {
+ if (event.metaKey && selectee.startselected) {
+ selectee.$element.removeClass('ui-selecting');
+ selectee.selecting = false;
+ selectee.$element.addClass('ui-selected');
+ selectee.selected = true;
+ } else {
+ selectee.$element.removeClass('ui-selecting');
+ selectee.selecting = false;
+ if (selectee.startselected) {
+ selectee.$element.addClass('ui-unselecting');
+ selectee.unselecting = true;
+ }
+ // selectable UNSELECTING callback
+ self._trigger("unselecting", event, {
+ unselecting: selectee.element
+ });
+ }
+ }
+ if (selectee.selected) {
+ if (!event.metaKey && !selectee.startselected) {
+ selectee.$element.removeClass('ui-selected');
+ selectee.selected = false;
+
+ selectee.$element.addClass('ui-unselecting');
+ selectee.unselecting = true;
+ // selectable UNSELECTING callback
+ self._trigger("unselecting", event, {
+ unselecting: selectee.element
+ });
+ }
+ }
+ }
+ });
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+ var self = this;
+
+ this.dragged = false;
+
+ var options = this.options;
+
+ $('.ui-unselecting', this.element[0]).each(function() {
+ var selectee = $.data(this, "selectable-item");
+ selectee.$element.removeClass('ui-unselecting');
+ selectee.unselecting = false;
+ selectee.startselected = false;
+ self._trigger("unselected", event, {
+ unselected: selectee.element
+ });
+ });
+ $('.ui-selecting', this.element[0]).each(function() {
+ var selectee = $.data(this, "selectable-item");
+ selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
+ selectee.selecting = false;
+ selectee.selected = true;
+ selectee.startselected = true;
+ self._trigger("selected", event, {
+ selected: selectee.element
+ });
+ });
+ this._trigger("stop", event);
+
+ this.helper.remove();
+
+ return false;
+ }
+
+});
+
+$.extend($.ui.selectable, {
+ version: "1.8.16"
+});
+
+})(jQuery);
+/*
+ * jQuery UI Sortable 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Sortables
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget("ui.sortable", $.ui.mouse, {
+ widgetEventPrefix: "sort",
+ options: {
+ appendTo: "parent",
+ axis: false,
+ connectWith: false,
+ containment: false,
+ cursor: 'auto',
+ cursorAt: false,
+ dropOnEmpty: true,
+ forcePlaceholderSize: false,
+ forceHelperSize: false,
+ grid: false,
+ handle: false,
+ helper: "original",
+ items: '> *',
+ opacity: false,
+ placeholder: false,
+ revert: false,
+ scroll: true,
+ scrollSensitivity: 20,
+ scrollSpeed: 20,
+ scope: "default",
+ tolerance: "intersect",
+ zIndex: 1000
+ },
+ _create: function() {
+
+ var o = this.options;
+ this.containerCache = {};
+ this.element.addClass("ui-sortable");
+
+ //Get the items
+ this.refresh();
+
+ //Let's determine if the items are being displayed horizontally
+ this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
+
+ //Let's determine the parent's offset
+ this.offset = this.element.offset();
+
+ //Initialize mouse events for interaction
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass("ui-sortable ui-sortable-disabled")
+ .removeData("sortable")
+ .unbind(".sortable");
+ this._mouseDestroy();
+
+ for ( var i = this.items.length - 1; i >= 0; i-- )
+ this.items[i].item.removeData("sortable-item");
+
+ return this;
+ },
+
+ _setOption: function(key, value){
+ if ( key === "disabled" ) {
+ this.options[ key ] = value;
+
+ this.widget()
+ [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
+ } else {
+ // Don't call widget base _setOption for disable as it adds ui-state-disabled class
+ $.Widget.prototype._setOption.apply(this, arguments);
+ }
+ },
+
+ _mouseCapture: function(event, overrideHandle) {
+
+ if (this.reverting) {
+ return false;
+ }
+
+ if(this.options.disabled || this.options.type == 'static') return false;
+
+ //We have to refresh the items data once first
+ this._refreshItems(event);
+
+ //Find out if the clicked node (or one of its parents) is a actual item in this.items
+ var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
+ if($.data(this, 'sortable-item') == self) {
+ currentItem = $(this);
+ return false;
+ }
+ });
+ if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target);
+
+ if(!currentItem) return false;
+ if(this.options.handle && !overrideHandle) {
+ var validHandle = false;
+
+ $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
+ if(!validHandle) return false;
+ }
+
+ this.currentItem = currentItem;
+ this._removeCurrentsFromItems();
+ return true;
+
+ },
+
+ _mouseStart: function(event, overrideHandle, noActivation) {
+
+ var o = this.options, self = this;
+ this.currentContainer = this;
+
+ //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
+ this.refreshPositions();
+
+ //Create and append the visible helper
+ this.helper = this._createHelper(event);
+
+ //Cache the helper size
+ this._cacheHelperProportions();
+
+ /*
+ * - Position generation -
+ * This block generates everything position related - it's the core of draggables.
+ */
+
+ //Cache the margins of the original element
+ this._cacheMargins();
+
+ //Get the next scrolling parent
+ this.scrollParent = this.helper.scrollParent();
+
+ //The element's absolute position on the page minus margins
+ this.offset = this.currentItem.offset();
+ this.offset = {
+ top: this.offset.top - this.margins.top,
+ left: this.offset.left - this.margins.left
+ };
+
+ // Only after we got the offset, we can change the helper's position to absolute
+ // TODO: Still need to figure out a way to make relative sorting possible
+ this.helper.css("position", "absolute");
+ this.cssPosition = this.helper.css("position");
+
+ $.extend(this.offset, {
+ click: { //Where the click happened, relative to the element
+ left: event.pageX - this.offset.left,
+ top: event.pageY - this.offset.top
+ },
+ parent: this._getParentOffset(),
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+ });
+
+ //Generate the original position
+ this.originalPosition = this._generatePosition(event);
+ this.originalPageX = event.pageX;
+ this.originalPageY = event.pageY;
+
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
+
+ //Cache the former DOM position
+ this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
+
+ //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
+ if(this.helper[0] != this.currentItem[0]) {
+ this.currentItem.hide();
+ }
+
+ //Create the placeholder
+ this._createPlaceholder();
+
+ //Set a containment if given in the options
+ if(o.containment)
+ this._setContainment();
+
+ if(o.cursor) { // cursor option
+ if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
+ $('body').css("cursor", o.cursor);
+ }
+
+ if(o.opacity) { // opacity option
+ if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
+ this.helper.css("opacity", o.opacity);
+ }
+
+ if(o.zIndex) { // zIndex option
+ if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
+ this.helper.css("zIndex", o.zIndex);
+ }
+
+ //Prepare scrolling
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
+ this.overflowOffset = this.scrollParent.offset();
+
+ //Call callbacks
+ this._trigger("start", event, this._uiHash());
+
+ //Recache the helper size
+ if(!this._preserveHelperProportions)
+ this._cacheHelperProportions();
+
+
+ //Post 'activate' events to possible containers
+ if(!noActivation) {
+ for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
+ }
+
+ //Prepare possible droppables
+ if($.ui.ddmanager)
+ $.ui.ddmanager.current = this;
+
+ if ($.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+
+ this.dragging = true;
+
+ this.helper.addClass("ui-sortable-helper");
+ this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+ return true;
+
+ },
+
+ _mouseDrag: function(event) {
+
+ //Compute the helpers position
+ this.position = this._generatePosition(event);
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ if (!this.lastPositionAbs) {
+ this.lastPositionAbs = this.positionAbs;
+ }
+
+ //Do scrolling
+ if(this.options.scroll) {
+ var o = this.options, scrolled = false;
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
+
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
+ else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
+
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
+ else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
+
+ } else {
+
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+
+ }
+
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+ }
+
+ //Regenerate the absolute position used for position checks
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ //Set the helper position
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+
+ //Rearrange
+ for (var i = this.items.length - 1; i >= 0; i--) {
+
+ //Cache variables and intersection, continue if no intersection
+ var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
+ if (!intersection) continue;
+
+ if(itemElement != this.currentItem[0] //cannot intersect with itself
+ && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
+ && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
+ && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
+ //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
+ ) {
+
+ this.direction = intersection == 1 ? "down" : "up";
+
+ if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
+ this._rearrange(event, item);
+ } else {
+ break;
+ }
+
+ this._trigger("change", event, this._uiHash());
+ break;
+ }
+ }
+
+ //Post events to containers
+ this._contactContainers(event);
+
+ //Interconnect with droppables
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
+
+ //Call callbacks
+ this._trigger('sort', event, this._uiHash());
+
+ this.lastPositionAbs = this.positionAbs;
+ return false;
+
+ },
+
+ _mouseStop: function(event, noPropagation) {
+
+ if(!event) return;
+
+ //If we are using droppables, inform the manager about the drop
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
+ $.ui.ddmanager.drop(this, event);
+
+ if(this.options.revert) {
+ var self = this;
+ var cur = self.placeholder.offset();
+
+ self.reverting = true;
+
+ $(this.helper).animate({
+ left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
+ top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
+ }, parseInt(this.options.revert, 10) || 500, function() {
+ self._clear(event);
+ });
+ } else {
+ this._clear(event, noPropagation);
+ }
+
+ return false;
+
+ },
+
+ cancel: function() {
+
+ var self = this;
+
+ if(this.dragging) {
+
+ this._mouseUp({ target: null });
+
+ if(this.options.helper == "original")
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+ else
+ this.currentItem.show();
+
+ //Post deactivating events to containers
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ this.containers[i]._trigger("deactivate", null, self._uiHash(this));
+ if(this.containers[i].containerCache.over) {
+ this.containers[i]._trigger("out", null, self._uiHash(this));
+ this.containers[i].containerCache.over = 0;
+ }
+ }
+
+ }
+
+ if (this.placeholder) {
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+ if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+ if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
+
+ $.extend(this, {
+ helper: null,
+ dragging: false,
+ reverting: false,
+ _noFinalSort: null
+ });
+
+ if(this.domPosition.prev) {
+ $(this.domPosition.prev).after(this.currentItem);
+ } else {
+ $(this.domPosition.parent).prepend(this.currentItem);
+ }
+ }
+
+ return this;
+
+ },
+
+ serialize: function(o) {
+
+ var items = this._getItemsAsjQuery(o && o.connected);
+ var str = []; o = o || {};
+
+ $(items).each(function() {
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
+ if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
+ });
+
+ if(!str.length && o.key) {
+ str.push(o.key + '=');
+ }
+
+ return str.join('&');
+
+ },
+
+ toArray: function(o) {
+
+ var items = this._getItemsAsjQuery(o && o.connected);
+ var ret = []; o = o || {};
+
+ items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
+ return ret;
+
+ },
+
+ /* Be careful with the following core functions */
+ _intersectsWith: function(item) {
+
+ var x1 = this.positionAbs.left,
+ x2 = x1 + this.helperProportions.width,
+ y1 = this.positionAbs.top,
+ y2 = y1 + this.helperProportions.height;
+
+ var l = item.left,
+ r = l + item.width,
+ t = item.top,
+ b = t + item.height;
+
+ var dyClick = this.offset.click.top,
+ dxClick = this.offset.click.left;
+
+ var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
+
+ if( this.options.tolerance == "pointer"
+ || this.options.forcePointerForContainers
+ || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
+ ) {
+ return isOverElement;
+ } else {
+
+ return (l < x1 + (this.helperProportions.width / 2) // Right Half
+ && x2 - (this.helperProportions.width / 2) < r // Left Half
+ && t < y1 + (this.helperProportions.height / 2) // Bottom Half
+ && y2 - (this.helperProportions.height / 2) < b ); // Top Half
+
+ }
+ },
+
+ _intersectsWithPointer: function(item) {
+
+ var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
+ isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
+ isOverElement = isOverElementHeight && isOverElementWidth,
+ verticalDirection = this._getDragVerticalDirection(),
+ horizontalDirection = this._getDragHorizontalDirection();
+
+ if (!isOverElement)
+ return false;
+
+ return this.floating ?
+ ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
+ : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
+
+ },
+
+ _intersectsWithSides: function(item) {
+
+ var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
+ isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
+ verticalDirection = this._getDragVerticalDirection(),
+ horizontalDirection = this._getDragHorizontalDirection();
+
+ if (this.floating && horizontalDirection) {
+ return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
+ } else {
+ return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
+ }
+
+ },
+
+ _getDragVerticalDirection: function() {
+ var delta = this.positionAbs.top - this.lastPositionAbs.top;
+ return delta != 0 && (delta > 0 ? "down" : "up");
+ },
+
+ _getDragHorizontalDirection: function() {
+ var delta = this.positionAbs.left - this.lastPositionAbs.left;
+ return delta != 0 && (delta > 0 ? "right" : "left");
+ },
+
+ refresh: function(event) {
+ this._refreshItems(event);
+ this.refreshPositions();
+ return this;
+ },
+
+ _connectWith: function() {
+ var options = this.options;
+ return options.connectWith.constructor == String
+ ? [options.connectWith]
+ : options.connectWith;
+ },
+
+ _getItemsAsjQuery: function(connected) {
+
+ var self = this;
+ var items = [];
+ var queries = [];
+ var connectWith = this._connectWith();
+
+ if(connectWith && connected) {
+ for (var i = connectWith.length - 1; i >= 0; i--){
+ var cur = $(connectWith[i]);
+ for (var j = cur.length - 1; j >= 0; j--){
+ var inst = $.data(cur[j], 'sortable');
+ if(inst && inst != this && !inst.options.disabled) {
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
+ }
+ };
+ };
+ }
+
+ queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
+
+ for (var i = queries.length - 1; i >= 0; i--){
+ queries[i][0].each(function() {
+ items.push(this);
+ });
+ };
+
+ return $(items);
+
+ },
+
+ _removeCurrentsFromItems: function() {
+
+ var list = this.currentItem.find(":data(sortable-item)");
+
+ for (var i=0; i < this.items.length; i++) {
+
+ for (var j=0; j < list.length; j++) {
+ if(list[j] == this.items[i].item[0])
+ this.items.splice(i,1);
+ };
+
+ };
+
+ },
+
+ _refreshItems: function(event) {
+
+ this.items = [];
+ this.containers = [this];
+ var items = this.items;
+ var self = this;
+ var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
+ var connectWith = this._connectWith();
+
+ if(connectWith) {
+ for (var i = connectWith.length - 1; i >= 0; i--){
+ var cur = $(connectWith[i]);
+ for (var j = cur.length - 1; j >= 0; j--){
+ var inst = $.data(cur[j], 'sortable');
+ if(inst && inst != this && !inst.options.disabled) {
+ queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
+ this.containers.push(inst);
+ }
+ };
+ };
+ }
+
+ for (var i = queries.length - 1; i >= 0; i--) {
+ var targetData = queries[i][1];
+ var _queries = queries[i][0];
+
+ for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
+ var item = $(_queries[j]);
+
+ item.data('sortable-item', targetData); // Data for target checking (mouse manager)
+
+ items.push({
+ item: item,
+ instance: targetData,
+ width: 0, height: 0,
+ left: 0, top: 0
+ });
+ };
+ };
+
+ },
+
+ refreshPositions: function(fast) {
+
+ //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
+ if(this.offsetParent && this.helper) {
+ this.offset.parent = this._getParentOffset();
+ }
+
+ for (var i = this.items.length - 1; i >= 0; i--){
+ var item = this.items[i];
+
+ //We ignore calculating positions of all connected containers when we're not over them
+ if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
+ continue;
+
+ var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
+
+ if (!fast) {
+ item.width = t.outerWidth();
+ item.height = t.outerHeight();
+ }
+
+ var p = t.offset();
+ item.left = p.left;
+ item.top = p.top;
+ };
+
+ if(this.options.custom && this.options.custom.refreshContainers) {
+ this.options.custom.refreshContainers.call(this);
+ } else {
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ var p = this.containers[i].element.offset();
+ this.containers[i].containerCache.left = p.left;
+ this.containers[i].containerCache.top = p.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(that) {
+
+ var self = that || this, o = self.options;
+
+ if(!o.placeholder || o.placeholder.constructor == String) {
+ var className = o.placeholder;
+ o.placeholder = {
+ element: function() {
+
+ var el = $(document.createElement(self.currentItem[0].nodeName))
+ .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
+ .removeClass("ui-sortable-helper")[0];
+
+ if(!className)
+ el.style.visibility = "hidden";
+
+ return el;
+ },
+ update: function(container, p) {
+
+ // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
+ // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
+ if(className && !o.forcePlaceholderSize) return;
+
+ //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
+ if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
+ if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
+ }
+ };
+ }
+
+ //Create the placeholder
+ self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
+
+ //Append it after the actual current item
+ self.currentItem.after(self.placeholder);
+
+ //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
+ o.placeholder.update(self, self.placeholder);
+
+ },
+
+ _contactContainers: function(event) {
+
+ // get innermost container that intersects with item
+ var innermostContainer = null, innermostIndex = null;
+
+
+ for (var i = this.containers.length - 1; i >= 0; i--){
+
+ // never consider a container that's located within the item itself
+ if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
+ continue;
+
+ if(this._intersectsWith(this.containers[i].containerCache)) {
+
+ // if we've already found a container and it's more "inner" than this, then continue
+ if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
+ continue;
+
+ innermostContainer = this.containers[i];
+ innermostIndex = i;
+
+ } else {
+ // container doesn't intersect. trigger "out" event if necessary
+ if(this.containers[i].containerCache.over) {
+ this.containers[i]._trigger("out", event, this._uiHash(this));
+ this.containers[i].containerCache.over = 0;
+ }
+ }
+
+ }
+
+ // if no intersecting containers found, return
+ if(!innermostContainer) return;
+
+ // move the item into the container if it's not there already
+ if(this.containers.length === 1) {
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+ this.containers[innermostIndex].containerCache.over = 1;
+ } else if(this.currentContainer != this.containers[innermostIndex]) {
+
+ //When entering a new container, we will find the item with the least distance and append our item near it
+ var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
+ for (var j = this.items.length - 1; j >= 0; j--) {
+ if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
+ var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top'];
+ if(Math.abs(cur - base) < dist) {
+ dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
+ }
+ }
+
+ if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
+ return;
+
+ this.currentContainer = this.containers[innermostIndex];
+ itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
+ this._trigger("change", event, this._uiHash());
+ this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
+
+ //Update the placeholder
+ this.options.placeholder.update(this.currentContainer, this.placeholder);
+
+ this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
+ this.containers[innermostIndex].containerCache.over = 1;
+ }
+
+
+ },
+
+ _createHelper: function(event) {
+
+ var o = this.options;
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
+
+ if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
+ $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
+
+ if(helper[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") };
+
+ if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
+ if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
+
+ return helper;
+
+ },
+
+ _adjustOffsetFromHelper: function(obj) {
+ if (typeof obj == 'string') {
+ obj = obj.split(' ');
+ }
+ if ($.isArray(obj)) {
+ obj = {left: +obj[0], top: +obj[1] || 0};
+ }
+ if ('left' in obj) {
+ this.offset.click.left = obj.left + this.margins.left;
+ }
+ if ('right' in obj) {
+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+ }
+ if ('top' in obj) {
+ this.offset.click.top = obj.top + this.margins.top;
+ }
+ if ('bottom' in obj) {
+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+ }
+ },
+
+ _getParentOffset: function() {
+
+
+ //Get the offsetParent and cache its position
+ this.offsetParent = this.helper.offsetParent();
+ var po = this.offsetParent.offset();
+
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
+ po.left += this.scrollParent.scrollLeft();
+ po.top += this.scrollParent.scrollTop();
+ }
+
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
+ po = { top: 0, left: 0 };
+
+ return {
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+ };
+
+ },
+
+ _getRelativeOffset: function() {
+
+ if(this.cssPosition == "relative") {
+ var p = this.currentItem.position();
+ return {
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+ };
+ } else {
+ 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 o = this.options;
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
+ 0 - this.offset.relative.left - this.offset.parent.left,
+ 0 - this.offset.relative.top - this.offset.parent.top,
+ $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
+ ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+ ];
+
+ if(!(/^(document|window|parent)$/).test(o.containment)) {
+ var ce = $(o.containment)[0];
+ var co = $(o.containment).offset();
+ var over = ($(ce).css("overflow") != 'hidden');
+
+ this.containment = [
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
+ co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
+ co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
+ ];
+ }
+
+ },
+
+ _convertPositionTo: function(d, pos) {
+
+ if(!pos) pos = this.position;
+ var mod = d == "absolute" ? 1 : -1;
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ return {
+ top: (
+ pos.top // The absolute mouse position
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+ ),
+ left: (
+ pos.left // The absolute mouse position
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+ )
+ };
+
+ },
+
+ _generatePosition: function(event) {
+
+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
+
+ // This is another very weird special case that only happens for relative elements:
+ // 1. If the css position is relative
+ // 2. and the scroll parent is the document or similar to the offset parent
+ // we have to refresh the relative offset during the scroll so there are no jumps
+ if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
+ this.offset.relative = this._getRelativeOffset();
+ }
+
+ var pageX = event.pageX;
+ var pageY = event.pageY;
+
+ /*
+ * - Position constraining -
+ * Constrain the position to a mix of grid, containment.
+ */
+
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+ if(this.containment) {
+ if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
+ if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
+ }
+
+ if(o.grid) {
+ var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+ pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
+
+ var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+ pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
+ }
+
+ }
+
+ return {
+ top: (
+ pageY // The absolute mouse position
+ - this.offset.click.top // Click offset (relative to the element)
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+ ),
+ left: (
+ pageX // The absolute mouse position
+ - this.offset.click.left // Click offset (relative to the element)
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+ )
+ };
+
+ },
+
+ _rearrange: function(event, i, a, hardRefresh) {
+
+ a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
+
+ //Various things done here to improve the performance:
+ // 1. we create a setTimeout, that calls refreshPositions
+ // 2. on the instance, we have a counter variable, that get's higher after every append
+ // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
+ // 4. this lets only the last addition to the timeout stack through
+ this.counter = this.counter ? ++this.counter : 1;
+ var self = this, counter = this.counter;
+
+ window.setTimeout(function() {
+ if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
+ },0);
+
+ },
+
+ _clear: function(event, noPropagation) {
+
+ this.reverting = false;
+ // We delay all events that have to be triggered to after the point where the placeholder has been removed and
+ // everything else normalized again
+ var delayedTriggers = [], self = this;
+
+ // We first have to update the dom position of the actual currentItem
+ // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
+ if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
+ this._noFinalSort = null;
+
+ if(this.helper[0] == this.currentItem[0]) {
+ for(var i in this._storedCSS) {
+ if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
+ }
+ this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
+ } else {
+ this.currentItem.show();
+ }
+
+ if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
+ if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
+ if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
+ if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ }
+ };
+ };
+
+ //Post events to containers
+ for (var i = this.containers.length - 1; i >= 0; i--){
+ if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ if(this.containers[i].containerCache.over) {
+ delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
+ this.containers[i].containerCache.over = 0;
+ }
+ }
+
+ //Do what was originally in plugins
+ if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
+ if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
+ if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
+
+ this.dragging = false;
+ if(this.cancelHelperRemoval) {
+ if(!noPropagation) {
+ this._trigger("beforeStop", event, this._uiHash());
+ for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+ this._trigger("stop", event, this._uiHash());
+ }
+ return false;
+ }
+
+ if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
+
+ //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
+ this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
+
+ if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
+
+ if(!noPropagation) {
+ for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
+ this._trigger("stop", event, this._uiHash());
+ }
+
+ this.fromOutside = false;
+ return true;
+
+ },
+
+ _trigger: function() {
+ if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
+ this.cancel();
+ }
+ },
+
+ _uiHash: function(inst) {
+ var self = inst || this;
+ return {
+ helper: self.helper,
+ placeholder: self.placeholder || $([]),
+ position: self.position,
+ originalPosition: self.originalPosition,
+ offset: self.positionAbs,
+ item: self.currentItem,
+ sender: inst ? inst.element : null
+ };
+ }
+
+});
+
+$.extend($.ui.sortable, {
+ version: "1.8.16"
+});
+
+})(jQuery);
+/*
+ * jQuery UI Effects 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/
+ */
+;jQuery.effects || (function($, undefined) {
+
+$.effects = {};
+
+
+
+/******************************************************************************/
+/****************************** COLOR ANIMATIONS ******************************/
+/******************************************************************************/
+
+// override the animation for color styles
+$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
+ 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
+function(i, attr) {
+ $.fx.step[attr] = function(fx) {
+ if (!fx.colorInit) {
+ fx.start = getColor(fx.elem, attr);
+ fx.end = getRGB(fx.end);
+ fx.colorInit = true;
+ }
+
+ fx.elem.style[attr] = 'rgb(' +
+ Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
+ Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
+ Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
+ };
+});
+
+// Color Conversion functions from highlightFade
+// By Blair Mitchelmore
+// http://jquery.offput.ca/highlightFade/
+
+// Parse strings looking for color tuples [255,255,255]
+function getRGB(color) {
+ var result;
+
+ // Check if we're already dealing with an array of colors
+ if ( color && color.constructor == Array && color.length == 3 )
+ return color;
+
+ // Look for rgb(num,num,num)
+ if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
+ return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
+
+ // Look for rgb(num%,num%,num%)
+ if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
+ return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
+
+ // Look for #a0b1c2
+ if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
+ return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
+
+ // Look for #fff
+ if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
+ return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
+
+ // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
+ if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
+ return colors['transparent'];
+
+ // Otherwise, we're most likely dealing with a named color
+ return colors[$.trim(color).toLowerCase()];
+}
+
+function getColor(elem, attr) {
+ var color;
+
+ do {
+ color = $.curCSS(elem, attr);
+
+ // Keep going until we find an element that has color, or we hit the body
+ if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
+ break;
+
+ attr = "backgroundColor";
+ } while ( elem = elem.parentNode );
+
+ return getRGB(color);
+};
+
+// Some named colors to work with
+// From Interface by Stefan Petre
+// http://interface.eyecon.ro/
+
+var colors = {
+ aqua:[0,255,255],
+ azure:[240,255,255],
+ beige:[245,245,220],
+ black:[0,0,0],
+ blue:[0,0,255],
+ brown:[165,42,42],
+ cyan:[0,255,255],
+ darkblue:[0,0,139],
+ darkcyan:[0,139,139],
+ darkgrey:[169,169,169],
+ darkgreen:[0,100,0],
+ 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],
+ darkviolet:[148,0,211],
+ fuchsia:[255,0,255],
+ gold:[255,215,0],
+ green:[0,128,0],
+ indigo:[75,0,130],
+ khaki:[240,230,140],
+ lightblue:[173,216,230],
+ lightcyan:[224,255,255],
+ lightgreen:[144,238,144],
+ lightgrey:[211,211,211],
+ lightpink:[255,182,193],
+ lightyellow:[255,255,224],
+ lime:[0,255,0],
+ magenta:[255,0,255],
+ maroon:[128,0,0],
+ navy:[0,0,128],
+ olive:[128,128,0],
+ orange:[255,165,0],
+ pink:[255,192,203],
+ purple:[128,0,128],
+ violet:[128,0,128],
+ red:[255,0,0],
+ silver:[192,192,192],
+ white:[255,255,255],
+ yellow:[255,255,0],
+ transparent: [255,255,255]
+};
+
+
+
+/******************************************************************************/
+/****************************** CLASS ANIMATIONS ******************************/
+/******************************************************************************/
+
+var classAnimationActions = ['add', 'remove', 'toggle'],
+ shorthandStyles = {
+ border: 1,
+ borderBottom: 1,
+ borderColor: 1,
+ borderLeft: 1,
+ borderRight: 1,
+ borderTop: 1,
+ borderWidth: 1,
+ margin: 1,
+ padding: 1
+ };
+
+function getElementStyles() {
+ var style = document.defaultView
+ ? document.defaultView.getComputedStyle(this, null)
+ : this.currentStyle,
+ newStyle = {},
+ key,
+ camelCase;
+
+ // webkit enumerates style porperties
+ if (style && style.length && style[0] && style[style[0]]) {
+ var len = style.length;
+ while (len--) {
+ key = style[len];
+ if (typeof style[key] == 'string') {
+ camelCase = key.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+ newStyle[camelCase] = style[key];
+ }
+ }
+ } else {
+ for (key in style) {
+ if (typeof style[key] === 'string') {
+ newStyle[key] = style[key];
+ }
+ }
+ }
+
+ return newStyle;
+}
+
+function filterStyles(styles) {
+ var name, value;
+ for (name in styles) {
+ value = styles[name];
+ if (
+ // ignore null and undefined values
+ value == null ||
+ // ignore functions (when does this occur?)
+ $.isFunction(value) ||
+ // shorthand styles that need to be expanded
+ name in shorthandStyles ||
+ // ignore scrollbars (break in IE)
+ (/scrollbar/).test(name) ||
+
+ // only colors or values that can be converted to numbers
+ (!(/color/i).test(name) && isNaN(parseFloat(value)))
+ ) {
+ delete styles[name];
+ }
+ }
+
+ return styles;
+}
+
+function styleDifference(oldStyle, newStyle) {
+ var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
+ name;
+
+ for (name in newStyle) {
+ if (oldStyle[name] != newStyle[name]) {
+ diff[name] = newStyle[name];
+ }
+ }
+
+ return diff;
+}
+
+$.effects.animateClass = function(value, duration, easing, callback) {
+ if ($.isFunction(easing)) {
+ callback = easing;
+ easing = null;
+ }
+
+ return this.queue(function() {
+ var that = $(this),
+ originalStyleAttr = that.attr('style') || ' ',
+ originalStyle = filterStyles(getElementStyles.call(this)),
+ newStyle,
+ className = that.attr('class');
+
+ $.each(classAnimationActions, function(i, action) {
+ if (value[action]) {
+ that[action + 'Class'](value[action]);
+ }
+ });
+ newStyle = filterStyles(getElementStyles.call(this));
+ that.attr('class', className);
+
+ that.animate(styleDifference(originalStyle, newStyle), {
+ queue: false,
+ duration: duration,
+ easing: easing,
+ complete: function() {
+ $.each(classAnimationActions, function(i, action) {
+ if (value[action]) { that[action + 'Class'](value[action]); }
+ });
+ // work around bug in IE by clearing the cssText before setting it
+ if (typeof that.attr('style') == 'object') {
+ that.attr('style').cssText = '';
+ that.attr('style').cssText = originalStyleAttr;
+ } else {
+ that.attr('style', originalStyleAttr);
+ }
+ if (callback) { callback.apply(this, arguments); }
+ $.dequeue( this );
+ }
+ });
+ });
+};
+
+$.fn.extend({
+ _addClass: $.fn.addClass,
+ addClass: function(classNames, speed, easing, callback) {
+ return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
+ },
+
+ _removeClass: $.fn.removeClass,
+ removeClass: function(classNames,speed,easing,callback) {
+ return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
+ },
+
+ _toggleClass: $.fn.toggleClass,
+ toggleClass: function(classNames, force, speed, easing, callback) {
+ if ( typeof force == "boolean" || force === undefined ) {
+ if ( !speed ) {
+ // without speed parameter;
+ return this._toggleClass(classNames, force);
+ } else {
+ return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
+ }
+ } else {
+ // without switch parameter;
+ return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
+ }
+ },
+
+ switchClass: function(remove,add,speed,easing,callback) {
+ return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
+ }
+});
+
+
+
+/******************************************************************************/
+/*********************************** EFFECTS **********************************/
+/******************************************************************************/
+
+$.extend($.effects, {
+ version: "1.8.16",
+
+ // Saves a set of properties in a data storage
+ save: function(element, set) {
+ for(var i=0; i < set.length; i++) {
+ if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
+ }
+ },
+
+ // Restores a set of previously saved properties from a data storage
+ restore: function(element, set) {
+ for(var i=0; i < set.length; i++) {
+ if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
+ }
+ },
+
+ setMode: function(el, mode) {
+ if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
+ return mode;
+ },
+
+ getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
+ // this should be a little more flexible in the future to handle a string & hash
+ var y, x;
+ switch (origin[0]) {
+ case 'top': y = 0; break;
+ case 'middle': y = 0.5; break;
+ case 'bottom': y = 1; break;
+ default: y = origin[0] / original.height;
+ };
+ switch (origin[1]) {
+ case 'left': x = 0; break;
+ case 'center': x = 0.5; break;
+ case 'right': x = 1; break;
+ default: x = origin[1] / original.width;
+ };
+ return {x: x, y: y};
+ },
+
+ // Wraps the element around a wrapper that copies position properties
+ createWrapper: function(element) {
+
+ // if the element is already wrapped, return it
+ if (element.parent().is('.ui-effects-wrapper')) {
+ return element.parent();
+ }
+
+ // wrap the element
+ var props = {
+ width: element.outerWidth(true),
+ height: element.outerHeight(true),
+ 'float': element.css('float')
+ },
+ wrapper = $('<div></div>')
+ .addClass('ui-effects-wrapper')
+ .css({
+ fontSize: '100%',
+ background: 'transparent',
+ border: 'none',
+ margin: 0,
+ padding: 0
+ }),
+ active = document.activeElement;
+
+ element.wrap(wrapper);
+
+ // Fixes #7595 - Elements lose focus when wrapped.
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+ $( active ).focus();
+ }
+
+ wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
+
+ // transfer positioning properties to the wrapper
+ if (element.css('position') == 'static') {
+ wrapper.css({ position: 'relative' });
+ element.css({ position: 'relative' });
+ } else {
+ $.extend(props, {
+ position: element.css('position'),
+ zIndex: element.css('z-index')
+ });
+ $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
+ props[pos] = element.css(pos);
+ if (isNaN(parseInt(props[pos], 10))) {
+ props[pos] = 'auto';
+ }
+ });
+ element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
+ }
+
+ return wrapper.css(props).show();
+ },
+
+ removeWrapper: function(element) {
+ var parent,
+ active = document.activeElement;
+
+ if (element.parent().is('.ui-effects-wrapper')) {
+ parent = element.parent().replaceWith(element);
+ // Fixes #7595 - Elements lose focus when wrapped.
+ if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
+ $( active ).focus();
+ }
+ return parent;
+ }
+
+ return element;
+ },
+
+ setTransition: function(element, list, factor, value) {
+ value = value || {};
+ $.each(list, function(i, x){
+ unit = element.cssUnit(x);
+ if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
+ });
+ return value;
+ }
+});
+
+
+function _normalizeArguments(effect, options, speed, callback) {
+ // shift params for method overloading
+ if (typeof effect == 'object') {
+ callback = options;
+ speed = null;
+ options = effect;
+ effect = options.effect;
+ }
+ if ($.isFunction(options)) {
+ callback = options;
+ speed = null;
+ options = {};
+ }
+ if (typeof options == 'number' || $.fx.speeds[options]) {
+ callback = speed;
+ speed = options;
+ options = {};
+ }
+ if ($.isFunction(speed)) {
+ callback = speed;
+ speed = null;
+ }
+
+ options = options || {};
+
+ speed = speed || options.duration;
+ speed = $.fx.off ? 0 : typeof speed == 'number'
+ ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
+
+ callback = callback || options.complete;
+
+ return [effect, options, speed, callback];
+}
+
+function standardSpeed( speed ) {
+ // valid standard speeds
+ if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
+ return true;
+ }
+
+ // invalid strings - treat as "normal" speed
+ if ( typeof speed === "string" && !$.effects[ speed ] ) {
+ return true;
+ }
+
+ return false;
+}
+
+$.fn.extend({
+ effect: function(effect, options, speed, callback) {
+ var args = _normalizeArguments.apply(this, arguments),
+ // TODO: make effects take actual parameters instead of a hash
+ args2 = {
+ options: args[1],
+ duration: args[2],
+ callback: args[3]
+ },
+ mode = args2.options.mode,
+ effectMethod = $.effects[effect];
+
+ if ( $.fx.off || !effectMethod ) {
+ // delegate to the original method (e.g., .show()) if possible
+ if ( mode ) {
+ return this[ mode ]( args2.duration, args2.callback );
+ } else {
+ return this.each(function() {
+ if ( args2.callback ) {
+ args2.callback.call( this );
+ }
+ });
+ }
+ }
+
+ return effectMethod.call(this, args2);
+ },
+
+ _show: $.fn.show,
+ show: function(speed) {
+ if ( standardSpeed( speed ) ) {
+ return this._show.apply(this, arguments);
+ } else {
+ var args = _normalizeArguments.apply(this, arguments);
+ args[1].mode = 'show';
+ return this.effect.apply(this, args);
+ }
+ },
+
+ _hide: $.fn.hide,
+ hide: function(speed) {
+ if ( standardSpeed( speed ) ) {
+ return this._hide.apply(this, arguments);
+ } else {
+ var args = _normalizeArguments.apply(this, arguments);
+ args[1].mode = 'hide';
+ return this.effect.apply(this, args);
+ }
+ },
+
+ // jQuery core overloads toggle and creates _toggle
+ __toggle: $.fn.toggle,
+ toggle: function(speed) {
+ if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
+ return this.__toggle.apply(this, arguments);
+ } else {
+ var args = _normalizeArguments.apply(this, arguments);
+ args[1].mode = 'toggle';
+ return this.effect.apply(this, args);
+ }
+ },
+
+ // helper functions
+ cssUnit: function(key) {
+ var style = this.css(key), val = [];
+ $.each( ['em','px','%','pt'], function(i, unit){
+ if(style.indexOf(unit) > 0)
+ val = [parseFloat(style), unit];
+ });
+ return val;
+ }
+});
+
+
+
+/******************************************************************************/
+/*********************************** EASING ***********************************/
+/******************************************************************************/
+
+/*
+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
+ *
+ * Uses the built in easing capabilities added In jQuery 1.1
+ * to offer multiple easing options
+ *
+ * TERMS OF USE - jQuery Easing
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2008 George McGinley Smith
+ * 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 author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+*/
+
+// t: current time, b: begInnIng value, c: change In value, d: duration
+$.easing.jswing = $.easing.swing;
+
+$.extend($.easing,
+{
+ def: 'easeOutQuad',
+ swing: function (x, t, b, c, d) {
+ //alert($.easing.default);
+ return $.easing[$.easing.def](x, t, b, c, d);
+ },
+ easeInQuad: function (x, t, b, c, d) {
+ return c*(t/=d)*t + b;
+ },
+ easeOutQuad: function (x, t, b, c, d) {
+ return -c *(t/=d)*(t-2) + b;
+ },
+ easeInOutQuad: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t + b;
+ return -c/2 * ((--t)*(t-2) - 1) + b;
+ },
+ easeInCubic: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t + b;
+ },
+ easeOutCubic: function (x, t, b, c, d) {
+ return c*((t=t/d-1)*t*t + 1) + b;
+ },
+ easeInOutCubic: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t + b;
+ return c/2*((t-=2)*t*t + 2) + b;
+ },
+ easeInQuart: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t*t + b;
+ },
+ easeOutQuart: function (x, t, b, c, d) {
+ return -c * ((t=t/d-1)*t*t*t - 1) + b;
+ },
+ easeInOutQuart: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
+ return -c/2 * ((t-=2)*t*t*t - 2) + b;
+ },
+ easeInQuint: function (x, t, b, c, d) {
+ return c*(t/=d)*t*t*t*t + b;
+ },
+ easeOutQuint: function (x, t, b, c, d) {
+ return c*((t=t/d-1)*t*t*t*t + 1) + b;
+ },
+ easeInOutQuint: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
+ return c/2*((t-=2)*t*t*t*t + 2) + b;
+ },
+ easeInSine: function (x, t, b, c, d) {
+ return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
+ },
+ easeOutSine: function (x, t, b, c, d) {
+ return c * Math.sin(t/d * (Math.PI/2)) + b;
+ },
+ easeInOutSine: function (x, t, b, c, d) {
+ return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
+ },
+ easeInExpo: function (x, t, b, c, d) {
+ return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
+ },
+ easeOutExpo: function (x, t, b, c, d) {
+ return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
+ },
+ easeInOutExpo: function (x, t, b, c, d) {
+ if (t==0) return b;
+ if (t==d) return b+c;
+ if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
+ return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
+ },
+ easeInCirc: function (x, t, b, c, d) {
+ return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
+ },
+ easeOutCirc: function (x, t, b, c, d) {
+ return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
+ },
+ easeInOutCirc: function (x, t, b, c, d) {
+ if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
+ return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
+ },
+ easeInElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+ },
+ easeOutElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
+ },
+ easeInOutElastic: function (x, t, b, c, d) {
+ var s=1.70158;var p=0;var a=c;
+ if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
+ if (a < Math.abs(c)) { a=c; var s=p/4; }
+ else var s = p/(2*Math.PI) * Math.asin (c/a);
+ if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
+ return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
+ },
+ easeInBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c*(t/=d)*t*((s+1)*t - s) + b;
+ },
+ easeOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
+ },
+ easeInOutBack: function (x, t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
+ return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
+ },
+ easeInBounce: function (x, t, b, c, d) {
+ return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
+ },
+ easeOutBounce: function (x, t, b, c, d) {
+ if ((t/=d) < (1/2.75)) {
+ return c*(7.5625*t*t) + b;
+ } else if (t < (2/2.75)) {
+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
+ } else if (t < (2.5/2.75)) {
+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
+ } else {
+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
+ }
+ },
+ easeInOutBounce: function (x, t, b, c, d) {
+ if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
+ return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
+ }
+});
+
+/*
+ *
+ * TERMS OF USE - EASING EQUATIONS
+ *
+ * Open source under the BSD License.
+ *
+ * Copyright 2001 Robert Penner
+ * 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 author nor the names of contributors may be used to endorse
+ * or promote products derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+})(jQuery);
+/*
+ * jQuery UI Effects Blind 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Blind
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.blind = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var direction = o.options.direction || 'vertical'; // Default direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var ref = (direction == 'vertical') ? 'height' : 'width';
+ var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
+ if(mode == 'show') wrapper.css(ref, 0); // Shift
+
+ // Animation
+ var animation = {};
+ animation[ref] = mode == 'show' ? distance : 0;
+
+ // Animate
+ wrapper.animate(animation, o.duration, o.options.easing, function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ });
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Bounce 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Bounce
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.bounce = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var direction = o.options.direction || 'up'; // Default direction
+ var distance = o.options.distance || 20; // Default distance
+ var times = o.options.times || 5; // Default # of times
+ var speed = o.duration || 250; // Default speed per bounce
+ if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+ var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
+ if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
+ if (mode == 'hide') distance = distance / (times * 2);
+ if (mode != 'hide') times--;
+
+ // Animate
+ if (mode == 'show') { // Show Bounce
+ var animation = {opacity: 1};
+ animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+ el.animate(animation, speed / 2, o.options.easing);
+ distance = distance / 2;
+ times--;
+ };
+ for (var i = 0; i < times; i++) { // Bounces
+ var animation1 = {}, animation2 = {};
+ animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+ el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
+ distance = (mode == 'hide') ? distance * 2 : distance / 2;
+ };
+ if (mode == 'hide') { // Last Bounce
+ var animation = {opacity: 0};
+ animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ el.animate(animation, speed / 2, o.options.easing, function(){
+ el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ } else {
+ var animation1 = {}, animation2 = {};
+ animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
+ el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ };
+ el.queue('fx', function() { el.dequeue(); });
+ el.dequeue();
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Clip 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Clip
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.clip = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right','height','width'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var direction = o.options.direction || 'vertical'; // Default direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var animate = el[0].tagName == 'IMG' ? wrapper : el;
+ var ref = {
+ size: (direction == 'vertical') ? 'height' : 'width',
+ position: (direction == 'vertical') ? 'top' : 'left'
+ };
+ var distance = (direction == 'vertical') ? animate.height() : animate.width();
+ if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
+
+ // Animation
+ var animation = {};
+ animation[ref.size] = mode == 'show' ? distance : 0;
+ animation[ref.position] = mode == 'show' ? 0 : distance / 2;
+
+ // Animate
+ animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Drop 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Drop
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.drop = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right','opacity'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var direction = o.options.direction || 'left'; // Default Direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+ var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
+ if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
+
+ // Animation
+ var animation = {opacity: mode == 'show' ? 1 : 0};
+ animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
+
+ // Animate
+ el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Explode 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Explode
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.explode = function(o) {
+
+ return this.queue(function() {
+
+ var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
+ var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
+
+ o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
+ var el = $(this).show().css('visibility', 'hidden');
+ var offset = el.offset();
+
+ //Substract the margins - not fixing the problem yet.
+ offset.top -= parseInt(el.css("marginTop"),10) || 0;
+ offset.left -= parseInt(el.css("marginLeft"),10) || 0;
+
+ var width = el.outerWidth(true);
+ var height = el.outerHeight(true);
+
+ for(var i=0;i<rows;i++) { // =
+ for(var j=0;j<cells;j++) { // ||
+ el
+ .clone()
+ .appendTo('body')
+ .wrap('<div></div>')
+ .css({
+ position: 'absolute',
+ visibility: 'visible',
+ left: -j*(width/cells),
+ top: -i*(height/rows)
+ })
+ .parent()
+ .addClass('ui-effects-explode')
+ .css({
+ position: 'absolute',
+ overflow: 'hidden',
+ width: width/cells,
+ height: height/rows,
+ left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
+ top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
+ opacity: o.options.mode == 'show' ? 0 : 1
+ }).animate({
+ left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
+ top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
+ opacity: o.options.mode == 'show' ? 1 : 0
+ }, o.duration || 500);
+ }
+ }
+
+ // Set a timeout, to call the callback approx. when the other animations have finished
+ setTimeout(function() {
+
+ o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
+ if(o.callback) o.callback.apply(el[0]); // Callback
+ el.dequeue();
+
+ $('div.ui-effects-explode').remove();
+
+ }, o.duration || 500);
+
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Fade 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Fade
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.fade = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ mode = $.effects.setMode(elem, o.options.mode || 'hide');
+
+ elem.animate({ opacity: mode }, {
+ queue: false,
+ duration: o.duration,
+ easing: o.options.easing,
+ complete: function() {
+ (o.callback && o.callback.apply(this, arguments));
+ elem.dequeue();
+ }
+ });
+ });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Fold 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Fold
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.fold = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
+ var size = o.options.size || 15; // Default fold size
+ var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
+ var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var widthFirst = ((mode == 'show') != horizFirst);
+ var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
+ var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
+ var percent = /([0-9]+)%/.exec(size);
+ if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
+ if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
+
+ // Animation
+ var animation1 = {}, animation2 = {};
+ animation1[ref[0]] = mode == 'show' ? distance[0] : size;
+ animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
+
+ // Animate
+ wrapper.animate(animation1, duration, o.options.easing)
+ .animate(animation2, duration, o.options.easing, function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(el[0], arguments); // Callback
+ el.dequeue();
+ });
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Highlight 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Highlight
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.highlight = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ props = ['backgroundImage', 'backgroundColor', 'opacity'],
+ mode = $.effects.setMode(elem, o.options.mode || 'show'),
+ animation = {
+ backgroundColor: elem.css('backgroundColor')
+ };
+
+ if (mode == 'hide') {
+ animation.opacity = 0;
+ }
+
+ $.effects.save(elem, props);
+ elem
+ .show()
+ .css({
+ backgroundImage: 'none',
+ backgroundColor: o.options.color || '#ffff99'
+ })
+ .animate(animation, {
+ queue: false,
+ duration: o.duration,
+ easing: o.options.easing,
+ complete: function() {
+ (mode == 'hide' && elem.hide());
+ $.effects.restore(elem, props);
+ (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
+ (o.callback && o.callback.apply(this, arguments));
+ elem.dequeue();
+ }
+ });
+ });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Pulsate 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Pulsate
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.pulsate = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ mode = $.effects.setMode(elem, o.options.mode || 'show');
+ times = ((o.options.times || 5) * 2) - 1;
+ duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
+ isVisible = elem.is(':visible'),
+ animateTo = 0;
+
+ if (!isVisible) {
+ elem.css('opacity', 0).show();
+ animateTo = 1;
+ }
+
+ if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
+ times--;
+ }
+
+ for (var i = 0; i < times; i++) {
+ elem.animate({ opacity: animateTo }, duration, o.options.easing);
+ animateTo = (animateTo + 1) % 2;
+ }
+
+ elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
+ if (animateTo == 0) {
+ elem.hide();
+ }
+ (o.callback && o.callback.apply(this, arguments));
+ });
+
+ elem
+ .queue('fx', function() { elem.dequeue(); })
+ .dequeue();
+ });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Scale 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Scale
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.puff = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ mode = $.effects.setMode(elem, o.options.mode || 'hide'),
+ percent = parseInt(o.options.percent, 10) || 150,
+ factor = percent / 100,
+ original = { height: elem.height(), width: elem.width() };
+
+ $.extend(o.options, {
+ fade: true,
+ mode: mode,
+ percent: mode == 'hide' ? percent : 100,
+ from: mode == 'hide'
+ ? original
+ : {
+ height: original.height * factor,
+ width: original.width * factor
+ }
+ });
+
+ elem.effect('scale', o.options, o.duration, o.callback);
+ elem.dequeue();
+ });
+};
+
+$.effects.scale = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this);
+
+ // Set options
+ var options = $.extend(true, {}, o.options);
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
+ var direction = o.options.direction || 'both'; // Set default axis
+ var origin = o.options.origin; // The origin of the scaling
+ if (mode != 'effect') { // Set default origin and restore for show/hide
+ options.origin = origin || ['middle','center'];
+ options.restore = true;
+ }
+ var original = {height: el.height(), width: el.width()}; // Save original
+ el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
+
+ // Adjust
+ var factor = { // Set scaling factor
+ y: direction != 'horizontal' ? (percent / 100) : 1,
+ x: direction != 'vertical' ? (percent / 100) : 1
+ };
+ el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
+
+ if (o.options.fade) { // Fade option to support puff
+ if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
+ if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
+ };
+
+ // Animation
+ options.from = el.from; options.to = el.to; options.mode = mode;
+
+ // Animate
+ el.effect('size', options, o.duration, o.callback);
+ el.dequeue();
+ });
+
+};
+
+$.effects.size = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
+ var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
+ var props2 = ['width','height','overflow']; // Copy for children
+ var cProps = ['fontSize'];
+ var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
+ var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var restore = o.options.restore || false; // Default restore
+ var scale = o.options.scale || 'both'; // Default scale mode
+ var origin = o.options.origin; // The origin of the sizing
+ var original = {height: el.height(), width: el.width()}; // Save original
+ el.from = o.options.from || original; // Default from state
+ el.to = o.options.to || original; // Default to state
+ // Adjust
+ if (origin) { // Calculate baseline shifts
+ var baseline = $.effects.getBaseline(origin, original);
+ el.from.top = (original.height - el.from.height) * baseline.y;
+ el.from.left = (original.width - el.from.width) * baseline.x;
+ el.to.top = (original.height - el.to.height) * baseline.y;
+ el.to.left = (original.width - el.to.width) * baseline.x;
+ };
+ var factor = { // Set scaling factor
+ from: {y: el.from.height / original.height, x: el.from.width / original.width},
+ to: {y: el.to.height / original.height, x: el.to.width / original.width}
+ };
+ if (scale == 'box' || scale == 'both') { // Scale the css box
+ if (factor.from.y != factor.to.y) { // Vertical props scaling
+ props = props.concat(vProps);
+ el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
+ el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
+ };
+ if (factor.from.x != factor.to.x) { // Horizontal props scaling
+ props = props.concat(hProps);
+ el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
+ el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
+ };
+ };
+ if (scale == 'content' || scale == 'both') { // Scale the content
+ if (factor.from.y != factor.to.y) { // Vertical props scaling
+ props = props.concat(cProps);
+ el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
+ el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
+ };
+ };
+ $.effects.save(el, restore ? props : props1); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ el.css('overflow','hidden').css(el.from); // Shift
+
+ // Animate
+ if (scale == 'content' || scale == 'both') { // Scale the children
+ vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
+ hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
+ props2 = props.concat(vProps).concat(hProps); // Concat
+ el.find("*[width]").each(function(){
+ child = $(this);
+ if (restore) $.effects.save(child, props2);
+ var c_original = {height: child.height(), width: child.width()}; // Save original
+ child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
+ child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
+ if (factor.from.y != factor.to.y) { // Vertical props scaling
+ child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
+ child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
+ };
+ if (factor.from.x != factor.to.x) { // Horizontal props scaling
+ child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
+ child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
+ };
+ child.css(child.from); // Shift children
+ child.animate(child.to, o.duration, o.options.easing, function(){
+ if (restore) $.effects.restore(child, props2); // Restore children
+ }); // Animate children
+ });
+ };
+
+ // Animate
+ el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if (el.to.opacity === 0) {
+ el.css('opacity', el.from.opacity);
+ }
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Shake 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Shake
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.shake = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
+ var direction = o.options.direction || 'left'; // Default direction
+ var distance = o.options.distance || 20; // Default distance
+ var times = o.options.times || 3; // Default # of times
+ var speed = o.duration || o.options.duration || 140; // Default speed per shake
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+
+ // Animation
+ var animation = {}, animation1 = {}, animation2 = {};
+ animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
+ animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
+ animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
+
+ // Animate
+ el.animate(animation, speed, o.options.easing);
+ for (var i = 1; i < times; i++) { // Shakes
+ el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
+ };
+ el.animate(animation1, speed, o.options.easing).
+ animate(animation, speed / 2, o.options.easing, function(){ // Last shake
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ });
+ el.queue('fx', function() { el.dequeue(); });
+ el.dequeue();
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Slide 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Slide
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.slide = function(o) {
+
+ return this.queue(function() {
+
+ // Create element
+ var el = $(this), props = ['position','top','bottom','left','right'];
+
+ // Set options
+ var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
+ var direction = o.options.direction || 'left'; // Default Direction
+
+ // Adjust
+ $.effects.save(el, props); el.show(); // Save & Show
+ $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
+ var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
+ var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
+ var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
+ if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
+
+ // Animation
+ var animation = {};
+ animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
+
+ // Animate
+ el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
+ if(mode == 'hide') el.hide(); // Hide
+ $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
+ if(o.callback) o.callback.apply(this, arguments); // Callback
+ el.dequeue();
+ }});
+
+ });
+
+};
+
+})(jQuery);
+/*
+ * jQuery UI Effects Transfer 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Effects/Transfer
+ *
+ * Depends:
+ * jquery.effects.core.js
+ */
+(function( $, undefined ) {
+
+$.effects.transfer = function(o) {
+ return this.queue(function() {
+ var elem = $(this),
+ target = $(o.options.to),
+ endPosition = target.offset(),
+ animation = {
+ top: endPosition.top,
+ left: endPosition.left,
+ height: target.innerHeight(),
+ width: target.innerWidth()
+ },
+ startPosition = elem.offset(),
+ transfer = $('<div class="ui-effects-transfer"></div>')
+ .appendTo(document.body)
+ .addClass(o.options.className)
+ .css({
+ top: startPosition.top,
+ left: startPosition.left,
+ height: elem.innerHeight(),
+ width: elem.innerWidth(),
+ position: 'absolute'
+ })
+ .animate(animation, o.duration, o.options.easing, function() {
+ transfer.remove();
+ (o.callback && o.callback.apply(elem[0], arguments));
+ elem.dequeue();
+ });
+ });
+};
+
+})(jQuery);
+/*
+ * jQuery UI Accordion 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Accordion
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget( "ui.accordion", {
+ options: {
+ active: 0,
+ animated: "slide",
+ autoHeight: true,
+ clearStyle: false,
+ collapsible: false,
+ event: "click",
+ fillSpace: false,
+ header: "> li > :first-child,> :not(li):even",
+ icons: {
+ header: "ui-icon-triangle-1-e",
+ headerSelected: "ui-icon-triangle-1-s"
+ },
+ navigation: false,
+ navigationFilter: function() {
+ return this.href.toLowerCase() === location.href.toLowerCase();
+ }
+ },
+
+ _create: function() {
+ var self = this,
+ options = self.options;
+
+ self.running = 0;
+
+ self.element
+ .addClass( "ui-accordion ui-widget ui-helper-reset" )
+ // in lack of child-selectors in CSS
+ // we need to mark top-LIs in a UL-accordion for some IE-fix
+ .children( "li" )
+ .addClass( "ui-accordion-li-fix" );
+
+ self.headers = self.element.find( options.header )
+ .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
+ .bind( "mouseenter.accordion", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).addClass( "ui-state-hover" );
+ })
+ .bind( "mouseleave.accordion", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).removeClass( "ui-state-hover" );
+ })
+ .bind( "focus.accordion", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).addClass( "ui-state-focus" );
+ })
+ .bind( "blur.accordion", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).removeClass( "ui-state-focus" );
+ });
+
+ self.headers.next()
+ .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
+
+ if ( options.navigation ) {
+ var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
+ if ( current.length ) {
+ var header = current.closest( ".ui-accordion-header" );
+ if ( header.length ) {
+ // anchor within header
+ self.active = header;
+ } else {
+ // anchor within content
+ self.active = current.closest( ".ui-accordion-content" ).prev();
+ }
+ }
+ }
+
+ self.active = self._findActive( self.active || options.active )
+ .addClass( "ui-state-default ui-state-active" )
+ .toggleClass( "ui-corner-all" )
+ .toggleClass( "ui-corner-top" );
+ self.active.next().addClass( "ui-accordion-content-active" );
+
+ self._createIcons();
+ self.resize();
+
+ // ARIA
+ self.element.attr( "role", "tablist" );
+
+ self.headers
+ .attr( "role", "tab" )
+ .bind( "keydown.accordion", function( event ) {
+ return self._keydown( event );
+ })
+ .next()
+ .attr( "role", "tabpanel" );
+
+ self.headers
+ .not( self.active || "" )
+ .attr({
+ "aria-expanded": "false",
+ "aria-selected": "false",
+ tabIndex: -1
+ })
+ .next()
+ .hide();
+
+ // make sure at least one header is in the tab order
+ if ( !self.active.length ) {
+ self.headers.eq( 0 ).attr( "tabIndex", 0 );
+ } else {
+ self.active
+ .attr({
+ "aria-expanded": "true",
+ "aria-selected": "true",
+ tabIndex: 0
+ });
+ }
+
+ // only need links in tab order for Safari
+ if ( !$.browser.safari ) {
+ self.headers.find( "a" ).attr( "tabIndex", -1 );
+ }
+
+ if ( options.event ) {
+ self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
+ self._clickHandler.call( self, event, this );
+ event.preventDefault();
+ });
+ }
+ },
+
+ _createIcons: function() {
+ var options = this.options;
+ if ( options.icons ) {
+ $( "<span></span>" )
+ .addClass( "ui-icon " + options.icons.header )
+ .prependTo( this.headers );
+ this.active.children( ".ui-icon" )
+ .toggleClass(options.icons.header)
+ .toggleClass(options.icons.headerSelected);
+ this.element.addClass( "ui-accordion-icons" );
+ }
+ },
+
+ _destroyIcons: function() {
+ this.headers.children( ".ui-icon" ).remove();
+ this.element.removeClass( "ui-accordion-icons" );
+ },
+
+ destroy: function() {
+ var options = this.options;
+
+ this.element
+ .removeClass( "ui-accordion ui-widget ui-helper-reset" )
+ .removeAttr( "role" );
+
+ this.headers
+ .unbind( ".accordion" )
+ .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
+ .removeAttr( "role" )
+ .removeAttr( "aria-expanded" )
+ .removeAttr( "aria-selected" )
+ .removeAttr( "tabIndex" );
+
+ this.headers.find( "a" ).removeAttr( "tabIndex" );
+ this._destroyIcons();
+ var contents = this.headers.next()
+ .css( "display", "" )
+ .removeAttr( "role" )
+ .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
+ if ( options.autoHeight || options.fillHeight ) {
+ contents.css( "height", "" );
+ }
+
+ return $.Widget.prototype.destroy.call( this );
+ },
+
+ _setOption: function( key, value ) {
+ $.Widget.prototype._setOption.apply( this, arguments );
+
+ if ( key == "active" ) {
+ this.activate( value );
+ }
+ if ( key == "icons" ) {
+ this._destroyIcons();
+ if ( value ) {
+ this._createIcons();
+ }
+ }
+ // #5332 - opacity doesn't cascade to positioned elements in IE
+ // so we need to add the disabled class to the headers and panels
+ if ( key == "disabled" ) {
+ this.headers.add(this.headers.next())
+ [ value ? "addClass" : "removeClass" ](
+ "ui-accordion-disabled ui-state-disabled" );
+ }
+ },
+
+ _keydown: function( event ) {
+ if ( this.options.disabled || event.altKey || event.ctrlKey ) {
+ return;
+ }
+
+ var keyCode = $.ui.keyCode,
+ length = this.headers.length,
+ currentIndex = this.headers.index( event.target ),
+ toFocus = false;
+
+ switch ( event.keyCode ) {
+ case keyCode.RIGHT:
+ case keyCode.DOWN:
+ toFocus = this.headers[ ( currentIndex + 1 ) % length ];
+ break;
+ case keyCode.LEFT:
+ case keyCode.UP:
+ toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
+ break;
+ case keyCode.SPACE:
+ case keyCode.ENTER:
+ this._clickHandler( { target: event.target }, event.target );
+ event.preventDefault();
+ }
+
+ if ( toFocus ) {
+ $( event.target ).attr( "tabIndex", -1 );
+ $( toFocus ).attr( "tabIndex", 0 );
+ toFocus.focus();
+ return false;
+ }
+
+ return true;
+ },
+
+ resize: function() {
+ var options = this.options,
+ maxHeight;
+
+ if ( options.fillSpace ) {
+ if ( $.browser.msie ) {
+ var defOverflow = this.element.parent().css( "overflow" );
+ this.element.parent().css( "overflow", "hidden");
+ }
+ maxHeight = this.element.parent().height();
+ if ($.browser.msie) {
+ this.element.parent().css( "overflow", defOverflow );
+ }
+
+ this.headers.each(function() {
+ maxHeight -= $( this ).outerHeight( true );
+ });
+
+ this.headers.next()
+ .each(function() {
+ $( this ).height( Math.max( 0, maxHeight -
+ $( this ).innerHeight() + $( this ).height() ) );
+ })
+ .css( "overflow", "auto" );
+ } else if ( options.autoHeight ) {
+ maxHeight = 0;
+ this.headers.next()
+ .each(function() {
+ maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
+ })
+ .height( maxHeight );
+ }
+
+ return this;
+ },
+
+ activate: function( index ) {
+ // TODO this gets called on init, changing the option without an explicit call for that
+ this.options.active = index;
+ // call clickHandler with custom event
+ var active = this._findActive( index )[ 0 ];
+ this._clickHandler( { target: active }, active );
+
+ return this;
+ },
+
+ _findActive: function( selector ) {
+ return selector
+ ? typeof selector === "number"
+ ? this.headers.filter( ":eq(" + selector + ")" )
+ : this.headers.not( this.headers.not( selector ) )
+ : selector === false
+ ? $( [] )
+ : this.headers.filter( ":eq(0)" );
+ },
+
+ // TODO isn't event.target enough? why the separate target argument?
+ _clickHandler: function( event, target ) {
+ var options = this.options;
+ if ( options.disabled ) {
+ return;
+ }
+
+ // called only when using activate(false) to close all parts programmatically
+ if ( !event.target ) {
+ if ( !options.collapsible ) {
+ return;
+ }
+ this.active
+ .removeClass( "ui-state-active ui-corner-top" )
+ .addClass( "ui-state-default ui-corner-all" )
+ .children( ".ui-icon" )
+ .removeClass( options.icons.headerSelected )
+ .addClass( options.icons.header );
+ this.active.next().addClass( "ui-accordion-content-active" );
+ var toHide = this.active.next(),
+ data = {
+ options: options,
+ newHeader: $( [] ),
+ oldHeader: options.active,
+ newContent: $( [] ),
+ oldContent: toHide
+ },
+ toShow = ( this.active = $( [] ) );
+ this._toggle( toShow, toHide, data );
+ return;
+ }
+
+ // get the click target
+ var clicked = $( event.currentTarget || target ),
+ clickedIsActive = clicked[0] === this.active[0];
+
+ // TODO the option is changed, is that correct?
+ // TODO if it is correct, shouldn't that happen after determining that the click is valid?
+ options.active = options.collapsible && clickedIsActive ?
+ false :
+ this.headers.index( clicked );
+
+ // if animations are still active, or the active header is the target, ignore click
+ if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
+ return;
+ }
+
+ // find elements to show and hide
+ var active = this.active,
+ toShow = clicked.next(),
+ toHide = this.active.next(),
+ data = {
+ options: options,
+ newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
+ oldHeader: this.active,
+ newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
+ oldContent: toHide
+ },
+ down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
+
+ // when the call to ._toggle() comes after the class changes
+ // it causes a very odd bug in IE 8 (see #6720)
+ this.active = clickedIsActive ? $([]) : clicked;
+ this._toggle( toShow, toHide, data, clickedIsActive, down );
+
+ // switch classes
+ active
+ .removeClass( "ui-state-active ui-corner-top" )
+ .addClass( "ui-state-default ui-corner-all" )
+ .children( ".ui-icon" )
+ .removeClass( options.icons.headerSelected )
+ .addClass( options.icons.header );
+ if ( !clickedIsActive ) {
+ clicked
+ .removeClass( "ui-state-default ui-corner-all" )
+ .addClass( "ui-state-active ui-corner-top" )
+ .children( ".ui-icon" )
+ .removeClass( options.icons.header )
+ .addClass( options.icons.headerSelected );
+ clicked
+ .next()
+ .addClass( "ui-accordion-content-active" );
+ }
+
+ return;
+ },
+
+ _toggle: function( toShow, toHide, data, clickedIsActive, down ) {
+ var self = this,
+ options = self.options;
+
+ self.toShow = toShow;
+ self.toHide = toHide;
+ self.data = data;
+
+ var complete = function() {
+ if ( !self ) {
+ return;
+ }
+ return self._completed.apply( self, arguments );
+ };
+
+ // trigger changestart event
+ self._trigger( "changestart", null, self.data );
+
+ // count elements to animate
+ self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
+
+ if ( options.animated ) {
+ var animOptions = {};
+
+ if ( options.collapsible && clickedIsActive ) {
+ animOptions = {
+ toShow: $( [] ),
+ toHide: toHide,
+ complete: complete,
+ down: down,
+ autoHeight: options.autoHeight || options.fillSpace
+ };
+ } else {
+ animOptions = {
+ toShow: toShow,
+ toHide: toHide,
+ complete: complete,
+ down: down,
+ autoHeight: options.autoHeight || options.fillSpace
+ };
+ }
+
+ if ( !options.proxied ) {
+ options.proxied = options.animated;
+ }
+
+ if ( !options.proxiedDuration ) {
+ options.proxiedDuration = options.duration;
+ }
+
+ options.animated = $.isFunction( options.proxied ) ?
+ options.proxied( animOptions ) :
+ options.proxied;
+
+ options.duration = $.isFunction( options.proxiedDuration ) ?
+ options.proxiedDuration( animOptions ) :
+ options.proxiedDuration;
+
+ var animations = $.ui.accordion.animations,
+ duration = options.duration,
+ easing = options.animated;
+
+ if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
+ easing = "slide";
+ }
+ if ( !animations[ easing ] ) {
+ animations[ easing ] = function( options ) {
+ this.slide( options, {
+ easing: easing,
+ duration: duration || 700
+ });
+ };
+ }
+
+ animations[ easing ]( animOptions );
+ } else {
+ if ( options.collapsible && clickedIsActive ) {
+ toShow.toggle();
+ } else {
+ toHide.hide();
+ toShow.show();
+ }
+
+ complete( true );
+ }
+
+ // TODO assert that the blur and focus triggers are really necessary, remove otherwise
+ toHide.prev()
+ .attr({
+ "aria-expanded": "false",
+ "aria-selected": "false",
+ tabIndex: -1
+ })
+ .blur();
+ toShow.prev()
+ .attr({
+ "aria-expanded": "true",
+ "aria-selected": "true",
+ tabIndex: 0
+ })
+ .focus();
+ },
+
+ _completed: function( cancel ) {
+ this.running = cancel ? 0 : --this.running;
+ if ( this.running ) {
+ return;
+ }
+
+ if ( this.options.clearStyle ) {
+ this.toShow.add( this.toHide ).css({
+ height: "",
+ overflow: ""
+ });
+ }
+
+ // other classes are removed before the animation; this one needs to stay until completed
+ this.toHide.removeClass( "ui-accordion-content-active" );
+ // Work around for rendering bug in IE (#5421)
+ if ( this.toHide.length ) {
+ this.toHide.parent()[0].className = this.toHide.parent()[0].className;
+ }
+
+ this._trigger( "change", null, this.data );
+ }
+});
+
+$.extend( $.ui.accordion, {
+ version: "1.8.16",
+ animations: {
+ slide: function( options, additions ) {
+ options = $.extend({
+ easing: "swing",
+ duration: 300
+ }, options, additions );
+ if ( !options.toHide.size() ) {
+ options.toShow.animate({
+ height: "show",
+ paddingTop: "show",
+ paddingBottom: "show"
+ }, options );
+ return;
+ }
+ if ( !options.toShow.size() ) {
+ options.toHide.animate({
+ height: "hide",
+ paddingTop: "hide",
+ paddingBottom: "hide"
+ }, options );
+ return;
+ }
+ var overflow = options.toShow.css( "overflow" ),
+ percentDone = 0,
+ showProps = {},
+ hideProps = {},
+ fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
+ originalWidth;
+ // fix width before calculating height of hidden element
+ var s = options.toShow;
+ originalWidth = s[0].style.width;
+ s.width( parseInt( s.parent().width(), 10 )
+ - parseInt( s.css( "paddingLeft" ), 10 )
+ - parseInt( s.css( "paddingRight" ), 10 )
+ - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 )
+ - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) );
+
+ $.each( fxAttrs, function( i, prop ) {
+ hideProps[ prop ] = "hide";
+
+ var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
+ showProps[ prop ] = {
+ value: parts[ 1 ],
+ unit: parts[ 2 ] || "px"
+ };
+ });
+ options.toShow.css({ height: 0, overflow: "hidden" }).show();
+ options.toHide
+ .filter( ":hidden" )
+ .each( options.complete )
+ .end()
+ .filter( ":visible" )
+ .animate( hideProps, {
+ step: function( now, settings ) {
+ // only calculate the percent when animating height
+ // IE gets very inconsistent results when animating elements
+ // with small values, which is common for padding
+ if ( settings.prop == "height" ) {
+ percentDone = ( settings.end - settings.start === 0 ) ? 0 :
+ ( settings.now - settings.start ) / ( settings.end - settings.start );
+ }
+
+ options.toShow[ 0 ].style[ settings.prop ] =
+ ( percentDone * showProps[ settings.prop ].value )
+ + showProps[ settings.prop ].unit;
+ },
+ duration: options.duration,
+ easing: options.easing,
+ complete: function() {
+ if ( !options.autoHeight ) {
+ options.toShow.css( "height", "" );
+ }
+ options.toShow.css({
+ width: originalWidth,
+ overflow: overflow
+ });
+ options.complete();
+ }
+ });
+ },
+ bounceslide: function( options ) {
+ this.slide( options, {
+ easing: options.down ? "easeOutBounce" : "swing",
+ duration: options.down ? 1000 : 200
+ });
+ }
+ }
+});
+
+})( jQuery );
+/*
+ * jQuery UI Autocomplete 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Autocomplete
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ * jquery.ui.position.js
+ */
+(function( $, undefined ) {
+
+// used to prevent race conditions with remote data sources
+var requestIndex = 0;
+
+$.widget( "ui.autocomplete", {
+ options: {
+ appendTo: "body",
+ autoFocus: false,
+ delay: 300,
+ minLength: 1,
+ position: {
+ my: "left top",
+ at: "left bottom",
+ collision: "none"
+ },
+ source: null
+ },
+
+ pending: 0,
+
+ _create: function() {
+ var self = this,
+ doc = this.element[ 0 ].ownerDocument,
+ suppressKeyPress;
+
+ this.element
+ .addClass( "ui-autocomplete-input" )
+ .attr( "autocomplete", "off" )
+ // TODO verify these actually work as intended
+ .attr({
+ role: "textbox",
+ "aria-autocomplete": "list",
+ "aria-haspopup": "true"
+ })
+ .bind( "keydown.autocomplete", function( event ) {
+ if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
+ return;
+ }
+
+ suppressKeyPress = false;
+ var keyCode = $.ui.keyCode;
+ switch( event.keyCode ) {
+ case keyCode.PAGE_UP:
+ self._move( "previousPage", event );
+ break;
+ case keyCode.PAGE_DOWN:
+ self._move( "nextPage", event );
+ break;
+ case keyCode.UP:
+ self._move( "previous", event );
+ // prevent moving cursor to beginning of text field in some browsers
+ event.preventDefault();
+ break;
+ case keyCode.DOWN:
+ self._move( "next", event );
+ // prevent moving cursor to end of text field in some browsers
+ event.preventDefault();
+ break;
+ case keyCode.ENTER:
+ case keyCode.NUMPAD_ENTER:
+ // when menu is open and has focus
+ if ( self.menu.active ) {
+ // #6055 - Opera still allows the keypress to occur
+ // which causes forms to submit
+ suppressKeyPress = true;
+ event.preventDefault();
+ }
+ //passthrough - ENTER and TAB both select the current element
+ case keyCode.TAB:
+ if ( !self.menu.active ) {
+ return;
+ }
+ self.menu.select( event );
+ break;
+ case keyCode.ESCAPE:
+ self.element.val( self.term );
+ self.close( event );
+ break;
+ default:
+ // keypress is triggered before the input value is changed
+ clearTimeout( self.searching );
+ self.searching = setTimeout(function() {
+ // only search if the value has changed
+ if ( self.term != self.element.val() ) {
+ self.selectedItem = null;
+ self.search( null, event );
+ }
+ }, self.options.delay );
+ break;
+ }
+ })
+ .bind( "keypress.autocomplete", function( event ) {
+ if ( suppressKeyPress ) {
+ suppressKeyPress = false;
+ event.preventDefault();
+ }
+ })
+ .bind( "focus.autocomplete", function() {
+ if ( self.options.disabled ) {
+ return;
+ }
+
+ self.selectedItem = null;
+ self.previous = self.element.val();
+ })
+ .bind( "blur.autocomplete", function( event ) {
+ if ( self.options.disabled ) {
+ return;
+ }
+
+ clearTimeout( self.searching );
+ // clicks on the menu (or a button to trigger a search) will cause a blur event
+ self.closing = setTimeout(function() {
+ self.close( event );
+ self._change( event );
+ }, 150 );
+ });
+ this._initSource();
+ this.response = function() {
+ return self._response.apply( self, arguments );
+ };
+ this.menu = $( "<ul></ul>" )
+ .addClass( "ui-autocomplete" )
+ .appendTo( $( this.options.appendTo || "body", doc )[0] )
+ // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
+ .mousedown(function( event ) {
+ // clicking on the scrollbar causes focus to shift to the body
+ // but we can't detect a mouseup or a click immediately afterward
+ // so we have to track the next mousedown and close the menu if
+ // the user clicks somewhere outside of the autocomplete
+ var menuElement = self.menu.element[ 0 ];
+ if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
+ setTimeout(function() {
+ $( document ).one( 'mousedown', function( event ) {
+ if ( event.target !== self.element[ 0 ] &&
+ event.target !== menuElement &&
+ !$.ui.contains( menuElement, event.target ) ) {
+ self.close();
+ }
+ });
+ }, 1 );
+ }
+
+ // use another timeout to make sure the blur-event-handler on the input was already triggered
+ setTimeout(function() {
+ clearTimeout( self.closing );
+ }, 13);
+ })
+ .menu({
+ focus: function( event, ui ) {
+ var item = ui.item.data( "item.autocomplete" );
+ if ( false !== self._trigger( "focus", event, { item: item } ) ) {
+ // use value to match what will end up in the input, if it was a key event
+ if ( /^key/.test(event.originalEvent.type) ) {
+ self.element.val( item.value );
+ }
+ }
+ },
+ selected: function( event, ui ) {
+ var item = ui.item.data( "item.autocomplete" ),
+ previous = self.previous;
+
+ // only trigger when focus was lost (click on menu)
+ if ( self.element[0] !== doc.activeElement ) {
+ self.element.focus();
+ self.previous = previous;
+ // #6109 - IE triggers two focus events and the second
+ // is asynchronous, so we need to reset the previous
+ // term synchronously and asynchronously :-(
+ setTimeout(function() {
+ self.previous = previous;
+ self.selectedItem = item;
+ }, 1);
+ }
+
+ if ( false !== self._trigger( "select", event, { item: item } ) ) {
+ self.element.val( item.value );
+ }
+ // reset the term after the select event
+ // this allows custom select handling to work properly
+ self.term = self.element.val();
+
+ self.close( event );
+ self.selectedItem = item;
+ },
+ blur: function( event, ui ) {
+ // don't set the value of the text field if it's already correct
+ // this prevents moving the cursor unnecessarily
+ if ( self.menu.element.is(":visible") &&
+ ( self.element.val() !== self.term ) ) {
+ self.element.val( self.term );
+ }
+ }
+ })
+ .zIndex( this.element.zIndex() + 1 )
+ // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
+ .css({ top: 0, left: 0 })
+ .hide()
+ .data( "menu" );
+ if ( $.fn.bgiframe ) {
+ this.menu.element.bgiframe();
+ }
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass( "ui-autocomplete-input" )
+ .removeAttr( "autocomplete" )
+ .removeAttr( "role" )
+ .removeAttr( "aria-autocomplete" )
+ .removeAttr( "aria-haspopup" );
+ this.menu.element.remove();
+ $.Widget.prototype.destroy.call( this );
+ },
+
+ _setOption: function( key, value ) {
+ $.Widget.prototype._setOption.apply( this, arguments );
+ if ( key === "source" ) {
+ this._initSource();
+ }
+ if ( key === "appendTo" ) {
+ this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
+ }
+ if ( key === "disabled" && value && this.xhr ) {
+ this.xhr.abort();
+ }
+ },
+
+ _initSource: function() {
+ var self = this,
+ array,
+ url;
+ if ( $.isArray(this.options.source) ) {
+ array = this.options.source;
+ this.source = function( request, response ) {
+ response( $.ui.autocomplete.filter(array, request.term) );
+ };
+ } else if ( typeof this.options.source === "string" ) {
+ url = this.options.source;
+ this.source = function( request, response ) {
+ if ( self.xhr ) {
+ self.xhr.abort();
+ }
+ self.xhr = $.ajax({
+ url: url,
+ data: request,
+ dataType: "json",
+ autocompleteRequest: ++requestIndex,
+ success: function( data, status ) {
+ if ( this.autocompleteRequest === requestIndex ) {
+ response( data );
+ }
+ },
+ error: function() {
+ if ( this.autocompleteRequest === requestIndex ) {
+ response( [] );
+ }
+ }
+ });
+ };
+ } else {
+ this.source = this.options.source;
+ }
+ },
+
+ search: function( value, event ) {
+ value = value != null ? value : this.element.val();
+
+ // always save the actual value, not the one passed as an argument
+ this.term = this.element.val();
+
+ if ( value.length < this.options.minLength ) {
+ return this.close( event );
+ }
+
+ clearTimeout( this.closing );
+ if ( this._trigger( "search", event ) === false ) {
+ return;
+ }
+
+ return this._search( value );
+ },
+
+ _search: function( value ) {
+ this.pending++;
+ this.element.addClass( "ui-autocomplete-loading" );
+
+ this.source( { term: value }, this.response );
+ },
+
+ _response: function( content ) {
+ if ( !this.options.disabled && content && content.length ) {
+ content = this._normalize( content );
+ this._suggest( content );
+ this._trigger( "open" );
+ } else {
+ this.close();
+ }
+ this.pending--;
+ if ( !this.pending ) {
+ this.element.removeClass( "ui-autocomplete-loading" );
+ }
+ },
+
+ close: function( event ) {
+ clearTimeout( this.closing );
+ if ( this.menu.element.is(":visible") ) {
+ this.menu.element.hide();
+ this.menu.deactivate();
+ this._trigger( "close", event );
+ }
+ },
+
+ _change: function( event ) {
+ if ( this.previous !== this.element.val() ) {
+ this._trigger( "change", event, { item: this.selectedItem } );
+ }
+ },
+
+ _normalize: function( items ) {
+ // assume all items have the right format when the first item is complete
+ if ( items.length && items[0].label && items[0].value ) {
+ return items;
+ }
+ return $.map( items, function(item) {
+ if ( typeof item === "string" ) {
+ return {
+ label: item,
+ value: item
+ };
+ }
+ return $.extend({
+ label: item.label || item.value,
+ value: item.value || item.label
+ }, item );
+ });
+ },
+
+ _suggest: function( items ) {
+ var ul = this.menu.element
+ .empty()
+ .zIndex( this.element.zIndex() + 1 );
+ this._renderMenu( ul, items );
+ // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
+ this.menu.deactivate();
+ this.menu.refresh();
+
+ // size and position menu
+ ul.show();
+ this._resizeMenu();
+ ul.position( $.extend({
+ of: this.element
+ }, this.options.position ));
+
+ if ( this.options.autoFocus ) {
+ this.menu.next( new $.Event("mouseover") );
+ }
+ },
+
+ _resizeMenu: function() {
+ var ul = this.menu.element;
+ ul.outerWidth( Math.max(
+ ul.width( "" ).outerWidth(),
+ this.element.outerWidth()
+ ) );
+ },
+
+ _renderMenu: function( ul, items ) {
+ var self = this;
+ $.each( items, function( index, item ) {
+ self._renderItem( ul, item );
+ });
+ },
+
+ _renderItem: function( ul, item) {
+ return $( "<li></li>" )
+ .data( "item.autocomplete", item )
+ .append( $( "<a></a>" ).text( item.label ) )
+ .appendTo( ul );
+ },
+
+ _move: function( direction, event ) {
+ if ( !this.menu.element.is(":visible") ) {
+ this.search( null, event );
+ return;
+ }
+ if ( this.menu.first() && /^previous/.test(direction) ||
+ this.menu.last() && /^next/.test(direction) ) {
+ this.element.val( this.term );
+ this.menu.deactivate();
+ return;
+ }
+ this.menu[ direction ]( event );
+ },
+
+ widget: function() {
+ return this.menu.element;
+ }
+});
+
+$.extend( $.ui.autocomplete, {
+ escapeRegex: function( value ) {
+ return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+ },
+ filter: function(array, term) {
+ var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
+ return $.grep( array, function(value) {
+ return matcher.test( value.label || value.value || value );
+ });
+ }
+});
+
+}( jQuery ));
+
+/*
+ * jQuery UI Menu (not officially released)
+ *
+ * This widget isn't yet finished and the API is subject to change. We plan to finish
+ * it for the next release. You're welcome to give it a try anyway and give us feedback,
+ * as long as you're okay with migrating your code later on. We can help with that, too.
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Menu
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function($) {
+
+$.widget("ui.menu", {
+ _create: function() {
+ var self = this;
+ this.element
+ .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
+ .attr({
+ role: "listbox",
+ "aria-activedescendant": "ui-active-menuitem"
+ })
+ .click(function( event ) {
+ if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
+ return;
+ }
+ // temporary
+ event.preventDefault();
+ self.select( event );
+ });
+ this.refresh();
+ },
+
+ refresh: function() {
+ var self = this;
+
+ // don't refresh list items that are already adapted
+ var items = this.element.children("li:not(.ui-menu-item):has(a)")
+ .addClass("ui-menu-item")
+ .attr("role", "menuitem");
+
+ items.children("a")
+ .addClass("ui-corner-all")
+ .attr("tabindex", -1)
+ // mouseenter doesn't work with event delegation
+ .mouseenter(function( event ) {
+ self.activate( event, $(this).parent() );
+ })
+ .mouseleave(function() {
+ self.deactivate();
+ });
+ },
+
+ activate: function( event, item ) {
+ this.deactivate();
+ if (this.hasScroll()) {
+ var offset = item.offset().top - this.element.offset().top,
+ scroll = this.element.scrollTop(),
+ elementHeight = this.element.height();
+ if (offset < 0) {
+ this.element.scrollTop( scroll + offset);
+ } else if (offset >= elementHeight) {
+ this.element.scrollTop( scroll + offset - elementHeight + item.height());
+ }
+ }
+ this.active = item.eq(0)
+ .children("a")
+ .addClass("ui-state-hover")
+ .attr("id", "ui-active-menuitem")
+ .end();
+ this._trigger("focus", event, { item: item });
+ },
+
+ deactivate: function() {
+ if (!this.active) { return; }
+
+ this.active.children("a")
+ .removeClass("ui-state-hover")
+ .removeAttr("id");
+ this._trigger("blur");
+ this.active = null;
+ },
+
+ next: function(event) {
+ this.move("next", ".ui-menu-item:first", event);
+ },
+
+ previous: function(event) {
+ this.move("prev", ".ui-menu-item:last", event);
+ },
+
+ first: function() {
+ return this.active && !this.active.prevAll(".ui-menu-item").length;
+ },
+
+ last: function() {
+ return this.active && !this.active.nextAll(".ui-menu-item").length;
+ },
+
+ move: function(direction, edge, event) {
+ if (!this.active) {
+ this.activate(event, this.element.children(edge));
+ return;
+ }
+ var next = this.active[direction + "All"](".ui-menu-item").eq(0);
+ if (next.length) {
+ this.activate(event, next);
+ } else {
+ this.activate(event, this.element.children(edge));
+ }
+ },
+
+ // TODO merge with previousPage
+ nextPage: function(event) {
+ if (this.hasScroll()) {
+ // TODO merge with no-scroll-else
+ if (!this.active || this.last()) {
+ this.activate(event, this.element.children(".ui-menu-item:first"));
+ return;
+ }
+ var base = this.active.offset().top,
+ height = this.element.height(),
+ result = this.element.children(".ui-menu-item").filter(function() {
+ var close = $(this).offset().top - base - height + $(this).height();
+ // TODO improve approximation
+ return close < 10 && close > -10;
+ });
+
+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
+ if (!result.length) {
+ result = this.element.children(".ui-menu-item:last");
+ }
+ this.activate(event, result);
+ } else {
+ this.activate(event, this.element.children(".ui-menu-item")
+ .filter(!this.active || this.last() ? ":first" : ":last"));
+ }
+ },
+
+ // TODO merge with nextPage
+ previousPage: function(event) {
+ if (this.hasScroll()) {
+ // TODO merge with no-scroll-else
+ if (!this.active || this.first()) {
+ this.activate(event, this.element.children(".ui-menu-item:last"));
+ return;
+ }
+
+ var base = this.active.offset().top,
+ height = this.element.height();
+ result = this.element.children(".ui-menu-item").filter(function() {
+ var close = $(this).offset().top - base + height - $(this).height();
+ // TODO improve approximation
+ return close < 10 && close > -10;
+ });
+
+ // TODO try to catch this earlier when scrollTop indicates the last page anyway
+ if (!result.length) {
+ result = this.element.children(".ui-menu-item:first");
+ }
+ this.activate(event, result);
+ } else {
+ this.activate(event, this.element.children(".ui-menu-item")
+ .filter(!this.active || this.first() ? ":last" : ":first"));
+ }
+ },
+
+ hasScroll: function() {
+ return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
+ },
+
+ select: function( event ) {
+ this._trigger("selected", event, { item: this.active });
+ }
+});
+
+}(jQuery));
+/*
+ * jQuery UI Button 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Button
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+var lastActive, startXPos, startYPos, clickDragged,
+ baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
+ stateClasses = "ui-state-hover ui-state-active ",
+ typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
+ formResetHandler = function() {
+ var buttons = $( this ).find( ":ui-button" );
+ setTimeout(function() {
+ buttons.button( "refresh" );
+ }, 1 );
+ },
+ radioGroup = function( radio ) {
+ var name = radio.name,
+ form = radio.form,
+ radios = $( [] );
+ if ( name ) {
+ if ( form ) {
+ radios = $( form ).find( "[name='" + name + "']" );
+ } else {
+ radios = $( "[name='" + name + "']", radio.ownerDocument )
+ .filter(function() {
+ return !this.form;
+ });
+ }
+ }
+ return radios;
+ };
+
+$.widget( "ui.button", {
+ options: {
+ disabled: null,
+ text: true,
+ label: null,
+ icons: {
+ primary: null,
+ secondary: null
+ }
+ },
+ _create: function() {
+ this.element.closest( "form" )
+ .unbind( "reset.button" )
+ .bind( "reset.button", formResetHandler );
+
+ if ( typeof this.options.disabled !== "boolean" ) {
+ this.options.disabled = this.element.propAttr( "disabled" );
+ }
+
+ this._determineButtonType();
+ this.hasTitle = !!this.buttonElement.attr( "title" );
+
+ var self = this,
+ options = this.options,
+ toggleButton = this.type === "checkbox" || this.type === "radio",
+ hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
+ focusClass = "ui-state-focus";
+
+ if ( options.label === null ) {
+ options.label = this.buttonElement.html();
+ }
+
+ if ( this.element.is( ":disabled" ) ) {
+ options.disabled = true;
+ }
+
+ this.buttonElement
+ .addClass( baseClasses )
+ .attr( "role", "button" )
+ .bind( "mouseenter.button", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).addClass( "ui-state-hover" );
+ if ( this === lastActive ) {
+ $( this ).addClass( "ui-state-active" );
+ }
+ })
+ .bind( "mouseleave.button", function() {
+ if ( options.disabled ) {
+ return;
+ }
+ $( this ).removeClass( hoverClass );
+ })
+ .bind( "click.button", function( event ) {
+ if ( options.disabled ) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ }
+ });
+
+ this.element
+ .bind( "focus.button", function() {
+ // no need to check disabled, focus won't be triggered anyway
+ self.buttonElement.addClass( focusClass );
+ })
+ .bind( "blur.button", function() {
+ self.buttonElement.removeClass( focusClass );
+ });
+
+ if ( toggleButton ) {
+ this.element.bind( "change.button", function() {
+ if ( clickDragged ) {
+ return;
+ }
+ self.refresh();
+ });
+ // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
+ // prevents issue where button state changes but checkbox/radio checked state
+ // does not in Firefox (see ticket #6970)
+ this.buttonElement
+ .bind( "mousedown.button", function( event ) {
+ if ( options.disabled ) {
+ return;
+ }
+ clickDragged = false;
+ startXPos = event.pageX;
+ startYPos = event.pageY;
+ })
+ .bind( "mouseup.button", function( event ) {
+ if ( options.disabled ) {
+ return;
+ }
+ if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
+ clickDragged = true;
+ }
+ });
+ }
+
+ if ( this.type === "checkbox" ) {
+ this.buttonElement.bind( "click.button", function() {
+ if ( options.disabled || clickDragged ) {
+ return false;
+ }
+ $( this ).toggleClass( "ui-state-active" );
+ self.buttonElement.attr( "aria-pressed", self.element[0].checked );
+ });
+ } else if ( this.type === "radio" ) {
+ this.buttonElement.bind( "click.button", function() {
+ if ( options.disabled || clickDragged ) {
+ return false;
+ }
+ $( this ).addClass( "ui-state-active" );
+ self.buttonElement.attr( "aria-pressed", "true" );
+
+ var radio = self.element[ 0 ];
+ radioGroup( radio )
+ .not( radio )
+ .map(function() {
+ return $( this ).button( "widget" )[ 0 ];
+ })
+ .removeClass( "ui-state-active" )
+ .attr( "aria-pressed", "false" );
+ });
+ } else {
+ this.buttonElement
+ .bind( "mousedown.button", function() {
+ if ( options.disabled ) {
+ return false;
+ }
+ $( this ).addClass( "ui-state-active" );
+ lastActive = this;
+ $( document ).one( "mouseup", function() {
+ lastActive = null;
+ });
+ })
+ .bind( "mouseup.button", function() {
+ if ( options.disabled ) {
+ return false;
+ }
+ $( this ).removeClass( "ui-state-active" );
+ })
+ .bind( "keydown.button", function(event) {
+ if ( options.disabled ) {
+ return false;
+ }
+ if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
+ $( this ).addClass( "ui-state-active" );
+ }
+ })
+ .bind( "keyup.button", function() {
+ $( this ).removeClass( "ui-state-active" );
+ });
+
+ if ( this.buttonElement.is("a") ) {
+ this.buttonElement.keyup(function(event) {
+ if ( event.keyCode === $.ui.keyCode.SPACE ) {
+ // TODO pass through original event correctly (just as 2nd argument doesn't work)
+ $( this ).click();
+ }
+ });
+ }
+ }
+
+ // TODO: pull out $.Widget's handling for the disabled option into
+ // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
+ // be overridden by individual plugins
+ this._setOption( "disabled", options.disabled );
+ this._resetButton();
+ },
+
+ _determineButtonType: function() {
+
+ if ( this.element.is(":checkbox") ) {
+ this.type = "checkbox";
+ } else if ( this.element.is(":radio") ) {
+ this.type = "radio";
+ } else if ( this.element.is("input") ) {
+ this.type = "input";
+ } else {
+ this.type = "button";
+ }
+
+ if ( this.type === "checkbox" || this.type === "radio" ) {
+ // we don't search against the document in case the element
+ // is disconnected from the DOM
+ var ancestor = this.element.parents().filter(":last"),
+ labelSelector = "label[for='" + this.element.attr("id") + "']";
+ this.buttonElement = ancestor.find( labelSelector );
+ if ( !this.buttonElement.length ) {
+ ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
+ this.buttonElement = ancestor.filter( labelSelector );
+ if ( !this.buttonElement.length ) {
+ this.buttonElement = ancestor.find( labelSelector );
+ }
+ }
+ this.element.addClass( "ui-helper-hidden-accessible" );
+
+ var checked = this.element.is( ":checked" );
+ if ( checked ) {
+ this.buttonElement.addClass( "ui-state-active" );
+ }
+ this.buttonElement.attr( "aria-pressed", checked );
+ } else {
+ this.buttonElement = this.element;
+ }
+ },
+
+ widget: function() {
+ return this.buttonElement;
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass( "ui-helper-hidden-accessible" );
+ this.buttonElement
+ .removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
+ .removeAttr( "role" )
+ .removeAttr( "aria-pressed" )
+ .html( this.buttonElement.find(".ui-button-text").html() );
+
+ if ( !this.hasTitle ) {
+ this.buttonElement.removeAttr( "title" );
+ }
+
+ $.Widget.prototype.destroy.call( this );
+ },
+
+ _setOption: function( key, value ) {
+ $.Widget.prototype._setOption.apply( this, arguments );
+ if ( key === "disabled" ) {
+ if ( value ) {
+ this.element.propAttr( "disabled", true );
+ } else {
+ this.element.propAttr( "disabled", false );
+ }
+ return;
+ }
+ this._resetButton();
+ },
+
+ refresh: function() {
+ var isDisabled = this.element.is( ":disabled" );
+ if ( isDisabled !== this.options.disabled ) {
+ this._setOption( "disabled", isDisabled );
+ }
+ if ( this.type === "radio" ) {
+ radioGroup( this.element[0] ).each(function() {
+ if ( $( this ).is( ":checked" ) ) {
+ $( this ).button( "widget" )
+ .addClass( "ui-state-active" )
+ .attr( "aria-pressed", "true" );
+ } else {
+ $( this ).button( "widget" )
+ .removeClass( "ui-state-active" )
+ .attr( "aria-pressed", "false" );
+ }
+ });
+ } else if ( this.type === "checkbox" ) {
+ if ( this.element.is( ":checked" ) ) {
+ this.buttonElement
+ .addClass( "ui-state-active" )
+ .attr( "aria-pressed", "true" );
+ } else {
+ this.buttonElement
+ .removeClass( "ui-state-active" )
+ .attr( "aria-pressed", "false" );
+ }
+ }
+ },
+
+ _resetButton: function() {
+ if ( this.type === "input" ) {
+ if ( this.options.label ) {
+ this.element.val( this.options.label );
+ }
+ return;
+ }
+ var buttonElement = this.buttonElement.removeClass( typeClasses ),
+ buttonText = $( "<span></span>" )
+ .addClass( "ui-button-text" )
+ .html( this.options.label )
+ .appendTo( buttonElement.empty() )
+ .text(),
+ icons = this.options.icons,
+ multipleIcons = icons.primary && icons.secondary,
+ buttonClasses = [];
+
+ if ( icons.primary || icons.secondary ) {
+ if ( this.options.text ) {
+ buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
+ }
+
+ if ( icons.primary ) {
+ buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
+ }
+
+ if ( icons.secondary ) {
+ buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
+ }
+
+ if ( !this.options.text ) {
+ buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
+
+ if ( !this.hasTitle ) {
+ buttonElement.attr( "title", buttonText );
+ }
+ }
+ } else {
+ buttonClasses.push( "ui-button-text-only" );
+ }
+ buttonElement.addClass( buttonClasses.join( " " ) );
+ }
+});
+
+$.widget( "ui.buttonset", {
+ options: {
+ items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
+ },
+
+ _create: function() {
+ this.element.addClass( "ui-buttonset" );
+ },
+
+ _init: function() {
+ this.refresh();
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "disabled" ) {
+ this.buttons.button( "option", key, value );
+ }
+
+ $.Widget.prototype._setOption.apply( this, arguments );
+ },
+
+ refresh: function() {
+ var ltr = this.element.css( "direction" ) === "ltr";
+
+ this.buttons = this.element.find( this.options.items )
+ .filter( ":ui-button" )
+ .button( "refresh" )
+ .end()
+ .not( ":ui-button" )
+ .button()
+ .end()
+ .map(function() {
+ return $( this ).button( "widget" )[ 0 ];
+ })
+ .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
+ .filter( ":first" )
+ .addClass( ltr ? "ui-corner-left" : "ui-corner-right" )
+ .end()
+ .filter( ":last" )
+ .addClass( ltr ? "ui-corner-right" : "ui-corner-left" )
+ .end()
+ .end();
+ },
+
+ destroy: function() {
+ this.element.removeClass( "ui-buttonset" );
+ this.buttons
+ .map(function() {
+ return $( this ).button( "widget" )[ 0 ];
+ })
+ .removeClass( "ui-corner-left ui-corner-right" )
+ .end()
+ .button( "destroy" );
+
+ $.Widget.prototype.destroy.call( this );
+ }
+});
+
+}( jQuery ) );
+/*
+ * jQuery UI Datepicker 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Datepicker
+ *
+ * Depends:
+ * jquery.ui.core.js
+ */
+(function( $, undefined ) {
+
+$.extend($.ui, { datepicker: { version: "1.8.16" } });
+
+var PROP_NAME = 'datepicker';
+var dpuuid = new Date().getTime();
+var instActive;
+
+/* Date picker manager.
+ Use the singleton instance of this class, $.datepicker, to interact with the date picker.
+ Settings for (groups of) date pickers are maintained in an instance object,
+ allowing multiple different settings on the same page. */
+
+function Datepicker() {
+ this.debug = false; // Change this to true to start debugging
+ this._curInst = null; // The current instance in use
+ this._keyEvent = false; // If the last event was a key event
+ this._disabledInputs = []; // List of date picker inputs that have been disabled
+ this._datepickerShowing = false; // True if the popup picker is showing , false if not
+ this._inDialog = false; // True if showing within a "dialog", false if not
+ this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
+ this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
+ this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
+ this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
+ this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
+ this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
+ this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
+ this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
+ this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
+ this.regional = []; // Available regional settings, indexed by language code
+ this.regional[''] = { // Default regional settings
+ closeText: 'Done', // Display text for close link
+ prevText: 'Prev', // Display text for previous month link
+ nextText: 'Next', // Display text for next month link
+ currentText: 'Today', // Display text for current month link
+ monthNames: ['January','February','March','April','May','June',
+ 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
+ monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
+ dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
+ dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
+ dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
+ weekHeader: 'Wk', // Column header for week of the year
+ dateFormat: 'mm/dd/yy', // See format options on parseDate
+ firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
+ isRTL: false, // True if right-to-left language, false if left-to-right
+ showMonthAfterYear: false, // True if the year select precedes month, false for month then year
+ yearSuffix: '' // Additional text to append to the year in the month headers
+ };
+ this._defaults = { // Global defaults for all the date picker instances
+ showOn: 'focus', // 'focus' for popup on focus,
+ // 'button' for trigger button, or 'both' for either
+ showAnim: 'fadeIn', // Name of jQuery animation for popup
+ showOptions: {}, // Options for enhanced animations
+ defaultDate: null, // Used when field is blank: actual date,
+ // +/-number for offset from today, null for today
+ appendText: '', // Display text following the input box, e.g. showing the format
+ buttonText: '...', // Text for trigger button
+ buttonImage: '', // URL for trigger button image
+ buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
+ hideIfNoPrevNext: false, // True to hide next/previous month links
+ // if not applicable, false to just disable them
+ navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
+ gotoCurrent: false, // True if today link goes back to current selection instead
+ changeMonth: false, // True if month can be selected directly, false if only prev/next
+ changeYear: false, // True if year can be selected directly, false if only prev/next
+ yearRange: 'c-10:c+10', // Range of years to display in drop-down,
+ // either relative to today's year (-nn:+nn), relative to currently displayed year
+ // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
+ showOtherMonths: false, // True to show dates in other months, false to leave blank
+ selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
+ showWeek: false, // True to show week of the year, false to not show it
+ calculateWeek: this.iso8601Week, // How to calculate the week of the year,
+ // takes a Date and returns the number of the week for it
+ shortYearCutoff: '+10', // Short year values < this are in the current century,
+ // > this are in the previous century,
+ // string value starting with '+' for current year + value
+ minDate: null, // The earliest selectable date, or null for no limit
+ maxDate: null, // The latest selectable date, or null for no limit
+ duration: 'fast', // Duration of display/closure
+ beforeShowDay: null, // Function that takes a date and returns an array with
+ // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
+ // [2] = cell title (optional), e.g. $.datepicker.noWeekends
+ beforeShow: null, // Function that takes an input field and
+ // returns a set of custom settings for the date picker
+ onSelect: null, // Define a callback function when a date is selected
+ onChangeMonthYear: null, // Define a callback function when the month or year is changed
+ onClose: null, // Define a callback function when the datepicker is closed
+ numberOfMonths: 1, // Number of months to show at a time
+ showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
+ stepMonths: 1, // Number of months to step back/forward
+ stepBigMonths: 12, // Number of months to step back/forward for the big links
+ altField: '', // Selector for an alternate field to store selected dates into
+ altFormat: '', // The date format to use for the alternate field
+ constrainInput: true, // The input is constrained by the current date format
+ showButtonPanel: false, // True to show button panel, false to not show it
+ autoSize: false, // True to size the input for the date format, false to leave as is
+ disabled: false // The initial disabled state
+ };
+ $.extend(this._defaults, this.regional['']);
+ this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
+}
+
+$.extend(Datepicker.prototype, {
+ /* Class name added to elements to indicate already configured with a date picker. */
+ markerClassName: 'hasDatepicker',
+
+ //Keep track of the maximum number of rows displayed (see #7043)
+ maxRows: 4,
+
+ /* Debug logging (if enabled). */
+ log: function () {
+ if (this.debug)
+ console.log.apply('', arguments);
+ },
+
+ // TODO rename to "widget" when switching to widget factory
+ _widgetDatepicker: function() {
+ return this.dpDiv;
+ },
+
+ /* Override the default settings for all instances of the date picker.
+ @param settings object - the new settings to use as defaults (anonymous object)
+ @return the manager object */
+ setDefaults: function(settings) {
+ extendRemove(this._defaults, settings || {});
+ return this;
+ },
+
+ /* Attach the date picker to a jQuery selection.
+ @param target element - the target input field or division or span
+ @param settings object - the new settings to use for this date picker instance (anonymous) */
+ _attachDatepicker: function(target, settings) {
+ // check for settings on the control itself - in namespace 'date:'
+ var inlineSettings = null;
+ for (var attrName in this._defaults) {
+ var attrValue = target.getAttribute('date:' + attrName);
+ if (attrValue) {
+ inlineSettings = inlineSettings || {};
+ try {
+ inlineSettings[attrName] = eval(attrValue);
+ } catch (err) {
+ inlineSettings[attrName] = attrValue;
+ }
+ }
+ }
+ var nodeName = target.nodeName.toLowerCase();
+ var inline = (nodeName == 'div' || nodeName == 'span');
+ if (!target.id) {
+ this.uuid += 1;
+ target.id = 'dp' + this.uuid;
+ }
+ var inst = this._newInst($(target), inline);
+ inst.settings = $.extend({}, settings || {}, inlineSettings || {});
+ if (nodeName == 'input') {
+ this._connectDatepicker(target, inst);
+ } else if (inline) {
+ this._inlineDatepicker(target, inst);
+ }
+ },
+
+ /* Create a new instance object. */
+ _newInst: function(target, inline) {
+ var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
+ return {id: id, input: target, // associated target
+ selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
+ drawMonth: 0, drawYear: 0, // month being drawn
+ inline: inline, // is datepicker inline or not
+ dpDiv: (!inline ? this.dpDiv : // presentation div
+ bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
+ },
+
+ /* Attach the date picker to an input field. */
+ _connectDatepicker: function(target, inst) {
+ var input = $(target);
+ inst.append = $([]);
+ inst.trigger = $([]);
+ if (input.hasClass(this.markerClassName))
+ return;
+ this._attachments(input, inst);
+ input.addClass(this.markerClassName).keydown(this._doKeyDown).
+ keypress(this._doKeyPress).keyup(this._doKeyUp).
+ bind("setData.datepicker", function(event, key, value) {
+ inst.settings[key] = value;
+ }).bind("getData.datepicker", function(event, key) {
+ return this._get(inst, key);
+ });
+ this._autoSize(inst);
+ $.data(target, PROP_NAME, inst);
+ //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
+ if( inst.settings.disabled ) {
+ this._disableDatepicker( target );
+ }
+ },
+
+ /* Make attachments based on settings. */
+ _attachments: function(input, inst) {
+ var appendText = this._get(inst, 'appendText');
+ var isRTL = this._get(inst, 'isRTL');
+ if (inst.append)
+ inst.append.remove();
+ if (appendText) {
+ inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
+ input[isRTL ? 'before' : 'after'](inst.append);
+ }
+ input.unbind('focus', this._showDatepicker);
+ if (inst.trigger)
+ inst.trigger.remove();
+ var showOn = this._get(inst, 'showOn');
+ if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
+ input.focus(this._showDatepicker);
+ if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
+ var buttonText = this._get(inst, 'buttonText');
+ var buttonImage = this._get(inst, 'buttonImage');
+ inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
+ $('<img/>').addClass(this._triggerClass).
+ attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
+ $('<button type="button"></button>').addClass(this._triggerClass).
+ html(buttonImage == '' ? buttonText : $('<img/>').attr(
+ { src:buttonImage, alt:buttonText, title:buttonText })));
+ input[isRTL ? 'before' : 'after'](inst.trigger);
+ inst.trigger.click(function() {
+ if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
+ $.datepicker._hideDatepicker();
+ else
+ $.datepicker._showDatepicker(input[0]);
+ return false;
+ });
+ }
+ },
+
+ /* Apply the maximum length for the date format. */
+ _autoSize: function(inst) {
+ if (this._get(inst, 'autoSize') && !inst.inline) {
+ var date = new Date(2009, 12 - 1, 20); // Ensure double digits
+ var dateFormat = this._get(inst, 'dateFormat');
+ if (dateFormat.match(/[DM]/)) {
+ var findMax = function(names) {
+ var max = 0;
+ var maxI = 0;
+ for (var i = 0; i < names.length; i++) {
+ if (names[i].length > max) {
+ max = names[i].length;
+ maxI = i;
+ }
+ }
+ return maxI;
+ };
+ date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
+ 'monthNames' : 'monthNamesShort'))));
+ date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
+ 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
+ }
+ inst.input.attr('size', this._formatDate(inst, date).length);
+ }
+ },
+
+ /* Attach an inline date picker to a div. */
+ _inlineDatepicker: function(target, inst) {
+ var divSpan = $(target);
+ if (divSpan.hasClass(this.markerClassName))
+ return;
+ divSpan.addClass(this.markerClassName).append(inst.dpDiv).
+ bind("setData.datepicker", function(event, key, value){
+ inst.settings[key] = value;
+ }).bind("getData.datepicker", function(event, key){
+ return this._get(inst, key);
+ });
+ $.data(target, PROP_NAME, inst);
+ this._setDate(inst, this._getDefaultDate(inst), true);
+ this._updateDatepicker(inst);
+ this._updateAlternate(inst);
+ //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
+ if( inst.settings.disabled ) {
+ this._disableDatepicker( target );
+ }
+ // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
+ // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
+ inst.dpDiv.css( "display", "block" );
+ },
+
+ /* Pop-up the date picker in a "dialog" box.
+ @param input element - ignored
+ @param date string or Date - the initial date to display
+ @param onSelect function - the function to call when a date is selected
+ @param settings object - update the dialog date picker instance's settings (anonymous object)
+ @param pos int[2] - coordinates for the dialog's position within the screen or
+ event - with x/y coordinates or
+ leave empty for default (screen centre)
+ @return the manager object */
+ _dialogDatepicker: function(input, date, onSelect, settings, pos) {
+ var inst = this._dialogInst; // internal instance
+ if (!inst) {
+ this.uuid += 1;
+ var id = 'dp' + this.uuid;
+ this._dialogInput = $('<input type="text" id="' + id +
+ '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
+ this._dialogInput.keydown(this._doKeyDown);
+ $('body').append(this._dialogInput);
+ inst = this._dialogInst = this._newInst(this._dialogInput, false);
+ inst.settings = {};
+ $.data(this._dialogInput[0], PROP_NAME, inst);
+ }
+ extendRemove(inst.settings, settings || {});
+ date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
+ this._dialogInput.val(date);
+
+ this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
+ if (!this._pos) {
+ var browserWidth = document.documentElement.clientWidth;
+ var browserHeight = document.documentElement.clientHeight;
+ var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
+ var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
+ this._pos = // should use actual width/height below
+ [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
+ }
+
+ // move input on screen for focus, but hidden behind dialog
+ this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
+ inst.settings.onSelect = onSelect;
+ this._inDialog = true;
+ this.dpDiv.addClass(this._dialogClass);
+ this._showDatepicker(this._dialogInput[0]);
+ if ($.blockUI)
+ $.blockUI(this.dpDiv);
+ $.data(this._dialogInput[0], PROP_NAME, inst);
+ return this;
+ },
+
+ /* Detach a datepicker from its control.
+ @param target element - the target input field or division or span */
+ _destroyDatepicker: function(target) {
+ var $target = $(target);
+ var inst = $.data(target, PROP_NAME);
+ if (!$target.hasClass(this.markerClassName)) {
+ return;
+ }
+ var nodeName = target.nodeName.toLowerCase();
+ $.removeData(target, PROP_NAME);
+ if (nodeName == 'input') {
+ inst.append.remove();
+ inst.trigger.remove();
+ $target.removeClass(this.markerClassName).
+ unbind('focus', this._showDatepicker).
+ unbind('keydown', this._doKeyDown).
+ unbind('keypress', this._doKeyPress).
+ unbind('keyup', this._doKeyUp);
+ } else if (nodeName == 'div' || nodeName == 'span')
+ $target.removeClass(this.markerClassName).empty();
+ },
+
+ /* Enable the date picker to a jQuery selection.
+ @param target element - the target input field or division or span */
+ _enableDatepicker: function(target) {
+ var $target = $(target);
+ var inst = $.data(target, PROP_NAME);
+ if (!$target.hasClass(this.markerClassName)) {
+ return;
+ }
+ var nodeName = target.nodeName.toLowerCase();
+ if (nodeName == 'input') {
+ target.disabled = false;
+ inst.trigger.filter('button').
+ each(function() { this.disabled = false; }).end().
+ filter('img').css({opacity: '1.0', cursor: ''});
+ }
+ else if (nodeName == 'div' || nodeName == 'span') {
+ var inline = $target.children('.' + this._inlineClass);
+ inline.children().removeClass('ui-state-disabled');
+ inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
+ removeAttr("disabled");
+ }
+ this._disabledInputs = $.map(this._disabledInputs,
+ function(value) { return (value == target ? null : value); }); // delete entry
+ },
+
+ /* Disable the date picker to a jQuery selection.
+ @param target element - the target input field or division or span */
+ _disableDatepicker: function(target) {
+ var $target = $(target);
+ var inst = $.data(target, PROP_NAME);
+ if (!$target.hasClass(this.markerClassName)) {
+ return;
+ }
+ var nodeName = target.nodeName.toLowerCase();
+ if (nodeName == 'input') {
+ target.disabled = true;
+ inst.trigger.filter('button').
+ each(function() { this.disabled = true; }).end().
+ filter('img').css({opacity: '0.5', cursor: 'default'});
+ }
+ else if (nodeName == 'div' || nodeName == 'span') {
+ var inline = $target.children('.' + this._inlineClass);
+ inline.children().addClass('ui-state-disabled');
+ inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
+ attr("disabled", "disabled");
+ }
+ this._disabledInputs = $.map(this._disabledInputs,
+ function(value) { return (value == target ? null : value); }); // delete entry
+ this._disabledInputs[this._disabledInputs.length] = target;
+ },
+
+ /* Is the first field in a jQuery collection disabled as a datepicker?
+ @param target element - the target input field or division or span
+ @return boolean - true if disabled, false if enabled */
+ _isDisabledDatepicker: function(target) {
+ if (!target) {
+ return false;
+ }
+ for (var i = 0; i < this._disabledInputs.length; i++) {
+ if (this._disabledInputs[i] == target)
+ return true;
+ }
+ return false;
+ },
+
+ /* Retrieve the instance data for the target control.
+ @param target element - the target input field or division or span
+ @return object - the associated instance data
+ @throws error if a jQuery problem getting data */
+ _getInst: function(target) {
+ try {
+ return $.data(target, PROP_NAME);
+ }
+ catch (err) {
+ throw 'Missing instance data for this datepicker';
+ }
+ },
+
+ /* Update or retrieve the settings for a date picker attached to an input field or division.
+ @param target element - the target input field or division or span
+ @param name object - the new settings to update or
+ string - the name of the setting to change or retrieve,
+ when retrieving also 'all' for all instance settings or
+ 'defaults' for all global defaults
+ @param value any - the new value for the setting
+ (omit if above is an object or to retrieve a value) */
+ _optionDatepicker: function(target, name, value) {
+ var inst = this._getInst(target);
+ if (arguments.length == 2 && typeof name == 'string') {
+ return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
+ (inst ? (name == 'all' ? $.extend({}, inst.settings) :
+ this._get(inst, name)) : null));
+ }
+ var settings = name || {};
+ if (typeof name == 'string') {
+ settings = {};
+ settings[name] = value;
+ }
+ if (inst) {
+ if (this._curInst == inst) {
+ this._hideDatepicker();
+ }
+ var date = this._getDateDatepicker(target, true);
+ var minDate = this._getMinMaxDate(inst, 'min');
+ var maxDate = this._getMinMaxDate(inst, 'max');
+ extendRemove(inst.settings, settings);
+ // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
+ if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
+ inst.settings.minDate = this._formatDate(inst, minDate);
+ if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
+ inst.settings.maxDate = this._formatDate(inst, maxDate);
+ this._attachments($(target), inst);
+ this._autoSize(inst);
+ this._setDate(inst, date);
+ this._updateAlternate(inst);
+ this._updateDatepicker(inst);
+ }
+ },
+
+ // change method deprecated
+ _changeDatepicker: function(target, name, value) {
+ this._optionDatepicker(target, name, value);
+ },
+
+ /* Redraw the date picker attached to an input field or division.
+ @param target element - the target input field or division or span */
+ _refreshDatepicker: function(target) {
+ var inst = this._getInst(target);
+ if (inst) {
+ this._updateDatepicker(inst);
+ }
+ },
+
+ /* Set the dates for a jQuery selection.
+ @param target element - the target input field or division or span
+ @param date Date - the new date */
+ _setDateDatepicker: function(target, date) {
+ var inst = this._getInst(target);
+ if (inst) {
+ this._setDate(inst, date);
+ this._updateDatepicker(inst);
+ this._updateAlternate(inst);
+ }
+ },
+
+ /* Get the date(s) for the first entry in a jQuery selection.
+ @param target element - the target input field or division or span
+ @param noDefault boolean - true if no default date is to be used
+ @return Date - the current date */
+ _getDateDatepicker: function(target, noDefault) {
+ var inst = this._getInst(target);
+ if (inst && !inst.inline)
+ this._setDateFromField(inst, noDefault);
+ return (inst ? this._getDate(inst) : null);
+ },
+
+ /* Handle keystrokes. */
+ _doKeyDown: function(event) {
+ var inst = $.datepicker._getInst(event.target);
+ var handled = true;
+ var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
+ inst._keyEvent = true;
+ if ($.datepicker._datepickerShowing)
+ switch (event.keyCode) {
+ case 9: $.datepicker._hideDatepicker();
+ handled = false;
+ break; // hide on tab out
+ case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
+ $.datepicker._currentClass + ')', inst.dpDiv);
+ if (sel[0])
+ $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
+ var onSelect = $.datepicker._get(inst, 'onSelect');
+ if (onSelect) {
+ var dateStr = $.datepicker._formatDate(inst);
+
+ // trigger custom callback
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
+ }
+ else
+ $.datepicker._hideDatepicker();
+ return false; // don't submit the form
+ break; // select the value on enter
+ case 27: $.datepicker._hideDatepicker();
+ break; // hide on escape
+ case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+ -$.datepicker._get(inst, 'stepBigMonths') :
+ -$.datepicker._get(inst, 'stepMonths')), 'M');
+ break; // previous month/year on page up/+ ctrl
+ case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+ +$.datepicker._get(inst, 'stepBigMonths') :
+ +$.datepicker._get(inst, 'stepMonths')), 'M');
+ break; // next month/year on page down/+ ctrl
+ case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
+ handled = event.ctrlKey || event.metaKey;
+ break; // clear on ctrl or command +end
+ case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
+ handled = event.ctrlKey || event.metaKey;
+ break; // current on ctrl or command +home
+ case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
+ handled = event.ctrlKey || event.metaKey;
+ // -1 day on ctrl or command +left
+ if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+ -$.datepicker._get(inst, 'stepBigMonths') :
+ -$.datepicker._get(inst, 'stepMonths')), 'M');
+ // next month/year on alt +left on Mac
+ break;
+ case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
+ handled = event.ctrlKey || event.metaKey;
+ break; // -1 week on ctrl or command +up
+ case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
+ handled = event.ctrlKey || event.metaKey;
+ // +1 day on ctrl or command +right
+ if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
+ +$.datepicker._get(inst, 'stepBigMonths') :
+ +$.datepicker._get(inst, 'stepMonths')), 'M');
+ // next month/year on alt +right
+ break;
+ case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
+ handled = event.ctrlKey || event.metaKey;
+ break; // +1 week on ctrl or command +down
+ default: handled = false;
+ }
+ else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
+ $.datepicker._showDatepicker(this);
+ else {
+ handled = false;
+ }
+ if (handled) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ },
+
+ /* Filter entered characters - based on date format. */
+ _doKeyPress: function(event) {
+ var inst = $.datepicker._getInst(event.target);
+ if ($.datepicker._get(inst, 'constrainInput')) {
+ var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
+ var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
+ return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
+ }
+ },
+
+ /* Synchronise manual entry and field/alternate field. */
+ _doKeyUp: function(event) {
+ var inst = $.datepicker._getInst(event.target);
+ if (inst.input.val() != inst.lastVal) {
+ try {
+ var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
+ (inst.input ? inst.input.val() : null),
+ $.datepicker._getFormatConfig(inst));
+ if (date) { // only if valid
+ $.datepicker._setDateFromField(inst);
+ $.datepicker._updateAlternate(inst);
+ $.datepicker._updateDatepicker(inst);
+ }
+ }
+ catch (event) {
+ $.datepicker.log(event);
+ }
+ }
+ return true;
+ },
+
+ /* Pop-up the date picker for a given input field.
+ If false returned from beforeShow event handler do not show.
+ @param input element - the input field attached to the date picker or
+ event - if triggered by focus */
+ _showDatepicker: function(input) {
+ input = input.target || input;
+ if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
+ input = $('input', input.parentNode)[0];
+ if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
+ return;
+ var inst = $.datepicker._getInst(input);
+ if ($.datepicker._curInst && $.datepicker._curInst != inst) {
+ if ( $.datepicker._datepickerShowing ) {
+ $.datepicker._triggerOnClose($.datepicker._curInst);
+ }
+ $.datepicker._curInst.dpDiv.stop(true, true);
+ }
+ var beforeShow = $.datepicker._get(inst, 'beforeShow');
+ var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
+ if(beforeShowSettings === false){
+ //false
+ return;
+ }
+ extendRemove(inst.settings, beforeShowSettings);
+ inst.lastVal = null;
+ $.datepicker._lastInput = input;
+ $.datepicker._setDateFromField(inst);
+ if ($.datepicker._inDialog) // hide cursor
+ input.value = '';
+ if (!$.datepicker._pos) { // position below input
+ $.datepicker._pos = $.datepicker._findPos(input);
+ $.datepicker._pos[1] += input.offsetHeight; // add the height
+ }
+ var isFixed = false;
+ $(input).parents().each(function() {
+ isFixed |= $(this).css('position') == 'fixed';
+ return !isFixed;
+ });
+ if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
+ $.datepicker._pos[0] -= document.documentElement.scrollLeft;
+ $.datepicker._pos[1] -= document.documentElement.scrollTop;
+ }
+ var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
+ $.datepicker._pos = null;
+ //to avoid flashes on Firefox
+ inst.dpDiv.empty();
+ // determine sizing offscreen
+ inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
+ $.datepicker._updateDatepicker(inst);
+ // fix width for dynamic number of date pickers
+ // and adjust position before showing
+ offset = $.datepicker._checkOffset(inst, offset, isFixed);
+ inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
+ 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
+ left: offset.left + 'px', top: offset.top + 'px'});
+ if (!inst.inline) {
+ var showAnim = $.datepicker._get(inst, 'showAnim');
+ var duration = $.datepicker._get(inst, 'duration');
+ var postProcess = function() {
+ var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
+ if( !! cover.length ){
+ var borders = $.datepicker._getBorders(inst.dpDiv);
+ cover.css({left: -borders[0], top: -borders[1],
+ width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
+ }
+ };
+ inst.dpDiv.zIndex($(input).zIndex()+1);
+ $.datepicker._datepickerShowing = true;
+ if ($.effects && $.effects[showAnim])
+ inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
+ else
+ inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
+ if (!showAnim || !duration)
+ postProcess();
+ if (inst.input.is(':visible') && !inst.input.is(':disabled'))
+ inst.input.focus();
+ $.datepicker._curInst = inst;
+ }
+ },
+
+ /* Generate the date picker content. */
+ _updateDatepicker: function(inst) {
+ var self = this;
+ self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
+ var borders = $.datepicker._getBorders(inst.dpDiv);
+ instActive = inst; // for delegate hover events
+ inst.dpDiv.empty().append(this._generateHTML(inst));
+ var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
+ if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
+ cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
+ }
+ inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
+ var numMonths = this._getNumberOfMonths(inst);
+ var cols = numMonths[1];
+ var width = 17;
+ inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
+ if (cols > 1)
+ inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
+ inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
+ 'Class']('ui-datepicker-multi');
+ inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
+ 'Class']('ui-datepicker-rtl');
+ if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
+ // #6694 - don't focus the input if it's already focused
+ // this breaks the change event in IE
+ inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
+ inst.input.focus();
+ // deffered render of the years select (to avoid flashes on Firefox)
+ if( inst.yearshtml ){
+ var origyearshtml = inst.yearshtml;
+ setTimeout(function(){
+ //assure that inst.yearshtml didn't change.
+ if( origyearshtml === inst.yearshtml && inst.yearshtml ){
+ inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
+ }
+ origyearshtml = inst.yearshtml = null;
+ }, 0);
+ }
+ },
+
+ /* Retrieve the size of left and top borders for an element.
+ @param elem (jQuery object) the element of interest
+ @return (number[2]) the left and top borders */
+ _getBorders: function(elem) {
+ var convert = function(value) {
+ return {thin: 1, medium: 2, thick: 3}[value] || value;
+ };
+ return [parseFloat(convert(elem.css('border-left-width'))),
+ parseFloat(convert(elem.css('border-top-width')))];
+ },
+
+ /* Check positioning to remain on screen. */
+ _checkOffset: function(inst, offset, isFixed) {
+ var dpWidth = inst.dpDiv.outerWidth();
+ var dpHeight = inst.dpDiv.outerHeight();
+ var inputWidth = inst.input ? inst.input.outerWidth() : 0;
+ var inputHeight = inst.input ? inst.input.outerHeight() : 0;
+ var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
+ var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
+
+ offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
+ offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
+ offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
+
+ // now check if datepicker is showing outside window viewport - move to a better place if so.
+ offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
+ Math.abs(offset.left + dpWidth - viewWidth) : 0);
+ offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
+ Math.abs(dpHeight + inputHeight) : 0);
+
+ return offset;
+ },
+
+ /* Find an object's position on the screen. */
+ _findPos: function(obj) {
+ var inst = this._getInst(obj);
+ var isRTL = this._get(inst, 'isRTL');
+ while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
+ obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
+ }
+ var position = $(obj).offset();
+ return [position.left, position.top];
+ },
+
+ /* Trigger custom callback of onClose. */
+ _triggerOnClose: function(inst) {
+ var onClose = this._get(inst, 'onClose');
+ if (onClose)
+ onClose.apply((inst.input ? inst.input[0] : null),
+ [(inst.input ? inst.input.val() : ''), inst]);
+ },
+
+ /* Hide the date picker from view.
+ @param input element - the input field attached to the date picker */
+ _hideDatepicker: function(input) {
+ var inst = this._curInst;
+ if (!inst || (input && inst != $.data(input, PROP_NAME)))
+ return;
+ if (this._datepickerShowing) {
+ var showAnim = this._get(inst, 'showAnim');
+ var duration = this._get(inst, 'duration');
+ var postProcess = function() {
+ $.datepicker._tidyDialog(inst);
+ this._curInst = null;
+ };
+ if ($.effects && $.effects[showAnim])
+ inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
+ else
+ inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
+ (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
+ if (!showAnim)
+ postProcess();
+ $.datepicker._triggerOnClose(inst);
+ this._datepickerShowing = false;
+ this._lastInput = null;
+ if (this._inDialog) {
+ this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
+ if ($.blockUI) {
+ $.unblockUI();
+ $('body').append(this.dpDiv);
+ }
+ }
+ this._inDialog = false;
+ }
+ },
+
+ /* Tidy up after a dialog display. */
+ _tidyDialog: function(inst) {
+ inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
+ },
+
+ /* Close date picker if clicked elsewhere. */
+ _checkExternalClick: function(event) {
+ if (!$.datepicker._curInst)
+ return;
+ var $target = $(event.target);
+ if ($target[0].id != $.datepicker._mainDivId &&
+ $target.parents('#' + $.datepicker._mainDivId).length == 0 &&
+ !$target.hasClass($.datepicker.markerClassName) &&
+ !$target.hasClass($.datepicker._triggerClass) &&
+ $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))
+ $.datepicker._hideDatepicker();
+ },
+
+ /* Adjust one of the date sub-fields. */
+ _adjustDate: function(id, offset, period) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ if (this._isDisabledDatepicker(target[0])) {
+ return;
+ }
+ this._adjustInstDate(inst, offset +
+ (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
+ period);
+ this._updateDatepicker(inst);
+ },
+
+ /* Action for current link. */
+ _gotoToday: function(id) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
+ inst.selectedDay = inst.currentDay;
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth;
+ inst.drawYear = inst.selectedYear = inst.currentYear;
+ }
+ else {
+ var date = new Date();
+ inst.selectedDay = date.getDate();
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
+ inst.drawYear = inst.selectedYear = date.getFullYear();
+ }
+ this._notifyChange(inst);
+ this._adjustDate(target);
+ },
+
+ /* Action for selecting a new month/year. */
+ _selectMonthYear: function(id, select, period) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
+ inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
+ parseInt(select.options[select.selectedIndex].value,10);
+ this._notifyChange(inst);
+ this._adjustDate(target);
+ },
+
+ /* Action for selecting a day. */
+ _selectDay: function(id, month, year, td) {
+ var target = $(id);
+ if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
+ return;
+ }
+ var inst = this._getInst(target[0]);
+ inst.selectedDay = inst.currentDay = $('a', td).html();
+ inst.selectedMonth = inst.currentMonth = month;
+ inst.selectedYear = inst.currentYear = year;
+ this._selectDate(id, this._formatDate(inst,
+ inst.currentDay, inst.currentMonth, inst.currentYear));
+ },
+
+ /* Erase the input field and hide the date picker. */
+ _clearDate: function(id) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ this._selectDate(target, '');
+ },
+
+ /* Update the input field with the selected date. */
+ _selectDate: function(id, dateStr) {
+ var target = $(id);
+ var inst = this._getInst(target[0]);
+ dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
+ if (inst.input)
+ inst.input.val(dateStr);
+ this._updateAlternate(inst);
+ var onSelect = this._get(inst, 'onSelect');
+ if (onSelect)
+ onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
+ else if (inst.input)
+ inst.input.trigger('change'); // fire the change event
+ if (inst.inline)
+ this._updateDatepicker(inst);
+ else {
+ this._hideDatepicker();
+ this._lastInput = inst.input[0];
+ if (typeof(inst.input[0]) != 'object')
+ inst.input.focus(); // restore focus
+ this._lastInput = null;
+ }
+ },
+
+ /* Update any alternate field to synchronise with the main field. */
+ _updateAlternate: function(inst) {
+ var altField = this._get(inst, 'altField');
+ if (altField) { // update alternate field too
+ var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
+ var date = this._getDate(inst);
+ var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
+ $(altField).each(function() { $(this).val(dateStr); });
+ }
+ },
+
+ /* Set as beforeShowDay function to prevent selection of weekends.
+ @param date Date - the date to customise
+ @return [boolean, string] - is this date selectable?, what is its CSS class? */
+ noWeekends: function(date) {
+ var day = date.getDay();
+ return [(day > 0 && day < 6), ''];
+ },
+
+ /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
+ @param date Date - the date to get the week for
+ @return number - the number of the week within the year that contains this date */
+ iso8601Week: function(date) {
+ var checkDate = new Date(date.getTime());
+ // Find Thursday of this week starting on Monday
+ checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
+ var time = checkDate.getTime();
+ checkDate.setMonth(0); // Compare with Jan 1
+ checkDate.setDate(1);
+ return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
+ },
+
+ /* Parse a string value into a date object.
+ See formatDate below for the possible formats.
+
+ @param format string - the expected format of the date
+ @param value string - the date in the above format
+ @param settings Object - attributes include:
+ shortYearCutoff number - the cutoff year for determining the century (optional)
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
+ dayNames string[7] - names of the days from Sunday (optional)
+ monthNamesShort string[12] - abbreviated names of the months (optional)
+ monthNames string[12] - names of the months (optional)
+ @return Date - the extracted date value or null if value is blank */
+ parseDate: function (format, value, settings) {
+ if (format == null || value == null)
+ throw 'Invalid arguments';
+ value = (typeof value == 'object' ? value.toString() : value + '');
+ if (value == '')
+ return null;
+ var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
+ shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
+ var year = -1;
+ var month = -1;
+ var day = -1;
+ var doy = -1;
+ var literal = false;
+ // Check whether a format character is doubled
+ var lookAhead = function(match) {
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+ if (matches)
+ iFormat++;
+ return matches;
+ };
+ // Extract a number from the string value
+ var getNumber = function(match) {
+ var isDoubled = lookAhead(match);
+ var size = (match == '@' ? 14 : (match == '!' ? 20 :
+ (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
+ var digits = new RegExp('^\\d{1,' + size + '}');
+ var num = value.substring(iValue).match(digits);
+ if (!num)
+ throw 'Missing number at position ' + iValue;
+ iValue += num[0].length;
+ return parseInt(num[0], 10);
+ };
+ // Extract a name from the string value and convert to an index
+ var getName = function(match, shortNames, longNames) {
+ var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
+ return [ [k, v] ];
+ }).sort(function (a, b) {
+ return -(a[1].length - b[1].length);
+ });
+ var index = -1;
+ $.each(names, function (i, pair) {
+ var name = pair[1];
+ if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
+ index = pair[0];
+ iValue += name.length;
+ return false;
+ }
+ });
+ if (index != -1)
+ return index + 1;
+ else
+ throw 'Unknown name at position ' + iValue;
+ };
+ // Confirm that a literal character matches the string value
+ var checkLiteral = function() {
+ if (value.charAt(iValue) != format.charAt(iFormat))
+ throw 'Unexpected literal at position ' + iValue;
+ iValue++;
+ };
+ var iValue = 0;
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
+ if (literal)
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+ literal = false;
+ else
+ checkLiteral();
+ else
+ switch (format.charAt(iFormat)) {
+ case 'd':
+ day = getNumber('d');
+ break;
+ case 'D':
+ getName('D', dayNamesShort, dayNames);
+ break;
+ case 'o':
+ doy = getNumber('o');
+ break;
+ case 'm':
+ month = getNumber('m');
+ break;
+ case 'M':
+ month = getName('M', monthNamesShort, monthNames);
+ break;
+ case 'y':
+ year = getNumber('y');
+ break;
+ case '@':
+ var date = new Date(getNumber('@'));
+ year = date.getFullYear();
+ month = date.getMonth() + 1;
+ day = date.getDate();
+ break;
+ case '!':
+ var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
+ year = date.getFullYear();
+ month = date.getMonth() + 1;
+ day = date.getDate();
+ break;
+ case "'":
+ if (lookAhead("'"))
+ checkLiteral();
+ else
+ literal = true;
+ break;
+ default:
+ checkLiteral();
+ }
+ }
+ if (iValue < value.length){
+ throw "Extra/unparsed characters found in date: " + value.substring(iValue);
+ }
+ if (year == -1)
+ year = new Date().getFullYear();
+ else if (year < 100)
+ year += new Date().getFullYear() - new Date().getFullYear() % 100 +
+ (year <= shortYearCutoff ? 0 : -100);
+ if (doy > -1) {
+ month = 1;
+ day = doy;
+ do {
+ var dim = this._getDaysInMonth(year, month - 1);
+ if (day <= dim)
+ break;
+ month++;
+ day -= dim;
+ } while (true);
+ }
+ var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
+ if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
+ throw 'Invalid date'; // E.g. 31/02/00
+ return date;
+ },
+
+ /* Standard date formats. */
+ ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
+ 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', // RFC 822
+ TICKS: '!',
+ TIMESTAMP: '@',
+ W3C: 'yy-mm-dd', // ISO 8601
+
+ _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
+ Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
+
+ /* Format a date object into a string value.
+ The format can be combinations of the following:
+ d - day of month (no leading zero)
+ dd - day of month (two digit)
+ o - day of year (no leading zeros)
+ oo - day of year (three digit)
+ D - day name short
+ DD - day name long
+ m - month of year (no leading zero)
+ mm - month of year (two digit)
+ M - month name short
+ MM - month name long
+ y - year (two digit)
+ yy - year (four digit)
+ @ - Unix timestamp (ms since 01/01/1970)
+ ! - Windows ticks (100ns since 01/01/0001)
+ '...' - literal text
+ '' - single quote
+
+ @param format string - the desired format of the date
+ @param date Date - the date value to format
+ @param settings Object - attributes include:
+ dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
+ dayNames string[7] - names of the days from Sunday (optional)
+ monthNamesShort string[12] - abbreviated names of the months (optional)
+ monthNames string[12] - names of the months (optional)
+ @return string - the date in the above format */
+ formatDate: function (format, date, settings) {
+ if (!date)
+ return '';
+ var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
+ var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
+ var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
+ var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
+ // Check whether a format character is doubled
+ var lookAhead = function(match) {
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+ if (matches)
+ iFormat++;
+ return matches;
+ };
+ // Format a number, with leading zero if necessary
+ var formatNumber = function(match, value, len) {
+ var num = '' + value;
+ if (lookAhead(match))
+ while (num.length < len)
+ num = '0' + num;
+ return num;
+ };
+ // Format a name, short or long as requested
+ var formatName = function(match, value, shortNames, longNames) {
+ return (lookAhead(match) ? longNames[value] : shortNames[value]);
+ };
+ var output = '';
+ var literal = false;
+ if (date)
+ for (var iFormat = 0; iFormat < format.length; iFormat++) {
+ if (literal)
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+ literal = false;
+ else
+ output += format.charAt(iFormat);
+ else
+ switch (format.charAt(iFormat)) {
+ case 'd':
+ output += formatNumber('d', date.getDate(), 2);
+ break;
+ case 'D':
+ output += formatName('D', date.getDay(), dayNamesShort, dayNames);
+ break;
+ case 'o':
+ output += formatNumber('o',
+ Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
+ break;
+ case 'm':
+ output += formatNumber('m', date.getMonth() + 1, 2);
+ break;
+ case 'M':
+ output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
+ break;
+ case 'y':
+ output += (lookAhead('y') ? date.getFullYear() :
+ (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
+ break;
+ case '@':
+ output += date.getTime();
+ break;
+ case '!':
+ output += date.getTime() * 10000 + this._ticksTo1970;
+ break;
+ case "'":
+ if (lookAhead("'"))
+ output += "'";
+ else
+ literal = true;
+ break;
+ default:
+ output += format.charAt(iFormat);
+ }
+ }
+ return output;
+ },
+
+ /* Extract all possible characters from the date format. */
+ _possibleChars: function (format) {
+ var chars = '';
+ var literal = false;
+ // Check whether a format character is doubled
+ var lookAhead = function(match) {
+ var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
+ if (matches)
+ iFormat++;
+ return matches;
+ };
+ for (var iFormat = 0; iFormat < format.length; iFormat++)
+ if (literal)
+ if (format.charAt(iFormat) == "'" && !lookAhead("'"))
+ literal = false;
+ else
+ chars += format.charAt(iFormat);
+ else
+ switch (format.charAt(iFormat)) {
+ case 'd': case 'm': case 'y': case '@':
+ chars += '0123456789';
+ break;
+ case 'D': case 'M':
+ return null; // Accept anything
+ case "'":
+ if (lookAhead("'"))
+ chars += "'";
+ else
+ literal = true;
+ break;
+ default:
+ chars += format.charAt(iFormat);
+ }
+ return chars;
+ },
+
+ /* Get a setting value, defaulting if necessary. */
+ _get: function(inst, name) {
+ return inst.settings[name] !== undefined ?
+ inst.settings[name] : this._defaults[name];
+ },
+
+ /* Parse existing date and initialise date picker. */
+ _setDateFromField: function(inst, noDefault) {
+ if (inst.input.val() == inst.lastVal) {
+ return;
+ }
+ var dateFormat = this._get(inst, 'dateFormat');
+ var dates = inst.lastVal = inst.input ? inst.input.val() : null;
+ var date, defaultDate;
+ date = defaultDate = this._getDefaultDate(inst);
+ var settings = this._getFormatConfig(inst);
+ try {
+ date = this.parseDate(dateFormat, dates, settings) || defaultDate;
+ } catch (event) {
+ this.log(event);
+ dates = (noDefault ? '' : dates);
+ }
+ inst.selectedDay = date.getDate();
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
+ inst.drawYear = inst.selectedYear = date.getFullYear();
+ inst.currentDay = (dates ? date.getDate() : 0);
+ inst.currentMonth = (dates ? date.getMonth() : 0);
+ inst.currentYear = (dates ? date.getFullYear() : 0);
+ this._adjustInstDate(inst);
+ },
+
+ /* Retrieve the default date shown on opening. */
+ _getDefaultDate: function(inst) {
+ return this._restrictMinMax(inst,
+ this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
+ },
+
+ /* A date may be specified as an exact value or a relative one. */
+ _determineDate: function(inst, date, defaultDate) {
+ var offsetNumeric = function(offset) {
+ var date = new Date();
+ date.setDate(date.getDate() + offset);
+ return date;
+ };
+ var offsetString = function(offset) {
+ try {
+ return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
+ offset, $.datepicker._getFormatConfig(inst));
+ }
+ catch (e) {
+ // Ignore
+ }
+ var date = (offset.toLowerCase().match(/^c/) ?
+ $.datepicker._getDate(inst) : null) || new Date();
+ var year = date.getFullYear();
+ var month = date.getMonth();
+ var day = date.getDate();
+ var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
+ var matches = pattern.exec(offset);
+ while (matches) {
+ switch (matches[2] || 'd') {
+ case 'd' : case 'D' :
+ day += parseInt(matches[1],10); break;
+ case 'w' : case 'W' :
+ day += parseInt(matches[1],10) * 7; break;
+ case 'm' : case 'M' :
+ month += parseInt(matches[1],10);
+ day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+ break;
+ case 'y': case 'Y' :
+ year += parseInt(matches[1],10);
+ day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
+ break;
+ }
+ matches = pattern.exec(offset);
+ }
+ return new Date(year, month, day);
+ };
+ var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
+ (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
+ newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
+ if (newDate) {
+ newDate.setHours(0);
+ newDate.setMinutes(0);
+ newDate.setSeconds(0);
+ newDate.setMilliseconds(0);
+ }
+ return this._daylightSavingAdjust(newDate);
+ },
+
+ /* Handle switch to/from daylight saving.
+ Hours may be non-zero on daylight saving cut-over:
+ > 12 when midnight changeover, but then cannot generate
+ midnight datetime, so jump to 1AM, otherwise reset.
+ @param date (Date) the date to check
+ @return (Date) the corrected date */
+ _daylightSavingAdjust: function(date) {
+ if (!date) return null;
+ date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
+ return date;
+ },
+
+ /* Set the date(s) directly. */
+ _setDate: function(inst, date, noChange) {
+ var clear = !date;
+ var origMonth = inst.selectedMonth;
+ var origYear = inst.selectedYear;
+ var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
+ inst.selectedDay = inst.currentDay = newDate.getDate();
+ inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
+ inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
+ if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
+ this._notifyChange(inst);
+ this._adjustInstDate(inst);
+ if (inst.input) {
+ inst.input.val(clear ? '' : this._formatDate(inst));
+ }
+ },
+
+ /* Retrieve the date(s) directly. */
+ _getDate: function(inst) {
+ var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
+ this._daylightSavingAdjust(new Date(
+ inst.currentYear, inst.currentMonth, inst.currentDay)));
+ return startDate;
+ },
+
+ /* Generate the HTML for the current state of the date picker. */
+ _generateHTML: function(inst) {
+ var today = new Date();
+ today = this._daylightSavingAdjust(
+ new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
+ var isRTL = this._get(inst, 'isRTL');
+ var showButtonPanel = this._get(inst, 'showButtonPanel');
+ var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
+ var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
+ var numMonths = this._getNumberOfMonths(inst);
+ var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
+ var stepMonths = this._get(inst, 'stepMonths');
+ var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
+ var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
+ new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
+ var minDate = this._getMinMaxDate(inst, 'min');
+ var maxDate = this._getMinMaxDate(inst, 'max');
+ var drawMonth = inst.drawMonth - showCurrentAtPos;
+ var drawYear = inst.drawYear;
+ if (drawMonth < 0) {
+ drawMonth += 12;
+ drawYear--;
+ }
+ if (maxDate) {
+ var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
+ maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
+ maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
+ while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
+ drawMonth--;
+ if (drawMonth < 0) {
+ drawMonth = 11;
+ drawYear--;
+ }
+ }
+ }
+ inst.drawMonth = drawMonth;
+ inst.drawYear = drawYear;
+ var prevText = this._get(inst, 'prevText');
+ prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
+ this._getFormatConfig(inst)));
+ var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
+ '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+ '.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
+ ' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
+ (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+ prevText +'"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>'));
+ var nextText = this._get(inst, 'nextText');
+ nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
+ this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
+ this._getFormatConfig(inst)));
+ var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
+ '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+ '.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
+ ' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
+ (hideIfNoPrevNext ? '' : '<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+ nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>'));
+ var currentText = this._get(inst, 'currentText');
+ var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
+ currentText = (!navigationAsDateFormat ? currentText :
+ this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
+ var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+ '.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
+ var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
+ (this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
+ '.datepicker._gotoToday(\'#' + inst.id + '\');"' +
+ '>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
+ var firstDay = parseInt(this._get(inst, 'firstDay'),10);
+ firstDay = (isNaN(firstDay) ? 0 : firstDay);
+ var showWeek = this._get(inst, 'showWeek');
+ var dayNames = this._get(inst, 'dayNames');
+ var dayNamesShort = this._get(inst, 'dayNamesShort');
+ var dayNamesMin = this._get(inst, 'dayNamesMin');
+ var monthNames = this._get(inst, 'monthNames');
+ var monthNamesShort = this._get(inst, 'monthNamesShort');
+ var beforeShowDay = this._get(inst, 'beforeShowDay');
+ var showOtherMonths = this._get(inst, 'showOtherMonths');
+ var selectOtherMonths = this._get(inst, 'selectOtherMonths');
+ var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
+ var defaultDate = this._getDefaultDate(inst);
+ var html = '';
+ for (var row = 0; row < numMonths[0]; row++) {
+ var group = '';
+ this.maxRows = 4;
+ for (var col = 0; col < numMonths[1]; col++) {
+ var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
+ var cornerClass = ' ui-corner-all';
+ var calender = '';
+ if (isMultiMonth) {
+ calender += '<div class="ui-datepicker-group';
+ if (numMonths[1] > 1)
+ switch (col) {
+ case 0: calender += ' ui-datepicker-group-first';
+ cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
+ case numMonths[1]-1: calender += ' ui-datepicker-group-last';
+ cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
+ default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
+ }
+ calender += '">';
+ }
+ calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
+ (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
+ (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
+ this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
+ row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
+ '</div><table class="ui-datepicker-calendar"><thead>' +
+ '<tr>';
+ var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
+ for (var dow = 0; dow < 7; dow++) { // days of the week
+ var day = (dow + firstDay) % 7;
+ thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
+ '<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
+ }
+ calender += thead + '</tr></thead><tbody>';
+ var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
+ if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
+ inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
+ var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
+ var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
+ var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
+ this.maxRows = numRows;
+ var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
+ for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
+ calender += '<tr>';
+ var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
+ this._get(inst, 'calculateWeek')(printDate) + '</td>');
+ for (var dow = 0; dow < 7; dow++) { // create date picker days
+ var daySettings = (beforeShowDay ?
+ beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
+ var otherMonth = (printDate.getMonth() != drawMonth);
+ var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
+ (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
+ tbody += '<td class="' +
+ ((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
+ (otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
+ ((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
+ (defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
+ // or defaultDate is current printedDate and defaultDate is selectedDate
+ ' ' + this._dayOverClass : '') + // highlight selected day
+ (unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
+ (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
+ (printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
+ (printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
+ ((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
+ (unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
+ inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
+ (otherMonth && !showOtherMonths ? '&#xa0;' : // display for other months
+ (unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
+ (printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
+ (printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
+ (otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
+ '" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
+ printDate.setDate(printDate.getDate() + 1);
+ printDate = this._daylightSavingAdjust(printDate);
+ }
+ calender += tbody + '</tr>';
+ }
+ drawMonth++;
+ if (drawMonth > 11) {
+ drawMonth = 0;
+ drawYear++;
+ }
+ calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
+ ((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
+ group += calender;
+ }
+ html += group;
+ }
+ html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
+ '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
+ inst._keyEvent = false;
+ return html;
+ },
+
+ /* Generate the month and year header. */
+ _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
+ secondary, monthNames, monthNamesShort) {
+ var changeMonth = this._get(inst, 'changeMonth');
+ var changeYear = this._get(inst, 'changeYear');
+ var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
+ var html = '<div class="ui-datepicker-title">';
+ var monthHtml = '';
+ // month selection
+ if (secondary || !changeMonth)
+ monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
+ else {
+ var inMinYear = (minDate && minDate.getFullYear() == drawYear);
+ var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
+ monthHtml += '<select class="ui-datepicker-month" ' +
+ 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
+ '>';
+ for (var month = 0; month < 12; month++) {
+ if ((!inMinYear || month >= minDate.getMonth()) &&
+ (!inMaxYear || month <= maxDate.getMonth()))
+ monthHtml += '<option value="' + month + '"' +
+ (month == drawMonth ? ' selected="selected"' : '') +
+ '>' + monthNamesShort[month] + '</option>';
+ }
+ monthHtml += '</select>';
+ }
+ if (!showMonthAfterYear)
+ html += monthHtml + (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '');
+ // year selection
+ if ( !inst.yearshtml ) {
+ inst.yearshtml = '';
+ if (secondary || !changeYear)
+ html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
+ else {
+ // determine range of years to display
+ var years = this._get(inst, 'yearRange').split(':');
+ var thisYear = new Date().getFullYear();
+ var determineYear = function(value) {
+ var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
+ (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
+ parseInt(value, 10)));
+ return (isNaN(year) ? thisYear : year);
+ };
+ var year = determineYear(years[0]);
+ var endYear = Math.max(year, determineYear(years[1] || ''));
+ year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
+ endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
+ inst.yearshtml += '<select class="ui-datepicker-year" ' +
+ 'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
+ '>';
+ for (; year <= endYear; year++) {
+ inst.yearshtml += '<option value="' + year + '"' +
+ (year == drawYear ? ' selected="selected"' : '') +
+ '>' + year + '</option>';
+ }
+ inst.yearshtml += '</select>';
+
+ html += inst.yearshtml;
+ inst.yearshtml = null;
+ }
+ }
+ html += this._get(inst, 'yearSuffix');
+ if (showMonthAfterYear)
+ html += (secondary || !(changeMonth && changeYear) ? '&#xa0;' : '') + monthHtml;
+ html += '</div>'; // Close datepicker_header
+ return html;
+ },
+
+ /* Adjust one of the date sub-fields. */
+ _adjustInstDate: function(inst, offset, period) {
+ var year = inst.drawYear + (period == 'Y' ? offset : 0);
+ var month = inst.drawMonth + (period == 'M' ? offset : 0);
+ var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
+ (period == 'D' ? offset : 0);
+ var date = this._restrictMinMax(inst,
+ this._daylightSavingAdjust(new Date(year, month, day)));
+ inst.selectedDay = date.getDate();
+ inst.drawMonth = inst.selectedMonth = date.getMonth();
+ inst.drawYear = inst.selectedYear = date.getFullYear();
+ if (period == 'M' || period == 'Y')
+ this._notifyChange(inst);
+ },
+
+ /* Ensure a date is within any min/max bounds. */
+ _restrictMinMax: function(inst, date) {
+ var minDate = this._getMinMaxDate(inst, 'min');
+ var maxDate = this._getMinMaxDate(inst, 'max');
+ var newDate = (minDate && date < minDate ? minDate : date);
+ newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
+ return newDate;
+ },
+
+ /* Notify change of month/year. */
+ _notifyChange: function(inst) {
+ var onChange = this._get(inst, 'onChangeMonthYear');
+ if (onChange)
+ onChange.apply((inst.input ? inst.input[0] : null),
+ [inst.selectedYear, inst.selectedMonth + 1, inst]);
+ },
+
+ /* Determine the number of months to show. */
+ _getNumberOfMonths: function(inst) {
+ var numMonths = this._get(inst, 'numberOfMonths');
+ return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
+ },
+
+ /* Determine the current maximum date - ensure no time components are set. */
+ _getMinMaxDate: function(inst, minMax) {
+ return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
+ },
+
+ /* Find the number of days in a given month. */
+ _getDaysInMonth: function(year, month) {
+ return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
+ },
+
+ /* Find the day of the week of the first of a month. */
+ _getFirstDayOfMonth: function(year, month) {
+ return new Date(year, month, 1).getDay();
+ },
+
+ /* Determines if we should allow a "next/prev" month display change. */
+ _canAdjustMonth: function(inst, offset, curYear, curMonth) {
+ var numMonths = this._getNumberOfMonths(inst);
+ var date = this._daylightSavingAdjust(new Date(curYear,
+ curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
+ if (offset < 0)
+ date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
+ return this._isInRange(inst, date);
+ },
+
+ /* Is the given date in the accepted range? */
+ _isInRange: function(inst, date) {
+ var minDate = this._getMinMaxDate(inst, 'min');
+ var maxDate = this._getMinMaxDate(inst, 'max');
+ return ((!minDate || date.getTime() >= minDate.getTime()) &&
+ (!maxDate || date.getTime() <= maxDate.getTime()));
+ },
+
+ /* Provide the configuration settings for formatting/parsing. */
+ _getFormatConfig: function(inst) {
+ var shortYearCutoff = this._get(inst, 'shortYearCutoff');
+ shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
+ new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
+ return {shortYearCutoff: shortYearCutoff,
+ dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
+ monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
+ },
+
+ /* Format the given date for display. */
+ _formatDate: function(inst, day, month, year) {
+ if (!day) {
+ inst.currentDay = inst.selectedDay;
+ inst.currentMonth = inst.selectedMonth;
+ inst.currentYear = inst.selectedYear;
+ }
+ var date = (day ? (typeof day == 'object' ? day :
+ this._daylightSavingAdjust(new Date(year, month, day))) :
+ this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
+ return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
+ }
+});
+
+/*
+ * Bind hover events for datepicker elements.
+ * Done via delegate so the binding only occurs once in the lifetime of the parent div.
+ * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
+ */
+function bindHover(dpDiv) {
+ var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
+ return dpDiv.bind('mouseout', function(event) {
+ var elem = $( event.target ).closest( selector );
+ if ( !elem.length ) {
+ return;
+ }
+ elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
+ })
+ .bind('mouseover', function(event) {
+ var elem = $( event.target ).closest( selector );
+ if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) ||
+ !elem.length ) {
+ return;
+ }
+ elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
+ elem.addClass('ui-state-hover');
+ if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover');
+ if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover');
+ });
+}
+
+/* jQuery extend now ignores nulls! */
+function extendRemove(target, props) {
+ $.extend(target, props);
+ for (var name in props)
+ if (props[name] == null || props[name] == undefined)
+ target[name] = props[name];
+ return target;
+};
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+ return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
+ (a.constructor && a.constructor.toString().match(/\Array\(\)/))));
+};
+
+/* Invoke the datepicker functionality.
+ @param options string - a command, optionally followed by additional parameters or
+ Object - settings for attaching new datepicker functionality
+ @return jQuery object */
+$.fn.datepicker = function(options){
+
+ /* Verify an empty collection wasn't passed - Fixes #6976 */
+ if ( !this.length ) {
+ return this;
+ }
+
+ /* Initialise the date picker. */
+ if (!$.datepicker.initialized) {
+ $(document).mousedown($.datepicker._checkExternalClick).
+ find('body').append($.datepicker.dpDiv);
+ $.datepicker.initialized = true;
+ }
+
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
+ if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
+ return $.datepicker['_' + options + 'Datepicker'].
+ apply($.datepicker, [this[0]].concat(otherArgs));
+ if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
+ return $.datepicker['_' + options + 'Datepicker'].
+ apply($.datepicker, [this[0]].concat(otherArgs));
+ return this.each(function() {
+ typeof options == 'string' ?
+ $.datepicker['_' + options + 'Datepicker'].
+ apply($.datepicker, [this].concat(otherArgs)) :
+ $.datepicker._attachDatepicker(this, options);
+ });
+};
+
+$.datepicker = new Datepicker(); // singleton instance
+$.datepicker.initialized = false;
+$.datepicker.uuid = new Date().getTime();
+$.datepicker.version = "1.8.16";
+
+// Workaround for #4055
+// Add another global to avoid noConflict issues with inline event handlers
+window['DP_jQuery_' + dpuuid] = $;
+
+})(jQuery);
+/*
+ * jQuery UI Dialog 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ * jquery.ui.button.js
+ * jquery.ui.draggable.js
+ * jquery.ui.mouse.js
+ * jquery.ui.position.js
+ * jquery.ui.resizable.js
+ */
+(function( $, undefined ) {
+
+var uiDialogClasses =
+ 'ui-dialog ' +
+ 'ui-widget ' +
+ 'ui-widget-content ' +
+ 'ui-corner-all ',
+ sizeRelatedOptions = {
+ buttons: true,
+ height: true,
+ maxHeight: true,
+ maxWidth: true,
+ minHeight: true,
+ minWidth: true,
+ width: true
+ },
+ resizableRelatedOptions = {
+ maxHeight: true,
+ maxWidth: true,
+ minHeight: true,
+ minWidth: true
+ },
+ // support for jQuery 1.3.2 - handle common attrFn methods for dialog
+ attrFn = $.attrFn || {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true,
+ click: true
+ };
+
+$.widget("ui.dialog", {
+ options: {
+ autoOpen: true,
+ buttons: {},
+ closeOnEscape: true,
+ closeText: 'close',
+ dialogClass: '',
+ draggable: true,
+ hide: null,
+ height: 'auto',
+ maxHeight: false,
+ maxWidth: false,
+ minHeight: 150,
+ minWidth: 150,
+ modal: false,
+ position: {
+ my: 'center',
+ at: 'center',
+ collision: 'fit',
+ // ensure that the titlebar is never outside the document
+ using: function(pos) {
+ var topOffset = $(this).css(pos).offset().top;
+ if (topOffset < 0) {
+ $(this).css('top', pos.top - topOffset);
+ }
+ }
+ },
+ resizable: true,
+ show: null,
+ stack: true,
+ title: '',
+ width: 300,
+ zIndex: 1000
+ },
+
+ _create: function() {
+ this.originalTitle = this.element.attr('title');
+ // #5742 - .attr() might return a DOMElement
+ if ( typeof this.originalTitle !== "string" ) {
+ this.originalTitle = "";
+ }
+
+ this.options.title = this.options.title || this.originalTitle;
+ var self = this,
+ options = self.options,
+
+ title = options.title || '&#160;',
+ titleId = $.ui.dialog.getTitleId(self.element),
+
+ uiDialog = (self.uiDialog = $('<div></div>'))
+ .appendTo(document.body)
+ .hide()
+ .addClass(uiDialogClasses + options.dialogClass)
+ .css({
+ zIndex: options.zIndex
+ })
+ // setting tabIndex makes the div focusable
+ // setting outline to 0 prevents a border on focus in Mozilla
+ .attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
+ if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
+ event.keyCode === $.ui.keyCode.ESCAPE) {
+
+ self.close(event);
+ event.preventDefault();
+ }
+ })
+ .attr({
+ role: 'dialog',
+ 'aria-labelledby': titleId
+ })
+ .mousedown(function(event) {
+ self.moveToTop(false, event);
+ }),
+
+ uiDialogContent = self.element
+ .show()
+ .removeAttr('title')
+ .addClass(
+ 'ui-dialog-content ' +
+ 'ui-widget-content')
+ .appendTo(uiDialog),
+
+ uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
+ .addClass(
+ 'ui-dialog-titlebar ' +
+ 'ui-widget-header ' +
+ 'ui-corner-all ' +
+ 'ui-helper-clearfix'
+ )
+ .prependTo(uiDialog),
+
+ uiDialogTitlebarClose = $('<a href="#"></a>')
+ .addClass(
+ 'ui-dialog-titlebar-close ' +
+ 'ui-corner-all'
+ )
+ .attr('role', 'button')
+ .hover(
+ function() {
+ uiDialogTitlebarClose.addClass('ui-state-hover');
+ },
+ function() {
+ uiDialogTitlebarClose.removeClass('ui-state-hover');
+ }
+ )
+ .focus(function() {
+ uiDialogTitlebarClose.addClass('ui-state-focus');
+ })
+ .blur(function() {
+ uiDialogTitlebarClose.removeClass('ui-state-focus');
+ })
+ .click(function(event) {
+ self.close(event);
+ return false;
+ })
+ .appendTo(uiDialogTitlebar),
+
+ uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
+ .addClass(
+ 'ui-icon ' +
+ 'ui-icon-closethick'
+ )
+ .text(options.closeText)
+ .appendTo(uiDialogTitlebarClose),
+
+ uiDialogTitle = $('<span></span>')
+ .addClass('ui-dialog-title')
+ .attr('id', titleId)
+ .html(title)
+ .prependTo(uiDialogTitlebar);
+
+ //handling of deprecated beforeclose (vs beforeClose) option
+ //Ticket #4669 http://dev.jqueryui.com/ticket/4669
+ //TODO: remove in 1.9pre
+ if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
+ options.beforeClose = options.beforeclose;
+ }
+
+ uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
+
+ if (options.draggable && $.fn.draggable) {
+ self._makeDraggable();
+ }
+ if (options.resizable && $.fn.resizable) {
+ self._makeResizable();
+ }
+
+ self._createButtons(options.buttons);
+ self._isOpen = false;
+
+ if ($.fn.bgiframe) {
+ uiDialog.bgiframe();
+ }
+ },
+
+ _init: function() {
+ if ( this.options.autoOpen ) {
+ this.open();
+ }
+ },
+
+ destroy: function() {
+ var self = this;
+
+ if (self.overlay) {
+ self.overlay.destroy();
+ }
+ self.uiDialog.hide();
+ self.element
+ .unbind('.dialog')
+ .removeData('dialog')
+ .removeClass('ui-dialog-content ui-widget-content')
+ .hide().appendTo('body');
+ self.uiDialog.remove();
+
+ if (self.originalTitle) {
+ self.element.attr('title', self.originalTitle);
+ }
+
+ return self;
+ },
+
+ widget: function() {
+ return this.uiDialog;
+ },
+
+ close: function(event) {
+ var self = this,
+ maxZ, thisZ;
+
+ if (false === self._trigger('beforeClose', event)) {
+ return;
+ }
+
+ if (self.overlay) {
+ self.overlay.destroy();
+ }
+ self.uiDialog.unbind('keypress.ui-dialog');
+
+ self._isOpen = false;
+
+ if (self.options.hide) {
+ self.uiDialog.hide(self.options.hide, function() {
+ self._trigger('close', event);
+ });
+ } else {
+ self.uiDialog.hide();
+ self._trigger('close', event);
+ }
+
+ $.ui.dialog.overlay.resize();
+
+ // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
+ if (self.options.modal) {
+ maxZ = 0;
+ $('.ui-dialog').each(function() {
+ if (this !== self.uiDialog[0]) {
+ thisZ = $(this).css('z-index');
+ if(!isNaN(thisZ)) {
+ maxZ = Math.max(maxZ, thisZ);
+ }
+ }
+ });
+ $.ui.dialog.maxZ = maxZ;
+ }
+
+ return self;
+ },
+
+ isOpen: function() {
+ return this._isOpen;
+ },
+
+ // the force parameter allows us to move modal dialogs to their correct
+ // position on open
+ moveToTop: function(force, event) {
+ var self = this,
+ options = self.options,
+ saveScroll;
+
+ if ((options.modal && !force) ||
+ (!options.stack && !options.modal)) {
+ return self._trigger('focus', event);
+ }
+
+ if (options.zIndex > $.ui.dialog.maxZ) {
+ $.ui.dialog.maxZ = options.zIndex;
+ }
+ if (self.overlay) {
+ $.ui.dialog.maxZ += 1;
+ self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
+ }
+
+ //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
+ // http://ui.jquery.com/bugs/ticket/3193
+ saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() };
+ $.ui.dialog.maxZ += 1;
+ self.uiDialog.css('z-index', $.ui.dialog.maxZ);
+ self.element.attr(saveScroll);
+ self._trigger('focus', event);
+
+ return self;
+ },
+
+ open: function() {
+ if (this._isOpen) { return; }
+
+ var self = this,
+ options = self.options,
+ uiDialog = self.uiDialog;
+
+ self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
+ self._size();
+ self._position(options.position);
+ uiDialog.show(options.show);
+ self.moveToTop(true);
+
+ // prevent tabbing out of modal dialogs
+ if (options.modal) {
+ uiDialog.bind('keypress.ui-dialog', function(event) {
+ if (event.keyCode !== $.ui.keyCode.TAB) {
+ return;
+ }
+
+ var tabbables = $(':tabbable', this),
+ first = tabbables.filter(':first'),
+ last = tabbables.filter(':last');
+
+ if (event.target === last[0] && !event.shiftKey) {
+ first.focus(1);
+ return false;
+ } else if (event.target === first[0] && event.shiftKey) {
+ last.focus(1);
+ return false;
+ }
+ });
+ }
+
+ // set focus to the first tabbable element in the content area or the first button
+ // if there are no tabbable elements, set focus on the dialog itself
+ $(self.element.find(':tabbable').get().concat(
+ uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
+ uiDialog.get()))).eq(0).focus();
+
+ self._isOpen = true;
+ self._trigger('open');
+
+ return self;
+ },
+
+ _createButtons: function(buttons) {
+ var self = this,
+ hasButtons = false,
+ uiDialogButtonPane = $('<div></div>')
+ .addClass(
+ 'ui-dialog-buttonpane ' +
+ 'ui-widget-content ' +
+ 'ui-helper-clearfix'
+ ),
+ uiButtonSet = $( "<div></div>" )
+ .addClass( "ui-dialog-buttonset" )
+ .appendTo( uiDialogButtonPane );
+
+ // if we already have a button pane, remove it
+ self.uiDialog.find('.ui-dialog-buttonpane').remove();
+
+ if (typeof buttons === 'object' && buttons !== null) {
+ $.each(buttons, function() {
+ return !(hasButtons = true);
+ });
+ }
+ if (hasButtons) {
+ $.each(buttons, function(name, props) {
+ props = $.isFunction( props ) ?
+ { click: props, text: name } :
+ props;
+ var button = $('<button type="button"></button>')
+ .click(function() {
+ props.click.apply(self.element[0], arguments);
+ })
+ .appendTo(uiButtonSet);
+ // can't use .attr( props, true ) with jQuery 1.3.2.
+ $.each( props, function( key, value ) {
+ if ( key === "click" ) {
+ return;
+ }
+ if ( key in attrFn ) {
+ button[ key ]( value );
+ } else {
+ button.attr( key, value );
+ }
+ });
+ if ($.fn.button) {
+ button.button();
+ }
+ });
+ uiDialogButtonPane.appendTo(self.uiDialog);
+ }
+ },
+
+ _makeDraggable: function() {
+ var self = this,
+ options = self.options,
+ doc = $(document),
+ heightBeforeDrag;
+
+ function filteredUi(ui) {
+ return {
+ position: ui.position,
+ offset: ui.offset
+ };
+ }
+
+ self.uiDialog.draggable({
+ cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
+ handle: '.ui-dialog-titlebar',
+ containment: 'document',
+ start: function(event, ui) {
+ heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
+ $(this).height($(this).height()).addClass("ui-dialog-dragging");
+ self._trigger('dragStart', event, filteredUi(ui));
+ },
+ drag: function(event, ui) {
+ self._trigger('drag', event, filteredUi(ui));
+ },
+ stop: function(event, ui) {
+ options.position = [ui.position.left - doc.scrollLeft(),
+ ui.position.top - doc.scrollTop()];
+ $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
+ self._trigger('dragStop', event, filteredUi(ui));
+ $.ui.dialog.overlay.resize();
+ }
+ });
+ },
+
+ _makeResizable: function(handles) {
+ handles = (handles === undefined ? this.options.resizable : handles);
+ var self = this,
+ options = self.options,
+ // .ui-resizable has position: relative defined in the stylesheet
+ // but dialogs have to use absolute or fixed positioning
+ position = self.uiDialog.css('position'),
+ resizeHandles = (typeof handles === 'string' ?
+ handles :
+ 'n,e,s,w,se,sw,ne,nw'
+ );
+
+ function filteredUi(ui) {
+ return {
+ originalPosition: ui.originalPosition,
+ originalSize: ui.originalSize,
+ position: ui.position,
+ size: ui.size
+ };
+ }
+
+ self.uiDialog.resizable({
+ cancel: '.ui-dialog-content',
+ containment: 'document',
+ alsoResize: self.element,
+ maxWidth: options.maxWidth,
+ maxHeight: options.maxHeight,
+ minWidth: options.minWidth,
+ minHeight: self._minHeight(),
+ handles: resizeHandles,
+ start: function(event, ui) {
+ $(this).addClass("ui-dialog-resizing");
+ self._trigger('resizeStart', event, filteredUi(ui));
+ },
+ resize: function(event, ui) {
+ self._trigger('resize', event, filteredUi(ui));
+ },
+ stop: function(event, ui) {
+ $(this).removeClass("ui-dialog-resizing");
+ options.height = $(this).height();
+ options.width = $(this).width();
+ self._trigger('resizeStop', event, filteredUi(ui));
+ $.ui.dialog.overlay.resize();
+ }
+ })
+ .css('position', position)
+ .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
+ },
+
+ _minHeight: function() {
+ var options = this.options;
+
+ if (options.height === 'auto') {
+ return options.minHeight;
+ } else {
+ return Math.min(options.minHeight, options.height);
+ }
+ },
+
+ _position: function(position) {
+ var myAt = [],
+ offset = [0, 0],
+ isVisible;
+
+ if (position) {
+ // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
+ // if (typeof position == 'string' || $.isArray(position)) {
+ // myAt = $.isArray(position) ? position : position.split(' ');
+
+ if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
+ myAt = position.split ? position.split(' ') : [position[0], position[1]];
+ if (myAt.length === 1) {
+ myAt[1] = myAt[0];
+ }
+
+ $.each(['left', 'top'], function(i, offsetPosition) {
+ if (+myAt[i] === myAt[i]) {
+ offset[i] = myAt[i];
+ myAt[i] = offsetPosition;
+ }
+ });
+
+ position = {
+ my: myAt.join(" "),
+ at: myAt.join(" "),
+ offset: offset.join(" ")
+ };
+ }
+
+ position = $.extend({}, $.ui.dialog.prototype.options.position, position);
+ } else {
+ position = $.ui.dialog.prototype.options.position;
+ }
+
+ // need to show the dialog to get the actual offset in the position plugin
+ isVisible = this.uiDialog.is(':visible');
+ if (!isVisible) {
+ this.uiDialog.show();
+ }
+ this.uiDialog
+ // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
+ .css({ top: 0, left: 0 })
+ .position($.extend({ of: window }, position));
+ if (!isVisible) {
+ this.uiDialog.hide();
+ }
+ },
+
+ _setOptions: function( options ) {
+ var self = this,
+ resizableOptions = {},
+ resize = false;
+
+ $.each( options, function( key, value ) {
+ self._setOption( key, value );
+
+ if ( key in sizeRelatedOptions ) {
+ resize = true;
+ }
+ if ( key in resizableRelatedOptions ) {
+ resizableOptions[ key ] = value;
+ }
+ });
+
+ if ( resize ) {
+ this._size();
+ }
+ if ( this.uiDialog.is( ":data(resizable)" ) ) {
+ this.uiDialog.resizable( "option", resizableOptions );
+ }
+ },
+
+ _setOption: function(key, value){
+ var self = this,
+ uiDialog = self.uiDialog;
+
+ switch (key) {
+ //handling of deprecated beforeclose (vs beforeClose) option
+ //Ticket #4669 http://dev.jqueryui.com/ticket/4669
+ //TODO: remove in 1.9pre
+ case "beforeclose":
+ key = "beforeClose";
+ break;
+ case "buttons":
+ self._createButtons(value);
+ break;
+ case "closeText":
+ // ensure that we always pass a string
+ self.uiDialogTitlebarCloseText.text("" + value);
+ break;
+ case "dialogClass":
+ uiDialog
+ .removeClass(self.options.dialogClass)
+ .addClass(uiDialogClasses + value);
+ break;
+ case "disabled":
+ if (value) {
+ uiDialog.addClass('ui-dialog-disabled');
+ } else {
+ uiDialog.removeClass('ui-dialog-disabled');
+ }
+ break;
+ case "draggable":
+ var isDraggable = uiDialog.is( ":data(draggable)" );
+ if ( isDraggable && !value ) {
+ uiDialog.draggable( "destroy" );
+ }
+
+ if ( !isDraggable && value ) {
+ self._makeDraggable();
+ }
+ break;
+ case "position":
+ self._position(value);
+ break;
+ case "resizable":
+ // currently resizable, becoming non-resizable
+ var isResizable = uiDialog.is( ":data(resizable)" );
+ if (isResizable && !value) {
+ uiDialog.resizable('destroy');
+ }
+
+ // currently resizable, changing handles
+ if (isResizable && typeof value === 'string') {
+ uiDialog.resizable('option', 'handles', value);
+ }
+
+ // currently non-resizable, becoming resizable
+ if (!isResizable && value !== false) {
+ self._makeResizable(value);
+ }
+ break;
+ case "title":
+ // convert whatever was passed in o a string, for html() to not throw up
+ $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || '&#160;'));
+ break;
+ }
+
+ $.Widget.prototype._setOption.apply(self, arguments);
+ },
+
+ _size: function() {
+ /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
+ * divs will both have width and height set, so we need to reset them
+ */
+ var options = this.options,
+ nonContentHeight,
+ minContentHeight,
+ isVisible = this.uiDialog.is( ":visible" );
+
+ // reset content sizing
+ this.element.show().css({
+ width: 'auto',
+ minHeight: 0,
+ height: 0
+ });
+
+ if (options.minWidth > options.width) {
+ options.width = options.minWidth;
+ }
+
+ // reset wrapper sizing
+ // determine the height of all the non-content elements
+ nonContentHeight = this.uiDialog.css({
+ height: 'auto',
+ width: options.width
+ })
+ .height();
+ minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
+
+ if ( options.height === "auto" ) {
+ // only needed for IE6 support
+ if ( $.support.minHeight ) {
+ this.element.css({
+ minHeight: minContentHeight,
+ height: "auto"
+ });
+ } else {
+ this.uiDialog.show();
+ var autoHeight = this.element.css( "height", "auto" ).height();
+ if ( !isVisible ) {
+ this.uiDialog.hide();
+ }
+ this.element.height( Math.max( autoHeight, minContentHeight ) );
+ }
+ } else {
+ this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
+ }
+
+ if (this.uiDialog.is(':data(resizable)')) {
+ this.uiDialog.resizable('option', 'minHeight', this._minHeight());
+ }
+ }
+});
+
+$.extend($.ui.dialog, {
+ version: "1.8.16",
+
+ uuid: 0,
+ maxZ: 0,
+
+ getTitleId: function($el) {
+ var id = $el.attr('id');
+ if (!id) {
+ this.uuid += 1;
+ id = this.uuid;
+ }
+ return 'ui-dialog-title-' + id;
+ },
+
+ overlay: function(dialog) {
+ this.$el = $.ui.dialog.overlay.create(dialog);
+ }
+});
+
+$.extend($.ui.dialog.overlay, {
+ instances: [],
+ // reuse old instances due to IE memory leak with alpha transparency (see #5185)
+ oldInstances: [],
+ maxZ: 0,
+ events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
+ function(event) { return event + '.dialog-overlay'; }).join(' '),
+ create: function(dialog) {
+ if (this.instances.length === 0) {
+ // prevent use of anchors and inputs
+ // we use a setTimeout in case the overlay is created from an
+ // event that we're going to be cancelling (see #2804)
+ setTimeout(function() {
+ // handle $(el).dialog().dialog('close') (see #4065)
+ if ($.ui.dialog.overlay.instances.length) {
+ $(document).bind($.ui.dialog.overlay.events, function(event) {
+ // stop events if the z-index of the target is < the z-index of the overlay
+ // we cannot return true when we don't want to cancel the event (#3523)
+ if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
+ return false;
+ }
+ });
+ }
+ }, 1);
+
+ // allow closing by pressing the escape key
+ $(document).bind('keydown.dialog-overlay', function(event) {
+ if (dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
+ event.keyCode === $.ui.keyCode.ESCAPE) {
+
+ dialog.close(event);
+ event.preventDefault();
+ }
+ });
+
+ // handle window resize
+ $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
+ }
+
+ var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
+ .appendTo(document.body)
+ .css({
+ width: this.width(),
+ height: this.height()
+ });
+
+ if ($.fn.bgiframe) {
+ $el.bgiframe();
+ }
+
+ this.instances.push($el);
+ return $el;
+ },
+
+ destroy: function($el) {
+ var indexOf = $.inArray($el, this.instances);
+ if (indexOf != -1){
+ this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
+ }
+
+ if (this.instances.length === 0) {
+ $([document, window]).unbind('.dialog-overlay');
+ }
+
+ $el.remove();
+
+ // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
+ var maxZ = 0;
+ $.each(this.instances, function() {
+ maxZ = Math.max(maxZ, this.css('z-index'));
+ });
+ this.maxZ = maxZ;
+ },
+
+ height: function() {
+ var scrollHeight,
+ offsetHeight;
+ // handle IE 6
+ if ($.browser.msie && $.browser.version < 7) {
+ scrollHeight = Math.max(
+ document.documentElement.scrollHeight,
+ document.body.scrollHeight
+ );
+ offsetHeight = Math.max(
+ document.documentElement.offsetHeight,
+ document.body.offsetHeight
+ );
+
+ if (scrollHeight < offsetHeight) {
+ return $(window).height() + 'px';
+ } else {
+ return scrollHeight + 'px';
+ }
+ // handle "good" browsers
+ } else {
+ return $(document).height() + 'px';
+ }
+ },
+
+ width: function() {
+ var scrollWidth,
+ offsetWidth;
+ // handle IE
+ if ( $.browser.msie ) {
+ scrollWidth = Math.max(
+ document.documentElement.scrollWidth,
+ document.body.scrollWidth
+ );
+ offsetWidth = Math.max(
+ document.documentElement.offsetWidth,
+ document.body.offsetWidth
+ );
+
+ if (scrollWidth < offsetWidth) {
+ return $(window).width() + 'px';
+ } else {
+ return scrollWidth + 'px';
+ }
+ // handle "good" browsers
+ } else {
+ return $(document).width() + 'px';
+ }
+ },
+
+ resize: function() {
+ /* If the dialog is draggable and the user drags it past the
+ * right edge of the window, the document becomes wider so we
+ * need to stretch the overlay. If the user then drags the
+ * dialog back to the left, the document will become narrower,
+ * so we need to shrink the overlay to the appropriate size.
+ * This is handled by shrinking the overlay before setting it
+ * to the full document size.
+ */
+ var $overlays = $([]);
+ $.each($.ui.dialog.overlay.instances, function() {
+ $overlays = $overlays.add(this);
+ });
+
+ $overlays.css({
+ width: 0,
+ height: 0
+ }).css({
+ width: $.ui.dialog.overlay.width(),
+ height: $.ui.dialog.overlay.height()
+ });
+ }
+});
+
+$.extend($.ui.dialog.overlay.prototype, {
+ destroy: function() {
+ $.ui.dialog.overlay.destroy(this.$el);
+ }
+});
+
+}(jQuery));
+/*
+ * jQuery UI Position 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Position
+ */
+(function( $, undefined ) {
+
+$.ui = $.ui || {};
+
+var horizontalPositions = /left|center|right/,
+ verticalPositions = /top|center|bottom/,
+ center = "center",
+ _position = $.fn.position,
+ _offset = $.fn.offset;
+
+$.fn.position = function( options ) {
+ if ( !options || !options.of ) {
+ return _position.apply( this, arguments );
+ }
+
+ // make a copy, we don't want to modify arguments
+ options = $.extend( {}, options );
+
+ var target = $( options.of ),
+ targetElem = target[0],
+ collision = ( options.collision || "flip" ).split( " " ),
+ offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
+ targetWidth,
+ targetHeight,
+ basePosition;
+
+ if ( targetElem.nodeType === 9 ) {
+ targetWidth = target.width();
+ targetHeight = target.height();
+ basePosition = { top: 0, left: 0 };
+ // TODO: use $.isWindow() in 1.9
+ } else if ( targetElem.setTimeout ) {
+ targetWidth = target.width();
+ targetHeight = target.height();
+ basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
+ } else if ( targetElem.preventDefault ) {
+ // force left top to allow flipping
+ options.at = "left top";
+ targetWidth = targetHeight = 0;
+ basePosition = { top: options.of.pageY, left: options.of.pageX };
+ } else {
+ targetWidth = target.outerWidth();
+ targetHeight = target.outerHeight();
+ basePosition = target.offset();
+ }
+
+ // force my and at to have valid horizontal and veritcal positions
+ // if a value is missing or invalid, it will be converted to center
+ $.each( [ "my", "at" ], function() {
+ var pos = ( options[this] || "" ).split( " " );
+ if ( pos.length === 1) {
+ pos = horizontalPositions.test( pos[0] ) ?
+ pos.concat( [center] ) :
+ verticalPositions.test( pos[0] ) ?
+ [ center ].concat( pos ) :
+ [ center, center ];
+ }
+ pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
+ pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
+ options[ this ] = pos;
+ });
+
+ // normalize collision option
+ if ( collision.length === 1 ) {
+ collision[ 1 ] = collision[ 0 ];
+ }
+
+ // normalize offset option
+ offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
+ if ( offset.length === 1 ) {
+ offset[ 1 ] = offset[ 0 ];
+ }
+ offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
+
+ if ( options.at[0] === "right" ) {
+ basePosition.left += targetWidth;
+ } else if ( options.at[0] === center ) {
+ basePosition.left += targetWidth / 2;
+ }
+
+ if ( options.at[1] === "bottom" ) {
+ basePosition.top += targetHeight;
+ } else if ( options.at[1] === center ) {
+ basePosition.top += targetHeight / 2;
+ }
+
+ basePosition.left += offset[ 0 ];
+ basePosition.top += offset[ 1 ];
+
+ return this.each(function() {
+ var elem = $( this ),
+ elemWidth = elem.outerWidth(),
+ elemHeight = elem.outerHeight(),
+ marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
+ marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
+ collisionWidth = elemWidth + marginLeft +
+ ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
+ collisionHeight = elemHeight + marginTop +
+ ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
+ position = $.extend( {}, basePosition ),
+ collisionPosition;
+
+ if ( options.my[0] === "right" ) {
+ position.left -= elemWidth;
+ } else if ( options.my[0] === center ) {
+ position.left -= elemWidth / 2;
+ }
+
+ if ( options.my[1] === "bottom" ) {
+ position.top -= elemHeight;
+ } else if ( options.my[1] === center ) {
+ position.top -= elemHeight / 2;
+ }
+
+ // prevent fractions (see #5280)
+ position.left = Math.round( position.left );
+ position.top = Math.round( position.top );
+
+ collisionPosition = {
+ left: position.left - marginLeft,
+ top: position.top - marginTop
+ };
+
+ $.each( [ "left", "top" ], function( i, dir ) {
+ if ( $.ui.position[ collision[i] ] ) {
+ $.ui.position[ collision[i] ][ dir ]( position, {
+ targetWidth: targetWidth,
+ targetHeight: targetHeight,
+ elemWidth: elemWidth,
+ elemHeight: elemHeight,
+ collisionPosition: collisionPosition,
+ collisionWidth: collisionWidth,
+ collisionHeight: collisionHeight,
+ offset: offset,
+ my: options.my,
+ at: options.at
+ });
+ }
+ });
+
+ if ( $.fn.bgiframe ) {
+ elem.bgiframe();
+ }
+ elem.offset( $.extend( position, { using: options.using } ) );
+ });
+};
+
+$.ui.position = {
+ fit: {
+ left: function( position, data ) {
+ var win = $( window ),
+ over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
+ position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
+ },
+ top: function( position, data ) {
+ var win = $( window ),
+ over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
+ position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
+ }
+ },
+
+ flip: {
+ left: function( position, data ) {
+ if ( data.at[0] === center ) {
+ return;
+ }
+ var win = $( window ),
+ over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
+ myOffset = data.my[ 0 ] === "left" ?
+ -data.elemWidth :
+ data.my[ 0 ] === "right" ?
+ data.elemWidth :
+ 0,
+ atOffset = data.at[ 0 ] === "left" ?
+ data.targetWidth :
+ -data.targetWidth,
+ offset = -2 * data.offset[ 0 ];
+ position.left += data.collisionPosition.left < 0 ?
+ myOffset + atOffset + offset :
+ over > 0 ?
+ myOffset + atOffset + offset :
+ 0;
+ },
+ top: function( position, data ) {
+ if ( data.at[1] === center ) {
+ return;
+ }
+ var win = $( window ),
+ over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
+ myOffset = data.my[ 1 ] === "top" ?
+ -data.elemHeight :
+ data.my[ 1 ] === "bottom" ?
+ data.elemHeight :
+ 0,
+ atOffset = data.at[ 1 ] === "top" ?
+ data.targetHeight :
+ -data.targetHeight,
+ offset = -2 * data.offset[ 1 ];
+ position.top += data.collisionPosition.top < 0 ?
+ myOffset + atOffset + offset :
+ over > 0 ?
+ myOffset + atOffset + offset :
+ 0;
+ }
+ }
+};
+
+// offset setter from jQuery 1.4
+if ( !$.offset.setOffset ) {
+ $.offset.setOffset = function( elem, options ) {
+ // set position first, in-case top/left are set even on static elem
+ if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
+ elem.style.position = "relative";
+ }
+ var curElem = $( elem ),
+ curOffset = curElem.offset(),
+ curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
+ curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
+ props = {
+ top: (options.top - curOffset.top) + curTop,
+ left: (options.left - curOffset.left) + curLeft
+ };
+
+ if ( 'using' in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ };
+
+ $.fn.offset = function( options ) {
+ var elem = this[ 0 ];
+ if ( !elem || !elem.ownerDocument ) { return null; }
+ if ( options ) {
+ return this.each(function() {
+ $.offset.setOffset( this, options );
+ });
+ }
+ return _offset.call( this );
+ };
+}
+
+}( jQuery ));
+/*
+ * jQuery UI Progressbar 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Progressbar
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+$.widget( "ui.progressbar", {
+ options: {
+ value: 0,
+ max: 100
+ },
+
+ min: 0,
+
+ _create: function() {
+ this.element
+ .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+ .attr({
+ role: "progressbar",
+ "aria-valuemin": this.min,
+ "aria-valuemax": this.options.max,
+ "aria-valuenow": this._value()
+ });
+
+ this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
+ .appendTo( this.element );
+
+ this.oldValue = this._value();
+ this._refreshValue();
+ },
+
+ destroy: function() {
+ this.element
+ .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
+ .removeAttr( "role" )
+ .removeAttr( "aria-valuemin" )
+ .removeAttr( "aria-valuemax" )
+ .removeAttr( "aria-valuenow" );
+
+ this.valueDiv.remove();
+
+ $.Widget.prototype.destroy.apply( this, arguments );
+ },
+
+ value: function( newValue ) {
+ if ( newValue === undefined ) {
+ return this._value();
+ }
+
+ this._setOption( "value", newValue );
+ return this;
+ },
+
+ _setOption: function( key, value ) {
+ if ( key === "value" ) {
+ this.options.value = value;
+ this._refreshValue();
+ if ( this._value() === this.options.max ) {
+ this._trigger( "complete" );
+ }
+ }
+
+ $.Widget.prototype._setOption.apply( this, arguments );
+ },
+
+ _value: function() {
+ var val = this.options.value;
+ // normalize invalid value
+ if ( typeof val !== "number" ) {
+ val = 0;
+ }
+ return Math.min( this.options.max, Math.max( this.min, val ) );
+ },
+
+ _percentage: function() {
+ return 100 * this._value() / this.options.max;
+ },
+
+ _refreshValue: function() {
+ var value = this.value();
+ var percentage = this._percentage();
+
+ if ( this.oldValue !== value ) {
+ this.oldValue = value;
+ this._trigger( "change" );
+ }
+
+ this.valueDiv
+ .toggle( value > this.min )
+ .toggleClass( "ui-corner-right", value === this.options.max )
+ .width( percentage.toFixed(0) + "%" );
+ this.element.attr( "aria-valuenow", value );
+ }
+});
+
+$.extend( $.ui.progressbar, {
+ version: "1.8.16"
+});
+
+})( jQuery );
+/*
+ * jQuery UI Slider 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+// number of pages in a slider
+// (how many times can you page up/down to go through the whole range)
+var numPages = 5;
+
+$.widget( "ui.slider", $.ui.mouse, {
+
+ widgetEventPrefix: "slide",
+
+ options: {
+ animate: false,
+ distance: 0,
+ max: 100,
+ min: 0,
+ orientation: "horizontal",
+ range: false,
+ step: 1,
+ value: 0,
+ values: null
+ },
+
+ _create: function() {
+ var self = this,
+ o = this.options,
+ existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
+ handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
+ handleCount = ( o.values && o.values.length ) || 1,
+ handles = [];
+
+ this._keySliding = false;
+ this._mouseSliding = false;
+ this._animateOff = true;
+ this._handleIndex = null;
+ this._detectOrientation();
+ this._mouseInit();
+
+ this.element
+ .addClass( "ui-slider" +
+ " ui-slider-" + this.orientation +
+ " ui-widget" +
+ " ui-widget-content" +
+ " ui-corner-all" +
+ ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
+
+ this.range = $([]);
+
+ if ( o.range ) {
+ if ( o.range === true ) {
+ if ( !o.values ) {
+ o.values = [ this._valueMin(), this._valueMin() ];
+ }
+ if ( o.values.length && o.values.length !== 2 ) {
+ o.values = [ o.values[0], o.values[0] ];
+ }
+ }
+
+ this.range = $( "<div></div>" )
+ .appendTo( this.element )
+ .addClass( "ui-slider-range" +
+ // note: this isn't the most fittingly semantic framework class for this element,
+ // but worked best visually with a variety of themes
+ " ui-widget-header" +
+ ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
+ }
+
+ for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
+ handles.push( handle );
+ }
+
+ this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
+
+ this.handle = this.handles.eq( 0 );
+
+ this.handles.add( this.range ).filter( "a" )
+ .click(function( event ) {
+ event.preventDefault();
+ })
+ .hover(function() {
+ if ( !o.disabled ) {
+ $( this ).addClass( "ui-state-hover" );
+ }
+ }, function() {
+ $( this ).removeClass( "ui-state-hover" );
+ })
+ .focus(function() {
+ if ( !o.disabled ) {
+ $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
+ $( this ).addClass( "ui-state-focus" );
+ } else {
+ $( this ).blur();
+ }
+ })
+ .blur(function() {
+ $( this ).removeClass( "ui-state-focus" );
+ });
+
+ this.handles.each(function( i ) {
+ $( this ).data( "index.ui-slider-handle", i );
+ });
+
+ this.handles
+ .keydown(function( event ) {
+ var ret = true,
+ index = $( this ).data( "index.ui-slider-handle" ),
+ allowed,
+ curVal,
+ newVal,
+ step;
+
+ if ( self.options.disabled ) {
+ return;
+ }
+
+ switch ( event.keyCode ) {
+ case $.ui.keyCode.HOME:
+ case $.ui.keyCode.END:
+ case $.ui.keyCode.PAGE_UP:
+ case $.ui.keyCode.PAGE_DOWN:
+ case $.ui.keyCode.UP:
+ case $.ui.keyCode.RIGHT:
+ case $.ui.keyCode.DOWN:
+ case $.ui.keyCode.LEFT:
+ ret = false;
+ if ( !self._keySliding ) {
+ self._keySliding = true;
+ $( this ).addClass( "ui-state-active" );
+ allowed = self._start( event, index );
+ if ( allowed === false ) {
+ return;
+ }
+ }
+ break;
+ }
+
+ step = self.options.step;
+ if ( self.options.values && self.options.values.length ) {
+ curVal = newVal = self.values( index );
+ } else {
+ curVal = newVal = self.value();
+ }
+
+ switch ( event.keyCode ) {
+ case $.ui.keyCode.HOME:
+ newVal = self._valueMin();
+ break;
+ case $.ui.keyCode.END:
+ newVal = self._valueMax();
+ break;
+ case $.ui.keyCode.PAGE_UP:
+ newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
+ break;
+ case $.ui.keyCode.PAGE_DOWN:
+ newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
+ break;
+ case $.ui.keyCode.UP:
+ case $.ui.keyCode.RIGHT:
+ if ( curVal === self._valueMax() ) {
+ return;
+ }
+ newVal = self._trimAlignValue( curVal + step );
+ break;
+ case $.ui.keyCode.DOWN:
+ case $.ui.keyCode.LEFT:
+ if ( curVal === self._valueMin() ) {
+ return;
+ }
+ newVal = self._trimAlignValue( curVal - step );
+ break;
+ }
+
+ self._slide( event, index, newVal );
+
+ return ret;
+
+ })
+ .keyup(function( event ) {
+ var index = $( this ).data( "index.ui-slider-handle" );
+
+ if ( self._keySliding ) {
+ self._keySliding = false;
+ self._stop( event, index );
+ self._change( event, index );
+ $( this ).removeClass( "ui-state-active" );
+ }
+
+ });
+
+ this._refreshValue();
+
+ this._animateOff = false;
+ },
+
+ destroy: function() {
+ this.handles.remove();
+ this.range.remove();
+
+ this.element
+ .removeClass( "ui-slider" +
+ " ui-slider-horizontal" +
+ " ui-slider-vertical" +
+ " ui-slider-disabled" +
+ " ui-widget" +
+ " ui-widget-content" +
+ " ui-corner-all" )
+ .removeData( "slider" )
+ .unbind( ".slider" );
+
+ this._mouseDestroy();
+
+ return this;
+ },
+
+ _mouseCapture: function( event ) {
+ var o = this.options,
+ position,
+ normValue,
+ distance,
+ closestHandle,
+ self,
+ index,
+ allowed,
+ offset,
+ mouseOverHandle;
+
+ if ( o.disabled ) {
+ return false;
+ }
+
+ this.elementSize = {
+ width: this.element.outerWidth(),
+ height: this.element.outerHeight()
+ };
+ this.elementOffset = this.element.offset();
+
+ position = { x: event.pageX, y: event.pageY };
+ normValue = this._normValueFromMouse( position );
+ distance = this._valueMax() - this._valueMin() + 1;
+ self = this;
+ this.handles.each(function( i ) {
+ var thisDistance = Math.abs( normValue - self.values(i) );
+ if ( distance > thisDistance ) {
+ distance = thisDistance;
+ closestHandle = $( this );
+ index = i;
+ }
+ });
+
+ // workaround for bug #3736 (if both handles of a range are at 0,
+ // the first is always used as the one with least distance,
+ // and moving it is obviously prevented by preventing negative ranges)
+ if( o.range === true && this.values(1) === o.min ) {
+ index += 1;
+ closestHandle = $( this.handles[index] );
+ }
+
+ allowed = this._start( event, index );
+ if ( allowed === false ) {
+ return false;
+ }
+ this._mouseSliding = true;
+
+ self._handleIndex = index;
+
+ closestHandle
+ .addClass( "ui-state-active" )
+ .focus();
+
+ offset = closestHandle.offset();
+ mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
+ this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
+ left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
+ top: event.pageY - offset.top -
+ ( closestHandle.height() / 2 ) -
+ ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
+ ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
+ ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
+ };
+
+ if ( !this.handles.hasClass( "ui-state-hover" ) ) {
+ this._slide( event, index, normValue );
+ }
+ this._animateOff = true;
+ return true;
+ },
+
+ _mouseStart: function( event ) {
+ return true;
+ },
+
+ _mouseDrag: function( event ) {
+ var position = { x: event.pageX, y: event.pageY },
+ normValue = this._normValueFromMouse( position );
+
+ this._slide( event, this._handleIndex, normValue );
+
+ return false;
+ },
+
+ _mouseStop: function( event ) {
+ this.handles.removeClass( "ui-state-active" );
+ this._mouseSliding = false;
+
+ this._stop( event, this._handleIndex );
+ this._change( event, this._handleIndex );
+
+ this._handleIndex = null;
+ this._clickOffset = null;
+ this._animateOff = false;
+
+ return false;
+ },
+
+ _detectOrientation: function() {
+ this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
+ },
+
+ _normValueFromMouse: function( position ) {
+ var pixelTotal,
+ pixelMouse,
+ percentMouse,
+ valueTotal,
+ valueMouse;
+
+ if ( this.orientation === "horizontal" ) {
+ pixelTotal = this.elementSize.width;
+ pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
+ } else {
+ pixelTotal = this.elementSize.height;
+ pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
+ }
+
+ percentMouse = ( pixelMouse / pixelTotal );
+ if ( percentMouse > 1 ) {
+ percentMouse = 1;
+ }
+ if ( percentMouse < 0 ) {
+ percentMouse = 0;
+ }
+ if ( this.orientation === "vertical" ) {
+ percentMouse = 1 - percentMouse;
+ }
+
+ valueTotal = this._valueMax() - this._valueMin();
+ valueMouse = this._valueMin() + percentMouse * valueTotal;
+
+ return this._trimAlignValue( valueMouse );
+ },
+
+ _start: function( event, index ) {
+ var uiHash = {
+ handle: this.handles[ index ],
+ value: this.value()
+ };
+ if ( this.options.values && this.options.values.length ) {
+ uiHash.value = this.values( index );
+ uiHash.values = this.values();
+ }
+ return this._trigger( "start", event, uiHash );
+ },
+
+ _slide: function( event, index, newVal ) {
+ var otherVal,
+ newValues,
+ allowed;
+
+ if ( this.options.values && this.options.values.length ) {
+ otherVal = this.values( index ? 0 : 1 );
+
+ if ( ( this.options.values.length === 2 && this.options.range === true ) &&
+ ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
+ ) {
+ newVal = otherVal;
+ }
+
+ if ( newVal !== this.values( index ) ) {
+ newValues = this.values();
+ newValues[ index ] = newVal;
+ // A slide can be canceled by returning false from the slide callback
+ allowed = this._trigger( "slide", event, {
+ handle: this.handles[ index ],
+ value: newVal,
+ values: newValues
+ } );
+ otherVal = this.values( index ? 0 : 1 );
+ if ( allowed !== false ) {
+ this.values( index, newVal, true );
+ }
+ }
+ } else {
+ if ( newVal !== this.value() ) {
+ // A slide can be canceled by returning false from the slide callback
+ allowed = this._trigger( "slide", event, {
+ handle: this.handles[ index ],
+ value: newVal
+ } );
+ if ( allowed !== false ) {
+ this.value( newVal );
+ }
+ }
+ }
+ },
+
+ _stop: function( event, index ) {
+ var uiHash = {
+ handle: this.handles[ index ],
+ value: this.value()
+ };
+ if ( this.options.values && this.options.values.length ) {
+ uiHash.value = this.values( index );
+ uiHash.values = this.values();
+ }
+
+ this._trigger( "stop", event, uiHash );
+ },
+
+ _change: function( event, index ) {
+ if ( !this._keySliding && !this._mouseSliding ) {
+ var uiHash = {
+ handle: this.handles[ index ],
+ value: this.value()
+ };
+ if ( this.options.values && this.options.values.length ) {
+ uiHash.value = this.values( index );
+ uiHash.values = this.values();
+ }
+
+ this._trigger( "change", event, uiHash );
+ }
+ },
+
+ value: function( newValue ) {
+ if ( arguments.length ) {
+ this.options.value = this._trimAlignValue( newValue );
+ this._refreshValue();
+ this._change( null, 0 );
+ return;
+ }
+
+ return this._value();
+ },
+
+ values: function( index, newValue ) {
+ var vals,
+ newValues,
+ i;
+
+ if ( arguments.length > 1 ) {
+ this.options.values[ index ] = this._trimAlignValue( newValue );
+ this._refreshValue();
+ this._change( null, index );
+ return;
+ }
+
+ if ( arguments.length ) {
+ if ( $.isArray( arguments[ 0 ] ) ) {
+ vals = this.options.values;
+ newValues = arguments[ 0 ];
+ for ( i = 0; i < vals.length; i += 1 ) {
+ vals[ i ] = this._trimAlignValue( newValues[ i ] );
+ this._change( null, i );
+ }
+ this._refreshValue();
+ } else {
+ if ( this.options.values && this.options.values.length ) {
+ return this._values( index );
+ } else {
+ return this.value();
+ }
+ }
+ } else {
+ return this._values();
+ }
+ },
+
+ _setOption: function( key, value ) {
+ var i,
+ valsLength = 0;
+
+ if ( $.isArray( this.options.values ) ) {
+ valsLength = this.options.values.length;
+ }
+
+ $.Widget.prototype._setOption.apply( this, arguments );
+
+ switch ( key ) {
+ case "disabled":
+ if ( value ) {
+ this.handles.filter( ".ui-state-focus" ).blur();
+ this.handles.removeClass( "ui-state-hover" );
+ this.handles.propAttr( "disabled", true );
+ this.element.addClass( "ui-disabled" );
+ } else {
+ this.handles.propAttr( "disabled", false );
+ this.element.removeClass( "ui-disabled" );
+ }
+ break;
+ case "orientation":
+ this._detectOrientation();
+ this.element
+ .removeClass( "ui-slider-horizontal ui-slider-vertical" )
+ .addClass( "ui-slider-" + this.orientation );
+ this._refreshValue();
+ break;
+ case "value":
+ this._animateOff = true;
+ this._refreshValue();
+ this._change( null, 0 );
+ this._animateOff = false;
+ break;
+ case "values":
+ this._animateOff = true;
+ this._refreshValue();
+ for ( i = 0; i < valsLength; i += 1 ) {
+ this._change( null, i );
+ }
+ this._animateOff = false;
+ break;
+ }
+ },
+
+ //internal value getter
+ // _value() returns value trimmed by min and max, aligned by step
+ _value: function() {
+ var val = this.options.value;
+ val = this._trimAlignValue( val );
+
+ return val;
+ },
+
+ //internal values getter
+ // _values() returns array of values trimmed by min and max, aligned by step
+ // _values( index ) returns single value trimmed by min and max, aligned by step
+ _values: function( index ) {
+ var val,
+ vals,
+ i;
+
+ if ( arguments.length ) {
+ val = this.options.values[ index ];
+ val = this._trimAlignValue( val );
+
+ return val;
+ } else {
+ // .slice() creates a copy of the array
+ // this copy gets trimmed by min and max and then returned
+ vals = this.options.values.slice();
+ for ( i = 0; i < vals.length; i+= 1) {
+ vals[ i ] = this._trimAlignValue( vals[ i ] );
+ }
+
+ return vals;
+ }
+ },
+
+ // returns the step-aligned value that val is closest to, between (inclusive) min and max
+ _trimAlignValue: function( val ) {
+ if ( val <= this._valueMin() ) {
+ return this._valueMin();
+ }
+ if ( val >= this._valueMax() ) {
+ return this._valueMax();
+ }
+ var step = ( this.options.step > 0 ) ? this.options.step : 1,
+ valModStep = (val - this._valueMin()) % step,
+ alignValue = val - valModStep;
+
+ if ( Math.abs(valModStep) * 2 >= step ) {
+ alignValue += ( valModStep > 0 ) ? step : ( -step );
+ }
+
+ // Since JavaScript has problems with large floats, round
+ // the final value to 5 digits after the decimal point (see #4124)
+ return parseFloat( alignValue.toFixed(5) );
+ },
+
+ _valueMin: function() {
+ return this.options.min;
+ },
+
+ _valueMax: function() {
+ return this.options.max;
+ },
+
+ _refreshValue: function() {
+ var oRange = this.options.range,
+ o = this.options,
+ self = this,
+ animate = ( !this._animateOff ) ? o.animate : false,
+ valPercent,
+ _set = {},
+ lastValPercent,
+ value,
+ valueMin,
+ valueMax;
+
+ if ( this.options.values && this.options.values.length ) {
+ this.handles.each(function( i, j ) {
+ valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
+ _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+ $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+ if ( self.options.range === true ) {
+ if ( self.orientation === "horizontal" ) {
+ if ( i === 0 ) {
+ self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
+ }
+ if ( i === 1 ) {
+ self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+ }
+ } else {
+ if ( i === 0 ) {
+ self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
+ }
+ if ( i === 1 ) {
+ self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
+ }
+ }
+ }
+ lastValPercent = valPercent;
+ });
+ } else {
+ value = this.value();
+ valueMin = this._valueMin();
+ valueMax = this._valueMax();
+ valPercent = ( valueMax !== valueMin ) ?
+ ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
+ 0;
+ _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
+ this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
+
+ if ( oRange === "min" && this.orientation === "horizontal" ) {
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
+ }
+ if ( oRange === "max" && this.orientation === "horizontal" ) {
+ this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+ }
+ if ( oRange === "min" && this.orientation === "vertical" ) {
+ this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
+ }
+ if ( oRange === "max" && this.orientation === "vertical" ) {
+ this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
+ }
+ }
+ }
+
+});
+
+$.extend( $.ui.slider, {
+ version: "1.8.16"
+});
+
+}(jQuery));
+/*
+ * jQuery UI Tabs 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Tabs
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.widget.js
+ */
+(function( $, undefined ) {
+
+var tabId = 0,
+ listId = 0;
+
+function getNextTabId() {
+ return ++tabId;
+}
+
+function getNextListId() {
+ return ++listId;
+}
+
+$.widget( "ui.tabs", {
+ options: {
+ add: null,
+ ajaxOptions: null,
+ cache: false,
+ cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
+ collapsible: false,
+ disable: null,
+ disabled: [],
+ enable: null,
+ event: "click",
+ fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
+ idPrefix: "ui-tabs-",
+ load: null,
+ panelTemplate: "<div></div>",
+ remove: null,
+ select: null,
+ show: null,
+ spinner: "<em>Loading&#8230;</em>",
+ tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
+ },
+
+ _create: function() {
+ this._tabify( true );
+ },
+
+ _setOption: function( key, value ) {
+ if ( key == "selected" ) {
+ if (this.options.collapsible && value == this.options.selected ) {
+ return;
+ }
+ this.select( value );
+ } else {
+ this.options[ key ] = value;
+ this._tabify();
+ }
+ },
+
+ _tabId: function( a ) {
+ return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
+ this.options.idPrefix + getNextTabId();
+ },
+
+ _sanitizeSelector: function( hash ) {
+ // we need this because an id may contain a ":"
+ return hash.replace( /:/g, "\\:" );
+ },
+
+ _cookie: function() {
+ var cookie = this.cookie ||
+ ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
+ return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
+ },
+
+ _ui: function( tab, panel ) {
+ return {
+ tab: tab,
+ panel: panel,
+ index: this.anchors.index( tab )
+ };
+ },
+
+ _cleanup: function() {
+ // restore all former loading tabs labels
+ this.lis.filter( ".ui-state-processing" )
+ .removeClass( "ui-state-processing" )
+ .find( "span:data(label.tabs)" )
+ .each(function() {
+ var el = $( this );
+ el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
+ });
+ },
+
+ _tabify: function( init ) {
+ var self = this,
+ o = this.options,
+ fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
+
+ this.list = this.element.find( "ol,ul" ).eq( 0 );
+ this.lis = $( " > li:has(a[href])", this.list );
+ this.anchors = this.lis.map(function() {
+ return $( "a", this )[ 0 ];
+ });
+ this.panels = $( [] );
+
+ this.anchors.each(function( i, a ) {
+ var href = $( a ).attr( "href" );
+ // For dynamically created HTML that contains a hash as href IE < 8 expands
+ // such href to the full page url with hash and then misinterprets tab as ajax.
+ // Same consideration applies for an added tab with a fragment identifier
+ // since a[href=#fragment-identifier] does unexpectedly not match.
+ // Thus normalize href attribute...
+ var hrefBase = href.split( "#" )[ 0 ],
+ baseEl;
+ if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
+ ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
+ href = a.hash;
+ a.href = href;
+ }
+
+ // inline tab
+ if ( fragmentId.test( href ) ) {
+ self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
+ // remote tab
+ // prevent loading the page itself if href is just "#"
+ } else if ( href && href !== "#" ) {
+ // required for restore on destroy
+ $.data( a, "href.tabs", href );
+
+ // TODO until #3808 is fixed strip fragment identifier from url
+ // (IE fails to load from such url)
+ $.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
+
+ var id = self._tabId( a );
+ a.href = "#" + id;
+ var $panel = self.element.find( "#" + id );
+ if ( !$panel.length ) {
+ $panel = $( o.panelTemplate )
+ .attr( "id", id )
+ .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+ .insertAfter( self.panels[ i - 1 ] || self.list );
+ $panel.data( "destroy.tabs", true );
+ }
+ self.panels = self.panels.add( $panel );
+ // invalid tab href
+ } else {
+ o.disabled.push( i );
+ }
+ });
+
+ // initialization from scratch
+ if ( init ) {
+ // attach necessary classes for styling
+ this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
+ this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
+ this.lis.addClass( "ui-state-default ui-corner-top" );
+ this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
+
+ // Selected tab
+ // use "selected" option or try to retrieve:
+ // 1. from fragment identifier in url
+ // 2. from cookie
+ // 3. from selected class attribute on <li>
+ if ( o.selected === undefined ) {
+ if ( location.hash ) {
+ this.anchors.each(function( i, a ) {
+ if ( a.hash == location.hash ) {
+ o.selected = i;
+ return false;
+ }
+ });
+ }
+ if ( typeof o.selected !== "number" && o.cookie ) {
+ o.selected = parseInt( self._cookie(), 10 );
+ }
+ if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
+ o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
+ }
+ o.selected = o.selected || ( this.lis.length ? 0 : -1 );
+ } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
+ o.selected = -1;
+ }
+
+ // sanity check - default to first tab...
+ o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
+ ? o.selected
+ : 0;
+
+ // Take disabling tabs via class attribute from HTML
+ // into account and update option properly.
+ // A selected tab cannot become disabled.
+ o.disabled = $.unique( o.disabled.concat(
+ $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
+ return self.lis.index( n );
+ })
+ ) ).sort();
+
+ if ( $.inArray( o.selected, o.disabled ) != -1 ) {
+ o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
+ }
+
+ // highlight selected tab
+ this.panels.addClass( "ui-tabs-hide" );
+ this.lis.removeClass( "ui-tabs-selected ui-state-active" );
+ // check for length avoids error when initializing empty list
+ if ( o.selected >= 0 && this.anchors.length ) {
+ self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
+ this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
+
+ // seems to be expected behavior that the show callback is fired
+ self.element.queue( "tabs", function() {
+ self._trigger( "show", null,
+ self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
+ });
+
+ this.load( o.selected );
+ }
+
+ // clean up to avoid memory leaks in certain versions of IE 6
+ // TODO: namespace this event
+ $( window ).bind( "unload", function() {
+ self.lis.add( self.anchors ).unbind( ".tabs" );
+ self.lis = self.anchors = self.panels = null;
+ });
+ // update selected after add/remove
+ } else {
+ o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
+ }
+
+ // update collapsible
+ // TODO: use .toggleClass()
+ this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
+
+ // set or update cookie after init and add/remove respectively
+ if ( o.cookie ) {
+ this._cookie( o.selected, o.cookie );
+ }
+
+ // disable tabs
+ for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
+ $( li )[ $.inArray( i, o.disabled ) != -1 &&
+ // TODO: use .toggleClass()
+ !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
+ }
+
+ // reset cache if switching from cached to not cached
+ if ( o.cache === false ) {
+ this.anchors.removeData( "cache.tabs" );
+ }
+
+ // remove all handlers before, tabify may run on existing tabs after add or option change
+ this.lis.add( this.anchors ).unbind( ".tabs" );
+
+ if ( o.event !== "mouseover" ) {
+ var addState = function( state, el ) {
+ if ( el.is( ":not(.ui-state-disabled)" ) ) {
+ el.addClass( "ui-state-" + state );
+ }
+ };
+ var removeState = function( state, el ) {
+ el.removeClass( "ui-state-" + state );
+ };
+ this.lis.bind( "mouseover.tabs" , function() {
+ addState( "hover", $( this ) );
+ });
+ this.lis.bind( "mouseout.tabs", function() {
+ removeState( "hover", $( this ) );
+ });
+ this.anchors.bind( "focus.tabs", function() {
+ addState( "focus", $( this ).closest( "li" ) );
+ });
+ this.anchors.bind( "blur.tabs", function() {
+ removeState( "focus", $( this ).closest( "li" ) );
+ });
+ }
+
+ // set up animations
+ var hideFx, showFx;
+ if ( o.fx ) {
+ if ( $.isArray( o.fx ) ) {
+ hideFx = o.fx[ 0 ];
+ showFx = o.fx[ 1 ];
+ } else {
+ hideFx = showFx = o.fx;
+ }
+ }
+
+ // Reset certain styles left over from animation
+ // and prevent IE's ClearType bug...
+ function resetStyle( $el, fx ) {
+ $el.css( "display", "" );
+ if ( !$.support.opacity && fx.opacity ) {
+ $el[ 0 ].style.removeAttribute( "filter" );
+ }
+ }
+
+ // Show a tab...
+ var showTab = showFx
+ ? function( clicked, $show ) {
+ $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
+ $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
+ .animate( showFx, showFx.duration || "normal", function() {
+ resetStyle( $show, showFx );
+ self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
+ });
+ }
+ : function( clicked, $show ) {
+ $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
+ $show.removeClass( "ui-tabs-hide" );
+ self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
+ };
+
+ // Hide a tab, $show is optional...
+ var hideTab = hideFx
+ ? function( clicked, $hide ) {
+ $hide.animate( hideFx, hideFx.duration || "normal", function() {
+ self.lis.removeClass( "ui-tabs-selected ui-state-active" );
+ $hide.addClass( "ui-tabs-hide" );
+ resetStyle( $hide, hideFx );
+ self.element.dequeue( "tabs" );
+ });
+ }
+ : function( clicked, $hide, $show ) {
+ self.lis.removeClass( "ui-tabs-selected ui-state-active" );
+ $hide.addClass( "ui-tabs-hide" );
+ self.element.dequeue( "tabs" );
+ };
+
+ // attach tab event handler, unbind to avoid duplicates from former tabifying...
+ this.anchors.bind( o.event + ".tabs", function() {
+ var el = this,
+ $li = $(el).closest( "li" ),
+ $hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
+ $show = self.element.find( self._sanitizeSelector( el.hash ) );
+
+ // If tab is already selected and not collapsible or tab disabled or
+ // or is already loading or click callback returns false stop here.
+ // Check if click handler returns false last so that it is not executed
+ // for a disabled or loading tab!
+ if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
+ $li.hasClass( "ui-state-disabled" ) ||
+ $li.hasClass( "ui-state-processing" ) ||
+ self.panels.filter( ":animated" ).length ||
+ self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
+ this.blur();
+ return false;
+ }
+
+ o.selected = self.anchors.index( this );
+
+ self.abort();
+
+ // if tab may be closed
+ if ( o.collapsible ) {
+ if ( $li.hasClass( "ui-tabs-selected" ) ) {
+ o.selected = -1;
+
+ if ( o.cookie ) {
+ self._cookie( o.selected, o.cookie );
+ }
+
+ self.element.queue( "tabs", function() {
+ hideTab( el, $hide );
+ }).dequeue( "tabs" );
+
+ this.blur();
+ return false;
+ } else if ( !$hide.length ) {
+ if ( o.cookie ) {
+ self._cookie( o.selected, o.cookie );
+ }
+
+ self.element.queue( "tabs", function() {
+ showTab( el, $show );
+ });
+
+ // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
+ self.load( self.anchors.index( this ) );
+
+ this.blur();
+ return false;
+ }
+ }
+
+ if ( o.cookie ) {
+ self._cookie( o.selected, o.cookie );
+ }
+
+ // show new tab
+ if ( $show.length ) {
+ if ( $hide.length ) {
+ self.element.queue( "tabs", function() {
+ hideTab( el, $hide );
+ });
+ }
+ self.element.queue( "tabs", function() {
+ showTab( el, $show );
+ });
+
+ self.load( self.anchors.index( this ) );
+ } else {
+ throw "jQuery UI Tabs: Mismatching fragment identifier.";
+ }
+
+ // Prevent IE from keeping other link focussed when using the back button
+ // and remove dotted border from clicked link. This is controlled via CSS
+ // in modern browsers; blur() removes focus from address bar in Firefox
+ // which can become a usability and annoying problem with tabs('rotate').
+ if ( $.browser.msie ) {
+ this.blur();
+ }
+ });
+
+ // disable click in any case
+ this.anchors.bind( "click.tabs", function(){
+ return false;
+ });
+ },
+
+ _getIndex: function( index ) {
+ // meta-function to give users option to provide a href string instead of a numerical index.
+ // also sanitizes numerical indexes to valid values.
+ if ( typeof index == "string" ) {
+ index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
+ }
+
+ return index;
+ },
+
+ destroy: function() {
+ var o = this.options;
+
+ this.abort();
+
+ this.element
+ .unbind( ".tabs" )
+ .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
+ .removeData( "tabs" );
+
+ this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
+
+ this.anchors.each(function() {
+ var href = $.data( this, "href.tabs" );
+ if ( href ) {
+ this.href = href;
+ }
+ var $this = $( this ).unbind( ".tabs" );
+ $.each( [ "href", "load", "cache" ], function( i, prefix ) {
+ $this.removeData( prefix + ".tabs" );
+ });
+ });
+
+ this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
+ if ( $.data( this, "destroy.tabs" ) ) {
+ $( this ).remove();
+ } else {
+ $( this ).removeClass([
+ "ui-state-default",
+ "ui-corner-top",
+ "ui-tabs-selected",
+ "ui-state-active",
+ "ui-state-hover",
+ "ui-state-focus",
+ "ui-state-disabled",
+ "ui-tabs-panel",
+ "ui-widget-content",
+ "ui-corner-bottom",
+ "ui-tabs-hide"
+ ].join( " " ) );
+ }
+ });
+
+ if ( o.cookie ) {
+ this._cookie( null, o.cookie );
+ }
+
+ return this;
+ },
+
+ add: function( url, label, index ) {
+ if ( index === undefined ) {
+ index = this.anchors.length;
+ }
+
+ var self = this,
+ o = this.options,
+ $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
+ id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
+
+ $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
+
+ // try to find an existing element before creating a new one
+ var $panel = self.element.find( "#" + id );
+ if ( !$panel.length ) {
+ $panel = $( o.panelTemplate )
+ .attr( "id", id )
+ .data( "destroy.tabs", true );
+ }
+ $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
+
+ if ( index >= this.lis.length ) {
+ $li.appendTo( this.list );
+ $panel.appendTo( this.list[ 0 ].parentNode );
+ } else {
+ $li.insertBefore( this.lis[ index ] );
+ $panel.insertBefore( this.panels[ index ] );
+ }
+
+ o.disabled = $.map( o.disabled, function( n, i ) {
+ return n >= index ? ++n : n;
+ });
+
+ this._tabify();
+
+ if ( this.anchors.length == 1 ) {
+ o.selected = 0;
+ $li.addClass( "ui-tabs-selected ui-state-active" );
+ $panel.removeClass( "ui-tabs-hide" );
+ this.element.queue( "tabs", function() {
+ self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
+ });
+
+ this.load( 0 );
+ }
+
+ this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
+ return this;
+ },
+
+ remove: function( index ) {
+ index = this._getIndex( index );
+ var o = this.options,
+ $li = this.lis.eq( index ).remove(),
+ $panel = this.panels.eq( index ).remove();
+
+ // If selected tab was removed focus tab to the right or
+ // in case the last tab was removed the tab to the left.
+ if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
+ this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
+ }
+
+ o.disabled = $.map(
+ $.grep( o.disabled, function(n, i) {
+ return n != index;
+ }),
+ function( n, i ) {
+ return n >= index ? --n : n;
+ });
+
+ this._tabify();
+
+ this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
+ return this;
+ },
+
+ enable: function( index ) {
+ index = this._getIndex( index );
+ var o = this.options;
+ if ( $.inArray( index, o.disabled ) == -1 ) {
+ return;
+ }
+
+ this.lis.eq( index ).removeClass( "ui-state-disabled" );
+ o.disabled = $.grep( o.disabled, function( n, i ) {
+ return n != index;
+ });
+
+ this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
+ return this;
+ },
+
+ disable: function( index ) {
+ index = this._getIndex( index );
+ var self = this, o = this.options;
+ // cannot disable already selected tab
+ if ( index != o.selected ) {
+ this.lis.eq( index ).addClass( "ui-state-disabled" );
+
+ o.disabled.push( index );
+ o.disabled.sort();
+
+ this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
+ }
+
+ return this;
+ },
+
+ select: function( index ) {
+ index = this._getIndex( index );
+ if ( index == -1 ) {
+ if ( this.options.collapsible && this.options.selected != -1 ) {
+ index = this.options.selected;
+ } else {
+ return this;
+ }
+ }
+ this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
+ return this;
+ },
+
+ load: function( index ) {
+ index = this._getIndex( index );
+ var self = this,
+ o = this.options,
+ a = this.anchors.eq( index )[ 0 ],
+ url = $.data( a, "load.tabs" );
+
+ this.abort();
+
+ // not remote or from cache
+ if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
+ this.element.dequeue( "tabs" );
+ return;
+ }
+
+ // load remote from here on
+ this.lis.eq( index ).addClass( "ui-state-processing" );
+
+ if ( o.spinner ) {
+ var span = $( "span", a );
+ span.data( "label.tabs", span.html() ).html( o.spinner );
+ }
+
+ this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
+ url: url,
+ success: function( r, s ) {
+ self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
+
+ // take care of tab labels
+ self._cleanup();
+
+ if ( o.cache ) {
+ $.data( a, "cache.tabs", true );
+ }
+
+ self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
+ try {
+ o.ajaxOptions.success( r, s );
+ }
+ catch ( e ) {}
+ },
+ error: function( xhr, s, e ) {
+ // take care of tab labels
+ self._cleanup();
+
+ self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
+ try {
+ // Passing index avoid a race condition when this method is
+ // called after the user has selected another tab.
+ // Pass the anchor that initiated this request allows
+ // loadError to manipulate the tab content panel via $(a.hash)
+ o.ajaxOptions.error( xhr, s, index, a );
+ }
+ catch ( e ) {}
+ }
+ } ) );
+
+ // last, so that load event is fired before show...
+ self.element.dequeue( "tabs" );
+
+ return this;
+ },
+
+ abort: function() {
+ // stop possibly running animations
+ this.element.queue( [] );
+ this.panels.stop( false, true );
+
+ // "tabs" queue must not contain more than two elements,
+ // which are the callbacks for the latest clicked tab...
+ this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
+
+ // terminate pending requests from other tabs
+ if ( this.xhr ) {
+ this.xhr.abort();
+ delete this.xhr;
+ }
+
+ // take care of tab labels
+ this._cleanup();
+ return this;
+ },
+
+ url: function( index, url ) {
+ this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
+ return this;
+ },
+
+ length: function() {
+ return this.anchors.length;
+ }
+});
+
+$.extend( $.ui.tabs, {
+ version: "1.8.16"
+});
+
+/*
+ * Tabs Extensions
+ */
+
+/*
+ * Rotate
+ */
+$.extend( $.ui.tabs.prototype, {
+ rotation: null,
+ rotate: function( ms, continuing ) {
+ var self = this,
+ o = this.options;
+
+ var rotate = self._rotate || ( self._rotate = function( e ) {
+ clearTimeout( self.rotation );
+ self.rotation = setTimeout(function() {
+ var t = o.selected;
+ self.select( ++t < self.anchors.length ? t : 0 );
+ }, ms );
+
+ if ( e ) {
+ e.stopPropagation();
+ }
+ });
+
+ var stop = self._unrotate || ( self._unrotate = !continuing
+ ? function(e) {
+ if (e.clientX) { // in case of a true click
+ self.rotate(null);
+ }
+ }
+ : function( e ) {
+ t = o.selected;
+ rotate();
+ });
+
+ // start rotation
+ if ( ms ) {
+ this.element.bind( "tabsshow", rotate );
+ this.anchors.bind( o.event + ".tabs", stop );
+ rotate();
+ // stop rotation
+ } else {
+ clearTimeout( self.rotation );
+ this.element.unbind( "tabsshow", rotate );
+ this.anchors.unbind( o.event + ".tabs", stop );
+ delete this._rotate;
+ delete this._unrotate;
+ }
+
+ return this;
+ }
+});
+
+})( jQuery );
diff --git a/lib/scripts/jquery/jquery-ui.min.js b/lib/scripts/jquery/jquery-ui.min.js
new file mode 100644
index 000000000..0202506b5
--- /dev/null
+++ b/lib/scripts/jquery/jquery-ui.min.js
@@ -0,0 +1,414 @@
+/*!
+ * jQuery UI 1.8.16
+ *
+ * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function(a,d){function c(h,g){var i=h.nodeName.toLowerCase();if("area"===i){g=h.parentNode;i=g.name;if(!h.href||!i||g.nodeName.toLowerCase()!=="map")return false;h=a("img[usemap=#"+i+"]")[0];return!!h&&e(h)}return(/input|select|textarea|button|object/.test(i)?!h.disabled:"a"==i?h.href||g:g)&&e(h)}function e(h){return!a(h).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.ui=a.ui||{};if(!a.ui.version){a.extend(a.ui,{version:"1.8.16",
+keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(h,g){return typeof h==="number"?this.each(function(){var i=
+this;setTimeout(function(){a(i).focus();g&&g.call(i)},h)}):this._focus.apply(this,arguments)},scrollParent:function(){var h;h=a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,
+"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!h.length?a(document):h},zIndex:function(h){if(h!==d)return this.css("zIndex",h);if(this.length){h=a(this[0]);for(var g;h.length&&h[0]!==document;){g=h.css("position");if(g==="absolute"||g==="relative"||g==="fixed"){g=parseInt(h.css("zIndex"),10);if(!isNaN(g)&&g!==0)return g}h=h.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":
+"mousedown")+".ui-disableSelection",function(h){h.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(h,g){function i(l,o,n,k){a.each(b,function(){o-=parseFloat(a.curCSS(l,"padding"+this,true))||0;if(n)o-=parseFloat(a.curCSS(l,"border"+this+"Width",true))||0;if(k)o-=parseFloat(a.curCSS(l,"margin"+this,true))||0});return o}var b=g==="Width"?["Left","Right"]:["Top","Bottom"],f=g.toLowerCase(),j={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,
+outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+g]=function(l){if(l===d)return j["inner"+g].call(this);return this.each(function(){a(this).css(f,i(this,l)+"px")})};a.fn["outer"+g]=function(l,o){if(typeof l!=="number")return j["outer"+g].call(this,l);return this.each(function(){a(this).css(f,i(this,l,true,o)+"px")})}});a.extend(a.expr[":"],{data:function(h,g,i){return!!a.data(h,i[3])},focusable:function(h){return c(h,!isNaN(a.attr(h,"tabindex")))},tabbable:function(h){var g=a.attr(h,
+"tabindex"),i=isNaN(g);return(i||g>=0)&&c(h,!i)}});a(function(){var h=document.body,g=h.appendChild(g=document.createElement("div"));a.extend(g.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=g.offsetHeight===100;a.support.selectstart="onselectstart"in g;h.removeChild(g).style.display="none"});a.extend(a.ui,{plugin:{add:function(h,g,i){h=a.ui[h].prototype;for(var b in i){h.plugins[b]=h.plugins[b]||[];h.plugins[b].push([g,i[b]])}},call:function(h,g,i){if((g=h.plugins[g])&&
+h.element[0].parentNode)for(var b=0;b<g.length;b++)h.options[g[b][0]]&&g[b][1].apply(h.element,i)}},contains:function(h,g){return document.compareDocumentPosition?h.compareDocumentPosition(g)&16:h!==g&&h.contains(g)},hasScroll:function(h,g){if(a(h).css("overflow")==="hidden")return false;g=g&&g==="left"?"scrollLeft":"scrollTop";var i=false;if(h[g]>0)return true;h[g]=1;i=h[g]>0;h[g]=0;return i},isOverAxis:function(h,g,i){return h>g&&h<g+i},isOver:function(h,g,i,b,f,j){return a.ui.isOverAxis(h,i,f)&&
+a.ui.isOverAxis(g,b,j)}})}})(jQuery);
+(function(a,d){if(a.cleanData){var c=a.cleanData;a.cleanData=function(h){for(var g=0,i;(i=h[g])!=null;g++)try{a(i).triggerHandler("remove")}catch(b){}c(h)}}else{var e=a.fn.remove;a.fn.remove=function(h,g){return this.each(function(){if(!g)if(!h||a.filter(h,[this]).length)a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(i){}});return e.call(a(this),h,g)})}}a.widget=function(h,g,i){var b=h.split(".")[0],f;h=h.split(".")[1];f=b+"-"+h;if(!i){i=g;g=a.Widget}a.expr[":"][f]=
+function(j){return!!a.data(j,h)};a[b]=a[b]||{};a[b][h]=function(j,l){arguments.length&&this._createWidget(j,l)};g=new g;g.options=a.extend(true,{},g.options);a[b][h].prototype=a.extend(true,g,{namespace:b,widgetName:h,widgetEventPrefix:a[b][h].prototype.widgetEventPrefix||h,widgetBaseClass:f},i);a.widget.bridge(h,a[b][h])};a.widget.bridge=function(h,g){a.fn[h]=function(i){var b=typeof i==="string",f=Array.prototype.slice.call(arguments,1),j=this;i=!b&&f.length?a.extend.apply(null,[true,i].concat(f)):
+i;if(b&&i.charAt(0)==="_")return j;b?this.each(function(){var l=a.data(this,h),o=l&&a.isFunction(l[i])?l[i].apply(l,f):l;if(o!==l&&o!==d){j=o;return false}}):this.each(function(){var l=a.data(this,h);l?l.option(i||{})._init():a.data(this,h,new g(i,this))});return j}};a.Widget=function(h,g){arguments.length&&this._createWidget(h,g)};a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(h,g){a.data(g,this.widgetName,this);this.element=a(g);this.options=
+a.extend(true,{},this.options,this._getCreateOptions(),h);var i=this;this.element.bind("remove."+this.widgetName,function(){i.destroy()});this._create();this._trigger("create");this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+
+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(h,g){var i=h;if(arguments.length===0)return a.extend({},this.options);if(typeof h==="string"){if(g===d)return this.options[h];i={};i[h]=g}this._setOptions(i);return this},_setOptions:function(h){var g=this;a.each(h,function(i,b){g._setOption(i,b)});return this},_setOption:function(h,g){this.options[h]=g;if(h==="disabled")this.widget()[g?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",
+g);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(h,g,i){var b=this.options[h];g=a.Event(g);g.type=(h===this.widgetEventPrefix?h:this.widgetEventPrefix+h).toLowerCase();i=i||{};if(g.originalEvent){h=a.event.props.length;for(var f;h;){f=a.event.props[--h];g[f]=g.originalEvent[f]}}this.element.trigger(g,i);return!(a.isFunction(b)&&b.call(this.element[0],g,i)===false||g.isDefaultPrevented())}}})(jQuery);
+(function(a){var d=false;a(document).mouseup(function(){d=false});a.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var c=this;this.element.bind("mousedown."+this.widgetName,function(e){return c._mouseDown(e)}).bind("click."+this.widgetName,function(e){if(true===a.data(e.target,c.widgetName+".preventClickEvent")){a.removeData(e.target,c.widgetName+".preventClickEvent");e.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+
+this.widgetName)},_mouseDown:function(c){if(!d){this._mouseStarted&&this._mouseUp(c);this._mouseDownEvent=c;var e=this,h=c.which==1,g=typeof this.options.cancel=="string"&&c.target.nodeName?a(c.target).closest(this.options.cancel).length:false;if(!h||g||!this._mouseCapture(c))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){e.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(c)&&this._mouseDelayMet(c)){this._mouseStarted=
+this._mouseStart(c)!==false;if(!this._mouseStarted){c.preventDefault();return true}}true===a.data(c.target,this.widgetName+".preventClickEvent")&&a.removeData(c.target,this.widgetName+".preventClickEvent");this._mouseMoveDelegate=function(i){return e._mouseMove(i)};this._mouseUpDelegate=function(i){return e._mouseUp(i)};a(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.preventDefault();return d=true}},_mouseMove:function(c){if(a.browser.msie&&
+!(document.documentMode>=9)&&!c.button)return this._mouseUp(c);if(this._mouseStarted){this._mouseDrag(c);return c.preventDefault()}if(this._mouseDistanceMet(c)&&this._mouseDelayMet(c))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,c)!==false)?this._mouseDrag(c):this._mouseUp(c);return!this._mouseStarted},_mouseUp:function(c){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=
+false;c.target==this._mouseDownEvent.target&&a.data(c.target,this.widgetName+".preventClickEvent",true);this._mouseStop(c)}return false},_mouseDistanceMet:function(c){return Math.max(Math.abs(this._mouseDownEvent.pageX-c.pageX),Math.abs(this._mouseDownEvent.pageY-c.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
+(function(a){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper==
+"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(d){var c=
+this.options;if(this.helper||c.disabled||a(d.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(d);if(!this.handle)return false;if(c.iframeFix)a(c.iframeFix===true?"iframe":c.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(a(this).offset()).appendTo("body")});return true},_mouseStart:function(d){var c=this.options;
+this.helper=this._createHelper(d);this._cacheHelperProportions();if(a.ui.ddmanager)a.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:d.pageX-this.offset.left,top:d.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});
+this.originalPosition=this.position=this._generatePosition(d);this.originalPageX=d.pageX;this.originalPageY=d.pageY;c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt);c.containment&&this._setContainment();if(this._trigger("start",d)===false){this._clear();return false}this._cacheHelperProportions();a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,d);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(d,true);a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,d);return true},
+_mouseDrag:function(d,c){this.position=this._generatePosition(d);this.positionAbs=this._convertPositionTo("absolute");if(!c){c=this._uiHash();if(this._trigger("drag",d,c)===false){this._mouseUp({});return false}this.position=c.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,d);return false},_mouseStop:function(d){var c=
+false;if(a.ui.ddmanager&&!this.options.dropBehaviour)c=a.ui.ddmanager.drop(this,d);if(this.dropped){c=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===true||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var e=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,
+10),function(){e._trigger("stop",d)!==false&&e._clear()})}else this._trigger("stop",d)!==false&&this._clear();return false},_mouseUp:function(d){this.options.iframeFix===true&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,d);return a.ui.mouse.prototype._mouseUp.call(this,d)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(d){var c=!this.options.handle||
+!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==d.target)c=true});return c},_createHelper:function(d){var c=this.options;d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[d])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo);d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&
+d.css("position","absolute");return d},_adjustOffsetFromHelper:function(d){if(typeof d=="string")d=d.split(" ");if(a.isArray(d))d={left:+d[0],top:+d[1]||0};if("left"in d)this.offset.click.left=d.left+this.margins.left;if("right"in d)this.offset.click.left=this.helperProportions.width-d.right+this.margins.left;if("top"in d)this.offset.click.top=d.top+this.margins.top;if("bottom"in d)this.offset.click.top=this.helperProportions.height-d.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=
+this.helper.offsetParent();var d=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){d.left+=this.scrollParent.scrollLeft();d.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)d={top:0,left:0};return{top:d.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:d.left+(parseInt(this.offsetParent.css("borderLeftWidth"),
+10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var d=this.element.position();return{top:d.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:d.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_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 d=this.options;if(d.containment=="parent")d.containment=this.helper[0].parentNode;if(d.containment=="document"||d.containment=="window")this.containment=[d.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,d.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,
+(d.containment=="document"?0:a(window).scrollLeft())+a(d.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(d.containment=="document"?0:a(window).scrollTop())+(a(d.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(d.containment)&&d.containment.constructor!=Array){d=a(d.containment);var c=d[0];if(c){d.offset();var e=a(c).css("overflow")!=
+"hidden";this.containment=[(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0),(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0),(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),
+10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=d}}else if(d.containment.constructor==Array)this.containment=d.containment},_convertPositionTo:function(d,c){if(!c)c=this.position;d=d=="absolute"?1:-1;var e=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(e[0].tagName);return{top:c.top+
+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():h?0:e.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():h?0:e.scrollLeft())*d)}},_generatePosition:function(d){var c=this.options,e=this.cssPosition=="absolute"&&
+!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(e[0].tagName),g=d.pageX,i=d.pageY;if(this.originalPosition){var b;if(this.containment){if(this.relative_container){b=this.relative_container.offset();b=[this.containment[0]+b.left,this.containment[1]+b.top,this.containment[2]+b.left,this.containment[3]+b.top]}else b=this.containment;if(d.pageX-this.offset.click.left<b[0])g=b[0]+this.offset.click.left;
+if(d.pageY-this.offset.click.top<b[1])i=b[1]+this.offset.click.top;if(d.pageX-this.offset.click.left>b[2])g=b[2]+this.offset.click.left;if(d.pageY-this.offset.click.top>b[3])i=b[3]+this.offset.click.top}if(c.grid){i=c.grid[1]?this.originalPageY+Math.round((i-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;i=b?!(i-this.offset.click.top<b[1]||i-this.offset.click.top>b[3])?i:!(i-this.offset.click.top<b[1])?i-c.grid[1]:i+c.grid[1]:i;g=c.grid[0]?this.originalPageX+Math.round((g-this.originalPageX)/
+c.grid[0])*c.grid[0]:this.originalPageX;g=b?!(g-this.offset.click.left<b[0]||g-this.offset.click.left>b[2])?g:!(g-this.offset.click.left<b[0])?g-c.grid[0]:g+c.grid[0]:g}}return{top:i-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():h?0:e.scrollTop()),left:g-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&a.browser.version<
+526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():h?0:e.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=false},_trigger:function(d,c,e){e=e||this._uiHash();a.ui.plugin.call(this,d,[c,e]);if(d=="drag")this.positionAbs=this._convertPositionTo("absolute");return a.Widget.prototype._trigger.call(this,d,c,
+e)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});a.extend(a.ui.draggable,{version:"1.8.16"});a.ui.plugin.add("draggable","connectToSortable",{start:function(d,c){var e=a(this).data("draggable"),h=e.options,g=a.extend({},c,{item:e.element});e.sortables=[];a(h.connectToSortable).each(function(){var i=a.data(this,"sortable");if(i&&!i.options.disabled){e.sortables.push({instance:i,shouldRevert:i.options.revert});
+i.refreshPositions();i._trigger("activate",d,g)}})},stop:function(d,c){var e=a(this).data("draggable"),h=a.extend({},c,{item:e.element});a.each(e.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;e.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert)this.instance.options.revert=true;this.instance._mouseStop(d);this.instance.options.helper=this.instance.options._helper;e.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})}else{this.instance.cancelHelperRemoval=
+false;this.instance._trigger("deactivate",d,h)}})},drag:function(d,c){var e=a(this).data("draggable"),h=this;a.each(e.sortables,function(){this.instance.positionAbs=e.positionAbs;this.instance.helperProportions=e.helperProportions;this.instance.offset.click=e.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=a(h).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",true);
+this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return c.helper[0]};d.target=this.instance.currentItem[0];this.instance._mouseCapture(d,true);this.instance._mouseStart(d,true,true);this.instance.offset.click.top=e.offset.click.top;this.instance.offset.click.left=e.offset.click.left;this.instance.offset.parent.left-=e.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=e.offset.parent.top-this.instance.offset.parent.top;
+e._trigger("toSortable",d);e.dropped=this.instance.element;e.currentItem=e.element;this.instance.fromOutside=e}this.instance.currentItem&&this.instance._mouseDrag(d)}else if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",d,this.instance._uiHash(this.instance));this.instance._mouseStop(d,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();this.instance.placeholder&&
+this.instance.placeholder.remove();e._trigger("fromSortable",d);e.dropped=false}})}});a.ui.plugin.add("draggable","cursor",{start:function(){var d=a("body"),c=a(this).data("draggable").options;if(d.css("cursor"))c._cursor=d.css("cursor");d.css("cursor",c.cursor)},stop:function(){var d=a(this).data("draggable").options;d._cursor&&a("body").css("cursor",d._cursor)}});a.ui.plugin.add("draggable","opacity",{start:function(d,c){d=a(c.helper);c=a(this).data("draggable").options;if(d.css("opacity"))c._opacity=
+d.css("opacity");d.css("opacity",c.opacity)},stop:function(d,c){d=a(this).data("draggable").options;d._opacity&&a(c.helper).css("opacity",d._opacity)}});a.ui.plugin.add("draggable","scroll",{start:function(){var d=a(this).data("draggable");if(d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML")d.overflowOffset=d.scrollParent.offset()},drag:function(d){var c=a(this).data("draggable"),e=c.options,h=false;if(c.scrollParent[0]!=document&&c.scrollParent[0].tagName!="HTML"){if(!e.axis||e.axis!=
+"x")if(c.overflowOffset.top+c.scrollParent[0].offsetHeight-d.pageY<e.scrollSensitivity)c.scrollParent[0].scrollTop=h=c.scrollParent[0].scrollTop+e.scrollSpeed;else if(d.pageY-c.overflowOffset.top<e.scrollSensitivity)c.scrollParent[0].scrollTop=h=c.scrollParent[0].scrollTop-e.scrollSpeed;if(!e.axis||e.axis!="y")if(c.overflowOffset.left+c.scrollParent[0].offsetWidth-d.pageX<e.scrollSensitivity)c.scrollParent[0].scrollLeft=h=c.scrollParent[0].scrollLeft+e.scrollSpeed;else if(d.pageX-c.overflowOffset.left<
+e.scrollSensitivity)c.scrollParent[0].scrollLeft=h=c.scrollParent[0].scrollLeft-e.scrollSpeed}else{if(!e.axis||e.axis!="x")if(d.pageY-a(document).scrollTop()<e.scrollSensitivity)h=a(document).scrollTop(a(document).scrollTop()-e.scrollSpeed);else if(a(window).height()-(d.pageY-a(document).scrollTop())<e.scrollSensitivity)h=a(document).scrollTop(a(document).scrollTop()+e.scrollSpeed);if(!e.axis||e.axis!="y")if(d.pageX-a(document).scrollLeft()<e.scrollSensitivity)h=a(document).scrollLeft(a(document).scrollLeft()-
+e.scrollSpeed);else if(a(window).width()-(d.pageX-a(document).scrollLeft())<e.scrollSensitivity)h=a(document).scrollLeft(a(document).scrollLeft()+e.scrollSpeed)}h!==false&&a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(c,d)}});a.ui.plugin.add("draggable","snap",{start:function(){var d=a(this).data("draggable"),c=d.options;d.snapElements=[];a(c.snap.constructor!=String?c.snap.items||":data(draggable)":c.snap).each(function(){var e=a(this),h=e.offset();this!=d.element[0]&&d.snapElements.push({item:this,
+width:e.outerWidth(),height:e.outerHeight(),top:h.top,left:h.left})})},drag:function(d,c){for(var e=a(this).data("draggable"),h=e.options,g=h.snapTolerance,i=c.offset.left,b=i+e.helperProportions.width,f=c.offset.top,j=f+e.helperProportions.height,l=e.snapElements.length-1;l>=0;l--){var o=e.snapElements[l].left,n=o+e.snapElements[l].width,k=e.snapElements[l].top,m=k+e.snapElements[l].height;if(o-g<i&&i<n+g&&k-g<f&&f<m+g||o-g<i&&i<n+g&&k-g<j&&j<m+g||o-g<b&&b<n+g&&k-g<f&&f<m+g||o-g<b&&b<n+g&&k-g<j&&
+j<m+g){if(h.snapMode!="inner"){var p=Math.abs(k-j)<=g,q=Math.abs(m-f)<=g,s=Math.abs(o-b)<=g,r=Math.abs(n-i)<=g;if(p)c.position.top=e._convertPositionTo("relative",{top:k-e.helperProportions.height,left:0}).top-e.margins.top;if(q)c.position.top=e._convertPositionTo("relative",{top:m,left:0}).top-e.margins.top;if(s)c.position.left=e._convertPositionTo("relative",{top:0,left:o-e.helperProportions.width}).left-e.margins.left;if(r)c.position.left=e._convertPositionTo("relative",{top:0,left:n}).left-e.margins.left}var u=
+p||q||s||r;if(h.snapMode!="outer"){p=Math.abs(k-f)<=g;q=Math.abs(m-j)<=g;s=Math.abs(o-i)<=g;r=Math.abs(n-b)<=g;if(p)c.position.top=e._convertPositionTo("relative",{top:k,left:0}).top-e.margins.top;if(q)c.position.top=e._convertPositionTo("relative",{top:m-e.helperProportions.height,left:0}).top-e.margins.top;if(s)c.position.left=e._convertPositionTo("relative",{top:0,left:o}).left-e.margins.left;if(r)c.position.left=e._convertPositionTo("relative",{top:0,left:n-e.helperProportions.width}).left-e.margins.left}if(!e.snapElements[l].snapping&&
+(p||q||s||r||u))e.options.snap.snap&&e.options.snap.snap.call(e.element,d,a.extend(e._uiHash(),{snapItem:e.snapElements[l].item}));e.snapElements[l].snapping=p||q||s||r||u}else{e.snapElements[l].snapping&&e.options.snap.release&&e.options.snap.release.call(e.element,d,a.extend(e._uiHash(),{snapItem:e.snapElements[l].item}));e.snapElements[l].snapping=false}}}});a.ui.plugin.add("draggable","stack",{start:function(){var d=a(this).data("draggable").options;d=a.makeArray(a(d.stack)).sort(function(e,h){return(parseInt(a(e).css("zIndex"),
+10)||0)-(parseInt(a(h).css("zIndex"),10)||0)});if(d.length){var c=parseInt(d[0].style.zIndex)||0;a(d).each(function(e){this.style.zIndex=c+e});this[0].style.zIndex=c+d.length}}});a.ui.plugin.add("draggable","zIndex",{start:function(d,c){d=a(c.helper);c=a(this).data("draggable").options;if(d.css("zIndex"))c._zIndex=d.css("zIndex");d.css("zIndex",c.zIndex)},stop:function(d,c){d=a(this).data("draggable").options;d._zIndex&&a(c.helper).css("zIndex",d._zIndex)}})})(jQuery);
+(function(a){a.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"},_create:function(){var d=this.options,c=d.accept;this.isover=0;this.isout=1;this.accept=a.isFunction(c)?c:function(e){return e.is(c)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};a.ui.ddmanager.droppables[d.scope]=a.ui.ddmanager.droppables[d.scope]||[];a.ui.ddmanager.droppables[d.scope].push(this);
+d.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){for(var d=a.ui.ddmanager.droppables[this.options.scope],c=0;c<d.length;c++)d[c]==this&&d.splice(c,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(d,c){if(d=="accept")this.accept=a.isFunction(c)?c:function(e){return e.is(c)};a.Widget.prototype._setOption.apply(this,arguments)},_activate:function(d){var c=a.ui.ddmanager.current;this.options.activeClass&&
+this.element.addClass(this.options.activeClass);c&&this._trigger("activate",d,this.ui(c))},_deactivate:function(d){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass);c&&this._trigger("deactivate",d,this.ui(c))},_over:function(d){var c=a.ui.ddmanager.current;if(!(!c||(c.currentItem||c.element)[0]==this.element[0]))if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.hoverClass&&this.element.addClass(this.options.hoverClass);
+this._trigger("over",d,this.ui(c))}},_out:function(d){var c=a.ui.ddmanager.current;if(!(!c||(c.currentItem||c.element)[0]==this.element[0]))if(this.accept.call(this.element[0],c.currentItem||c.element)){this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("out",d,this.ui(c))}},_drop:function(d,c){var e=c||a.ui.ddmanager.current;if(!e||(e.currentItem||e.element)[0]==this.element[0])return false;var h=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var g=
+a.data(this,"droppable");if(g.options.greedy&&!g.options.disabled&&g.options.scope==e.options.scope&&g.accept.call(g.element[0],e.currentItem||e.element)&&a.ui.intersect(e,a.extend(g,{offset:g.element.offset()}),g.options.tolerance)){h=true;return false}});if(h)return false;if(this.accept.call(this.element[0],e.currentItem||e.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass);this.options.hoverClass&&this.element.removeClass(this.options.hoverClass);this._trigger("drop",
+d,this.ui(e));return this.element}return false},ui:function(d){return{draggable:d.currentItem||d.element,helper:d.helper,position:d.position,offset:d.positionAbs}}});a.extend(a.ui.droppable,{version:"1.8.16"});a.ui.intersect=function(d,c,e){if(!c.offset)return false;var h=(d.positionAbs||d.position.absolute).left,g=h+d.helperProportions.width,i=(d.positionAbs||d.position.absolute).top,b=i+d.helperProportions.height,f=c.offset.left,j=f+c.proportions.width,l=c.offset.top,o=l+c.proportions.height;
+switch(e){case "fit":return f<=h&&g<=j&&l<=i&&b<=o;case "intersect":return f<h+d.helperProportions.width/2&&g-d.helperProportions.width/2<j&&l<i+d.helperProportions.height/2&&b-d.helperProportions.height/2<o;case "pointer":return a.ui.isOver((d.positionAbs||d.position.absolute).top+(d.clickOffset||d.offset.click).top,(d.positionAbs||d.position.absolute).left+(d.clickOffset||d.offset.click).left,l,f,c.proportions.height,c.proportions.width);case "touch":return(i>=l&&i<=o||b>=l&&b<=o||i<l&&b>o)&&(h>=
+f&&h<=j||g>=f&&g<=j||h<f&&g>j);default:return false}};a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(d,c){var e=a.ui.ddmanager.droppables[d.options.scope]||[],h=c?c.type:null,g=(d.currentItem||d.element).find(":data(droppable)").andSelf(),i=0;a:for(;i<e.length;i++)if(!(e[i].options.disabled||d&&!e[i].accept.call(e[i].element[0],d.currentItem||d.element))){for(var b=0;b<g.length;b++)if(g[b]==e[i].element[0]){e[i].proportions.height=0;continue a}e[i].visible=e[i].element.css("display")!=
+"none";if(e[i].visible){h=="mousedown"&&e[i]._activate.call(e[i],c);e[i].offset=e[i].element.offset();e[i].proportions={width:e[i].element[0].offsetWidth,height:e[i].element[0].offsetHeight}}}},drop:function(d,c){var e=false;a.each(a.ui.ddmanager.droppables[d.options.scope]||[],function(){if(this.options){if(!this.options.disabled&&this.visible&&a.ui.intersect(d,this,this.options.tolerance))e=e||this._drop.call(this,c);if(!this.options.disabled&&this.visible&&this.accept.call(this.element[0],d.currentItem||
+d.element)){this.isout=1;this.isover=0;this._deactivate.call(this,c)}}});return e},dragStart:function(d,c){d.element.parents(":not(body,html)").bind("scroll.droppable",function(){d.options.refreshPositions||a.ui.ddmanager.prepareOffsets(d,c)})},drag:function(d,c){d.options.refreshPositions&&a.ui.ddmanager.prepareOffsets(d,c);a.each(a.ui.ddmanager.droppables[d.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var e=a.ui.intersect(d,this,this.options.tolerance);
+if(e=!e&&this.isover==1?"isout":e&&this.isover==0?"isover":null){var h;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");if(g.length){h=a.data(g[0],"droppable");h.greedyChild=e=="isover"?1:0}}if(h&&e=="isover"){h.isover=0;h.isout=1;h._out.call(h,c)}this[e]=1;this[e=="isout"?"isover":"isout"]=0;this[e=="isover"?"_over":"_out"].call(this,c);if(h&&e=="isout"){h.isout=0;h.isover=1;h._over.call(h,c)}}}})},dragStop:function(d,c){d.element.parents(":not(body,html)").unbind("scroll.droppable");
+d.options.refreshPositions||a.ui.ddmanager.prepareOffsets(d,c)}}})(jQuery);
+(function(a){a.widget("ui.resizable",a.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var e=this,h=this.options;this.element.addClass("ui-resizable");a.extend(this,{_aspectRatio:!!h.aspectRatio,aspectRatio:h.aspectRatio,originalElement:this.element,
+_proportionallyResizeElements:[],_helper:h.helper||h.ghost||h.animate?h.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&a.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(a('<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("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom: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({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=h.handles||(!a(".ui-resizable-handle",this.element).length?"e,s,se":{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"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var g=this.handles.split(",");this.handles={};for(var i=0;i<g.length;i++){var b=a.trim(g[i]),f=a('<div class="ui-resizable-handle '+("ui-resizable-"+b)+'"></div>');/sw|se|ne|nw/.test(b)&&f.css({zIndex:++h.zIndex});"se"==b&&f.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[b]=".ui-resizable-"+b;this.element.append(f)}}this._renderAxis=function(j){j=j||this.element;for(var l in this.handles){if(this.handles[l].constructor==
+String)this.handles[l]=a(this.handles[l],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var o=a(this.handles[l],this.element),n=0;n=/sw|ne|nw|se|n|s/.test(l)?o.outerHeight():o.outerWidth();o=["padding",/ne|nw|n/.test(l)?"Top":/se|sw|s/.test(l)?"Bottom":/^e$/.test(l)?"Right":"Left"].join("");j.css(o,n);this._proportionallyResize()}a(this.handles[l])}};this._renderAxis(this.element);this._handles=a(".ui-resizable-handle",this.element).disableSelection();
+this._handles.mouseover(function(){if(!e.resizing){if(this.className)var j=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);e.axis=j&&j[1]?j[1]:"se"}});if(h.autoHide){this._handles.hide();a(this.element).addClass("ui-resizable-autohide").hover(function(){if(!h.disabled){a(this).removeClass("ui-resizable-autohide");e._handles.show()}},function(){if(!h.disabled)if(!e.resizing){a(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();
+var e=function(g){a(g).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){e(this.element);var h=this.element;h.after(this.originalElement.css({position:h.css("position"),width:h.outerWidth(),height:h.outerHeight(),top:h.css("top"),left:h.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);e(this.originalElement);return this},_mouseCapture:function(e){var h=
+false;for(var g in this.handles)if(a(this.handles[g])[0]==e.target)h=true;return!this.options.disabled&&h},_mouseStart:function(e){var h=this.options,g=this.element.position(),i=this.element;this.resizing=true;this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()};if(i.is(".ui-draggable")||/absolute/.test(i.css("position")))i.css({position:"absolute",top:g.top,left:g.left});a.browser.opera&&/relative/.test(i.css("position"))&&i.css({position:"relative",top:"auto",left:"auto"});
+this._renderProxy();g=d(this.helper.css("left"));var b=d(this.helper.css("top"));if(h.containment){g+=a(h.containment).scrollLeft()||0;b+=a(h.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:g,top:b};this.size=this._helper?{width:i.outerWidth(),height:i.outerHeight()}:{width:i.width(),height:i.height()};this.originalSize=this._helper?{width:i.outerWidth(),height:i.outerHeight()}:{width:i.width(),height:i.height()};this.originalPosition={left:g,top:b};this.sizeDiff=
+{width:i.outerWidth()-i.width(),height:i.outerHeight()-i.height()};this.originalMousePosition={left:e.pageX,top:e.pageY};this.aspectRatio=typeof h.aspectRatio=="number"?h.aspectRatio:this.originalSize.width/this.originalSize.height||1;h=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",h=="auto"?this.axis+"-resize":h);i.addClass("ui-resizable-resizing");this._propagate("start",e);return true},_mouseDrag:function(e){var h=this.helper,g=this.originalMousePosition,i=this._change[this.axis];
+if(!i)return false;g=i.apply(this,[e,e.pageX-g.left||0,e.pageY-g.top||0]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey)g=this._updateRatio(g,e);g=this._respectSize(g,e);this._propagate("resize",e);h.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(g);this._trigger("resize",e,this.ui());return false},
+_mouseStop:function(e){this.resizing=false;var h=this.options,g=this;if(this._helper){var i=this._proportionallyResizeElements,b=i.length&&/textarea/i.test(i[0].nodeName);i=b&&a.ui.hasScroll(i[0],"left")?0:g.sizeDiff.height;b=b?0:g.sizeDiff.width;b={width:g.helper.width()-b,height:g.helper.height()-i};i=parseInt(g.element.css("left"),10)+(g.position.left-g.originalPosition.left)||null;var f=parseInt(g.element.css("top"),10)+(g.position.top-g.originalPosition.top)||null;h.animate||this.element.css(a.extend(b,
+{top:f,left:i}));g.helper.height(g.size.height);g.helper.width(g.size.width);this._helper&&!h.animate&&this._proportionallyResize()}a("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",e);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(e){var h=this.options,g,i,b;h={minWidth:c(h.minWidth)?h.minWidth:0,maxWidth:c(h.maxWidth)?h.maxWidth:Infinity,minHeight:c(h.minHeight)?h.minHeight:0,maxHeight:c(h.maxHeight)?h.maxHeight:
+Infinity};if(this._aspectRatio||e){e=h.minHeight*this.aspectRatio;i=h.minWidth/this.aspectRatio;g=h.maxHeight*this.aspectRatio;b=h.maxWidth/this.aspectRatio;if(e>h.minWidth)h.minWidth=e;if(i>h.minHeight)h.minHeight=i;if(g<h.maxWidth)h.maxWidth=g;if(b<h.maxHeight)h.maxHeight=b}this._vBoundaries=h},_updateCache:function(e){this.offset=this.helper.offset();if(c(e.left))this.position.left=e.left;if(c(e.top))this.position.top=e.top;if(c(e.height))this.size.height=e.height;if(c(e.width))this.size.width=
+e.width},_updateRatio:function(e){var h=this.position,g=this.size,i=this.axis;if(c(e.height))e.width=e.height*this.aspectRatio;else if(c(e.width))e.height=e.width/this.aspectRatio;if(i=="sw"){e.left=h.left+(g.width-e.width);e.top=null}if(i=="nw"){e.top=h.top+(g.height-e.height);e.left=h.left+(g.width-e.width)}return e},_respectSize:function(e){var h=this._vBoundaries,g=this.axis,i=c(e.width)&&h.maxWidth&&h.maxWidth<e.width,b=c(e.height)&&h.maxHeight&&h.maxHeight<e.height,f=c(e.width)&&h.minWidth&&
+h.minWidth>e.width,j=c(e.height)&&h.minHeight&&h.minHeight>e.height;if(f)e.width=h.minWidth;if(j)e.height=h.minHeight;if(i)e.width=h.maxWidth;if(b)e.height=h.maxHeight;var l=this.originalPosition.left+this.originalSize.width,o=this.position.top+this.size.height,n=/sw|nw|w/.test(g);g=/nw|ne|n/.test(g);if(f&&n)e.left=l-h.minWidth;if(i&&n)e.left=l-h.maxWidth;if(j&&g)e.top=o-h.minHeight;if(b&&g)e.top=o-h.maxHeight;if((h=!e.width&&!e.height)&&!e.left&&e.top)e.top=null;else if(h&&!e.top&&e.left)e.left=
+null;return e},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var e=this.helper||this.element,h=0;h<this._proportionallyResizeElements.length;h++){var g=this._proportionallyResizeElements[h];if(!this.borderDif){var i=[g.css("borderTopWidth"),g.css("borderRightWidth"),g.css("borderBottomWidth"),g.css("borderLeftWidth")],b=[g.css("paddingTop"),g.css("paddingRight"),g.css("paddingBottom"),g.css("paddingLeft")];this.borderDif=a.map(i,function(f,j){f=parseInt(f,10)||
+0;j=parseInt(b[j],10)||0;return f+j})}a.browser.msie&&(a(e).is(":hidden")||a(e).parents(":hidden").length)||g.css({height:e.height()-this.borderDif[0]-this.borderDif[2]||0,width:e.width()-this.borderDif[1]-this.borderDif[3]||0})}},_renderProxy:function(){var e=this.options;this.elementOffset=this.element.offset();if(this._helper){this.helper=this.helper||a('<div style="overflow:hidden;"></div>');var h=a.browser.msie&&a.browser.version<7,g=h?1:0;h=h?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+
+h,height:this.element.outerHeight()+h,position:"absolute",left:this.elementOffset.left-g+"px",top:this.elementOffset.top-g+"px",zIndex:++e.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(e,h){return{width:this.originalSize.width+h}},w:function(e,h){return{left:this.originalPosition.left+h,width:this.originalSize.width-h}},n:function(e,h,g){return{top:this.originalPosition.top+g,height:this.originalSize.height-g}},s:function(e,h,g){return{height:this.originalSize.height+
+g}},se:function(e,h,g){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,h,g]))},sw:function(e,h,g){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,h,g]))},ne:function(e,h,g){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,h,g]))},nw:function(e,h,g){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,h,g]))}},_propagate:function(e,h){a.ui.plugin.call(this,e,[h,this.ui()]);
+e!="resize"&&this._trigger(e,h,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}}});a.extend(a.ui.resizable,{version:"1.8.16"});a.ui.plugin.add("resizable","alsoResize",{start:function(){var e=a(this).data("resizable").options,h=function(g){a(g).each(function(){var i=a(this);i.data("resizable-alsoresize",{width:parseInt(i.width(),
+10),height:parseInt(i.height(),10),left:parseInt(i.css("left"),10),top:parseInt(i.css("top"),10),position:i.css("position")})})};if(typeof e.alsoResize=="object"&&!e.alsoResize.parentNode)if(e.alsoResize.length){e.alsoResize=e.alsoResize[0];h(e.alsoResize)}else a.each(e.alsoResize,function(g){h(g)});else h(e.alsoResize)},resize:function(e,h){var g=a(this).data("resizable");e=g.options;var i=g.originalSize,b=g.originalPosition,f={height:g.size.height-i.height||0,width:g.size.width-i.width||0,top:g.position.top-
+b.top||0,left:g.position.left-b.left||0},j=function(l,o){a(l).each(function(){var n=a(this),k=a(this).data("resizable-alsoresize"),m={},p=o&&o.length?o:n.parents(h.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(p,function(q,s){if((q=(k[s]||0)+(f[s]||0))&&q>=0)m[s]=q||null});if(a.browser.opera&&/relative/.test(n.css("position"))){g._revertToRelativePosition=true;n.css({position:"absolute",top:"auto",left:"auto"})}n.css(m)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?
+a.each(e.alsoResize,function(l,o){j(l,o)}):j(e.alsoResize)},stop:function(){var e=a(this).data("resizable"),h=e.options,g=function(i){a(i).each(function(){var b=a(this);b.css({position:b.data("resizable-alsoresize").position})})};if(e._revertToRelativePosition){e._revertToRelativePosition=false;typeof h.alsoResize=="object"&&!h.alsoResize.nodeType?a.each(h.alsoResize,function(i){g(i)}):g(h.alsoResize)}a(this).removeData("resizable-alsoresize")}});a.ui.plugin.add("resizable","animate",{stop:function(e){var h=
+a(this).data("resizable"),g=h.options,i=h._proportionallyResizeElements,b=i.length&&/textarea/i.test(i[0].nodeName),f=b&&a.ui.hasScroll(i[0],"left")?0:h.sizeDiff.height;b={width:h.size.width-(b?0:h.sizeDiff.width),height:h.size.height-f};f=parseInt(h.element.css("left"),10)+(h.position.left-h.originalPosition.left)||null;var j=parseInt(h.element.css("top"),10)+(h.position.top-h.originalPosition.top)||null;h.element.animate(a.extend(b,j&&f?{top:j,left:f}:{}),{duration:g.animateDuration,easing:g.animateEasing,
+step:function(){var l={width:parseInt(h.element.css("width"),10),height:parseInt(h.element.css("height"),10),top:parseInt(h.element.css("top"),10),left:parseInt(h.element.css("left"),10)};i&&i.length&&a(i[0]).css({width:l.width,height:l.height});h._updateCache(l);h._propagate("resize",e)}})}});a.ui.plugin.add("resizable","containment",{start:function(){var e=a(this).data("resizable"),h=e.element,g=e.options.containment;if(h=g instanceof a?g.get(0):/parent/.test(g)?h.parent().get(0):g){e.containerElement=
+a(h);if(/document/.test(g)||g==document){e.containerOffset={left:0,top:0};e.containerPosition={left:0,top:0};e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight}}else{var i=a(h),b=[];a(["Top","Right","Left","Bottom"]).each(function(l,o){b[l]=d(i.css("padding"+o))});e.containerOffset=i.offset();e.containerPosition=i.position();e.containerSize={height:i.innerHeight()-b[3],width:i.innerWidth()-b[1]};g=e.containerOffset;
+var f=e.containerSize.height,j=e.containerSize.width;j=a.ui.hasScroll(h,"left")?h.scrollWidth:j;f=a.ui.hasScroll(h)?h.scrollHeight:f;e.parentData={element:h,left:g.left,top:g.top,width:j,height:f}}}},resize:function(e){var h=a(this).data("resizable"),g=h.options,i=h.containerOffset,b=h.position;e=h._aspectRatio||e.shiftKey;var f={top:0,left:0},j=h.containerElement;if(j[0]!=document&&/static/.test(j.css("position")))f=i;if(b.left<(h._helper?i.left:0)){h.size.width+=h._helper?h.position.left-i.left:
+h.position.left-f.left;if(e)h.size.height=h.size.width/g.aspectRatio;h.position.left=g.helper?i.left:0}if(b.top<(h._helper?i.top:0)){h.size.height+=h._helper?h.position.top-i.top:h.position.top;if(e)h.size.width=h.size.height*g.aspectRatio;h.position.top=h._helper?i.top:0}h.offset.left=h.parentData.left+h.position.left;h.offset.top=h.parentData.top+h.position.top;g=Math.abs((h._helper?h.offset.left-f.left:h.offset.left-f.left)+h.sizeDiff.width);i=Math.abs((h._helper?h.offset.top-f.top:h.offset.top-
+i.top)+h.sizeDiff.height);b=h.containerElement.get(0)==h.element.parent().get(0);f=/relative|absolute/.test(h.containerElement.css("position"));if(b&&f)g-=h.parentData.left;if(g+h.size.width>=h.parentData.width){h.size.width=h.parentData.width-g;if(e)h.size.height=h.size.width/h.aspectRatio}if(i+h.size.height>=h.parentData.height){h.size.height=h.parentData.height-i;if(e)h.size.width=h.size.height*h.aspectRatio}},stop:function(){var e=a(this).data("resizable"),h=e.options,g=e.containerOffset,i=e.containerPosition,
+b=e.containerElement,f=a(e.helper),j=f.offset(),l=f.outerWidth()-e.sizeDiff.width;f=f.outerHeight()-e.sizeDiff.height;e._helper&&!h.animate&&/relative/.test(b.css("position"))&&a(this).css({left:j.left-i.left-g.left,width:l,height:f});e._helper&&!h.animate&&/static/.test(b.css("position"))&&a(this).css({left:j.left-i.left-g.left,width:l,height:f})}});a.ui.plugin.add("resizable","ghost",{start:function(){var e=a(this).data("resizable"),h=e.options,g=e.size;e.ghost=e.originalElement.clone();e.ghost.css({opacity:0.25,
+display:"block",position:"relative",height:g.height,width:g.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");e.ghost.appendTo(e.helper)},resize:function(){var e=a(this).data("resizable");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=a(this).data("resizable");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}});a.ui.plugin.add("resizable","grid",{resize:function(){var e=
+a(this).data("resizable"),h=e.options,g=e.size,i=e.originalSize,b=e.originalPosition,f=e.axis;h.grid=typeof h.grid=="number"?[h.grid,h.grid]:h.grid;var j=Math.round((g.width-i.width)/(h.grid[0]||1))*(h.grid[0]||1);h=Math.round((g.height-i.height)/(h.grid[1]||1))*(h.grid[1]||1);if(/^(se|s|e)$/.test(f)){e.size.width=i.width+j;e.size.height=i.height+h}else if(/^(ne)$/.test(f)){e.size.width=i.width+j;e.size.height=i.height+h;e.position.top=b.top-h}else{if(/^(sw)$/.test(f)){e.size.width=i.width+j;e.size.height=
+i.height+h}else{e.size.width=i.width+j;e.size.height=i.height+h;e.position.top=b.top-h}e.position.left=b.left-j}}});var d=function(e){return parseInt(e,10)||0},c=function(e){return!isNaN(parseInt(e,10))}})(jQuery);
+(function(a){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var d=this;this.element.addClass("ui-selectable");this.dragged=false;var c;this.refresh=function(){c=a(d.options.filter,d.element[0]);c.each(function(){var e=a(this),h=e.offset();a.data(this,"selectable-item",{element:this,$element:e,left:h.left,top:h.top,right:h.left+e.outerWidth(),bottom:h.top+e.outerHeight(),startselected:false,selected:e.hasClass("ui-selected"),
+selecting:e.hasClass("ui-selecting"),unselecting:e.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=a("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(d){var c=this;this.opos=[d.pageX,
+d.pageY];if(!this.options.disabled){var e=this.options;this.selectees=a(e.filter,this.element[0]);this._trigger("start",d);a(e.appendTo).append(this.helper);this.helper.css({left:d.clientX,top:d.clientY,width:0,height:0});e.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var h=a.data(this,"selectable-item");h.startselected=true;if(!d.metaKey){h.$element.removeClass("ui-selected");h.selected=false;h.$element.addClass("ui-unselecting");h.unselecting=true;c._trigger("unselecting",
+d,{unselecting:h.element})}});a(d.target).parents().andSelf().each(function(){var h=a.data(this,"selectable-item");if(h){var g=!d.metaKey||!h.$element.hasClass("ui-selected");h.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");h.unselecting=!g;h.selecting=g;(h.selected=g)?c._trigger("selecting",d,{selecting:h.element}):c._trigger("unselecting",d,{unselecting:h.element});return false}})}},_mouseDrag:function(d){var c=this;this.dragged=true;if(!this.options.disabled){var e=
+this.options,h=this.opos[0],g=this.opos[1],i=d.pageX,b=d.pageY;if(h>i){var f=i;i=h;h=f}if(g>b){f=b;b=g;g=f}this.helper.css({left:h,top:g,width:i-h,height:b-g});this.selectees.each(function(){var j=a.data(this,"selectable-item");if(!(!j||j.element==c.element[0])){var l=false;if(e.tolerance=="touch")l=!(j.left>i||j.right<h||j.top>b||j.bottom<g);else if(e.tolerance=="fit")l=j.left>h&&j.right<i&&j.top>g&&j.bottom<b;if(l){if(j.selected){j.$element.removeClass("ui-selected");j.selected=false}if(j.unselecting){j.$element.removeClass("ui-unselecting");
+j.unselecting=false}if(!j.selecting){j.$element.addClass("ui-selecting");j.selecting=true;c._trigger("selecting",d,{selecting:j.element})}}else{if(j.selecting)if(d.metaKey&&j.startselected){j.$element.removeClass("ui-selecting");j.selecting=false;j.$element.addClass("ui-selected");j.selected=true}else{j.$element.removeClass("ui-selecting");j.selecting=false;if(j.startselected){j.$element.addClass("ui-unselecting");j.unselecting=true}c._trigger("unselecting",d,{unselecting:j.element})}if(j.selected)if(!d.metaKey&&
+!j.startselected){j.$element.removeClass("ui-selected");j.selected=false;j.$element.addClass("ui-unselecting");j.unselecting=true;c._trigger("unselecting",d,{unselecting:j.element})}}}});return false}},_mouseStop:function(d){var c=this;this.dragged=false;a(".ui-unselecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-unselecting");e.unselecting=false;e.startselected=false;c._trigger("unselected",d,{unselected:e.element})});a(".ui-selecting",this.element[0]).each(function(){var e=
+a.data(this,"selectable-item");e.$element.removeClass("ui-selecting").addClass("ui-selected");e.selecting=false;e.selected=true;e.startselected=true;c._trigger("selected",d,{selected:e.element})});this._trigger("stop",d);this.helper.remove();return false}});a.extend(a.ui.selectable,{version:"1.8.16"})})(jQuery);
+(function(a){a.widget("ui.sortable",a.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:false,connectWith:false,containment:false,cursor:"auto",cursorAt:false,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var d=this.options;this.containerCache={};this.element.addClass("ui-sortable");
+this.refresh();this.floating=this.items.length?d.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var d=this.items.length-1;d>=0;d--)this.items[d].item.removeData("sortable-item");return this},_setOption:function(d,c){if(d===
+"disabled"){this.options[d]=c;this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")}else a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(d,c){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(d);var e=null,h=this;a(d.target).parents().each(function(){if(a.data(this,"sortable-item")==h){e=a(this);return false}});if(a.data(d.target,"sortable-item")==h)e=a(d.target);if(!e)return false;if(this.options.handle&&
+!c){var g=false;a(this.options.handle,e).find("*").andSelf().each(function(){if(this==d.target)g=true});if(!g)return false}this.currentItem=e;this._removeCurrentsFromItems();return true},_mouseStart:function(d,c,e){c=this.options;var h=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(d);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};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");a.extend(this.offset,{click:{left:d.pageX-this.offset.left,top:d.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(d);this.originalPageX=d.pageX;this.originalPageY=d.pageY;c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};
+this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();c.containment&&this._setContainment();if(c.cursor){if(a("body").css("cursor"))this._storedCursor=a("body").css("cursor");a("body").css("cursor",c.cursor)}if(c.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",c.opacity)}if(c.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",c.zIndex)}if(this.scrollParent[0]!=
+document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",d,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!e)for(e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("activate",d,h._uiHash(this));if(a.ui.ddmanager)a.ui.ddmanager.current=this;a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,d);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(d);
+return true},_mouseDrag:function(d){this.position=this._generatePosition(d);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var c=this.options,e=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-d.pageY<c.scrollSensitivity)this.scrollParent[0].scrollTop=e=this.scrollParent[0].scrollTop+c.scrollSpeed;else if(d.pageY-this.overflowOffset.top<
+c.scrollSensitivity)this.scrollParent[0].scrollTop=e=this.scrollParent[0].scrollTop-c.scrollSpeed;if(this.overflowOffset.left+this.scrollParent[0].offsetWidth-d.pageX<c.scrollSensitivity)this.scrollParent[0].scrollLeft=e=this.scrollParent[0].scrollLeft+c.scrollSpeed;else if(d.pageX-this.overflowOffset.left<c.scrollSensitivity)this.scrollParent[0].scrollLeft=e=this.scrollParent[0].scrollLeft-c.scrollSpeed}else{if(d.pageY-a(document).scrollTop()<c.scrollSensitivity)e=a(document).scrollTop(a(document).scrollTop()-
+c.scrollSpeed);else if(a(window).height()-(d.pageY-a(document).scrollTop())<c.scrollSensitivity)e=a(document).scrollTop(a(document).scrollTop()+c.scrollSpeed);if(d.pageX-a(document).scrollLeft()<c.scrollSensitivity)e=a(document).scrollLeft(a(document).scrollLeft()-c.scrollSpeed);else if(a(window).width()-(d.pageX-a(document).scrollLeft())<c.scrollSensitivity)e=a(document).scrollLeft(a(document).scrollLeft()+c.scrollSpeed)}e!==false&&a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,
+d)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(c=this.items.length-1;c>=0;c--){e=this.items[c];var h=e.item[0],g=this._intersectsWithPointer(e);if(g)if(h!=this.currentItem[0]&&this.placeholder[g==1?"next":"prev"]()[0]!=h&&!a.ui.contains(this.placeholder[0],h)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],
+h):true)){this.direction=g==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(e))this._rearrange(d,e);else break;this._trigger("change",d,this._uiHash());break}}this._contactContainers(d);a.ui.ddmanager&&a.ui.ddmanager.drag(this,d);this._trigger("sort",d,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(d,c){if(d){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,d);if(this.options.revert){var e=this;c=e.placeholder.offset();
+e.reverting=true;a(this.helper).animate({left:c.left-this.offset.parent.left-e.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:c.top-this.offset.parent.top-e.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){e._clear(d)})}else this._clear(d,c);return false}},cancel:function(){var d=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):
+this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,d._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,d._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();a.extend(this,{helper:null,
+dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(d){var c=this._getItemsAsjQuery(d&&d.connected),e=[];d=d||{};a(c).each(function(){var h=(a(d.item||this).attr(d.attribute||"id")||"").match(d.expression||/(.+)[-=_](.+)/);if(h)e.push((d.key||h[1]+"[]")+"="+(d.key&&d.expression?h[1]:h[2]))});!e.length&&d.key&&e.push(d.key+"=");return e.join("&")},
+toArray:function(d){var c=this._getItemsAsjQuery(d&&d.connected),e=[];d=d||{};c.each(function(){e.push(a(d.item||this).attr(d.attribute||"id")||"")});return e},_intersectsWith:function(d){var c=this.positionAbs.left,e=c+this.helperProportions.width,h=this.positionAbs.top,g=h+this.helperProportions.height,i=d.left,b=i+d.width,f=d.top,j=f+d.height,l=this.offset.click.top,o=this.offset.click.left;l=h+l>f&&h+l<j&&c+o>i&&c+o<b;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||
+this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>d[this.floating?"width":"height"]?l:i<c+this.helperProportions.width/2&&e-this.helperProportions.width/2<b&&f<h+this.helperProportions.height/2&&g-this.helperProportions.height/2<j},_intersectsWithPointer:function(d){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,d.top,d.height);d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,d.left,d.width);c=c&&d;d=this._getDragVerticalDirection();
+var e=this._getDragHorizontalDirection();if(!c)return false;return this.floating?e&&e=="right"||d=="down"?2:1:d&&(d=="down"?2:1)},_intersectsWithSides:function(d){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,d.top+d.height/2,d.height);d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,d.left+d.width/2,d.width);var e=this._getDragVerticalDirection(),h=this._getDragHorizontalDirection();return this.floating&&h?h=="right"&&d||h=="left"&&!d:e&&(e=="down"&&c||e=="up"&&!c)},
+_getDragVerticalDirection:function(){var d=this.positionAbs.top-this.lastPositionAbs.top;return d!=0&&(d>0?"down":"up")},_getDragHorizontalDirection:function(){var d=this.positionAbs.left-this.lastPositionAbs.left;return d!=0&&(d>0?"right":"left")},refresh:function(d){this._refreshItems(d);this.refreshPositions();return this},_connectWith:function(){var d=this.options;return d.connectWith.constructor==String?[d.connectWith]:d.connectWith},_getItemsAsjQuery:function(d){var c=[],e=[],h=this._connectWith();
+if(h&&d)for(d=h.length-1;d>=0;d--)for(var g=a(h[d]),i=g.length-1;i>=0;i--){var b=a.data(g[i],"sortable");if(b&&b!=this&&!b.options.disabled)e.push([a.isFunction(b.options.items)?b.options.items.call(b.element):a(b.options.items,b.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),b])}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),
+this]);for(d=e.length-1;d>=0;d--)e[d][0].each(function(){c.push(this)});return a(c)},_removeCurrentsFromItems:function(){for(var d=this.currentItem.find(":data(sortable-item)"),c=0;c<this.items.length;c++)for(var e=0;e<d.length;e++)d[e]==this.items[c].item[0]&&this.items.splice(c,1)},_refreshItems:function(d){this.items=[];this.containers=[this];var c=this.items,e=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],d,{item:this.currentItem}):a(this.options.items,this.element),
+this]],h=this._connectWith();if(h)for(var g=h.length-1;g>=0;g--)for(var i=a(h[g]),b=i.length-1;b>=0;b--){var f=a.data(i[b],"sortable");if(f&&f!=this&&!f.options.disabled){e.push([a.isFunction(f.options.items)?f.options.items.call(f.element[0],d,{item:this.currentItem}):a(f.options.items,f.element),f]);this.containers.push(f)}}for(g=e.length-1;g>=0;g--){d=e[g][1];h=e[g][0];b=0;for(i=h.length;b<i;b++){f=a(h[b]);f.data("sortable-item",d);c.push({item:f,instance:d,width:0,height:0,left:0,top:0})}}},refreshPositions:function(d){if(this.offsetParent&&
+this.helper)this.offset.parent=this._getParentOffset();for(var c=this.items.length-1;c>=0;c--){var e=this.items[c];if(!(e.instance!=this.currentContainer&&this.currentContainer&&e.item[0]!=this.currentItem[0])){var h=this.options.toleranceElement?a(this.options.toleranceElement,e.item):e.item;if(!d){e.width=h.outerWidth();e.height=h.outerHeight()}h=h.offset();e.left=h.left;e.top=h.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(c=
+this.containers.length-1;c>=0;c--){h=this.containers[c].element.offset();this.containers[c].containerCache.left=h.left;this.containers[c].containerCache.top=h.top;this.containers[c].containerCache.width=this.containers[c].element.outerWidth();this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(d){var c=d||this,e=c.options;if(!e.placeholder||e.placeholder.constructor==String){var h=e.placeholder;e.placeholder={element:function(){var g=
+a(document.createElement(c.currentItem[0].nodeName)).addClass(h||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!h)g.style.visibility="hidden";return g},update:function(g,i){if(!(h&&!e.forcePlaceholderSize)){i.height()||i.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10));i.width()||i.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||
+0,10))}}}}c.placeholder=a(e.placeholder.element.call(c.element,c.currentItem));c.currentItem.after(c.placeholder);e.placeholder.update(c,c.placeholder)},_contactContainers:function(d){for(var c=null,e=null,h=this.containers.length-1;h>=0;h--)if(!a.ui.contains(this.currentItem[0],this.containers[h].element[0]))if(this._intersectsWith(this.containers[h].containerCache)){if(!(c&&a.ui.contains(this.containers[h].element[0],c.element[0]))){c=this.containers[h];e=h}}else if(this.containers[h].containerCache.over){this.containers[h]._trigger("out",
+d,this._uiHash(this));this.containers[h].containerCache.over=0}if(c)if(this.containers.length===1){this.containers[e]._trigger("over",d,this._uiHash(this));this.containers[e].containerCache.over=1}else if(this.currentContainer!=this.containers[e]){c=1E4;h=null;for(var g=this.positionAbs[this.containers[e].floating?"left":"top"],i=this.items.length-1;i>=0;i--)if(a.ui.contains(this.containers[e].element[0],this.items[i].item[0])){var b=this.items[i][this.containers[e].floating?"left":"top"];if(Math.abs(b-
+g)<c){c=Math.abs(b-g);h=this.items[i]}}if(h||this.options.dropOnEmpty){this.currentContainer=this.containers[e];h?this._rearrange(d,h,null,true):this._rearrange(d,null,this.containers[e].element,true);this._trigger("change",d,this._uiHash());this.containers[e]._trigger("change",d,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder);this.containers[e]._trigger("over",d,this._uiHash(this));this.containers[e].containerCache.over=1}}},_createHelper:function(d){var c=
+this.options;d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[d,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]);if(d[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")};if(d[0].style.width==
+""||c.forceHelperSize)d.width(this.currentItem.width());if(d[0].style.height==""||c.forceHelperSize)d.height(this.currentItem.height());return d},_adjustOffsetFromHelper:function(d){if(typeof d=="string")d=d.split(" ");if(a.isArray(d))d={left:+d[0],top:+d[1]||0};if("left"in d)this.offset.click.left=d.left+this.margins.left;if("right"in d)this.offset.click.left=this.helperProportions.width-d.right+this.margins.left;if("top"in d)this.offset.click.top=d.top+this.margins.top;if("bottom"in d)this.offset.click.top=
+this.helperProportions.height-d.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var d=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){d.left+=this.scrollParent.scrollLeft();d.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)d=
+{top:0,left:0};return{top:d.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:d.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var d=this.currentItem.position();return{top:d.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:d.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else 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 d=this.options;if(d.containment=="parent")d.containment=this.helper[0].parentNode;if(d.containment=="document"||d.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(d.containment=="document"?
+document:window).width()-this.helperProportions.width-this.margins.left,(a(d.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(d.containment)){var c=a(d.containment)[0];d=a(d.containment).offset();var e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),
+10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(d,c){if(!c)c=
+this.position;d=d=="absolute"?1:-1;var e=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(e[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():h?0:e.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&
+this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():h?0:e.scrollLeft())*d)}},_generatePosition:function(d){var c=this.options,e=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(e[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0]))this.offset.relative=this._getRelativeOffset();
+var g=d.pageX,i=d.pageY;if(this.originalPosition){if(this.containment){if(d.pageX-this.offset.click.left<this.containment[0])g=this.containment[0]+this.offset.click.left;if(d.pageY-this.offset.click.top<this.containment[1])i=this.containment[1]+this.offset.click.top;if(d.pageX-this.offset.click.left>this.containment[2])g=this.containment[2]+this.offset.click.left;if(d.pageY-this.offset.click.top>this.containment[3])i=this.containment[3]+this.offset.click.top}if(c.grid){i=this.originalPageY+Math.round((i-
+this.originalPageY)/c.grid[1])*c.grid[1];i=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-c.grid[1]:i+c.grid[1]:i;g=this.originalPageX+Math.round((g-this.originalPageX)/c.grid[0])*c.grid[0];g=this.containment?!(g-this.offset.click.left<this.containment[0]||g-this.offset.click.left>this.containment[2])?g:!(g-this.offset.click.left<this.containment[0])?g-c.grid[0]:g+c.grid[0]:g}}return{top:i-
+this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():h?0:e.scrollTop()),left:g-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():h?0:e.scrollLeft())}},_rearrange:function(d,c,e,h){e?e[0].appendChild(this.placeholder[0]):c.item[0].parentNode.insertBefore(this.placeholder[0],
+this.direction=="down"?c.item[0]:c.item[0].nextSibling);this.counter=this.counter?++this.counter:1;var g=this,i=this.counter;window.setTimeout(function(){i==g.counter&&g.refreshPositions(!h)},0)},_clear:function(d,c){this.reverting=false;var e=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem);this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var h in this._storedCSS)if(this._storedCSS[h]=="auto"||this._storedCSS[h]=="static")this._storedCSS[h]=
+"";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!c&&e.push(function(g){this._trigger("receive",g,this._uiHash(this.fromOutside))});if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!c)e.push(function(g){this._trigger("update",g,this._uiHash())});if(!a.ui.contains(this.element[0],this.currentItem[0])){c||e.push(function(g){this._trigger("remove",
+g,this._uiHash())});for(h=this.containers.length-1;h>=0;h--)if(a.ui.contains(this.containers[h].element[0],this.currentItem[0])&&!c){e.push(function(g){return function(i){g._trigger("receive",i,this._uiHash(this))}}.call(this,this.containers[h]));e.push(function(g){return function(i){g._trigger("update",i,this._uiHash(this))}}.call(this,this.containers[h]))}}for(h=this.containers.length-1;h>=0;h--){c||e.push(function(g){return function(i){g._trigger("deactivate",i,this._uiHash(this))}}.call(this,
+this.containers[h]));if(this.containers[h].containerCache.over){e.push(function(g){return function(i){g._trigger("out",i,this._uiHash(this))}}.call(this,this.containers[h]));this.containers[h].containerCache.over=0}}this._storedCursor&&a("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",
+d,this._uiHash());for(h=0;h<e.length;h++)e[h].call(this,d);this._trigger("stop",d,this._uiHash())}return false}c||this._trigger("beforeStop",d,this._uiHash());this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.helper[0]!=this.currentItem[0]&&this.helper.remove();this.helper=null;if(!c){for(h=0;h<e.length;h++)e[h].call(this,d);this._trigger("stop",d,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){a.Widget.prototype._trigger.apply(this,arguments)===false&&this.cancel()},
+_uiHash:function(d){var c=d||this;return{helper:c.helper,placeholder:c.placeholder||a([]),position:c.position,originalPosition:c.originalPosition,offset:c.positionAbs,item:c.currentItem,sender:d?d.element:null}}});a.extend(a.ui.sortable,{version:"1.8.16"})})(jQuery);
+jQuery.effects||function(a,d){function c(n){var k;if(n&&n.constructor==Array&&n.length==3)return n;if(k=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(n))return[parseInt(k[1],10),parseInt(k[2],10),parseInt(k[3],10)];if(k=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(n))return[parseFloat(k[1])*2.55,parseFloat(k[2])*2.55,parseFloat(k[3])*2.55];if(k=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(n))return[parseInt(k[1],
+16),parseInt(k[2],16),parseInt(k[3],16)];if(k=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(n))return[parseInt(k[1]+k[1],16),parseInt(k[2]+k[2],16),parseInt(k[3]+k[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(n))return j.transparent;return j[a.trim(n).toLowerCase()]}function e(n,k){var m;do{m=a.curCSS(n,k);if(m!=""&&m!="transparent"||a.nodeName(n,"body"))break;k="backgroundColor"}while(n=n.parentNode);return c(m)}function h(){var n=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,
+k={},m,p;if(n&&n.length&&n[0]&&n[n[0]])for(var q=n.length;q--;){m=n[q];if(typeof n[m]=="string"){p=m.replace(/\-(\w)/g,function(s,r){return r.toUpperCase()});k[p]=n[m]}}else for(m in n)if(typeof n[m]==="string")k[m]=n[m];return k}function g(n){var k,m;for(k in n){m=n[k];if(m==null||a.isFunction(m)||k in o||/scrollbar/.test(k)||!/color/i.test(k)&&isNaN(parseFloat(m)))delete n[k]}return n}function i(n,k){var m={_:0},p;for(p in k)if(n[p]!=k[p])m[p]=k[p];return m}function b(n,k,m,p){if(typeof n=="object"){p=
+k;m=null;k=n;n=k.effect}if(a.isFunction(k)){p=k;m=null;k={}}if(typeof k=="number"||a.fx.speeds[k]){p=m;m=k;k={}}if(a.isFunction(m)){p=m;m=null}k=k||{};m=m||k.duration;m=a.fx.off?0:typeof m=="number"?m:m in a.fx.speeds?a.fx.speeds[m]:a.fx.speeds._default;p=p||k.complete;return[n,k,m,p]}function f(n){if(!n||typeof n==="number"||a.fx.speeds[n])return true;if(typeof n==="string"&&!a.effects[n])return true;return false}a.effects={};a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor",
+"borderTopColor","borderColor","color","outlineColor"],function(n,k){a.fx.step[k]=function(m){if(!m.colorInit){m.start=e(m.elem,k);m.end=c(m.end);m.colorInit=true}m.elem.style[k]="rgb("+Math.max(Math.min(parseInt(m.pos*(m.end[0]-m.start[0])+m.start[0],10),255),0)+","+Math.max(Math.min(parseInt(m.pos*(m.end[1]-m.start[1])+m.start[1],10),255),0)+","+Math.max(Math.min(parseInt(m.pos*(m.end[2]-m.start[2])+m.start[2],10),255),0)+")"}});var j={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,
+0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],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],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,
+211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},l=["add","remove","toggle"],o={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(n,k,m,
+p){if(a.isFunction(m)){p=m;m=null}return this.queue(function(){var q=a(this),s=q.attr("style")||" ",r=g(h.call(this)),u,v=q.attr("class");a.each(l,function(w,x){n[x]&&q[x+"Class"](n[x])});u=g(h.call(this));q.attr("class",v);q.animate(i(r,u),{queue:false,duration:k,easing:m,complete:function(){a.each(l,function(w,x){n[x]&&q[x+"Class"](n[x])});if(typeof q.attr("style")=="object"){q.attr("style").cssText="";q.attr("style").cssText=s}else q.attr("style",s);p&&p.apply(this,arguments);a.dequeue(this)}})})};
+a.fn.extend({_addClass:a.fn.addClass,addClass:function(n,k,m,p){return k?a.effects.animateClass.apply(this,[{add:n},k,m,p]):this._addClass(n)},_removeClass:a.fn.removeClass,removeClass:function(n,k,m,p){return k?a.effects.animateClass.apply(this,[{remove:n},k,m,p]):this._removeClass(n)},_toggleClass:a.fn.toggleClass,toggleClass:function(n,k,m,p,q){return typeof k=="boolean"||k===d?m?a.effects.animateClass.apply(this,[k?{add:n}:{remove:n},m,p,q]):this._toggleClass(n,k):a.effects.animateClass.apply(this,
+[{toggle:n},k,m,p])},switchClass:function(n,k,m,p,q){return a.effects.animateClass.apply(this,[{add:k,remove:n},m,p,q])}});a.extend(a.effects,{version:"1.8.16",save:function(n,k){for(var m=0;m<k.length;m++)k[m]!==null&&n.data("ec.storage."+k[m],n[0].style[k[m]])},restore:function(n,k){for(var m=0;m<k.length;m++)k[m]!==null&&n.css(k[m],n.data("ec.storage."+k[m]))},setMode:function(n,k){if(k=="toggle")k=n.is(":hidden")?"show":"hide";return k},getBaseline:function(n,k){var m;switch(n[0]){case "top":m=
+0;break;case "middle":m=0.5;break;case "bottom":m=1;break;default:m=n[0]/k.height}switch(n[1]){case "left":n=0;break;case "center":n=0.5;break;case "right":n=1;break;default:n=n[1]/k.width}return{x:n,y:m}},createWrapper:function(n){if(n.parent().is(".ui-effects-wrapper"))return n.parent();var k={width:n.outerWidth(true),height:n.outerHeight(true),"float":n.css("float")},m=a("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),
+p=document.activeElement;n.wrap(m);if(n[0]===p||a.contains(n[0],p))a(p).focus();m=n.parent();if(n.css("position")=="static"){m.css({position:"relative"});n.css({position:"relative"})}else{a.extend(k,{position:n.css("position"),zIndex:n.css("z-index")});a.each(["top","left","bottom","right"],function(q,s){k[s]=n.css(s);if(isNaN(parseInt(k[s],10)))k[s]="auto"});n.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return m.css(k).show()},removeWrapper:function(n){var k,m=document.activeElement;
+if(n.parent().is(".ui-effects-wrapper")){k=n.parent().replaceWith(n);if(n[0]===m||a.contains(n[0],m))a(m).focus();return k}return n},setTransition:function(n,k,m,p){p=p||{};a.each(k,function(q,s){unit=n.cssUnit(s);if(unit[0]>0)p[s]=unit[0]*m+unit[1]});return p}});a.fn.extend({effect:function(n){var k=b.apply(this,arguments),m={options:k[1],duration:k[2],callback:k[3]};k=m.options.mode;var p=a.effects[n];if(a.fx.off||!p)return k?this[k](m.duration,m.callback):this.each(function(){m.callback&&m.callback.call(this)});
+return p.call(this,m)},_show:a.fn.show,show:function(n){if(f(n))return this._show.apply(this,arguments);else{var k=b.apply(this,arguments);k[1].mode="show";return this.effect.apply(this,k)}},_hide:a.fn.hide,hide:function(n){if(f(n))return this._hide.apply(this,arguments);else{var k=b.apply(this,arguments);k[1].mode="hide";return this.effect.apply(this,k)}},__toggle:a.fn.toggle,toggle:function(n){if(f(n)||typeof n==="boolean"||a.isFunction(n))return this.__toggle.apply(this,arguments);else{var k=b.apply(this,
+arguments);k[1].mode="toggle";return this.effect.apply(this,k)}},cssUnit:function(n){var k=this.css(n),m=[];a.each(["em","px","%","pt"],function(p,q){if(k.indexOf(q)>0)m=[parseFloat(k),q]});return m}});a.easing.jswing=a.easing.swing;a.extend(a.easing,{def:"easeOutQuad",swing:function(n,k,m,p,q){return a.easing[a.easing.def](n,k,m,p,q)},easeInQuad:function(n,k,m,p,q){return p*(k/=q)*k+m},easeOutQuad:function(n,k,m,p,q){return-p*(k/=q)*(k-2)+m},easeInOutQuad:function(n,k,m,p,q){if((k/=q/2)<1)return p/
+2*k*k+m;return-p/2*(--k*(k-2)-1)+m},easeInCubic:function(n,k,m,p,q){return p*(k/=q)*k*k+m},easeOutCubic:function(n,k,m,p,q){return p*((k=k/q-1)*k*k+1)+m},easeInOutCubic:function(n,k,m,p,q){if((k/=q/2)<1)return p/2*k*k*k+m;return p/2*((k-=2)*k*k+2)+m},easeInQuart:function(n,k,m,p,q){return p*(k/=q)*k*k*k+m},easeOutQuart:function(n,k,m,p,q){return-p*((k=k/q-1)*k*k*k-1)+m},easeInOutQuart:function(n,k,m,p,q){if((k/=q/2)<1)return p/2*k*k*k*k+m;return-p/2*((k-=2)*k*k*k-2)+m},easeInQuint:function(n,k,m,
+p,q){return p*(k/=q)*k*k*k*k+m},easeOutQuint:function(n,k,m,p,q){return p*((k=k/q-1)*k*k*k*k+1)+m},easeInOutQuint:function(n,k,m,p,q){if((k/=q/2)<1)return p/2*k*k*k*k*k+m;return p/2*((k-=2)*k*k*k*k+2)+m},easeInSine:function(n,k,m,p,q){return-p*Math.cos(k/q*(Math.PI/2))+p+m},easeOutSine:function(n,k,m,p,q){return p*Math.sin(k/q*(Math.PI/2))+m},easeInOutSine:function(n,k,m,p,q){return-p/2*(Math.cos(Math.PI*k/q)-1)+m},easeInExpo:function(n,k,m,p,q){return k==0?m:p*Math.pow(2,10*(k/q-1))+m},easeOutExpo:function(n,
+k,m,p,q){return k==q?m+p:p*(-Math.pow(2,-10*k/q)+1)+m},easeInOutExpo:function(n,k,m,p,q){if(k==0)return m;if(k==q)return m+p;if((k/=q/2)<1)return p/2*Math.pow(2,10*(k-1))+m;return p/2*(-Math.pow(2,-10*--k)+2)+m},easeInCirc:function(n,k,m,p,q){return-p*(Math.sqrt(1-(k/=q)*k)-1)+m},easeOutCirc:function(n,k,m,p,q){return p*Math.sqrt(1-(k=k/q-1)*k)+m},easeInOutCirc:function(n,k,m,p,q){if((k/=q/2)<1)return-p/2*(Math.sqrt(1-k*k)-1)+m;return p/2*(Math.sqrt(1-(k-=2)*k)+1)+m},easeInElastic:function(n,k,m,
+p,q){n=1.70158;var s=0,r=p;if(k==0)return m;if((k/=q)==1)return m+p;s||(s=q*0.3);if(r<Math.abs(p)){r=p;n=s/4}else n=s/(2*Math.PI)*Math.asin(p/r);return-(r*Math.pow(2,10*(k-=1))*Math.sin((k*q-n)*2*Math.PI/s))+m},easeOutElastic:function(n,k,m,p,q){n=1.70158;var s=0,r=p;if(k==0)return m;if((k/=q)==1)return m+p;s||(s=q*0.3);if(r<Math.abs(p)){r=p;n=s/4}else n=s/(2*Math.PI)*Math.asin(p/r);return r*Math.pow(2,-10*k)*Math.sin((k*q-n)*2*Math.PI/s)+p+m},easeInOutElastic:function(n,k,m,p,q){n=1.70158;var s=
+0,r=p;if(k==0)return m;if((k/=q/2)==2)return m+p;s||(s=q*0.3*1.5);if(r<Math.abs(p)){r=p;n=s/4}else n=s/(2*Math.PI)*Math.asin(p/r);if(k<1)return-0.5*r*Math.pow(2,10*(k-=1))*Math.sin((k*q-n)*2*Math.PI/s)+m;return r*Math.pow(2,-10*(k-=1))*Math.sin((k*q-n)*2*Math.PI/s)*0.5+p+m},easeInBack:function(n,k,m,p,q,s){if(s==d)s=1.70158;return p*(k/=q)*k*((s+1)*k-s)+m},easeOutBack:function(n,k,m,p,q,s){if(s==d)s=1.70158;return p*((k=k/q-1)*k*((s+1)*k+s)+1)+m},easeInOutBack:function(n,k,m,p,q,s){if(s==d)s=1.70158;
+if((k/=q/2)<1)return p/2*k*k*(((s*=1.525)+1)*k-s)+m;return p/2*((k-=2)*k*(((s*=1.525)+1)*k+s)+2)+m},easeInBounce:function(n,k,m,p,q){return p-a.easing.easeOutBounce(n,q-k,0,p,q)+m},easeOutBounce:function(n,k,m,p,q){return(k/=q)<1/2.75?p*7.5625*k*k+m:k<2/2.75?p*(7.5625*(k-=1.5/2.75)*k+0.75)+m:k<2.5/2.75?p*(7.5625*(k-=2.25/2.75)*k+0.9375)+m:p*(7.5625*(k-=2.625/2.75)*k+0.984375)+m},easeInOutBounce:function(n,k,m,p,q){if(k<q/2)return a.easing.easeInBounce(n,k*2,0,p,q)*0.5+m;return a.easing.easeOutBounce(n,
+k*2-q,0,p,q)*0.5+p*0.5+m}})}(jQuery);
+(function(a){a.effects.blind=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"],h=a.effects.setMode(c,d.options.mode||"hide"),g=d.options.direction||"vertical";a.effects.save(c,e);c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),b=g=="vertical"?"height":"width";g=g=="vertical"?i.height():i.width();h=="show"&&i.css(b,0);var f={};f[b]=h=="show"?g:0;i.animate(f,d.duration,d.options.easing,function(){h=="hide"&&c.hide();a.effects.restore(c,
+e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery);
+(function(a){a.effects.bounce=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"],h=a.effects.setMode(c,d.options.mode||"effect"),g=d.options.direction||"up",i=d.options.distance||20,b=d.options.times||5,f=d.duration||250;/show|hide/.test(h)&&e.push("opacity");a.effects.save(c,e);c.show();a.effects.createWrapper(c);var j=g=="up"||g=="down"?"top":"left";g=g=="up"||g=="left"?"pos":"neg";i=d.options.distance||(j=="top"?c.outerHeight({margin:true})/3:c.outerWidth({margin:true})/
+3);if(h=="show")c.css("opacity",0).css(j,g=="pos"?-i:i);if(h=="hide")i/=b*2;h!="hide"&&b--;if(h=="show"){var l={opacity:1};l[j]=(g=="pos"?"+=":"-=")+i;c.animate(l,f/2,d.options.easing);i/=2;b--}for(l=0;l<b;l++){var o={},n={};o[j]=(g=="pos"?"-=":"+=")+i;n[j]=(g=="pos"?"+=":"-=")+i;c.animate(o,f/2,d.options.easing).animate(n,f/2,d.options.easing);i=h=="hide"?i*2:i/2}if(h=="hide"){l={opacity:0};l[j]=(g=="pos"?"-=":"+=")+i;c.animate(l,f/2,d.options.easing,function(){c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);
+d.callback&&d.callback.apply(this,arguments)})}else{o={};n={};o[j]=(g=="pos"?"-=":"+=")+i;n[j]=(g=="pos"?"+=":"-=")+i;c.animate(o,f/2,d.options.easing).animate(n,f/2,d.options.easing,function(){a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments)})}c.queue("fx",function(){c.dequeue()});c.dequeue()})}})(jQuery);
+(function(a){a.effects.clip=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right","height","width"],h=a.effects.setMode(c,d.options.mode||"hide"),g=d.options.direction||"vertical";a.effects.save(c,e);c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"});i=c[0].tagName=="IMG"?i:c;var b={size:g=="vertical"?"height":"width",position:g=="vertical"?"top":"left"};g=g=="vertical"?i.height():i.width();if(h=="show"){i.css(b.size,0);i.css(b.position,
+g/2)}var f={};f[b.size]=h=="show"?g:0;f[b.position]=h=="show"?0:g/2;i.animate(f,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){h=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(c[0],arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.drop=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right","opacity"],h=a.effects.setMode(c,d.options.mode||"hide"),g=d.options.direction||"left";a.effects.save(c,e);c.show();a.effects.createWrapper(c);var i=g=="up"||g=="down"?"top":"left";g=g=="up"||g=="left"?"pos":"neg";var b=d.options.distance||(i=="top"?c.outerHeight({margin:true})/2:c.outerWidth({margin:true})/2);if(h=="show")c.css("opacity",0).css(i,g=="pos"?-b:b);var f={opacity:h==
+"show"?1:0};f[i]=(h=="show"?g=="pos"?"+=":"-=":g=="pos"?"-=":"+=")+b;c.animate(f,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){h=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.explode=function(d){return this.queue(function(){var c=d.options.pieces?Math.round(Math.sqrt(d.options.pieces)):3,e=d.options.pieces?Math.round(Math.sqrt(d.options.pieces)):3;d.options.mode=d.options.mode=="toggle"?a(this).is(":visible")?"hide":"show":d.options.mode;var h=a(this).show().css("visibility","hidden"),g=h.offset();g.top-=parseInt(h.css("marginTop"),10)||0;g.left-=parseInt(h.css("marginLeft"),10)||0;for(var i=h.outerWidth(true),b=h.outerHeight(true),f=0;f<c;f++)for(var j=
+0;j<e;j++)h.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-j*(i/e),top:-f*(b/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:i/e,height:b/c,left:g.left+j*(i/e)+(d.options.mode=="show"?(j-Math.floor(e/2))*(i/e):0),top:g.top+f*(b/c)+(d.options.mode=="show"?(f-Math.floor(c/2))*(b/c):0),opacity:d.options.mode=="show"?0:1}).animate({left:g.left+j*(i/e)+(d.options.mode=="show"?0:(j-Math.floor(e/2))*(i/e)),top:g.top+
+f*(b/c)+(d.options.mode=="show"?0:(f-Math.floor(c/2))*(b/c)),opacity:d.options.mode=="show"?1:0},d.duration||500);setTimeout(function(){d.options.mode=="show"?h.css({visibility:"visible"}):h.css({visibility:"visible"}).hide();d.callback&&d.callback.apply(h[0]);h.dequeue();a("div.ui-effects-explode").remove()},d.duration||500)})}})(jQuery);
+(function(a){a.effects.fade=function(d){return this.queue(function(){var c=a(this),e=a.effects.setMode(c,d.options.mode||"hide");c.animate({opacity:e},{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.fold=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"],h=a.effects.setMode(c,d.options.mode||"hide"),g=d.options.size||15,i=!!d.options.horizFirst,b=d.duration?d.duration/2:a.fx.speeds._default/2;a.effects.save(c,e);c.show();var f=a.effects.createWrapper(c).css({overflow:"hidden"}),j=h=="show"!=i,l=j?["width","height"]:["height","width"];j=j?[f.width(),f.height()]:[f.height(),f.width()];var o=/([0-9]+)%/.exec(g);if(o)g=parseInt(o[1],
+10)/100*j[h=="hide"?0:1];if(h=="show")f.css(i?{height:0,width:g}:{height:g,width:0});i={};o={};i[l[0]]=h=="show"?j[0]:g;o[l[1]]=h=="show"?j[1]:0;f.animate(i,b,d.options.easing).animate(o,b,d.options.easing,function(){h=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery);
+(function(a){a.effects.highlight=function(d){return this.queue(function(){var c=a(this),e=["backgroundImage","backgroundColor","opacity"],h=a.effects.setMode(c,d.options.mode||"show"),g={backgroundColor:c.css("backgroundColor")};if(h=="hide")g.opacity=0;a.effects.save(c,e);c.show().css({backgroundImage:"none",backgroundColor:d.options.color||"#ffff99"}).animate(g,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){h=="hide"&&c.hide();a.effects.restore(c,e);h=="show"&&!a.support.opacity&&
+this.style.removeAttribute("filter");d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.pulsate=function(d){return this.queue(function(){var c=a(this),e=a.effects.setMode(c,d.options.mode||"show");times=(d.options.times||5)*2-1;duration=d.duration?d.duration/2:a.fx.speeds._default/2;isVisible=c.is(":visible");animateTo=0;if(!isVisible){c.css("opacity",0).show();animateTo=1}if(e=="hide"&&isVisible||e=="show"&&!isVisible)times--;for(e=0;e<times;e++){c.animate({opacity:animateTo},duration,d.options.easing);animateTo=(animateTo+1)%2}c.animate({opacity:animateTo},duration,
+d.options.easing,function(){animateTo==0&&c.hide();d.callback&&d.callback.apply(this,arguments)});c.queue("fx",function(){c.dequeue()}).dequeue()})}})(jQuery);
+(function(a){a.effects.puff=function(d){return this.queue(function(){var c=a(this),e=a.effects.setMode(c,d.options.mode||"hide"),h=parseInt(d.options.percent,10)||150,g=h/100,i={height:c.height(),width:c.width()};a.extend(d.options,{fade:true,mode:e,percent:e=="hide"?h:100,from:e=="hide"?i:{height:i.height*g,width:i.width*g}});c.effect("scale",d.options,d.duration,d.callback);c.dequeue()})};a.effects.scale=function(d){return this.queue(function(){var c=a(this),e=a.extend(true,{},d.options),h=a.effects.setMode(c,
+d.options.mode||"effect"),g=parseInt(d.options.percent,10)||(parseInt(d.options.percent,10)==0?0:h=="hide"?0:100),i=d.options.direction||"both",b=d.options.origin;if(h!="effect"){e.origin=b||["middle","center"];e.restore=true}b={height:c.height(),width:c.width()};c.from=d.options.from||(h=="show"?{height:0,width:0}:b);g={y:i!="horizontal"?g/100:1,x:i!="vertical"?g/100:1};c.to={height:b.height*g.y,width:b.width*g.x};if(d.options.fade){if(h=="show"){c.from.opacity=0;c.to.opacity=1}if(h=="hide"){c.from.opacity=
+1;c.to.opacity=0}}e.from=c.from;e.to=c.to;e.mode=h;c.effect("size",e,d.duration,d.callback);c.dequeue()})};a.effects.size=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],g=["width","height","overflow"],i=["fontSize"],b=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],
+j=a.effects.setMode(c,d.options.mode||"effect"),l=d.options.restore||false,o=d.options.scale||"both",n=d.options.origin,k={height:c.height(),width:c.width()};c.from=d.options.from||k;c.to=d.options.to||k;if(n){n=a.effects.getBaseline(n,k);c.from.top=(k.height-c.from.height)*n.y;c.from.left=(k.width-c.from.width)*n.x;c.to.top=(k.height-c.to.height)*n.y;c.to.left=(k.width-c.to.width)*n.x}var m={from:{y:c.from.height/k.height,x:c.from.width/k.width},to:{y:c.to.height/k.height,x:c.to.width/k.width}};
+if(o=="box"||o=="both"){if(m.from.y!=m.to.y){e=e.concat(b);c.from=a.effects.setTransition(c,b,m.from.y,c.from);c.to=a.effects.setTransition(c,b,m.to.y,c.to)}if(m.from.x!=m.to.x){e=e.concat(f);c.from=a.effects.setTransition(c,f,m.from.x,c.from);c.to=a.effects.setTransition(c,f,m.to.x,c.to)}}if(o=="content"||o=="both")if(m.from.y!=m.to.y){e=e.concat(i);c.from=a.effects.setTransition(c,i,m.from.y,c.from);c.to=a.effects.setTransition(c,i,m.to.y,c.to)}a.effects.save(c,l?e:h);c.show();a.effects.createWrapper(c);
+c.css("overflow","hidden").css(c.from);if(o=="content"||o=="both"){b=b.concat(["marginTop","marginBottom"]).concat(i);f=f.concat(["marginLeft","marginRight"]);g=e.concat(b).concat(f);c.find("*[width]").each(function(){child=a(this);l&&a.effects.save(child,g);var p={height:child.height(),width:child.width()};child.from={height:p.height*m.from.y,width:p.width*m.from.x};child.to={height:p.height*m.to.y,width:p.width*m.to.x};if(m.from.y!=m.to.y){child.from=a.effects.setTransition(child,b,m.from.y,child.from);
+child.to=a.effects.setTransition(child,b,m.to.y,child.to)}if(m.from.x!=m.to.x){child.from=a.effects.setTransition(child,f,m.from.x,child.from);child.to=a.effects.setTransition(child,f,m.to.x,child.to)}child.css(child.from);child.animate(child.to,d.duration,d.options.easing,function(){l&&a.effects.restore(child,g)})})}c.animate(c.to,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){c.to.opacity===0&&c.css("opacity",c.from.opacity);j=="hide"&&c.hide();a.effects.restore(c,
+l?e:h);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.shake=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"];a.effects.setMode(c,d.options.mode||"effect");var h=d.options.direction||"left",g=d.options.distance||20,i=d.options.times||3,b=d.duration||d.options.duration||140;a.effects.save(c,e);c.show();a.effects.createWrapper(c);var f=h=="up"||h=="down"?"top":"left",j=h=="up"||h=="left"?"pos":"neg";h={};var l={},o={};h[f]=(j=="pos"?"-=":"+=")+g;l[f]=(j=="pos"?"+=":"-=")+g*2;o[f]=
+(j=="pos"?"-=":"+=")+g*2;c.animate(h,b,d.options.easing);for(g=1;g<i;g++)c.animate(l,b,d.options.easing).animate(o,b,d.options.easing);c.animate(l,b,d.options.easing).animate(h,b/2,d.options.easing,function(){a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments)});c.queue("fx",function(){c.dequeue()});c.dequeue()})}})(jQuery);
+(function(a){a.effects.slide=function(d){return this.queue(function(){var c=a(this),e=["position","top","bottom","left","right"],h=a.effects.setMode(c,d.options.mode||"show"),g=d.options.direction||"left";a.effects.save(c,e);c.show();a.effects.createWrapper(c).css({overflow:"hidden"});var i=g=="up"||g=="down"?"top":"left";g=g=="up"||g=="left"?"pos":"neg";var b=d.options.distance||(i=="top"?c.outerHeight({margin:true}):c.outerWidth({margin:true}));if(h=="show")c.css(i,g=="pos"?isNaN(b)?"-"+b:-b:b);
+var f={};f[i]=(h=="show"?g=="pos"?"+=":"-=":g=="pos"?"-=":"+=")+b;c.animate(f,{queue:false,duration:d.duration,easing:d.options.easing,complete:function(){h=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d.callback&&d.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery);
+(function(a){a.effects.transfer=function(d){return this.queue(function(){var c=a(this),e=a(d.options.to),h=e.offset();e={top:h.top,left:h.left,height:e.innerHeight(),width:e.innerWidth()};h=c.offset();var g=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(d.options.className).css({top:h.top,left:h.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(e,d.duration,d.options.easing,function(){g.remove();d.callback&&d.callback.apply(c[0],arguments);
+c.dequeue()})})}})(jQuery);
+(function(a){a.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var d=this,c=d.options;d.running=0;d.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");d.headers=
+d.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||a(this).removeClass("ui-state-focus")});d.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");
+if(c.navigation){var e=d.element.find("a").filter(c.navigationFilter).eq(0);if(e.length){var h=e.closest(".ui-accordion-header");d.active=h.length?h:e.closest(".ui-accordion-content").prev()}}d.active=d._findActive(d.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");d.active.next().addClass("ui-accordion-content-active");d._createIcons();d.resize();d.element.attr("role","tablist");d.headers.attr("role","tab").bind("keydown.accordion",
+function(g){return d._keydown(g)}).next().attr("role","tabpanel");d.headers.not(d.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();d.active.length?d.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):d.headers.eq(0).attr("tabIndex",0);a.browser.safari||d.headers.find("a").attr("tabIndex",-1);c.event&&d.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(g){d._clickHandler.call(d,g,this);g.preventDefault()})},_createIcons:function(){var d=
+this.options;if(d.icons){a("<span></span>").addClass("ui-icon "+d.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(d.icons.header).toggleClass(d.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var d=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex");
+this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(d.autoHeight||d.fillHeight)c.css("height","");return a.Widget.prototype.destroy.call(this)},_setOption:function(d,c){a.Widget.prototype._setOption.apply(this,arguments);d=="active"&&this.activate(c);if(d=="icons"){this._destroyIcons();
+c&&this._createIcons()}if(d=="disabled")this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(d){if(!(this.options.disabled||d.altKey||d.ctrlKey)){var c=a.ui.keyCode,e=this.headers.length,h=this.headers.index(d.target),g=false;switch(d.keyCode){case c.RIGHT:case c.DOWN:g=this.headers[(h+1)%e];break;case c.LEFT:case c.UP:g=this.headers[(h-1+e)%e];break;case c.SPACE:case c.ENTER:this._clickHandler({target:d.target},d.target);
+d.preventDefault()}if(g){a(d.target).attr("tabIndex",-1);a(g).attr("tabIndex",0);g.focus();return false}return true}},resize:function(){var d=this.options,c;if(d.fillSpace){if(a.browser.msie){var e=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height();a.browser.msie&&this.element.parent().css("overflow",e);this.headers.each(function(){c-=a(this).outerHeight(true)});this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+
+a(this).height()))}).css("overflow","auto")}else if(d.autoHeight){c=0;this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c)}return this},activate:function(d){this.options.active=d;d=this._findActive(d)[0];this._clickHandler({target:d},d);return this},_findActive:function(d){return d?typeof d==="number"?this.headers.filter(":eq("+d+")"):this.headers.not(this.headers.not(d)):d===false?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(d,c){var e=this.options;
+if(!e.disabled)if(d.target){d=a(d.currentTarget||c);c=d[0]===this.active[0];e.active=e.collapsible&&c?false:this.headers.index(d);if(!(this.running||!e.collapsible&&c)){var h=this.active;f=d.next();i=this.active.next();b={options:e,newHeader:c&&e.collapsible?a([]):d,oldHeader:this.active,newContent:c&&e.collapsible?a([]):f,oldContent:i};var g=this.headers.index(this.active[0])>this.headers.index(d[0]);this.active=c?a([]):d;this._toggle(f,i,b,c,g);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(e.icons.headerSelected).addClass(e.icons.header);
+if(!c){d.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(e.icons.header).addClass(e.icons.headerSelected);d.next().addClass("ui-accordion-content-active")}}}else if(e.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(e.icons.headerSelected).addClass(e.icons.header);this.active.next().addClass("ui-accordion-content-active");var i=this.active.next(),
+b={options:e,newHeader:a([]),oldHeader:e.active,newContent:a([]),oldContent:i},f=this.active=a([]);this._toggle(f,i,b)}},_toggle:function(d,c,e,h,g){var i=this,b=i.options;i.toShow=d;i.toHide=c;i.data=e;var f=function(){if(i)return i._completed.apply(i,arguments)};i._trigger("changestart",null,i.data);i.running=c.size()===0?d.size():c.size();if(b.animated){e={};e=b.collapsible&&h?{toShow:a([]),toHide:c,complete:f,down:g,autoHeight:b.autoHeight||b.fillSpace}:{toShow:d,toHide:c,complete:f,down:g,autoHeight:b.autoHeight||
+b.fillSpace};if(!b.proxied)b.proxied=b.animated;if(!b.proxiedDuration)b.proxiedDuration=b.duration;b.animated=a.isFunction(b.proxied)?b.proxied(e):b.proxied;b.duration=a.isFunction(b.proxiedDuration)?b.proxiedDuration(e):b.proxiedDuration;h=a.ui.accordion.animations;var j=b.duration,l=b.animated;if(l&&!h[l]&&!a.easing[l])l="slide";h[l]||(h[l]=function(o){this.slide(o,{easing:l,duration:j||700})});h[l](e)}else{if(b.collapsible&&h)d.toggle();else{c.hide();d.show()}f(true)}c.prev().attr({"aria-expanded":"false",
+"aria-selected":"false",tabIndex:-1}).blur();d.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(d){this.running=d?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});a.extend(a.ui.accordion,{version:"1.8.16",
+animations:{slide:function(d,c){d=a.extend({easing:"swing",duration:300},d,c);if(d.toHide.size())if(d.toShow.size()){var e=d.toShow.css("overflow"),h=0,g={},i={},b;c=d.toShow;b=c[0].style.width;c.width(parseInt(c.parent().width(),10)-parseInt(c.css("paddingLeft"),10)-parseInt(c.css("paddingRight"),10)-(parseInt(c.css("borderLeftWidth"),10)||0)-(parseInt(c.css("borderRightWidth"),10)||0));a.each(["height","paddingTop","paddingBottom"],function(f,j){i[j]="hide";f=(""+a.css(d.toShow[0],j)).match(/^([\d+-.]+)(.*)$/);
+g[j]={value:f[1],unit:f[2]||"px"}});d.toShow.css({height:0,overflow:"hidden"}).show();d.toHide.filter(":hidden").each(d.complete).end().filter(":visible").animate(i,{step:function(f,j){if(j.prop=="height")h=j.end-j.start===0?0:(j.now-j.start)/(j.end-j.start);d.toShow[0].style[j.prop]=h*g[j.prop].value+g[j.prop].unit},duration:d.duration,easing:d.easing,complete:function(){d.autoHeight||d.toShow.css("height","");d.toShow.css({width:b,overflow:e});d.complete()}})}else d.toHide.animate({height:"hide",
+paddingTop:"hide",paddingBottom:"hide"},d);else d.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},d)},bounceslide:function(d){this.slide(d,{easing:d.down?"easeOutBounce":"swing",duration:d.down?1E3:200})}}})})(jQuery);
+(function(a){var d=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var c=this,e=this.element[0].ownerDocument,h;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(g){if(!(c.options.disabled||c.element.propAttr("readOnly"))){h=
+false;var i=a.ui.keyCode;switch(g.keyCode){case i.PAGE_UP:c._move("previousPage",g);break;case i.PAGE_DOWN:c._move("nextPage",g);break;case i.UP:c._move("previous",g);g.preventDefault();break;case i.DOWN:c._move("next",g);g.preventDefault();break;case i.ENTER:case i.NUMPAD_ENTER:if(c.menu.active){h=true;g.preventDefault()}case i.TAB:if(!c.menu.active)return;c.menu.select(g);break;case i.ESCAPE:c.element.val(c.term);c.close(g);break;default:clearTimeout(c.searching);c.searching=setTimeout(function(){if(c.term!=
+c.element.val()){c.selectedItem=null;c.search(null,g)}},c.options.delay);break}}}).bind("keypress.autocomplete",function(g){if(h){h=false;g.preventDefault()}}).bind("focus.autocomplete",function(){if(!c.options.disabled){c.selectedItem=null;c.previous=c.element.val()}}).bind("blur.autocomplete",function(g){if(!c.options.disabled){clearTimeout(c.searching);c.closing=setTimeout(function(){c.close(g);c._change(g)},150)}});this._initSource();this.response=function(){return c._response.apply(c,arguments)};
+this.menu=a("<ul></ul>").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",e)[0]).mousedown(function(g){var i=c.menu.element[0];a(g.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(b){b.target!==c.element[0]&&b.target!==i&&!a.ui.contains(i,b.target)&&c.close()})},1);setTimeout(function(){clearTimeout(c.closing)},13)}).menu({focus:function(g,i){i=i.item.data("item.autocomplete");false!==c._trigger("focus",g,{item:i})&&/^key/.test(g.originalEvent.type)&&
+c.element.val(i.value)},selected:function(g,i){var b=i.item.data("item.autocomplete"),f=c.previous;if(c.element[0]!==e.activeElement){c.element.focus();c.previous=f;setTimeout(function(){c.previous=f;c.selectedItem=b},1)}false!==c._trigger("select",g,{item:b})&&c.element.val(b.value);c.term=c.element.val();c.close(g);c.selectedItem=b},blur:function(){c.menu.element.is(":visible")&&c.element.val()!==c.term&&c.element.val(c.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");
+a.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();a.Widget.prototype.destroy.call(this)},_setOption:function(c,e){a.Widget.prototype._setOption.apply(this,arguments);c==="source"&&this._initSource();if(c==="appendTo")this.menu.element.appendTo(a(e||"body",this.element[0].ownerDocument)[0]);c==="disabled"&&
+e&&this.xhr&&this.xhr.abort()},_initSource:function(){var c=this,e,h;if(a.isArray(this.options.source)){e=this.options.source;this.source=function(g,i){i(a.ui.autocomplete.filter(e,g.term))}}else if(typeof this.options.source==="string"){h=this.options.source;this.source=function(g,i){c.xhr&&c.xhr.abort();c.xhr=a.ajax({url:h,data:g,dataType:"json",autocompleteRequest:++d,success:function(b){this.autocompleteRequest===d&&i(b)},error:function(){this.autocompleteRequest===d&&i([])}})}}else this.source=
+this.options.source},search:function(c,e){c=c!=null?c:this.element.val();this.term=this.element.val();if(c.length<this.options.minLength)return this.close(e);clearTimeout(this.closing);if(this._trigger("search",e)!==false)return this._search(c)},_search:function(c){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:c},this.response)},_response:function(c){if(!this.options.disabled&&c&&c.length){c=this._normalize(c);this._suggest(c);this._trigger("open")}else this.close();
+this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(c){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.deactivate();this._trigger("close",c)}},_change:function(c){this.previous!==this.element.val()&&this._trigger("change",c,{item:this.selectedItem})},_normalize:function(c){if(c.length&&c[0].label&&c[0].value)return c;return a.map(c,function(e){if(typeof e==="string")return{label:e,value:e};return a.extend({label:e.label||
+e.value,value:e.value||e.label},e)})},_suggest:function(c){var e=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(e,c);this.menu.deactivate();this.menu.refresh();e.show();this._resizeMenu();e.position(a.extend({of:this.element},this.options.position));this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var c=this.menu.element;c.outerWidth(Math.max(c.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(c,e){var h=this;
+a.each(e,function(g,i){h._renderItem(c,i)})},_renderItem:function(c,e){return a("<li></li>").data("item.autocomplete",e).append(a("<a></a>").text(e.label)).appendTo(c)},_move:function(c,e){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(c)||this.menu.last()&&/^next/.test(c)){this.element.val(this.term);this.menu.deactivate()}else this.menu[c](e);else this.search(null,e)},widget:function(){return this.menu.element}});a.extend(a.ui.autocomplete,{escapeRegex:function(c){return c.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,
+"\\$&")},filter:function(c,e){var h=new RegExp(a.ui.autocomplete.escapeRegex(e),"i");return a.grep(c,function(g){return h.test(g.label||g.value||g)})}})})(jQuery);
+(function(a){a.widget("ui.menu",{_create:function(){var d=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){if(a(c.target).closest(".ui-menu-item a").length){c.preventDefault();d.select(c)}});this.refresh()},refresh:function(){var d=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex",
+-1).mouseenter(function(c){d.activate(c,a(this).parent())}).mouseleave(function(){d.deactivate()})},activate:function(d,c){this.deactivate();if(this.hasScroll()){var e=c.offset().top-this.element.offset().top,h=this.element.scrollTop(),g=this.element.height();if(e<0)this.element.scrollTop(h+e);else e>=g&&this.element.scrollTop(h+e-g+c.height())}this.active=c.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",d,{item:c})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id");
+this._trigger("blur");this.active=null}},next:function(d){this.move("next",".ui-menu-item:first",d)},previous:function(d){this.move("prev",".ui-menu-item:last",d)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(d,c,e){if(this.active){d=this.active[d+"All"](".ui-menu-item").eq(0);d.length?this.activate(e,d):this.activate(e,this.element.children(c))}else this.activate(e,
+this.element.children(c))},nextPage:function(d){if(this.hasScroll())if(!this.active||this.last())this.activate(d,this.element.children(".ui-menu-item:first"));else{var c=this.active.offset().top,e=this.element.height(),h=this.element.children(".ui-menu-item").filter(function(){var g=a(this).offset().top-c-e+a(this).height();return g<10&&g>-10});h.length||(h=this.element.children(".ui-menu-item:last"));this.activate(d,h)}else this.activate(d,this.element.children(".ui-menu-item").filter(!this.active||
+this.last()?":first":":last"))},previousPage:function(d){if(this.hasScroll())if(!this.active||this.first())this.activate(d,this.element.children(".ui-menu-item:last"));else{var c=this.active.offset().top,e=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var h=a(this).offset().top-c+e-a(this).height();return h<10&&h>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(d,result)}else this.activate(d,this.element.children(".ui-menu-item").filter(!this.active||
+this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[a.fn.prop?"prop":"attr"]("scrollHeight")},select:function(d){this._trigger("selected",d,{item:this.active})}})})(jQuery);
+(function(a){var d,c,e,h,g=function(){var b=a(this).find(":ui-button");setTimeout(function(){b.button("refresh")},1)},i=function(b){var f=b.name,j=b.form,l=a([]);if(f)l=j?a(j).find("[name='"+f+"']"):a("[name='"+f+"']",b.ownerDocument).filter(function(){return!this.form});return l};a.widget("ui.button",{options:{disabled:null,text:true,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",g);if(typeof this.options.disabled!==
+"boolean")this.options.disabled=this.element.propAttr("disabled");this._determineButtonType();this.hasTitle=!!this.buttonElement.attr("title");var b=this,f=this.options,j=this.type==="checkbox"||this.type==="radio",l="ui-state-hover"+(!j?" ui-state-active":"");if(f.label===null)f.label=this.buttonElement.html();if(this.element.is(":disabled"))f.disabled=true;this.buttonElement.addClass("ui-button ui-widget ui-state-default ui-corner-all").attr("role","button").bind("mouseenter.button",function(){if(!f.disabled){a(this).addClass("ui-state-hover");
+this===d&&a(this).addClass("ui-state-active")}}).bind("mouseleave.button",function(){f.disabled||a(this).removeClass(l)}).bind("click.button",function(o){if(f.disabled){o.preventDefault();o.stopImmediatePropagation()}});this.element.bind("focus.button",function(){b.buttonElement.addClass("ui-state-focus")}).bind("blur.button",function(){b.buttonElement.removeClass("ui-state-focus")});if(j){this.element.bind("change.button",function(){h||b.refresh()});this.buttonElement.bind("mousedown.button",function(o){if(!f.disabled){h=
+false;c=o.pageX;e=o.pageY}}).bind("mouseup.button",function(o){if(!f.disabled)if(c!==o.pageX||e!==o.pageY)h=true})}if(this.type==="checkbox")this.buttonElement.bind("click.button",function(){if(f.disabled||h)return false;a(this).toggleClass("ui-state-active");b.buttonElement.attr("aria-pressed",b.element[0].checked)});else if(this.type==="radio")this.buttonElement.bind("click.button",function(){if(f.disabled||h)return false;a(this).addClass("ui-state-active");b.buttonElement.attr("aria-pressed","true");
+var o=b.element[0];i(o).not(o).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")});else{this.buttonElement.bind("mousedown.button",function(){if(f.disabled)return false;a(this).addClass("ui-state-active");d=this;a(document).one("mouseup",function(){d=null})}).bind("mouseup.button",function(){if(f.disabled)return false;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(o){if(f.disabled)return false;if(o.keyCode==a.ui.keyCode.SPACE||
+o.keyCode==a.ui.keyCode.ENTER)a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")});this.buttonElement.is("a")&&this.buttonElement.keyup(function(o){o.keyCode===a.ui.keyCode.SPACE&&a(this).click()})}this._setOption("disabled",f.disabled);this._resetButton()},_determineButtonType:function(){this.type=this.element.is(":checkbox")?"checkbox":this.element.is(":radio")?"radio":this.element.is("input")?"input":"button";if(this.type==="checkbox"||this.type===
+"radio"){var b=this.element.parents().filter(":last"),f="label[for='"+this.element.attr("id")+"']";this.buttonElement=b.find(f);if(!this.buttonElement.length){b=b.length?b.siblings():this.element.siblings();this.buttonElement=b.filter(f);if(!this.buttonElement.length)this.buttonElement=b.find(f)}this.element.addClass("ui-helper-hidden-accessible");(b=this.element.is(":checked"))&&this.buttonElement.addClass("ui-state-active");this.buttonElement.attr("aria-pressed",b)}else this.buttonElement=this.element},
+widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible");this.buttonElement.removeClass("ui-button ui-widget ui-state-default ui-corner-all ui-state-hover ui-state-active ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only").removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html());this.hasTitle||this.buttonElement.removeAttr("title");
+a.Widget.prototype.destroy.call(this)},_setOption:function(b,f){a.Widget.prototype._setOption.apply(this,arguments);if(b==="disabled")f?this.element.propAttr("disabled",true):this.element.propAttr("disabled",false);else this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b);if(this.type==="radio")i(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed",
+"true"):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")});else if(this.type==="checkbox")this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false")},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass("ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only"),
+f=a("<span></span>").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),j=this.options.icons,l=j.primary&&j.secondary,o=[];if(j.primary||j.secondary){if(this.options.text)o.push("ui-button-text-icon"+(l?"s":j.primary?"-primary":"-secondary"));j.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+j.primary+"'></span>");j.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+j.secondary+"'></span>");if(!this.options.text){o.push(l?"ui-button-icons-only":
+"ui-button-icon-only");this.hasTitle||b.attr("title",f)}}else o.push("ui-button-text-only");b.addClass(o.join(" "))}}});a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,f){b==="disabled"&&this.buttons.button("option",b,f);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")===
+"ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(b?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");
+a.Widget.prototype.destroy.call(this)}})})(jQuery);
+(function(a,d){function c(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._inDialog=this._datepickerShowing=false;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:false,showMonthAfterYear:false,yearSuffix:""};this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,yearRange:"c-10:c+10",showOtherMonths:false,selectOtherMonths:false,showWeek:false,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:true,showButtonPanel:false,autoSize:false,disabled:false};a.extend(this._defaults,this.regional[""]);this.dpDiv=e(a('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}function e(b){return b.bind("mouseout",
+function(f){f=a(f.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");f.length&&f.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(f){f=a(f.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(a.datepicker._isDisabledDatepicker(i.inline?b.parent()[0]:i.input[0])||!f.length)){f.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
+f.addClass("ui-state-hover");f.hasClass("ui-datepicker-prev")&&f.addClass("ui-datepicker-prev-hover");f.hasClass("ui-datepicker-next")&&f.addClass("ui-datepicker-next-hover")}})}function h(b,f){a.extend(b,f);for(var j in f)if(f[j]==null||f[j]==d)b[j]=f[j];return b}a.extend(a.ui,{datepicker:{version:"1.8.16"}});var g=(new Date).getTime(),i;a.extend(c.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},
+setDefaults:function(b){h(this._defaults,b||{});return this},_attachDatepicker:function(b,f){var j=null;for(var l in this._defaults){var o=b.getAttribute("date:"+l);if(o){j=j||{};try{j[l]=eval(o)}catch(n){j[l]=o}}}l=b.nodeName.toLowerCase();o=l=="div"||l=="span";if(!b.id){this.uuid+=1;b.id="dp"+this.uuid}var k=this._newInst(a(b),o);k.settings=a.extend({},f||{},j||{});if(l=="input")this._connectDatepicker(b,k);else o&&this._inlineDatepicker(b,k)},_newInst:function(b,f){return{id:b[0].id.replace(/([^A-Za-z0-9_-])/g,
+"\\\\$1"),input:b,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:f,dpDiv:!f?this.dpDiv:e(a('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(b,f){var j=a(b);f.append=a([]);f.trigger=a([]);if(!j.hasClass(this.markerClassName)){this._attachments(j,f);j.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",
+function(l,o,n){f.settings[o]=n}).bind("getData.datepicker",function(l,o){return this._get(f,o)});this._autoSize(f);a.data(b,"datepicker",f);f.settings.disabled&&this._disableDatepicker(b)}},_attachments:function(b,f){var j=this._get(f,"appendText"),l=this._get(f,"isRTL");f.append&&f.append.remove();if(j){f.append=a('<span class="'+this._appendClass+'">'+j+"</span>");b[l?"before":"after"](f.append)}b.unbind("focus",this._showDatepicker);f.trigger&&f.trigger.remove();j=this._get(f,"showOn");if(j==
+"focus"||j=="both")b.focus(this._showDatepicker);if(j=="button"||j=="both"){j=this._get(f,"buttonText");var o=this._get(f,"buttonImage");f.trigger=a(this._get(f,"buttonImageOnly")?a("<img/>").addClass(this._triggerClass).attr({src:o,alt:j,title:j}):a('<button type="button"></button>').addClass(this._triggerClass).html(o==""?j:a("<img/>").attr({src:o,alt:j,title:j})));b[l?"before":"after"](f.trigger);f.trigger.click(function(){a.datepicker._datepickerShowing&&a.datepicker._lastInput==b[0]?a.datepicker._hideDatepicker():
+a.datepicker._showDatepicker(b[0]);return false})}},_autoSize:function(b){if(this._get(b,"autoSize")&&!b.inline){var f=new Date(2009,11,20),j=this._get(b,"dateFormat");if(j.match(/[DM]/)){var l=function(o){for(var n=0,k=0,m=0;m<o.length;m++)if(o[m].length>n){n=o[m].length;k=m}return k};f.setMonth(l(this._get(b,j.match(/MM/)?"monthNames":"monthNamesShort")));f.setDate(l(this._get(b,j.match(/DD/)?"dayNames":"dayNamesShort"))+20-f.getDay())}b.input.attr("size",this._formatDate(b,f).length)}},_inlineDatepicker:function(b,
+f){var j=a(b);if(!j.hasClass(this.markerClassName)){j.addClass(this.markerClassName).append(f.dpDiv).bind("setData.datepicker",function(l,o,n){f.settings[o]=n}).bind("getData.datepicker",function(l,o){return this._get(f,o)});a.data(b,"datepicker",f);this._setDate(f,this._getDefaultDate(f),true);this._updateDatepicker(f);this._updateAlternate(f);f.settings.disabled&&this._disableDatepicker(b);f.dpDiv.css("display","block")}},_dialogDatepicker:function(b,f,j,l,o){b=this._dialogInst;if(!b){this.uuid+=
+1;this._dialogInput=a('<input type="text" id="'+("dp"+this.uuid)+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');this._dialogInput.keydown(this._doKeyDown);a("body").append(this._dialogInput);b=this._dialogInst=this._newInst(this._dialogInput,false);b.settings={};a.data(this._dialogInput[0],"datepicker",b)}h(b.settings,l||{});f=f&&f.constructor==Date?this._formatDate(b,f):f;this._dialogInput.val(f);this._pos=o?o.length?o:[o.pageX,o.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/
+2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");b.settings.onSelect=j;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);a.blockUI&&a.blockUI(this.dpDiv);a.data(this._dialogInput[0],"datepicker",b);return this},_destroyDatepicker:function(b){var f=
+a(b),j=a.data(b,"datepicker");if(f.hasClass(this.markerClassName)){var l=b.nodeName.toLowerCase();a.removeData(b,"datepicker");if(l=="input"){j.append.remove();j.trigger.remove();f.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(l=="div"||l=="span")f.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(b){var f=a(b),j=a.data(b,"datepicker");if(f.hasClass(this.markerClassName)){var l=
+b.nodeName.toLowerCase();if(l=="input"){b.disabled=false;j.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(l=="div"||l=="span"){f=f.children("."+this._inlineClass);f.children().removeClass("ui-state-disabled");f.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=a.map(this._disabledInputs,function(o){return o==b?null:o})}},_disableDatepicker:function(b){var f=a(b),j=a.data(b,
+"datepicker");if(f.hasClass(this.markerClassName)){var l=b.nodeName.toLowerCase();if(l=="input"){b.disabled=true;j.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(l=="div"||l=="span"){f=f.children("."+this._inlineClass);f.children().addClass("ui-state-disabled");f.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=a.map(this._disabledInputs,function(o){return o==
+b?null:o});this._disabledInputs[this._disabledInputs.length]=b}},_isDisabledDatepicker:function(b){if(!b)return false;for(var f=0;f<this._disabledInputs.length;f++)if(this._disabledInputs[f]==b)return true;return false},_getInst:function(b){try{return a.data(b,"datepicker")}catch(f){throw"Missing instance data for this datepicker";}},_optionDatepicker:function(b,f,j){var l=this._getInst(b);if(arguments.length==2&&typeof f=="string")return f=="defaults"?a.extend({},a.datepicker._defaults):l?f=="all"?
+a.extend({},l.settings):this._get(l,f):null;var o=f||{};if(typeof f=="string"){o={};o[f]=j}if(l){this._curInst==l&&this._hideDatepicker();var n=this._getDateDatepicker(b,true),k=this._getMinMaxDate(l,"min"),m=this._getMinMaxDate(l,"max");h(l.settings,o);if(k!==null&&o.dateFormat!==d&&o.minDate===d)l.settings.minDate=this._formatDate(l,k);if(m!==null&&o.dateFormat!==d&&o.maxDate===d)l.settings.maxDate=this._formatDate(l,m);this._attachments(a(b),l);this._autoSize(l);this._setDate(l,n);this._updateAlternate(l);
+this._updateDatepicker(l)}},_changeDatepicker:function(b,f,j){this._optionDatepicker(b,f,j)},_refreshDatepicker:function(b){(b=this._getInst(b))&&this._updateDatepicker(b)},_setDateDatepicker:function(b,f){if(b=this._getInst(b)){this._setDate(b,f);this._updateDatepicker(b);this._updateAlternate(b)}},_getDateDatepicker:function(b,f){(b=this._getInst(b))&&!b.inline&&this._setDateFromField(b,f);return b?this._getDate(b):null},_doKeyDown:function(b){var f=a.datepicker._getInst(b.target),j=true,l=f.dpDiv.is(".ui-datepicker-rtl");
+f._keyEvent=true;if(a.datepicker._datepickerShowing)switch(b.keyCode){case 9:a.datepicker._hideDatepicker();j=false;break;case 13:j=a("td."+a.datepicker._dayOverClass+":not(."+a.datepicker._currentClass+")",f.dpDiv);j[0]&&a.datepicker._selectDay(b.target,f.selectedMonth,f.selectedYear,j[0]);if(b=a.datepicker._get(f,"onSelect")){j=a.datepicker._formatDate(f);b.apply(f.input?f.input[0]:null,[j,f])}else a.datepicker._hideDatepicker();return false;case 27:a.datepicker._hideDatepicker();break;case 33:a.datepicker._adjustDate(b.target,
+b.ctrlKey?-a.datepicker._get(f,"stepBigMonths"):-a.datepicker._get(f,"stepMonths"),"M");break;case 34:a.datepicker._adjustDate(b.target,b.ctrlKey?+a.datepicker._get(f,"stepBigMonths"):+a.datepicker._get(f,"stepMonths"),"M");break;case 35:if(b.ctrlKey||b.metaKey)a.datepicker._clearDate(b.target);j=b.ctrlKey||b.metaKey;break;case 36:if(b.ctrlKey||b.metaKey)a.datepicker._gotoToday(b.target);j=b.ctrlKey||b.metaKey;break;case 37:if(b.ctrlKey||b.metaKey)a.datepicker._adjustDate(b.target,l?+1:-1,"D");j=
+b.ctrlKey||b.metaKey;if(b.originalEvent.altKey)a.datepicker._adjustDate(b.target,b.ctrlKey?-a.datepicker._get(f,"stepBigMonths"):-a.datepicker._get(f,"stepMonths"),"M");break;case 38:if(b.ctrlKey||b.metaKey)a.datepicker._adjustDate(b.target,-7,"D");j=b.ctrlKey||b.metaKey;break;case 39:if(b.ctrlKey||b.metaKey)a.datepicker._adjustDate(b.target,l?-1:+1,"D");j=b.ctrlKey||b.metaKey;if(b.originalEvent.altKey)a.datepicker._adjustDate(b.target,b.ctrlKey?+a.datepicker._get(f,"stepBigMonths"):+a.datepicker._get(f,
+"stepMonths"),"M");break;case 40:if(b.ctrlKey||b.metaKey)a.datepicker._adjustDate(b.target,+7,"D");j=b.ctrlKey||b.metaKey;break;default:j=false}else if(b.keyCode==36&&b.ctrlKey)a.datepicker._showDatepicker(this);else j=false;if(j){b.preventDefault();b.stopPropagation()}},_doKeyPress:function(b){var f=a.datepicker._getInst(b.target);if(a.datepicker._get(f,"constrainInput")){f=a.datepicker._possibleChars(a.datepicker._get(f,"dateFormat"));var j=String.fromCharCode(b.charCode==d?b.keyCode:b.charCode);
+return b.ctrlKey||b.metaKey||j<" "||!f||f.indexOf(j)>-1}},_doKeyUp:function(b){b=a.datepicker._getInst(b.target);if(b.input.val()!=b.lastVal)try{if(a.datepicker.parseDate(a.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,a.datepicker._getFormatConfig(b))){a.datepicker._setDateFromField(b);a.datepicker._updateAlternate(b);a.datepicker._updateDatepicker(b)}}catch(f){a.datepicker.log(f)}return true},_showDatepicker:function(b){b=b.target||b;if(b.nodeName.toLowerCase()!="input")b=a("input",
+b.parentNode)[0];if(!(a.datepicker._isDisabledDatepicker(b)||a.datepicker._lastInput==b)){var f=a.datepicker._getInst(b);if(a.datepicker._curInst&&a.datepicker._curInst!=f){a.datepicker._datepickerShowing&&a.datepicker._triggerOnClose(a.datepicker._curInst);a.datepicker._curInst.dpDiv.stop(true,true)}var j=a.datepicker._get(f,"beforeShow");j=j?j.apply(b,[b,f]):{};if(j!==false){h(f.settings,j);f.lastVal=null;a.datepicker._lastInput=b;a.datepicker._setDateFromField(f);if(a.datepicker._inDialog)b.value=
+"";if(!a.datepicker._pos){a.datepicker._pos=a.datepicker._findPos(b);a.datepicker._pos[1]+=b.offsetHeight}var l=false;a(b).parents().each(function(){l|=a(this).css("position")=="fixed";return!l});if(l&&a.browser.opera){a.datepicker._pos[0]-=document.documentElement.scrollLeft;a.datepicker._pos[1]-=document.documentElement.scrollTop}j={left:a.datepicker._pos[0],top:a.datepicker._pos[1]};a.datepicker._pos=null;f.dpDiv.empty();f.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});a.datepicker._updateDatepicker(f);
+j=a.datepicker._checkOffset(f,j,l);f.dpDiv.css({position:a.datepicker._inDialog&&a.blockUI?"static":l?"fixed":"absolute",display:"none",left:j.left+"px",top:j.top+"px"});if(!f.inline){j=a.datepicker._get(f,"showAnim");var o=a.datepicker._get(f,"duration"),n=function(){var k=f.dpDiv.find("iframe.ui-datepicker-cover");if(k.length){var m=a.datepicker._getBorders(f.dpDiv);k.css({left:-m[0],top:-m[1],width:f.dpDiv.outerWidth(),height:f.dpDiv.outerHeight()})}};f.dpDiv.zIndex(a(b).zIndex()+1);a.datepicker._datepickerShowing=
+true;a.effects&&a.effects[j]?f.dpDiv.show(j,a.datepicker._get(f,"showOptions"),o,n):f.dpDiv[j||"show"](j?o:null,n);if(!j||!o)n();f.input.is(":visible")&&!f.input.is(":disabled")&&f.input.focus();a.datepicker._curInst=f}}}},_updateDatepicker:function(b){this.maxRows=4;var f=a.datepicker._getBorders(b.dpDiv);i=b;b.dpDiv.empty().append(this._generateHTML(b));var j=b.dpDiv.find("iframe.ui-datepicker-cover");j.length&&j.css({left:-f[0],top:-f[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()});
+b.dpDiv.find("."+this._dayOverClass+" a").mouseover();f=this._getNumberOfMonths(b);j=f[1];b.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");j>1&&b.dpDiv.addClass("ui-datepicker-multi-"+j).css("width",17*j+"em");b.dpDiv[(f[0]!=1||f[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");b.dpDiv[(this._get(b,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");b==a.datepicker._curInst&&a.datepicker._datepickerShowing&&b.input&&b.input.is(":visible")&&
+!b.input.is(":disabled")&&b.input[0]!=document.activeElement&&b.input.focus();if(b.yearshtml){var l=b.yearshtml;setTimeout(function(){l===b.yearshtml&&b.yearshtml&&b.dpDiv.find("select.ui-datepicker-year:first").replaceWith(b.yearshtml);l=b.yearshtml=null},0)}},_getBorders:function(b){var f=function(j){return{thin:1,medium:2,thick:3}[j]||j};return[parseFloat(f(b.css("border-left-width"))),parseFloat(f(b.css("border-top-width")))]},_checkOffset:function(b,f,j){var l=b.dpDiv.outerWidth(),o=b.dpDiv.outerHeight(),
+n=b.input?b.input.outerWidth():0,k=b.input?b.input.outerHeight():0,m=document.documentElement.clientWidth+a(document).scrollLeft(),p=document.documentElement.clientHeight+a(document).scrollTop();f.left-=this._get(b,"isRTL")?l-n:0;f.left-=j&&f.left==b.input.offset().left?a(document).scrollLeft():0;f.top-=j&&f.top==b.input.offset().top+k?a(document).scrollTop():0;f.left-=Math.min(f.left,f.left+l>m&&m>l?Math.abs(f.left+l-m):0);f.top-=Math.min(f.top,f.top+o>p&&p>o?Math.abs(o+k):0);return f},_findPos:function(b){for(var f=
+this._get(this._getInst(b),"isRTL");b&&(b.type=="hidden"||b.nodeType!=1||a.expr.filters.hidden(b));)b=b[f?"previousSibling":"nextSibling"];b=a(b).offset();return[b.left,b.top]},_triggerOnClose:function(b){var f=this._get(b,"onClose");if(f)f.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b])},_hideDatepicker:function(b){var f=this._curInst;if(!(!f||b&&f!=a.data(b,"datepicker")))if(this._datepickerShowing){b=this._get(f,"showAnim");var j=this._get(f,"duration"),l=function(){a.datepicker._tidyDialog(f);
+this._curInst=null};a.effects&&a.effects[b]?f.dpDiv.hide(b,a.datepicker._get(f,"showOptions"),j,l):f.dpDiv[b=="slideDown"?"slideUp":b=="fadeIn"?"fadeOut":"hide"](b?j:null,l);b||l();a.datepicker._triggerOnClose(f);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(a.blockUI){a.unblockUI();a("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(b){b.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},
+_checkExternalClick:function(b){if(a.datepicker._curInst){b=a(b.target);b[0].id!=a.datepicker._mainDivId&&b.parents("#"+a.datepicker._mainDivId).length==0&&!b.hasClass(a.datepicker.markerClassName)&&!b.hasClass(a.datepicker._triggerClass)&&a.datepicker._datepickerShowing&&!(a.datepicker._inDialog&&a.blockUI)&&a.datepicker._hideDatepicker()}},_adjustDate:function(b,f,j){b=a(b);var l=this._getInst(b[0]);if(!this._isDisabledDatepicker(b[0])){this._adjustInstDate(l,f+(j=="M"?this._get(l,"showCurrentAtPos"):
+0),j);this._updateDatepicker(l)}},_gotoToday:function(b){b=a(b);var f=this._getInst(b[0]);if(this._get(f,"gotoCurrent")&&f.currentDay){f.selectedDay=f.currentDay;f.drawMonth=f.selectedMonth=f.currentMonth;f.drawYear=f.selectedYear=f.currentYear}else{var j=new Date;f.selectedDay=j.getDate();f.drawMonth=f.selectedMonth=j.getMonth();f.drawYear=f.selectedYear=j.getFullYear()}this._notifyChange(f);this._adjustDate(b)},_selectMonthYear:function(b,f,j){b=a(b);var l=this._getInst(b[0]);l["selected"+(j=="M"?
+"Month":"Year")]=l["draw"+(j=="M"?"Month":"Year")]=parseInt(f.options[f.selectedIndex].value,10);this._notifyChange(l);this._adjustDate(b)},_selectDay:function(b,f,j,l){var o=a(b);if(!(a(l).hasClass(this._unselectableClass)||this._isDisabledDatepicker(o[0]))){o=this._getInst(o[0]);o.selectedDay=o.currentDay=a("a",l).html();o.selectedMonth=o.currentMonth=f;o.selectedYear=o.currentYear=j;this._selectDate(b,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear))}},_clearDate:function(b){b=a(b);
+this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(b,f){b=this._getInst(a(b)[0]);f=f!=null?f:this._formatDate(b);b.input&&b.input.val(f);this._updateAlternate(b);var j=this._get(b,"onSelect");if(j)j.apply(b.input?b.input[0]:null,[f,b]);else b.input&&b.input.trigger("change");if(b.inline)this._updateDatepicker(b);else{this._hideDatepicker();this._lastInput=b.input[0];typeof b.input[0]!="object"&&b.input.focus();this._lastInput=null}},_updateAlternate:function(b){var f=this._get(b,"altField");
+if(f){var j=this._get(b,"altFormat")||this._get(b,"dateFormat"),l=this._getDate(b),o=this.formatDate(j,l,this._getFormatConfig(b));a(f).each(function(){a(this).val(o)})}},noWeekends:function(b){b=b.getDay();return[b>0&&b<6,""]},iso8601Week:function(b){b=new Date(b.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var f=b.getTime();b.setMonth(0);b.setDate(1);return Math.floor(Math.round((f-b)/864E5)/7)+1},parseDate:function(b,f,j){if(b==null||f==null)throw"Invalid arguments";f=typeof f=="object"?
+f.toString():f+"";if(f=="")return null;var l=(j?j.shortYearCutoff:null)||this._defaults.shortYearCutoff;l=typeof l!="string"?l:(new Date).getFullYear()%100+parseInt(l,10);for(var o=(j?j.dayNamesShort:null)||this._defaults.dayNamesShort,n=(j?j.dayNames:null)||this._defaults.dayNames,k=(j?j.monthNamesShort:null)||this._defaults.monthNamesShort,m=(j?j.monthNames:null)||this._defaults.monthNames,p=j=-1,q=-1,s=-1,r=false,u=function(z){(z=H+1<b.length&&b.charAt(H+1)==z)&&H++;return z},v=function(z){var I=
+u(z);z=new RegExp("^\\d{1,"+(z=="@"?14:z=="!"?20:z=="y"&&I?4:z=="o"?3:2)+"}");z=f.substring(y).match(z);if(!z)throw"Missing number at position "+y;y+=z[0].length;return parseInt(z[0],10)},w=function(z,I,N){z=a.map(u(z)?N:I,function(D,E){return[[E,D]]}).sort(function(D,E){return-(D[1].length-E[1].length)});var J=-1;a.each(z,function(D,E){D=E[1];if(f.substr(y,D.length).toLowerCase()==D.toLowerCase()){J=E[0];y+=D.length;return false}});if(J!=-1)return J+1;else throw"Unknown name at position "+y;},x=
+function(){if(f.charAt(y)!=b.charAt(H))throw"Unexpected literal at position "+y;y++},y=0,H=0;H<b.length;H++)if(r)if(b.charAt(H)=="'"&&!u("'"))r=false;else x();else switch(b.charAt(H)){case "d":q=v("d");break;case "D":w("D",o,n);break;case "o":s=v("o");break;case "m":p=v("m");break;case "M":p=w("M",k,m);break;case "y":j=v("y");break;case "@":var C=new Date(v("@"));j=C.getFullYear();p=C.getMonth()+1;q=C.getDate();break;case "!":C=new Date((v("!")-this._ticksTo1970)/1E4);j=C.getFullYear();p=C.getMonth()+
+1;q=C.getDate();break;case "'":if(u("'"))x();else r=true;break;default:x()}if(y<f.length)throw"Extra/unparsed characters found in date: "+f.substring(y);if(j==-1)j=(new Date).getFullYear();else if(j<100)j+=(new Date).getFullYear()-(new Date).getFullYear()%100+(j<=l?0:-100);if(s>-1){p=1;q=s;do{l=this._getDaysInMonth(j,p-1);if(q<=l)break;p++;q-=l}while(1)}C=this._daylightSavingAdjust(new Date(j,p-1,q));if(C.getFullYear()!=j||C.getMonth()+1!=p||C.getDate()!=q)throw"Invalid date";return C},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:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(b,f,j){if(!f)return"";var l=(j?j.dayNamesShort:null)||this._defaults.dayNamesShort,o=(j?j.dayNames:null)||this._defaults.dayNames,n=(j?j.monthNamesShort:null)||this._defaults.monthNamesShort;j=(j?j.monthNames:
+null)||this._defaults.monthNames;var k=function(u){(u=r+1<b.length&&b.charAt(r+1)==u)&&r++;return u},m=function(u,v,w){v=""+v;if(k(u))for(;v.length<w;)v="0"+v;return v},p=function(u,v,w,x){return k(u)?x[v]:w[v]},q="",s=false;if(f)for(var r=0;r<b.length;r++)if(s)if(b.charAt(r)=="'"&&!k("'"))s=false;else q+=b.charAt(r);else switch(b.charAt(r)){case "d":q+=m("d",f.getDate(),2);break;case "D":q+=p("D",f.getDay(),l,o);break;case "o":q+=m("o",Math.round(((new Date(f.getFullYear(),f.getMonth(),f.getDate())).getTime()-
+(new Date(f.getFullYear(),0,0)).getTime())/864E5),3);break;case "m":q+=m("m",f.getMonth()+1,2);break;case "M":q+=p("M",f.getMonth(),n,j);break;case "y":q+=k("y")?f.getFullYear():(f.getYear()%100<10?"0":"")+f.getYear()%100;break;case "@":q+=f.getTime();break;case "!":q+=f.getTime()*1E4+this._ticksTo1970;break;case "'":if(k("'"))q+="'";else s=true;break;default:q+=b.charAt(r)}return q},_possibleChars:function(b){for(var f="",j=false,l=function(n){(n=o+1<b.length&&b.charAt(o+1)==n)&&o++;return n},o=
+0;o<b.length;o++)if(j)if(b.charAt(o)=="'"&&!l("'"))j=false;else f+=b.charAt(o);else switch(b.charAt(o)){case "d":case "m":case "y":case "@":f+="0123456789";break;case "D":case "M":return null;case "'":if(l("'"))f+="'";else j=true;break;default:f+=b.charAt(o)}return f},_get:function(b,f){return b.settings[f]!==d?b.settings[f]:this._defaults[f]},_setDateFromField:function(b,f){if(b.input.val()!=b.lastVal){var j=this._get(b,"dateFormat"),l=b.lastVal=b.input?b.input.val():null,o,n;o=n=this._getDefaultDate(b);
+var k=this._getFormatConfig(b);try{o=this.parseDate(j,l,k)||n}catch(m){this.log(m);l=f?"":l}b.selectedDay=o.getDate();b.drawMonth=b.selectedMonth=o.getMonth();b.drawYear=b.selectedYear=o.getFullYear();b.currentDay=l?o.getDate():0;b.currentMonth=l?o.getMonth():0;b.currentYear=l?o.getFullYear():0;this._adjustInstDate(b)}},_getDefaultDate:function(b){return this._restrictMinMax(b,this._determineDate(b,this._get(b,"defaultDate"),new Date))},_determineDate:function(b,f,j){var l=function(n){var k=new Date;
+k.setDate(k.getDate()+n);return k},o=function(n){try{return a.datepicker.parseDate(a.datepicker._get(b,"dateFormat"),n,a.datepicker._getFormatConfig(b))}catch(k){}var m=(n.toLowerCase().match(/^c/)?a.datepicker._getDate(b):null)||new Date,p=m.getFullYear(),q=m.getMonth();m=m.getDate();for(var s=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,r=s.exec(n);r;){switch(r[2]||"d"){case "d":case "D":m+=parseInt(r[1],10);break;case "w":case "W":m+=parseInt(r[1],10)*7;break;case "m":case "M":q+=parseInt(r[1],10);m=
+Math.min(m,a.datepicker._getDaysInMonth(p,q));break;case "y":case "Y":p+=parseInt(r[1],10);m=Math.min(m,a.datepicker._getDaysInMonth(p,q));break}r=s.exec(n)}return new Date(p,q,m)};if(f=(f=f==null||f===""?j:typeof f=="string"?o(f):typeof f=="number"?isNaN(f)?j:l(f):new Date(f.getTime()))&&f.toString()=="Invalid Date"?j:f){f.setHours(0);f.setMinutes(0);f.setSeconds(0);f.setMilliseconds(0)}return this._daylightSavingAdjust(f)},_daylightSavingAdjust:function(b){if(!b)return null;b.setHours(b.getHours()>
+12?b.getHours()+2:0);return b},_setDate:function(b,f,j){var l=!f,o=b.selectedMonth,n=b.selectedYear;f=this._restrictMinMax(b,this._determineDate(b,f,new Date));b.selectedDay=b.currentDay=f.getDate();b.drawMonth=b.selectedMonth=b.currentMonth=f.getMonth();b.drawYear=b.selectedYear=b.currentYear=f.getFullYear();if((o!=b.selectedMonth||n!=b.selectedYear)&&!j)this._notifyChange(b);this._adjustInstDate(b);if(b.input)b.input.val(l?"":this._formatDate(b))},_getDate:function(b){return!b.currentYear||b.input&&
+b.input.val()==""?null:this._daylightSavingAdjust(new Date(b.currentYear,b.currentMonth,b.currentDay))},_generateHTML:function(b){var f=new Date;f=this._daylightSavingAdjust(new Date(f.getFullYear(),f.getMonth(),f.getDate()));var j=this._get(b,"isRTL"),l=this._get(b,"showButtonPanel"),o=this._get(b,"hideIfNoPrevNext"),n=this._get(b,"navigationAsDateFormat"),k=this._getNumberOfMonths(b),m=this._get(b,"showCurrentAtPos"),p=this._get(b,"stepMonths"),q=k[0]!=1||k[1]!=1,s=this._daylightSavingAdjust(!b.currentDay?
+new Date(9999,9,9):new Date(b.currentYear,b.currentMonth,b.currentDay)),r=this._getMinMaxDate(b,"min"),u=this._getMinMaxDate(b,"max");m=b.drawMonth-m;var v=b.drawYear;if(m<0){m+=12;v--}if(u){var w=this._daylightSavingAdjust(new Date(u.getFullYear(),u.getMonth()-k[0]*k[1]+1,u.getDate()));for(w=r&&w<r?r:w;this._daylightSavingAdjust(new Date(v,m,1))>w;){m--;if(m<0){m=11;v--}}}b.drawMonth=m;b.drawYear=v;w=this._get(b,"prevText");w=!n?w:this.formatDate(w,this._daylightSavingAdjust(new Date(v,m-p,1)),this._getFormatConfig(b));
+w=this._canAdjustMonth(b,-1,v,m)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+g+".datepicker._adjustDate('#"+b.id+"', -"+p+", 'M');\" title=\""+w+'"><span class="ui-icon ui-icon-circle-triangle-'+(j?"e":"w")+'">'+w+"</span></a>":o?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+w+'"><span class="ui-icon ui-icon-circle-triangle-'+(j?"e":"w")+'">'+w+"</span></a>";var x=this._get(b,"nextText");x=!n?x:this.formatDate(x,this._daylightSavingAdjust(new Date(v,
+m+p,1)),this._getFormatConfig(b));o=this._canAdjustMonth(b,+1,v,m)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+g+".datepicker._adjustDate('#"+b.id+"', +"+p+", 'M');\" title=\""+x+'"><span class="ui-icon ui-icon-circle-triangle-'+(j?"w":"e")+'">'+x+"</span></a>":o?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+x+'"><span class="ui-icon ui-icon-circle-triangle-'+(j?"w":"e")+'">'+x+"</span></a>";p=this._get(b,"currentText");x=this._get(b,"gotoCurrent")&&
+b.currentDay?s:f;p=!n?p:this.formatDate(p,x,this._getFormatConfig(b));n=!b.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+g+'.datepicker._hideDatepicker();">'+this._get(b,"closeText")+"</button>":"";l=l?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(j?n:"")+(this._isInRange(b,x)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+
+g+".datepicker._gotoToday('#"+b.id+"');\">"+p+"</button>":"")+(j?"":n)+"</div>":"";n=parseInt(this._get(b,"firstDay"),10);n=isNaN(n)?0:n;p=this._get(b,"showWeek");x=this._get(b,"dayNames");this._get(b,"dayNamesShort");var y=this._get(b,"dayNamesMin"),H=this._get(b,"monthNames"),C=this._get(b,"monthNamesShort"),z=this._get(b,"beforeShowDay"),I=this._get(b,"showOtherMonths"),N=this._get(b,"selectOtherMonths");this._get(b,"calculateWeek");for(var J=this._getDefaultDate(b),D="",E=0;E<k[0];E++){var P=
+"";this.maxRows=4;for(var L=0;L<k[1];L++){var Q=this._daylightSavingAdjust(new Date(v,m,b.selectedDay)),B=" ui-corner-all",F="";if(q){F+='<div class="ui-datepicker-group';if(k[1]>1)switch(L){case 0:F+=" ui-datepicker-group-first";B=" ui-corner-"+(j?"right":"left");break;case k[1]-1:F+=" ui-datepicker-group-last";B=" ui-corner-"+(j?"left":"right");break;default:F+=" ui-datepicker-group-middle";B="";break}F+='">'}F+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+B+'">'+(/all|left/.test(B)&&
+E==0?j?o:w:"")+(/all|right/.test(B)&&E==0?j?w:o:"")+this._generateMonthYearHeader(b,m,v,r,u,E>0||L>0,H,C)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var G=p?'<th class="ui-datepicker-week-col">'+this._get(b,"weekHeader")+"</th>":"";for(B=0;B<7;B++){var A=(B+n)%7;G+="<th"+((B+n+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+x[A]+'">'+y[A]+"</span></th>"}F+=G+"</tr></thead><tbody>";G=this._getDaysInMonth(v,m);if(v==b.selectedYear&&m==b.selectedMonth)b.selectedDay=Math.min(b.selectedDay,
+G);B=(this._getFirstDayOfMonth(v,m)-n+7)%7;G=Math.ceil((B+G)/7);this.maxRows=G=q?this.maxRows>G?this.maxRows:G:G;A=this._daylightSavingAdjust(new Date(v,m,1-B));for(var R=0;R<G;R++){F+="<tr>";var S=!p?"":'<td class="ui-datepicker-week-col">'+this._get(b,"calculateWeek")(A)+"</td>";for(B=0;B<7;B++){var M=z?z.apply(b.input?b.input[0]:null,[A]):[true,""],K=A.getMonth()!=m,O=K&&!N||!M[0]||r&&A<r||u&&A>u;S+='<td class="'+((B+n+6)%7>=5?" ui-datepicker-week-end":"")+(K?" ui-datepicker-other-month":"")+(A.getTime()==
+Q.getTime()&&m==b.selectedMonth&&b._keyEvent||J.getTime()==A.getTime()&&J.getTime()==Q.getTime()?" "+this._dayOverClass:"")+(O?" "+this._unselectableClass+" ui-state-disabled":"")+(K&&!I?"":" "+M[1]+(A.getTime()==s.getTime()?" "+this._currentClass:"")+(A.getTime()==f.getTime()?" ui-datepicker-today":""))+'"'+((!K||I)&&M[2]?' title="'+M[2]+'"':"")+(O?"":' onclick="DP_jQuery_'+g+".datepicker._selectDay('#"+b.id+"',"+A.getMonth()+","+A.getFullYear()+', this);return false;"')+">"+(K&&!I?"&#xa0;":O?'<span class="ui-state-default">'+
+A.getDate()+"</span>":'<a class="ui-state-default'+(A.getTime()==f.getTime()?" ui-state-highlight":"")+(A.getTime()==s.getTime()?" ui-state-active":"")+(K?" ui-priority-secondary":"")+'" href="#">'+A.getDate()+"</a>")+"</td>";A.setDate(A.getDate()+1);A=this._daylightSavingAdjust(A)}F+=S+"</tr>"}m++;if(m>11){m=0;v++}F+="</tbody></table>"+(q?"</div>"+(k[0]>0&&L==k[1]-1?'<div class="ui-datepicker-row-break"></div>':""):"");P+=F}D+=P}D+=l+(a.browser.msie&&parseInt(a.browser.version,10)<7&&!b.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':
+"");b._keyEvent=false;return D},_generateMonthYearHeader:function(b,f,j,l,o,n,k,m){var p=this._get(b,"changeMonth"),q=this._get(b,"changeYear"),s=this._get(b,"showMonthAfterYear"),r='<div class="ui-datepicker-title">',u="";if(n||!p)u+='<span class="ui-datepicker-month">'+k[f]+"</span>";else{k=l&&l.getFullYear()==j;var v=o&&o.getFullYear()==j;u+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+g+".datepicker._selectMonthYear('#"+b.id+"', this, 'M');\" >";for(var w=0;w<12;w++)if((!k||w>=l.getMonth())&&
+(!v||w<=o.getMonth()))u+='<option value="'+w+'"'+(w==f?' selected="selected"':"")+">"+m[w]+"</option>";u+="</select>"}s||(r+=u+(n||!(p&&q)?"&#xa0;":""));if(!b.yearshtml){b.yearshtml="";if(n||!q)r+='<span class="ui-datepicker-year">'+j+"</span>";else{m=this._get(b,"yearRange").split(":");var x=(new Date).getFullYear();k=function(y){y=y.match(/c[+-].*/)?j+parseInt(y.substring(1),10):y.match(/[+-].*/)?x+parseInt(y,10):parseInt(y,10);return isNaN(y)?x:y};f=k(m[0]);m=Math.max(f,k(m[1]||""));f=l?Math.max(f,
+l.getFullYear()):f;m=o?Math.min(m,o.getFullYear()):m;for(b.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+g+".datepicker._selectMonthYear('#"+b.id+"', this, 'Y');\" >";f<=m;f++)b.yearshtml+='<option value="'+f+'"'+(f==j?' selected="selected"':"")+">"+f+"</option>";b.yearshtml+="</select>";r+=b.yearshtml;b.yearshtml=null}}r+=this._get(b,"yearSuffix");if(s)r+=(n||!(p&&q)?"&#xa0;":"")+u;r+="</div>";return r},_adjustInstDate:function(b,f,j){var l=b.drawYear+(j=="Y"?f:0),o=b.drawMonth+
+(j=="M"?f:0);f=Math.min(b.selectedDay,this._getDaysInMonth(l,o))+(j=="D"?f:0);l=this._restrictMinMax(b,this._daylightSavingAdjust(new Date(l,o,f)));b.selectedDay=l.getDate();b.drawMonth=b.selectedMonth=l.getMonth();b.drawYear=b.selectedYear=l.getFullYear();if(j=="M"||j=="Y")this._notifyChange(b)},_restrictMinMax:function(b,f){var j=this._getMinMaxDate(b,"min");b=this._getMinMaxDate(b,"max");f=j&&f<j?j:f;return f=b&&f>b?b:f},_notifyChange:function(b){var f=this._get(b,"onChangeMonthYear");if(f)f.apply(b.input?
+b.input[0]:null,[b.selectedYear,b.selectedMonth+1,b])},_getNumberOfMonths:function(b){b=this._get(b,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(b,f){return this._determineDate(b,this._get(b,f+"Date"),null)},_getDaysInMonth:function(b,f){return 32-this._daylightSavingAdjust(new Date(b,f,32)).getDate()},_getFirstDayOfMonth:function(b,f){return(new Date(b,f,1)).getDay()},_canAdjustMonth:function(b,f,j,l){var o=this._getNumberOfMonths(b);j=this._daylightSavingAdjust(new Date(j,
+l+(f<0?f:o[0]*o[1]),1));f<0&&j.setDate(this._getDaysInMonth(j.getFullYear(),j.getMonth()));return this._isInRange(b,j)},_isInRange:function(b,f){var j=this._getMinMaxDate(b,"min");b=this._getMinMaxDate(b,"max");return(!j||f.getTime()>=j.getTime())&&(!b||f.getTime()<=b.getTime())},_getFormatConfig:function(b){var f=this._get(b,"shortYearCutoff");f=typeof f!="string"?f:(new Date).getFullYear()%100+parseInt(f,10);return{shortYearCutoff:f,dayNamesShort:this._get(b,"dayNamesShort"),dayNames:this._get(b,
+"dayNames"),monthNamesShort:this._get(b,"monthNamesShort"),monthNames:this._get(b,"monthNames")}},_formatDate:function(b,f,j,l){if(!f){b.currentDay=b.selectedDay;b.currentMonth=b.selectedMonth;b.currentYear=b.selectedYear}f=f?typeof f=="object"?f:this._daylightSavingAdjust(new Date(l,j,f)):this._daylightSavingAdjust(new Date(b.currentYear,b.currentMonth,b.currentDay));return this.formatDate(this._get(b,"dateFormat"),f,this._getFormatConfig(b))}});a.fn.datepicker=function(b){if(!this.length)return this;
+if(!a.datepicker.initialized){a(document).mousedown(a.datepicker._checkExternalClick).find("body").append(a.datepicker.dpDiv);a.datepicker.initialized=true}var f=Array.prototype.slice.call(arguments,1);if(typeof b=="string"&&(b=="isDisabled"||b=="getDate"||b=="widget"))return a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(f));if(b=="option"&&arguments.length==2&&typeof arguments[1]=="string")return a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(f));return this.each(function(){typeof b==
+"string"?a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this].concat(f)):a.datepicker._attachDatepicker(this,b)})};a.datepicker=new c;a.datepicker.initialized=false;a.datepicker.uuid=(new Date).getTime();a.datepicker.version="1.8.16";window["DP_jQuery_"+g]=a})(jQuery);
+(function(a,d){var c={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},e={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},h=a.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};a.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,
+position:{my:"center",at:"center",collision:"fit",using:function(g){var i=a(this).css(g).offset().top;i<0&&a(this).css("top",g.top-i)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var g=this,i=g.options,b=i.title||"&#160;",f=a.ui.dialog.getTitleId(g.element),j=(g.uiDialog=a("<div></div>")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+
+i.dialogClass).css({zIndex:i.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(n){if(i.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===a.ui.keyCode.ESCAPE){g.close(n);n.preventDefault()}}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(n){g.moveToTop(false,n)});g.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(j);var l=(g.uiDialogTitlebar=a("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(j),
+o=a('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){o.addClass("ui-state-hover")},function(){o.removeClass("ui-state-hover")}).focus(function(){o.addClass("ui-state-focus")}).blur(function(){o.removeClass("ui-state-focus")}).click(function(n){g.close(n);return false}).appendTo(l);(g.uiDialogTitlebarCloseText=a("<span></span>")).addClass("ui-icon ui-icon-closethick").text(i.closeText).appendTo(o);a("<span></span>").addClass("ui-dialog-title").attr("id",
+f).html(b).prependTo(l);if(a.isFunction(i.beforeclose)&&!a.isFunction(i.beforeClose))i.beforeClose=i.beforeclose;l.find("*").add(l).disableSelection();i.draggable&&a.fn.draggable&&g._makeDraggable();i.resizable&&a.fn.resizable&&g._makeResizable();g._createButtons(i.buttons);g._isOpen=false;a.fn.bgiframe&&j.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var g=this;g.overlay&&g.overlay.destroy();g.uiDialog.hide();g.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");
+g.uiDialog.remove();g.originalTitle&&g.element.attr("title",g.originalTitle);return g},widget:function(){return this.uiDialog},close:function(g){var i=this,b,f;if(false!==i._trigger("beforeClose",g)){i.overlay&&i.overlay.destroy();i.uiDialog.unbind("keypress.ui-dialog");i._isOpen=false;if(i.options.hide)i.uiDialog.hide(i.options.hide,function(){i._trigger("close",g)});else{i.uiDialog.hide();i._trigger("close",g)}a.ui.dialog.overlay.resize();if(i.options.modal){b=0;a(".ui-dialog").each(function(){if(this!==
+i.uiDialog[0]){f=a(this).css("z-index");isNaN(f)||(b=Math.max(b,f))}});a.ui.dialog.maxZ=b}return i}},isOpen:function(){return this._isOpen},moveToTop:function(g,i){var b=this,f=b.options;if(f.modal&&!g||!f.stack&&!f.modal)return b._trigger("focus",i);if(f.zIndex>a.ui.dialog.maxZ)a.ui.dialog.maxZ=f.zIndex;if(b.overlay){a.ui.dialog.maxZ+=1;b.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)}g={scrollTop:b.element.scrollTop(),scrollLeft:b.element.scrollLeft()};a.ui.dialog.maxZ+=1;
+b.uiDialog.css("z-index",a.ui.dialog.maxZ);b.element.attr(g);b._trigger("focus",i);return b},open:function(){if(!this._isOpen){var g=this,i=g.options,b=g.uiDialog;g.overlay=i.modal?new a.ui.dialog.overlay(g):null;g._size();g._position(i.position);b.show(i.show);g.moveToTop(true);i.modal&&b.bind("keypress.ui-dialog",function(f){if(f.keyCode===a.ui.keyCode.TAB){var j=a(":tabbable",this),l=j.filter(":first");j=j.filter(":last");if(f.target===j[0]&&!f.shiftKey){l.focus(1);return false}else if(f.target===
+l[0]&&f.shiftKey){j.focus(1);return false}}});a(g.element.find(":tabbable").get().concat(b.find(".ui-dialog-buttonpane :tabbable").get().concat(b.get()))).eq(0).focus();g._isOpen=true;g._trigger("open");return g}},_createButtons:function(g){var i=this,b=false,f=a("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),j=a("<div></div>").addClass("ui-dialog-buttonset").appendTo(f);i.uiDialog.find(".ui-dialog-buttonpane").remove();typeof g==="object"&&g!==null&&a.each(g,
+function(){return!(b=true)});if(b){a.each(g,function(l,o){o=a.isFunction(o)?{click:o,text:l}:o;var n=a('<button type="button"></button>').click(function(){o.click.apply(i.element[0],arguments)}).appendTo(j);a.each(o,function(k,m){if(k!=="click")k in h?n[k](m):n.attr(k,m)});a.fn.button&&n.button()});f.appendTo(i.uiDialog)}},_makeDraggable:function(){function g(l){return{position:l.position,offset:l.offset}}var i=this,b=i.options,f=a(document),j;i.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",
+handle:".ui-dialog-titlebar",containment:"document",start:function(l,o){j=b.height==="auto"?"auto":a(this).height();a(this).height(a(this).height()).addClass("ui-dialog-dragging");i._trigger("dragStart",l,g(o))},drag:function(l,o){i._trigger("drag",l,g(o))},stop:function(l,o){b.position=[o.position.left-f.scrollLeft(),o.position.top-f.scrollTop()];a(this).removeClass("ui-dialog-dragging").height(j);i._trigger("dragStop",l,g(o));a.ui.dialog.overlay.resize()}})},_makeResizable:function(g){function i(l){return{originalPosition:l.originalPosition,
+originalSize:l.originalSize,position:l.position,size:l.size}}g=g===d?this.options.resizable:g;var b=this,f=b.options,j=b.uiDialog.css("position");g=typeof g==="string"?g:"n,e,s,w,se,sw,ne,nw";b.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:b.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:b._minHeight(),handles:g,start:function(l,o){a(this).addClass("ui-dialog-resizing");b._trigger("resizeStart",l,i(o))},resize:function(l,o){b._trigger("resize",
+l,i(o))},stop:function(l,o){a(this).removeClass("ui-dialog-resizing");f.height=a(this).height();f.width=a(this).width();b._trigger("resizeStop",l,i(o));a.ui.dialog.overlay.resize()}}).css("position",j).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var g=this.options;return g.height==="auto"?g.minHeight:Math.min(g.minHeight,g.height)},_position:function(g){var i=[],b=[0,0],f;if(g){if(typeof g==="string"||typeof g==="object"&&"0"in g){i=g.split?g.split(" "):
+[g[0],g[1]];if(i.length===1)i[1]=i[0];a.each(["left","top"],function(j,l){if(+i[j]===i[j]){b[j]=i[j];i[j]=l}});g={my:i.join(" "),at:i.join(" "),offset:b.join(" ")}}g=a.extend({},a.ui.dialog.prototype.options.position,g)}else g=a.ui.dialog.prototype.options.position;(f=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},g));f||this.uiDialog.hide()},_setOptions:function(g){var i=this,b={},f=false;a.each(g,function(j,l){i._setOption(j,l);
+if(j in c)f=true;if(j in e)b[j]=l});f&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",b)},_setOption:function(g,i){var b=this,f=b.uiDialog;switch(g){case "beforeclose":g="beforeClose";break;case "buttons":b._createButtons(i);break;case "closeText":b.uiDialogTitlebarCloseText.text(""+i);break;case "dialogClass":f.removeClass(b.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+i);break;case "disabled":i?f.addClass("ui-dialog-disabled"):
+f.removeClass("ui-dialog-disabled");break;case "draggable":var j=f.is(":data(draggable)");j&&!i&&f.draggable("destroy");!j&&i&&b._makeDraggable();break;case "position":b._position(i);break;case "resizable":(j=f.is(":data(resizable)"))&&!i&&f.resizable("destroy");j&&typeof i==="string"&&f.resizable("option","handles",i);!j&&i!==false&&b._makeResizable(i);break;case "title":a(".ui-dialog-title",b.uiDialogTitlebar).html(""+(i||"&#160;"));break}a.Widget.prototype._setOption.apply(b,arguments)},_size:function(){var g=
+this.options,i,b,f=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(g.minWidth>g.width)g.width=g.minWidth;i=this.uiDialog.css({height:"auto",width:g.width}).height();b=Math.max(0,g.minHeight-i);if(g.height==="auto")if(a.support.minHeight)this.element.css({minHeight:b,height:"auto"});else{this.uiDialog.show();g=this.element.css("height","auto").height();f||this.uiDialog.hide();this.element.height(Math.max(g,b))}else this.element.height(Math.max(g.height-
+i,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});a.extend(a.ui.dialog,{version:"1.8.16",uuid:0,maxZ:0,getTitleId:function(g){g=g.attr("id");if(!g){this.uuid+=1;g=this.uuid}return"ui-dialog-title-"+g},overlay:function(g){this.$el=a.ui.dialog.overlay.create(g)}});a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(g){return g+".dialog-overlay"}).join(" "),
+create:function(g){if(this.instances.length===0){setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()<a.ui.dialog.overlay.maxZ)return false})},1);a(document).bind("keydown.dialog-overlay",function(b){if(g.options.closeOnEscape&&!b.isDefaultPrevented()&&b.keyCode&&b.keyCode===a.ui.keyCode.ESCAPE){g.close(b);b.preventDefault()}});a(window).bind("resize.dialog-overlay",a.ui.dialog.overlay.resize)}var i=(this.oldInstances.pop()||
+a("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});a.fn.bgiframe&&i.bgiframe();this.instances.push(i);return i},destroy:function(g){var i=a.inArray(g,this.instances);i!=-1&&this.oldInstances.push(this.instances.splice(i,1)[0]);this.instances.length===0&&a([document,window]).unbind(".dialog-overlay");g.remove();var b=0;a.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var g,i;if(a.browser.msie&&
+a.browser.version<7){g=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);i=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return g<i?a(window).height()+"px":g+"px"}else return a(document).height()+"px"},width:function(){var g,i;if(a.browser.msie){g=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);i=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return g<i?a(window).width()+"px":g+"px"}else return a(document).width()+
+"px"},resize:function(){var g=a([]);a.each(a.ui.dialog.overlay.instances,function(){g=g.add(this)});g.css({width:0,height:0}).css({width:a.ui.dialog.overlay.width(),height:a.ui.dialog.overlay.height()})}});a.extend(a.ui.dialog.overlay.prototype,{destroy:function(){a.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);
+(function(a){a.ui=a.ui||{};var d=/left|center|right/,c=/top|center|bottom/,e=a.fn.position,h=a.fn.offset;a.fn.position=function(g){if(!g||!g.of)return e.apply(this,arguments);g=a.extend({},g);var i=a(g.of),b=i[0],f=(g.collision||"flip").split(" "),j=g.offset?g.offset.split(" "):[0,0],l,o,n;if(b.nodeType===9){l=i.width();o=i.height();n={top:0,left:0}}else if(b.setTimeout){l=i.width();o=i.height();n={top:i.scrollTop(),left:i.scrollLeft()}}else if(b.preventDefault){g.at="left top";l=o=0;n={top:g.of.pageY,
+left:g.of.pageX}}else{l=i.outerWidth();o=i.outerHeight();n=i.offset()}a.each(["my","at"],function(){var k=(g[this]||"").split(" ");if(k.length===1)k=d.test(k[0])?k.concat(["center"]):c.test(k[0])?["center"].concat(k):["center","center"];k[0]=d.test(k[0])?k[0]:"center";k[1]=c.test(k[1])?k[1]:"center";g[this]=k});if(f.length===1)f[1]=f[0];j[0]=parseInt(j[0],10)||0;if(j.length===1)j[1]=j[0];j[1]=parseInt(j[1],10)||0;if(g.at[0]==="right")n.left+=l;else if(g.at[0]==="center")n.left+=l/2;if(g.at[1]==="bottom")n.top+=
+o;else if(g.at[1]==="center")n.top+=o/2;n.left+=j[0];n.top+=j[1];return this.each(function(){var k=a(this),m=k.outerWidth(),p=k.outerHeight(),q=parseInt(a.curCSS(this,"marginLeft",true))||0,s=parseInt(a.curCSS(this,"marginTop",true))||0,r=m+q+(parseInt(a.curCSS(this,"marginRight",true))||0),u=p+s+(parseInt(a.curCSS(this,"marginBottom",true))||0),v=a.extend({},n),w;if(g.my[0]==="right")v.left-=m;else if(g.my[0]==="center")v.left-=m/2;if(g.my[1]==="bottom")v.top-=p;else if(g.my[1]==="center")v.top-=
+p/2;v.left=Math.round(v.left);v.top=Math.round(v.top);w={left:v.left-q,top:v.top-s};a.each(["left","top"],function(x,y){a.ui.position[f[x]]&&a.ui.position[f[x]][y](v,{targetWidth:l,targetHeight:o,elemWidth:m,elemHeight:p,collisionPosition:w,collisionWidth:r,collisionHeight:u,offset:j,my:g.my,at:g.at})});a.fn.bgiframe&&k.bgiframe();k.offset(a.extend(v,{using:g.using}))})};a.ui.position={fit:{left:function(g,i){var b=a(window);b=i.collisionPosition.left+i.collisionWidth-b.width()-b.scrollLeft();g.left=
+b>0?g.left-b:Math.max(g.left-i.collisionPosition.left,g.left)},top:function(g,i){var b=a(window);b=i.collisionPosition.top+i.collisionHeight-b.height()-b.scrollTop();g.top=b>0?g.top-b:Math.max(g.top-i.collisionPosition.top,g.top)}},flip:{left:function(g,i){if(i.at[0]!=="center"){var b=a(window);b=i.collisionPosition.left+i.collisionWidth-b.width()-b.scrollLeft();var f=i.my[0]==="left"?-i.elemWidth:i.my[0]==="right"?i.elemWidth:0,j=i.at[0]==="left"?i.targetWidth:-i.targetWidth,l=-2*i.offset[0];g.left+=
+i.collisionPosition.left<0?f+j+l:b>0?f+j+l:0}},top:function(g,i){if(i.at[1]!=="center"){var b=a(window);b=i.collisionPosition.top+i.collisionHeight-b.height()-b.scrollTop();var f=i.my[1]==="top"?-i.elemHeight:i.my[1]==="bottom"?i.elemHeight:0,j=i.at[1]==="top"?i.targetHeight:-i.targetHeight,l=-2*i.offset[1];g.top+=i.collisionPosition.top<0?f+j+l:b>0?f+j+l:0}}}};if(!a.offset.setOffset){a.offset.setOffset=function(g,i){if(/static/.test(a.curCSS(g,"position")))g.style.position="relative";var b=a(g),
+f=b.offset(),j=parseInt(a.curCSS(g,"top",true),10)||0,l=parseInt(a.curCSS(g,"left",true),10)||0;f={top:i.top-f.top+j,left:i.left-f.left+l};"using"in i?i.using.call(g,f):b.css(f)};a.fn.offset=function(g){var i=this[0];if(!i||!i.ownerDocument)return null;if(g)return this.each(function(){a.offset.setOffset(this,g)});return h.call(this)}}})(jQuery);
+(function(a,d){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=a("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow");
+this.valueDiv.remove();a.Widget.prototype.destroy.apply(this,arguments)},value:function(c){if(c===d)return this._value();this._setOption("value",c);return this},_setOption:function(c,e){if(c==="value"){this.options.value=e;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var c=this.options.value;if(typeof c!=="number")c=0;return Math.min(this.options.max,Math.max(this.min,c))},_percentage:function(){return 100*
+this._value()/this.options.max},_refreshValue:function(){var c=this.value(),e=this._percentage();if(this.oldValue!==c){this.oldValue=c;this._trigger("change")}this.valueDiv.toggle(c>this.min).toggleClass("ui-corner-right",c===this.options.max).width(e.toFixed(0)+"%");this.element.attr("aria-valuenow",c)}});a.extend(a.ui.progressbar,{version:"1.8.16"})})(jQuery);
+(function(a){a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var d=this,c=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),h=c.values&&c.values.length||1,g=[];this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+
+this.orientation+" ui-widget ui-widget-content ui-corner-all"+(c.disabled?" ui-slider-disabled ui-disabled":""));this.range=a([]);if(c.range){if(c.range===true){if(!c.values)c.values=[this._valueMin(),this._valueMin()];if(c.values.length&&c.values.length!==2)c.values=[c.values[0],c.values[0]]}this.range=a("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(c.range==="min"||c.range==="max"?" ui-slider-range-"+c.range:""))}for(var i=e.length;i<h;i+=1)g.push("<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>");
+this.handles=e.add(a(g.join("")).appendTo(d.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(b){b.preventDefault()}).hover(function(){c.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){if(c.disabled)a(this).blur();else{a(".ui-slider .ui-state-focus").removeClass("ui-state-focus");a(this).addClass("ui-state-focus")}}).blur(function(){a(this).removeClass("ui-state-focus")});this.handles.each(function(b){a(this).data("index.ui-slider-handle",
+b)});this.handles.keydown(function(b){var f=true,j=a(this).data("index.ui-slider-handle"),l,o,n;if(!d.options.disabled){switch(b.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:f=false;if(!d._keySliding){d._keySliding=true;a(this).addClass("ui-state-active");l=d._start(b,j);if(l===false)return}break}n=d.options.step;l=d.options.values&&d.options.values.length?
+(o=d.values(j)):(o=d.value());switch(b.keyCode){case a.ui.keyCode.HOME:o=d._valueMin();break;case a.ui.keyCode.END:o=d._valueMax();break;case a.ui.keyCode.PAGE_UP:o=d._trimAlignValue(l+(d._valueMax()-d._valueMin())/5);break;case a.ui.keyCode.PAGE_DOWN:o=d._trimAlignValue(l-(d._valueMax()-d._valueMin())/5);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(l===d._valueMax())return;o=d._trimAlignValue(l+n);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(l===d._valueMin())return;o=d._trimAlignValue(l-
+n);break}d._slide(b,j,o);return f}}).keyup(function(b){var f=a(this).data("index.ui-slider-handle");if(d._keySliding){d._keySliding=false;d._stop(b,f);d._change(b,f);a(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy();
+return this},_mouseCapture:function(d){var c=this.options,e,h,g,i,b;if(c.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();e=this._normValueFromMouse({x:d.pageX,y:d.pageY});h=this._valueMax()-this._valueMin()+1;i=this;this.handles.each(function(f){var j=Math.abs(e-i.values(f));if(h>j){h=j;g=a(this);b=f}});if(c.range===true&&this.values(1)===c.min){b+=1;g=a(this.handles[b])}if(this._start(d,b)===false)return false;
+this._mouseSliding=true;i._handleIndex=b;g.addClass("ui-state-active").focus();c=g.offset();this._clickOffset=!a(d.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:d.pageX-c.left-g.width()/2,top:d.pageY-c.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(d,b,e);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(d){var c=
+this._normValueFromMouse({x:d.pageX,y:d.pageY});this._slide(d,this._handleIndex,c);return false},_mouseStop:function(d){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(d,this._handleIndex);this._change(d,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(d){var c;if(this.orientation==="horizontal"){c=
+this.elementSize.width;d=d.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{c=this.elementSize.height;d=d.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}c=d/c;if(c>1)c=1;if(c<0)c=0;if(this.orientation==="vertical")c=1-c;d=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+c*d)},_start:function(d,c){var e={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){e.value=this.values(c);
+e.values=this.values()}return this._trigger("start",d,e)},_slide:function(d,c,e){var h;if(this.options.values&&this.options.values.length){h=this.values(c?0:1);if(this.options.values.length===2&&this.options.range===true&&(c===0&&e>h||c===1&&e<h))e=h;if(e!==this.values(c)){h=this.values();h[c]=e;d=this._trigger("slide",d,{handle:this.handles[c],value:e,values:h});this.values(c?0:1);d!==false&&this.values(c,e,true)}}else if(e!==this.value()){d=this._trigger("slide",d,{handle:this.handles[c],value:e});
+d!==false&&this.value(e)}},_stop:function(d,c){var e={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){e.value=this.values(c);e.values=this.values()}this._trigger("stop",d,e)},_change:function(d,c){if(!this._keySliding&&!this._mouseSliding){var e={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){e.value=this.values(c);e.values=this.values()}this._trigger("change",d,e)}},value:function(d){if(arguments.length){this.options.value=
+this._trimAlignValue(d);this._refreshValue();this._change(null,0)}else return this._value()},values:function(d,c){var e,h,g;if(arguments.length>1){this.options.values[d]=this._trimAlignValue(c);this._refreshValue();this._change(null,d)}else if(arguments.length)if(a.isArray(arguments[0])){e=this.options.values;h=arguments[0];for(g=0;g<e.length;g+=1){e[g]=this._trimAlignValue(h[g]);this._change(null,g)}this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(d):
+this.value();else return this._values()},_setOption:function(d,c){var e,h=0;if(a.isArray(this.options.values))h=this.options.values.length;a.Widget.prototype._setOption.apply(this,arguments);switch(d){case "disabled":if(c){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.propAttr("disabled",true);this.element.addClass("ui-disabled")}else{this.handles.propAttr("disabled",false);this.element.removeClass("ui-disabled")}break;case "orientation":this._detectOrientation();
+this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue();break;case "value":this._animateOff=true;this._refreshValue();this._change(null,0);this._animateOff=false;break;case "values":this._animateOff=true;this._refreshValue();for(e=0;e<h;e+=1)this._change(null,e);this._animateOff=false;break}},_value:function(){var d=this.options.value;return d=this._trimAlignValue(d)},_values:function(d){var c,e;if(arguments.length){c=this.options.values[d];
+return c=this._trimAlignValue(c)}else{c=this.options.values.slice();for(e=0;e<c.length;e+=1)c[e]=this._trimAlignValue(c[e]);return c}},_trimAlignValue:function(d){if(d<=this._valueMin())return this._valueMin();if(d>=this._valueMax())return this._valueMax();var c=this.options.step>0?this.options.step:1,e=(d-this._valueMin())%c;d=d-e;if(Math.abs(e)*2>=c)d+=e>0?c:-c;return parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var d=
+this.options.range,c=this.options,e=this,h=!this._animateOff?c.animate:false,g,i={},b,f,j,l;if(this.options.values&&this.options.values.length)this.handles.each(function(o){g=(e.values(o)-e._valueMin())/(e._valueMax()-e._valueMin())*100;i[e.orientation==="horizontal"?"left":"bottom"]=g+"%";a(this).stop(1,1)[h?"animate":"css"](i,c.animate);if(e.options.range===true)if(e.orientation==="horizontal"){if(o===0)e.range.stop(1,1)[h?"animate":"css"]({left:g+"%"},c.animate);if(o===1)e.range[h?"animate":"css"]({width:g-
+b+"%"},{queue:false,duration:c.animate})}else{if(o===0)e.range.stop(1,1)[h?"animate":"css"]({bottom:g+"%"},c.animate);if(o===1)e.range[h?"animate":"css"]({height:g-b+"%"},{queue:false,duration:c.animate})}b=g});else{f=this.value();j=this._valueMin();l=this._valueMax();g=l!==j?(f-j)/(l-j)*100:0;i[e.orientation==="horizontal"?"left":"bottom"]=g+"%";this.handle.stop(1,1)[h?"animate":"css"](i,c.animate);if(d==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[h?"animate":"css"]({width:g+"%"},
+c.animate);if(d==="max"&&this.orientation==="horizontal")this.range[h?"animate":"css"]({width:100-g+"%"},{queue:false,duration:c.animate});if(d==="min"&&this.orientation==="vertical")this.range.stop(1,1)[h?"animate":"css"]({height:g+"%"},c.animate);if(d==="max"&&this.orientation==="vertical")this.range[h?"animate":"css"]({height:100-g+"%"},{queue:false,duration:c.animate})}}});a.extend(a.ui.slider,{version:"1.8.16"})})(jQuery);
+(function(a,d){function c(){return++h}function e(){return++g}var h=0,g=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading&#8230;</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(true)},_setOption:function(i,b){if(i=="selected")this.options.collapsible&&
+b==this.options.selected||this.select(b);else{this.options[i]=b;this._tabify()}},_tabId:function(i){return i.title&&i.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+c()},_sanitizeSelector:function(i){return i.replace(/:/g,"\\:")},_cookie:function(){var i=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+e());return a.cookie.apply(null,[i].concat(a.makeArray(arguments)))},_ui:function(i,b){return{tab:i,panel:b,index:this.anchors.index(i)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var i=
+a(this);i.html(i.data("label.tabs")).removeData("label.tabs")})},_tabify:function(i){function b(r,u){r.css("display","");!a.support.opacity&&u.opacity&&r[0].style.removeAttribute("filter")}var f=this,j=this.options,l=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=a(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);this.anchors.each(function(r,u){var v=a(u).attr("href"),w=v.split("#")[0],x;if(w&&(w===location.toString().split("#")[0]||
+(x=a("base")[0])&&w===x.href)){v=u.hash;u.href=v}if(l.test(v))f.panels=f.panels.add(f.element.find(f._sanitizeSelector(v)));else if(v&&v!=="#"){a.data(u,"href.tabs",v);a.data(u,"load.tabs",v.replace(/#.*$/,""));v=f._tabId(u);u.href="#"+v;u=f.element.find("#"+v);if(!u.length){u=a(j.panelTemplate).attr("id",v).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(f.panels[r-1]||f.list);u.data("destroy.tabs",true)}f.panels=f.panels.add(u)}else j.disabled.push(r)});if(i){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");
+this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(j.selected===d){location.hash&&this.anchors.each(function(r,u){if(u.hash==location.hash){j.selected=r;return false}});if(typeof j.selected!=="number"&&j.cookie)j.selected=parseInt(f._cookie(),10);if(typeof j.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)j.selected=
+this.lis.index(this.lis.filter(".ui-tabs-selected"));j.selected=j.selected||(this.lis.length?0:-1)}else if(j.selected===null)j.selected=-1;j.selected=j.selected>=0&&this.anchors[j.selected]||j.selected<0?j.selected:0;j.disabled=a.unique(j.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(r){return f.lis.index(r)}))).sort();a.inArray(j.selected,j.disabled)!=-1&&j.disabled.splice(a.inArray(j.selected,j.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");
+if(j.selected>=0&&this.anchors.length){f.element.find(f._sanitizeSelector(f.anchors[j.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(j.selected).addClass("ui-tabs-selected ui-state-active");f.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[j.selected],f.element.find(f._sanitizeSelector(f.anchors[j.selected].hash))[0]))});this.load(j.selected)}a(window).bind("unload",function(){f.lis.add(f.anchors).unbind(".tabs");f.lis=f.anchors=f.panels=null})}else j.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));
+this.element[j.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");j.cookie&&this._cookie(j.selected,j.cookie);i=0;for(var o;o=this.lis[i];i++)a(o)[a.inArray(i,j.disabled)!=-1&&!a(o).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");j.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(j.event!=="mouseover"){var n=function(r,u){u.is(":not(.ui-state-disabled)")&&u.addClass("ui-state-"+r)},k=function(r,u){u.removeClass("ui-state-"+
+r)};this.lis.bind("mouseover.tabs",function(){n("hover",a(this))});this.lis.bind("mouseout.tabs",function(){k("hover",a(this))});this.anchors.bind("focus.tabs",function(){n("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){k("focus",a(this).closest("li"))})}var m,p;if(j.fx)if(a.isArray(j.fx)){m=j.fx[0];p=j.fx[1]}else m=p=j.fx;var q=p?function(r,u){a(r).closest("li").addClass("ui-tabs-selected ui-state-active");u.hide().removeClass("ui-tabs-hide").animate(p,p.duration||"normal",
+function(){b(u,p);f._trigger("show",null,f._ui(r,u[0]))})}:function(r,u){a(r).closest("li").addClass("ui-tabs-selected ui-state-active");u.removeClass("ui-tabs-hide");f._trigger("show",null,f._ui(r,u[0]))},s=m?function(r,u){u.animate(m,m.duration||"normal",function(){f.lis.removeClass("ui-tabs-selected ui-state-active");u.addClass("ui-tabs-hide");b(u,m);f.element.dequeue("tabs")})}:function(r,u){f.lis.removeClass("ui-tabs-selected ui-state-active");u.addClass("ui-tabs-hide");f.element.dequeue("tabs")};
+this.anchors.bind(j.event+".tabs",function(){var r=this,u=a(r).closest("li"),v=f.panels.filter(":not(.ui-tabs-hide)"),w=f.element.find(f._sanitizeSelector(r.hash));if(u.hasClass("ui-tabs-selected")&&!j.collapsible||u.hasClass("ui-state-disabled")||u.hasClass("ui-state-processing")||f.panels.filter(":animated").length||f._trigger("select",null,f._ui(this,w[0]))===false){this.blur();return false}j.selected=f.anchors.index(this);f.abort();if(j.collapsible)if(u.hasClass("ui-tabs-selected")){j.selected=
+-1;j.cookie&&f._cookie(j.selected,j.cookie);f.element.queue("tabs",function(){s(r,v)}).dequeue("tabs");this.blur();return false}else if(!v.length){j.cookie&&f._cookie(j.selected,j.cookie);f.element.queue("tabs",function(){q(r,w)});f.load(f.anchors.index(this));this.blur();return false}j.cookie&&f._cookie(j.selected,j.cookie);if(w.length){v.length&&f.element.queue("tabs",function(){s(r,v)});f.element.queue("tabs",function(){q(r,w)});f.load(f.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";
+a.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(i){if(typeof i=="string")i=this.anchors.index(this.anchors.filter("[href$="+i+"]"));return i},destroy:function(){var i=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var b=
+a.data(this,"href.tabs");if(b)this.href=b;var f=a(this).unbind(".tabs");a.each(["href","load","cache"],function(j,l){f.removeData(l+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});i.cookie&&this._cookie(null,i.cookie);return this},add:function(i,
+b,f){if(f===d)f=this.anchors.length;var j=this,l=this.options;b=a(l.tabTemplate.replace(/#\{href\}/g,i).replace(/#\{label\}/g,b));i=!i.indexOf("#")?i.replace("#",""):this._tabId(a("a",b)[0]);b.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var o=j.element.find("#"+i);o.length||(o=a(l.panelTemplate).attr("id",i).data("destroy.tabs",true));o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(f>=this.lis.length){b.appendTo(this.list);o.appendTo(this.list[0].parentNode)}else{b.insertBefore(this.lis[f]);
+o.insertBefore(this.panels[f])}l.disabled=a.map(l.disabled,function(n){return n>=f?++n:n});this._tabify();if(this.anchors.length==1){l.selected=0;b.addClass("ui-tabs-selected ui-state-active");o.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){j._trigger("show",null,j._ui(j.anchors[0],j.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[f],this.panels[f]));return this},remove:function(i){i=this._getIndex(i);var b=this.options,f=this.lis.eq(i).remove(),j=this.panels.eq(i).remove();
+if(f.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(i+(i+1<this.anchors.length?1:-1));b.disabled=a.map(a.grep(b.disabled,function(l){return l!=i}),function(l){return l>=i?--l:l});this._tabify();this._trigger("remove",null,this._ui(f.find("a")[0],j[0]));return this},enable:function(i){i=this._getIndex(i);var b=this.options;if(a.inArray(i,b.disabled)!=-1){this.lis.eq(i).removeClass("ui-state-disabled");b.disabled=a.grep(b.disabled,function(f){return f!=i});this._trigger("enable",null,
+this._ui(this.anchors[i],this.panels[i]));return this}},disable:function(i){i=this._getIndex(i);var b=this.options;if(i!=b.selected){this.lis.eq(i).addClass("ui-state-disabled");b.disabled.push(i);b.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[i],this.panels[i]))}return this},select:function(i){i=this._getIndex(i);if(i==-1)if(this.options.collapsible&&this.options.selected!=-1)i=this.options.selected;else return this;this.anchors.eq(i).trigger(this.options.event+".tabs");return this},
+load:function(i){i=this._getIndex(i);var b=this,f=this.options,j=this.anchors.eq(i)[0],l=a.data(j,"load.tabs");this.abort();if(!l||this.element.queue("tabs").length!==0&&a.data(j,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(i).addClass("ui-state-processing");if(f.spinner){var o=a("span",j);o.data("label.tabs",o.html()).html(f.spinner)}this.xhr=a.ajax(a.extend({},f.ajaxOptions,{url:l,success:function(n,k){b.element.find(b._sanitizeSelector(j.hash)).html(n);b._cleanup();f.cache&&a.data(j,
+"cache.tabs",true);b._trigger("load",null,b._ui(b.anchors[i],b.panels[i]));try{f.ajaxOptions.success(n,k)}catch(m){}},error:function(n,k){b._cleanup();b._trigger("load",null,b._ui(b.anchors[i],b.panels[i]));try{f.ajaxOptions.error(n,k,i,j)}catch(m){}}}));b.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},
+url:function(i,b){this.anchors.eq(i).removeData("cache.tabs").data("load.tabs",b);return this},length:function(){return this.anchors.length}});a.extend(a.ui.tabs,{version:"1.8.16"});a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(i,b){var f=this,j=this.options,l=f._rotate||(f._rotate=function(o){clearTimeout(f.rotation);f.rotation=setTimeout(function(){var n=j.selected;f.select(++n<f.anchors.length?n:0)},i);o&&o.stopPropagation()});b=f._unrotate||(f._unrotate=!b?function(o){o.clientX&&
+f.rotate(null)}:function(){t=j.selected;l()});if(i){this.element.bind("tabsshow",l);this.anchors.bind(j.event+".tabs",b);l()}else{clearTimeout(f.rotation);this.element.unbind("tabsshow",l);this.anchors.unbind(j.event+".tabs",b);delete this._rotate;delete this._unrotate}return this}})})(jQuery);
diff --git a/lib/scripts/jquery/jquery.cookie.js b/lib/scripts/jquery/jquery.cookie.js
new file mode 100644
index 000000000..6a3e394b4
--- /dev/null
+++ b/lib/scripts/jquery/jquery.cookie.js
@@ -0,0 +1,41 @@
+/**
+ * jQuery Cookie plugin
+ *
+ * Copyright (c) 2010 Klaus Hartl (stilbuero.de)
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ */
+jQuery.cookie = function (key, value, options) {
+
+ // key and at least value given, set cookie...
+ if (arguments.length > 1 && String(value) !== "[object Object]") {
+ options = jQuery.extend({}, options);
+
+ if (value === null || value === undefined) {
+ options.expires = -1;
+ }
+
+ if (typeof options.expires === 'number') {
+ var days = options.expires, t = options.expires = new Date();
+ t.setDate(t.getDate() + days);
+ }
+
+ value = String(value);
+
+ return (document.cookie = [
+ encodeURIComponent(key), '=',
+ options.raw ? value : encodeURIComponent(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(''));
+ }
+
+ // key and possibly options given, get cookie...
+ options = value || {};
+ var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
+ return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
+};
diff --git a/lib/scripts/jquery/jquery.js b/lib/scripts/jquery/jquery.js
new file mode 100644
index 000000000..719e1d4ec
--- /dev/null
+++ b/lib/scripts/jquery/jquery.js
@@ -0,0 +1,9046 @@
+/*!
+ * jQuery JavaScript Library v1.6.4
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Sep 12 18:54:48 2011 -0400
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document,
+ navigator = window.navigator,
+ location = window.location;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context, rootjQuery );
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+ quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ trimLeft = /^\s+/,
+ trimRight = /\s+$/,
+
+ // Check for digits
+ rdigit = /\d/,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // JSON RegExp
+ rvalidchars = /^[\],:{}\s]*$/,
+ rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+ rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+ // Useragent RegExp
+ rwebkit = /(webkit)[ \/]([\w.]+)/,
+ ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+ rmsie = /(msie) ([\w.]+)/,
+ rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+ // Matches dashed string for camelizing
+ rdashAlpha = /-([a-z]|[0-9])/ig,
+ rmsPrefix = /^-ms-/,
+
+ // Used by jQuery.camelCase as callback to replace()
+ fcamelCase = function( all, letter ) {
+ return ( letter + "" ).toUpperCase();
+ },
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // The deferred used on DOM ready
+ readyList,
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwn = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ trim = String.prototype.trim,
+ indexOf = Array.prototype.indexOf,
+
+ // [[Class]] -> type pairs
+ class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+ constructor: jQuery,
+ init: function( selector, context, rootjQuery ) {
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // The body element only exists once, optimize finding it
+ if ( selector === "body" && !context && document.body ) {
+ this.context = document;
+ this[0] = document.body;
+ this.selector = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = quickExpr.exec( selector );
+ }
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ context = context instanceof jQuery ? context[0] : context;
+ doc = (context ? context.ownerDocument || context : document);
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
+ }
+
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById( match[2] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return (context || rootjQuery).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if (selector.selector !== undefined) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.6.4",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ toArray: function() {
+ return slice.call( this, 0 );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = this.constructor();
+
+ if ( jQuery.isArray( elems ) ) {
+ push.apply( ret, elems );
+
+ } else {
+ jQuery.merge( ret, elems );
+ }
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" ) {
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ } else if ( name ) {
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // Add the callback
+ readyList.done( fn );
+
+ return this;
+ },
+
+ eq: function( i ) {
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, +i + 1 );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray(src) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ if ( window.$ === jQuery ) {
+ window.$ = _$;
+ }
+
+ if ( deep && window.jQuery === jQuery ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Hold (or release) the ready event
+ holdReady: function( hold ) {
+ if ( hold ) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready( true );
+ }
+ },
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+ // Either a released hold or an DOMready/load event and not yet ready
+ if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ jQuery ] );
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.trigger ) {
+ jQuery( document ).trigger( "ready" ).unbind( "ready" );
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyList ) {
+ return;
+ }
+
+ readyList = jQuery._Deferred();
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return jQuery.type(obj) === "function";
+ },
+
+ isArray: Array.isArray || function( obj ) {
+ return jQuery.type(obj) === "array";
+ },
+
+ // A crude way of determining if an object is a window
+ isWindow: function( obj ) {
+ return obj && typeof obj === "object" && "setInterval" in obj;
+ },
+
+ isNaN: function( obj ) {
+ return obj == null || !rdigit.test( obj ) || isNaN( obj );
+ },
+
+ type: function( obj ) {
+ return obj == null ?
+ String( obj ) :
+ class2type[ toString.call(obj) ] || "object";
+ },
+
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ try {
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !hasOwn.call(obj, "constructor") &&
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+ } catch ( e ) {
+ // IE8,9 Will throw exceptions on certain host objects #9897
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwn.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw msg;
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ // Attempt to parse using the native JSON parser first
+ if ( window.JSON && window.JSON.parse ) {
+ return window.JSON.parse( data );
+ }
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+ .replace( rvalidtokens, "]" )
+ .replace( rvalidbraces, "")) ) {
+
+ return (new Function( "return " + data ))();
+
+ }
+ jQuery.error( "Invalid JSON: " + data );
+ },
+
+ // Cross-browser xml parsing
+ parseXML: function( data ) {
+ var xml, tmp;
+ try {
+ if ( window.DOMParser ) { // Standard
+ tmp = new DOMParser();
+ xml = tmp.parseFromString( data , "text/xml" );
+ } else { // IE
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
+ xml.async = "false";
+ xml.loadXML( data );
+ }
+ } catch( e ) {
+ xml = undefined;
+ }
+ if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+ jQuery.error( "Invalid XML: " + data );
+ }
+ return xml;
+ },
+
+ noop: function() {},
+
+ // Evaluates a script in a global context
+ // Workarounds based on findings by Jim Driscoll
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+ globalEval: function( data ) {
+ if ( data && rnotwhite.test( data ) ) {
+ // We use execScript on Internet Explorer
+ // We use an anonymous function so that context is window
+ // rather than jQuery in Firefox
+ ( window.execScript || function( data ) {
+ window[ "eval" ].call( window, data );
+ } )( data );
+ }
+ },
+
+ // Convert dashed to camelCase; used by the css and data modules
+ // Microsoft forgot to hump their vendor prefix (#9572)
+ camelCase: function( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction( object );
+
+ if ( args ) {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
+ break;
+ }
+ }
+ }
+ }
+
+ return object;
+ },
+
+ // Use native String.trim function wherever possible
+ trim: trim ?
+ function( text ) {
+ return text == null ?
+ "" :
+ trim.call( text );
+ } :
+
+ // Otherwise use our own trimming functionality
+ function( text ) {
+ return text == null ?
+ "" :
+ text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // The extra typeof function check is to prevent crashes
+ // in Safari 2 (See: #3039)
+ // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+ var type = jQuery.type( array );
+
+ if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ if ( !array ) {
+ return -1;
+ }
+
+ if ( indexOf ) {
+ return indexOf.call( array, elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var i = first.length,
+ j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [], retVal;
+ inv = !!inv;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ retVal = !!callback( elems[ i ], i );
+ if ( inv !== retVal ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var value, key, ret = [],
+ i = 0,
+ length = elems.length,
+ // jquery objects are treated as arrays
+ isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
+
+ // Go through the array, translating each of the items to their
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( key in elems ) {
+ value = callback( elems[ key ], key, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ if ( typeof context === "string" ) {
+ var tmp = fn[ context ];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in the spec
+ // this throws a TypeError, but we will just return undefined.
+ if ( !jQuery.isFunction( fn ) ) {
+ return undefined;
+ }
+
+ // Simulated bind
+ var args = slice.call( arguments, 2 ),
+ proxy = function() {
+ return fn.apply( context, args.concat( slice.call( arguments ) ) );
+ };
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+
+ return proxy;
+ },
+
+ // Mutifunctional method to get and set values to a collection
+ // The value/s can optionally be executed if it's a function
+ access: function( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ jQuery.access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : undefined;
+ },
+
+ now: function() {
+ return (new Date()).getTime();
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = rwebkit.exec( ua ) ||
+ ropera.exec( ua ) ||
+ rmsie.exec( ua ) ||
+ ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ sub: function() {
+ function jQuerySub( selector, context ) {
+ return new jQuerySub.fn.init( selector, context );
+ }
+ jQuery.extend( true, jQuerySub, this );
+ jQuerySub.superclass = this;
+ jQuerySub.fn = jQuerySub.prototype = this();
+ jQuerySub.fn.constructor = jQuerySub;
+ jQuerySub.sub = this.sub;
+ jQuerySub.fn.init = function init( selector, context ) {
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+ context = jQuerySub( context );
+ }
+
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+ };
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
+ var rootjQuerySub = jQuerySub(document);
+ return jQuerySub;
+ },
+
+ browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+// IE doesn't match non-breaking spaces with \s
+if ( rnotwhite.test( "\xA0" ) ) {
+ trimLeft = /^[\s\xA0]+/;
+ trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch(e) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+return jQuery;
+
+})();
+
+
+var // Promise methods
+ promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
+ // Static reference to slice
+ sliceDeferred = [].slice;
+
+jQuery.extend({
+ // Create a simple deferred (one callbacks list)
+ _Deferred: function() {
+ var // callbacks list
+ callbacks = [],
+ // stored [ context , args ]
+ fired,
+ // to avoid firing when already doing so
+ firing,
+ // flag to know if the deferred has been cancelled
+ cancelled,
+ // the deferred itself
+ deferred = {
+
+ // done( f1, f2, ...)
+ done: function() {
+ if ( !cancelled ) {
+ var args = arguments,
+ i,
+ length,
+ elem,
+ type,
+ _fired;
+ if ( fired ) {
+ _fired = fired;
+ fired = 0;
+ }
+ for ( i = 0, length = args.length; i < length; i++ ) {
+ elem = args[ i ];
+ type = jQuery.type( elem );
+ if ( type === "array" ) {
+ deferred.done.apply( deferred, elem );
+ } else if ( type === "function" ) {
+ callbacks.push( elem );
+ }
+ }
+ if ( _fired ) {
+ deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
+ }
+ }
+ return this;
+ },
+
+ // resolve with given context and args
+ resolveWith: function( context, args ) {
+ if ( !cancelled && !fired && !firing ) {
+ // make sure args are available (#8421)
+ args = args || [];
+ firing = 1;
+ try {
+ while( callbacks[ 0 ] ) {
+ callbacks.shift().apply( context, args );
+ }
+ }
+ finally {
+ fired = [ context, args ];
+ firing = 0;
+ }
+ }
+ return this;
+ },
+
+ // resolve with this as context and given arguments
+ resolve: function() {
+ deferred.resolveWith( this, arguments );
+ return this;
+ },
+
+ // Has this deferred been resolved?
+ isResolved: function() {
+ return !!( firing || fired );
+ },
+
+ // Cancel
+ cancel: function() {
+ cancelled = 1;
+ callbacks = [];
+ return this;
+ }
+ };
+
+ return deferred;
+ },
+
+ // Full fledged deferred (two callbacks list)
+ Deferred: function( func ) {
+ var deferred = jQuery._Deferred(),
+ failDeferred = jQuery._Deferred(),
+ promise;
+ // Add errorDeferred methods, then and promise
+ jQuery.extend( deferred, {
+ then: function( doneCallbacks, failCallbacks ) {
+ deferred.done( doneCallbacks ).fail( failCallbacks );
+ return this;
+ },
+ always: function() {
+ return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
+ },
+ fail: failDeferred.done,
+ rejectWith: failDeferred.resolveWith,
+ reject: failDeferred.resolve,
+ isRejected: failDeferred.isResolved,
+ pipe: function( fnDone, fnFail ) {
+ return jQuery.Deferred(function( newDefer ) {
+ jQuery.each( {
+ done: [ fnDone, "resolve" ],
+ fail: [ fnFail, "reject" ]
+ }, function( handler, data ) {
+ var fn = data[ 0 ],
+ action = data[ 1 ],
+ returned;
+ if ( jQuery.isFunction( fn ) ) {
+ deferred[ handler ](function() {
+ returned = fn.apply( this, arguments );
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
+ returned.promise().then( newDefer.resolve, newDefer.reject );
+ } else {
+ newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
+ }
+ });
+ } else {
+ deferred[ handler ]( newDefer[ action ] );
+ }
+ });
+ }).promise();
+ },
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ if ( obj == null ) {
+ if ( promise ) {
+ return promise;
+ }
+ promise = obj = {};
+ }
+ var i = promiseMethods.length;
+ while( i-- ) {
+ obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
+ }
+ return obj;
+ }
+ });
+ // Make sure only one callback list will be used
+ deferred.done( failDeferred.cancel ).fail( deferred.cancel );
+ // Unexpose cancel
+ delete deferred.cancel;
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( firstParam ) {
+ var args = arguments,
+ i = 0,
+ length = args.length,
+ count = length,
+ deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
+ firstParam :
+ jQuery.Deferred();
+ function resolveFunc( i ) {
+ return function( value ) {
+ args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
+ if ( !( --count ) ) {
+ // Strange bug in FF4:
+ // Values changed onto the arguments object sometimes end up as undefined values
+ // outside the $.when method. Cloning the object into a fresh array solves the issue
+ deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
+ }
+ };
+ }
+ if ( length > 1 ) {
+ for( ; i < length; i++ ) {
+ if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
+ args[ i ].promise().then( resolveFunc(i), deferred.reject );
+ } else {
+ --count;
+ }
+ }
+ if ( !count ) {
+ deferred.resolveWith( deferred, args );
+ }
+ } else if ( deferred !== firstParam ) {
+ deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
+ }
+ return deferred.promise();
+ }
+});
+
+
+
+jQuery.support = (function() {
+
+ var div = document.createElement( "div" ),
+ documentElement = document.documentElement,
+ all,
+ a,
+ select,
+ opt,
+ input,
+ marginDiv,
+ support,
+ fragment,
+ body,
+ testElementParent,
+ testElement,
+ testElementStyle,
+ tds,
+ events,
+ eventName,
+ i,
+ isSupported;
+
+ // Preliminary tests
+ div.setAttribute("className", "t");
+ div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+
+ all = div.getElementsByTagName( "*" );
+ a = div.getElementsByTagName( "a" )[ 0 ];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return {};
+ }
+
+ // First batch of supports tests
+ select = document.createElement( "select" );
+ opt = select.appendChild( document.createElement("option") );
+ input = div.getElementsByTagName( "input" )[ 0 ];
+
+ support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: ( div.firstChild.nodeType === 3 ),
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName( "tbody" ).length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName( "link" ).length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText instead)
+ style: /top/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.55$/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: ( input.value === "on" ),
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: opt.selected,
+
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+ getSetAttribute: div.className !== "t",
+
+ // Will be defined later
+ submitBubbles: true,
+ changeBubbles: true,
+ focusinBubbles: false,
+ deleteExpando: true,
+ noCloneEvent: true,
+ inlineBlockNeedsLayout: false,
+ shrinkWrapBlocks: false,
+ reliableMarginRight: true
+ };
+
+ // Make sure checked status is properly cloned
+ input.checked = true;
+ support.noCloneChecked = input.cloneNode( true ).checked;
+
+ // Make sure that the options inside disabled selects aren't marked as disabled
+ // (WebKit marks them as disabled)
+ select.disabled = true;
+ support.optDisabled = !opt.disabled;
+
+ // Test to see if it's possible to delete an expando from an element
+ // Fails in Internet Explorer
+ try {
+ delete div.test;
+ } catch( e ) {
+ support.deleteExpando = false;
+ }
+
+ if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
+ div.attachEvent( "onclick", function() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ support.noCloneEvent = false;
+ });
+ div.cloneNode( true ).fireEvent( "onclick" );
+ }
+
+ // Check if a radio maintains it's value
+ // after being appended to the DOM
+ input = document.createElement("input");
+ input.value = "t";
+ input.setAttribute("type", "radio");
+ support.radioValue = input.value === "t";
+
+ input.setAttribute("checked", "checked");
+ div.appendChild( input );
+ fragment = document.createDocumentFragment();
+ fragment.appendChild( div.firstChild );
+
+ // WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ div.innerHTML = "";
+
+ // Figure out if the W3C box model works as expected
+ div.style.width = div.style.paddingLeft = "1px";
+
+ body = document.getElementsByTagName( "body" )[ 0 ];
+ // We use our own, invisible, body unless the body is already present
+ // in which case we use a div (#9239)
+ testElement = document.createElement( body ? "div" : "body" );
+ testElementStyle = {
+ visibility: "hidden",
+ width: 0,
+ height: 0,
+ border: 0,
+ margin: 0,
+ background: "none"
+ };
+ if ( body ) {
+ jQuery.extend( testElementStyle, {
+ position: "absolute",
+ left: "-1000px",
+ top: "-1000px"
+ });
+ }
+ for ( i in testElementStyle ) {
+ testElement.style[ i ] = testElementStyle[ i ];
+ }
+ testElement.appendChild( div );
+ testElementParent = body || documentElement;
+ testElementParent.insertBefore( testElement, testElementParent.firstChild );
+
+ // Check if a disconnected checkbox will retain its checked
+ // value of true after appended to the DOM (IE6/7)
+ support.appendChecked = input.checked;
+
+ support.boxModel = div.offsetWidth === 2;
+
+ if ( "zoom" in div.style ) {
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ // (IE < 8 does this)
+ div.style.display = "inline";
+ div.style.zoom = 1;
+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
+
+ // Check if elements with layout shrink-wrap their children
+ // (IE 6 does this)
+ div.style.display = "";
+ div.innerHTML = "<div style='width:4px;'></div>";
+ support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
+ }
+
+ div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
+ tds = div.getElementsByTagName( "td" );
+
+ // Check if table cells still have offsetWidth/Height when they are set
+ // to display:none and there are still other visible table cells in a
+ // table row; if so, offsetWidth/Height are not reliable for use when
+ // determining if an element has been hidden directly using
+ // display:none (it is still safe to use offsets if a parent element is
+ // hidden; don safety goggles and see bug #4512 for more information).
+ // (only IE 8 fails this test)
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+ tds[ 0 ].style.display = "";
+ tds[ 1 ].style.display = "none";
+
+ // Check if empty table cells still have offsetWidth/Height
+ // (IE < 8 fail this test)
+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+ div.innerHTML = "";
+
+ // Check if div with explicit width and no margin-right incorrectly
+ // gets computed margin-right based on width of container. For more
+ // info see bug #3333
+ // Fails in WebKit before Feb 2011 nightlies
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ marginDiv = document.createElement( "div" );
+ marginDiv.style.width = "0";
+ marginDiv.style.marginRight = "0";
+ div.appendChild( marginDiv );
+ support.reliableMarginRight =
+ ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
+ }
+
+ // Remove the body element we added
+ testElement.innerHTML = "";
+ testElementParent.removeChild( testElement );
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ // We only care about the case where non-standard event systems
+ // are used, namely in IE. Short-circuiting here helps us to
+ // avoid an eval call (in setAttribute) which can cause CSP
+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+ if ( div.attachEvent ) {
+ for( i in {
+ submit: 1,
+ change: 1,
+ focusin: 1
+ } ) {
+ eventName = "on" + i;
+ isSupported = ( eventName in div );
+ if ( !isSupported ) {
+ div.setAttribute( eventName, "return;" );
+ isSupported = ( typeof div[ eventName ] === "function" );
+ }
+ support[ i + "Bubbles" ] = isSupported;
+ }
+ }
+
+ // Null connected elements to avoid leaks in IE
+ testElement = fragment = select = opt = body = marginDiv = div = input = null;
+
+ return support;
+})();
+
+// Keep track of boxModel
+jQuery.boxModel = jQuery.support.boxModel;
+
+
+
+
+var rbrace = /^(?:\{.*\}|\[.*\])$/,
+ rmultiDash = /([A-Z])/g;
+
+jQuery.extend({
+ cache: {},
+
+ // Please use with caution
+ uuid: 0,
+
+ // Unique for each copy of jQuery on the page
+ // Non-digits removed to match rinlinejQuery
+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ // Ban all objects except for Flash (which handle expandos)
+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+ "applet": true
+ },
+
+ hasData: function( elem ) {
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+
+ return !!elem && !isEmptyDataObject( elem );
+ },
+
+ data: function( elem, name, data, pvt /* Internal Use Only */ ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var thisCache, ret,
+ internalKey = jQuery.expando,
+ getByName = typeof name === "string",
+
+ // We have to handle DOM nodes and JS objects differently because IE6-7
+ // can't GC object references properly across the DOM-JS boundary
+ isNode = elem.nodeType,
+
+ // Only DOM nodes need the global jQuery cache; JS object data is
+ // attached directly to the object so GC can occur automatically
+ cache = isNode ? jQuery.cache : elem,
+
+ // Only defining an ID for JS objects if its cache already exists allows
+ // the code to shortcut on the same path as a DOM node with no cache
+ id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
+
+ // Avoid doing any more work than we need to when trying to get data on an
+ // object that has no data at all
+ if ( (!id || (pvt && id && (cache[ id ] && !cache[ id ][ internalKey ]))) && getByName && data === undefined ) {
+ return;
+ }
+
+ if ( !id ) {
+ // Only DOM nodes need a new unique ID for each element since their data
+ // ends up in the global cache
+ if ( isNode ) {
+ elem[ jQuery.expando ] = id = ++jQuery.uuid;
+ } else {
+ id = jQuery.expando;
+ }
+ }
+
+ if ( !cache[ id ] ) {
+ cache[ id ] = {};
+
+ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+ // metadata on plain JS objects when the object is serialized using
+ // JSON.stringify
+ if ( !isNode ) {
+ cache[ id ].toJSON = jQuery.noop;
+ }
+ }
+
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
+ // shallow copied over onto the existing cache
+ if ( typeof name === "object" || typeof name === "function" ) {
+ if ( pvt ) {
+ cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
+ } else {
+ cache[ id ] = jQuery.extend(cache[ id ], name);
+ }
+ }
+
+ thisCache = cache[ id ];
+
+ // Internal jQuery data is stored in a separate object inside the object's data
+ // cache in order to avoid key collisions between internal data and user-defined
+ // data
+ if ( pvt ) {
+ if ( !thisCache[ internalKey ] ) {
+ thisCache[ internalKey ] = {};
+ }
+
+ thisCache = thisCache[ internalKey ];
+ }
+
+ if ( data !== undefined ) {
+ thisCache[ jQuery.camelCase( name ) ] = data;
+ }
+
+ // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
+ // not attempt to inspect the internal events object using jQuery.data, as this
+ // internal data object is undocumented and subject to change.
+ if ( name === "events" && !thisCache[name] ) {
+ return thisCache[ internalKey ] && thisCache[ internalKey ].events;
+ }
+
+ // Check for both converted-to-camel and non-converted data property names
+ // If a data property was specified
+ if ( getByName ) {
+
+ // First Try to find as-is property data
+ ret = thisCache[ name ];
+
+ // Test for null|undefined property data
+ if ( ret == null ) {
+
+ // Try to find the camelCased property
+ ret = thisCache[ jQuery.camelCase( name ) ];
+ }
+ } else {
+ ret = thisCache;
+ }
+
+ return ret;
+ },
+
+ removeData: function( elem, name, pvt /* Internal Use Only */ ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var thisCache,
+
+ // Reference to internal data cache key
+ internalKey = jQuery.expando,
+
+ isNode = elem.nodeType,
+
+ // See jQuery.data for more information
+ cache = isNode ? jQuery.cache : elem,
+
+ // See jQuery.data for more information
+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+ // If there is already no cache entry for this object, there is no
+ // purpose in continuing
+ if ( !cache[ id ] ) {
+ return;
+ }
+
+ if ( name ) {
+
+ thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
+
+ if ( thisCache ) {
+
+ // Support interoperable removal of hyphenated or camelcased keys
+ if ( !thisCache[ name ] ) {
+ name = jQuery.camelCase( name );
+ }
+
+ delete thisCache[ name ];
+
+ // If there is no data left in the cache, we want to continue
+ // and let the cache object itself get destroyed
+ if ( !isEmptyDataObject(thisCache) ) {
+ return;
+ }
+ }
+ }
+
+ // See jQuery.data for more information
+ if ( pvt ) {
+ delete cache[ id ][ internalKey ];
+
+ // Don't destroy the parent cache unless the internal data object
+ // had been the only thing left in it
+ if ( !isEmptyDataObject(cache[ id ]) ) {
+ return;
+ }
+ }
+
+ var internalCache = cache[ id ][ internalKey ];
+
+ // Browsers that fail expando deletion also refuse to delete expandos on
+ // the window, but it will allow it on all other JS objects; other browsers
+ // don't care
+ // Ensure that `cache` is not a window object #10080
+ if ( jQuery.support.deleteExpando || !cache.setInterval ) {
+ delete cache[ id ];
+ } else {
+ cache[ id ] = null;
+ }
+
+ // We destroyed the entire user cache at once because it's faster than
+ // iterating through each key, but we need to continue to persist internal
+ // data if it existed
+ if ( internalCache ) {
+ cache[ id ] = {};
+ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+ // metadata on plain JS objects when the object is serialized using
+ // JSON.stringify
+ if ( !isNode ) {
+ cache[ id ].toJSON = jQuery.noop;
+ }
+
+ cache[ id ][ internalKey ] = internalCache;
+
+ // Otherwise, we need to eliminate the expando on the node to avoid
+ // false lookups in the cache for entries that no longer exist
+ } else if ( isNode ) {
+ // IE does not allow us to delete expando properties from nodes,
+ // nor does it have a removeAttribute function on Document nodes;
+ // we must handle all of these cases
+ if ( jQuery.support.deleteExpando ) {
+ delete elem[ jQuery.expando ];
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ } else {
+ elem[ jQuery.expando ] = null;
+ }
+ }
+ },
+
+ // For internal use only.
+ _data: function( elem, name, data ) {
+ return jQuery.data( elem, name, data, true );
+ },
+
+ // A method for determining if a DOM node can handle the data expando
+ acceptData: function( elem ) {
+ if ( elem.nodeName ) {
+ var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+ if ( match ) {
+ return !(match === true || elem.getAttribute("classid") !== match);
+ }
+ }
+
+ return true;
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ var data = null;
+
+ if ( typeof key === "undefined" ) {
+ if ( this.length ) {
+ data = jQuery.data( this[0] );
+
+ if ( this[0].nodeType === 1 ) {
+ var attr = this[0].attributes, name;
+ for ( var i = 0, l = attr.length; i < l; i++ ) {
+ name = attr[i].name;
+
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = jQuery.camelCase( name.substring(5) );
+
+ dataAttr( this[0], name, data[ name ] );
+ }
+ }
+ }
+ }
+
+ return data;
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ // Try to fetch any internally stored data first
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ data = dataAttr( this[0], key, data );
+ }
+
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+
+ } else {
+ return this.each(function() {
+ var $this = jQuery( this ),
+ args = [ parts[0], value ];
+
+ $this.triggerHandler( "setData" + parts[1] + "!", args );
+ jQuery.data( this, key, value );
+ $this.triggerHandler( "changeData" + parts[1] + "!", args );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+
+function dataAttr( elem, key, data ) {
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+
+ var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = data === "true" ? true :
+ data === "false" ? false :
+ data === "null" ? null :
+ !jQuery.isNaN( data ) ? parseFloat( data ) :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
+ } catch( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ jQuery.data( elem, key, data );
+
+ } else {
+ data = undefined;
+ }
+ }
+
+ return data;
+}
+
+// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
+// property to be considered empty objects; this property always exists in
+// order to make sure JSON.stringify does not expose internal metadata
+function isEmptyDataObject( obj ) {
+ for ( var name in obj ) {
+ if ( name !== "toJSON" ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+
+function handleQueueMarkDefer( elem, type, src ) {
+ var deferDataKey = type + "defer",
+ queueDataKey = type + "queue",
+ markDataKey = type + "mark",
+ defer = jQuery.data( elem, deferDataKey, undefined, true );
+ if ( defer &&
+ ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
+ ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
+ // Give room for hard-coded callbacks to fire first
+ // and eventually mark/queue something else on the element
+ setTimeout( function() {
+ if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
+ !jQuery.data( elem, markDataKey, undefined, true ) ) {
+ jQuery.removeData( elem, deferDataKey, true );
+ defer.resolve();
+ }
+ }, 0 );
+ }
+}
+
+jQuery.extend({
+
+ _mark: function( elem, type ) {
+ if ( elem ) {
+ type = (type || "fx") + "mark";
+ jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
+ }
+ },
+
+ _unmark: function( force, elem, type ) {
+ if ( force !== true ) {
+ type = elem;
+ elem = force;
+ force = false;
+ }
+ if ( elem ) {
+ type = type || "fx";
+ var key = type + "mark",
+ count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
+ if ( count ) {
+ jQuery.data( elem, key, count, true );
+ } else {
+ jQuery.removeData( elem, key, true );
+ handleQueueMarkDefer( elem, type, "mark" );
+ }
+ }
+ },
+
+ queue: function( elem, type, data ) {
+ if ( elem ) {
+ type = (type || "fx") + "queue";
+ var q = jQuery.data( elem, type, undefined, true );
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery.data( elem, type, jQuery.makeArray(data), true );
+ } else {
+ q.push( data );
+ }
+ }
+ return q || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ fn = queue.shift(),
+ defer;
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift("inprogress");
+ }
+
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ });
+ }
+
+ if ( !queue.length ) {
+ jQuery.removeData( elem, type + "queue", true );
+ handleQueueMarkDefer( elem, type, "queue" );
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function() {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function() {
+ var elem = this;
+ setTimeout(function() {
+ jQuery.dequeue( elem, type );
+ }, time );
+ });
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, object ) {
+ if ( typeof type !== "string" ) {
+ object = type;
+ type = undefined;
+ }
+ type = type || "fx";
+ var defer = jQuery.Deferred(),
+ elements = this,
+ i = elements.length,
+ count = 1,
+ deferDataKey = type + "defer",
+ queueDataKey = type + "queue",
+ markDataKey = type + "mark",
+ tmp;
+ function resolve() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ }
+ while( i-- ) {
+ if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
+ ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
+ jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
+ jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
+ count++;
+ tmp.done( resolve );
+ }
+ }
+ resolve();
+ return defer.promise();
+ }
+});
+
+
+
+
+var rclass = /[\n\t\r]/g,
+ rspace = /\s+/,
+ rreturn = /\r/g,
+ rtype = /^(?:button|input)$/i,
+ rfocusable = /^(?:button|input|object|select|textarea)$/i,
+ rclickable = /^a(?:rea)?$/i,
+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
+ nodeHook, boolHook;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name ) {
+ return this.each(function() {
+ jQuery.removeAttr( this, name );
+ });
+ },
+
+ prop: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.prop );
+ },
+
+ removeProp: function( name ) {
+ name = jQuery.propFix[ name ] || name;
+ return this.each(function() {
+ // try/catch handles cases where IE balks (such as removing a property on window)
+ try {
+ this[ name ] = undefined;
+ delete this[ name ];
+ } catch( e ) {}
+ });
+ },
+
+ addClass: function( value ) {
+ var classNames, i, l, elem,
+ setClass, c, cl;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( j ) {
+ jQuery( this ).addClass( value.call(this, j, this.className) );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ classNames = value.split( rspace );
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ elem = this[ i ];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className && classNames.length === 1 ) {
+ elem.className = value;
+
+ } else {
+ setClass = " " + elem.className + " ";
+
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
+ setClass += classNames[ c ] + " ";
+ }
+ }
+ elem.className = jQuery.trim( setClass );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ var classNames, i, l, elem, className, c, cl;
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( j ) {
+ jQuery( this ).removeClass( value.call(this, j, this.className) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ classNames = (value || "").split( rspace );
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ elem = this[ i ];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ className = (" " + elem.className + " ").replace( rclass, " " );
+ for ( c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[ c ] + " ", " ");
+ }
+ elem.className = jQuery.trim( className );
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value,
+ isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function( i ) {
+ jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className,
+ i = 0,
+ self = jQuery( this ),
+ state = stateVal,
+ classNames = value.split( rspace );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery._data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ";
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ var hooks, ret,
+ elem = this[0];
+
+ if ( !arguments.length ) {
+ if ( elem ) {
+ hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
+
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+ return ret;
+ }
+
+ ret = elem.value;
+
+ return typeof ret === "string" ?
+ // handle most common string cases
+ ret.replace(rreturn, "") :
+ // handle cases where value is null/undef or number
+ ret == null ? "" : ret;
+ }
+
+ return undefined;
+ }
+
+ var isFunction = jQuery.isFunction( value );
+
+ return this.each(function( i ) {
+ var self = jQuery(this), val;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call( this, i, self.val() );
+ } else {
+ val = value;
+ }
+
+ // Treat null/undefined as ""; convert numbers to string
+ if ( val == null ) {
+ val = "";
+ } else if ( typeof val === "number" ) {
+ val += "";
+ } else if ( jQuery.isArray( val ) ) {
+ val = jQuery.map(val, function ( value ) {
+ return value == null ? "" : value + "";
+ });
+ }
+
+ hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
+
+ // If set returns undefined, fall back to normal setting
+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ valHooks: {
+ option: {
+ get: function( elem ) {
+ // attributes.value is undefined in Blackberry 4.7 but
+ // uses .value. See #6932
+ var val = elem.attributes.value;
+ return !val || val.specified ? elem.value : elem.text;
+ }
+ },
+ select: {
+ get: function( elem ) {
+ var value,
+ index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ // Don't return options that are disabled or in a disabled optgroup
+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+ (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+ // Get the specific value for the option
+ value = jQuery( option ).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
+ if ( one && !values.length && options.length ) {
+ return jQuery( options[ index ] ).val();
+ }
+
+ return values;
+ },
+
+ set: function( elem, value ) {
+ var values = jQuery.makeArray( value );
+
+ jQuery(elem).find("option").each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ elem.selectedIndex = -1;
+ }
+ return values;
+ }
+ }
+ },
+
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attrFix: {
+ // Always normalize to ensure hook usage
+ tabindex: "tabIndex"
+ },
+
+ attr: function( elem, name, value, pass ) {
+ var nType = elem.nodeType;
+
+ // don't get/set attributes on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return undefined;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery( elem )[ name ]( value );
+ }
+
+ // Fallback to prop when attributes are not supported
+ if ( !("getAttribute" in elem) ) {
+ return jQuery.prop( elem, name, value );
+ }
+
+ var ret, hooks,
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ // Normalize the name if needed
+ if ( notxml ) {
+ name = jQuery.attrFix[ name ] || name;
+
+ hooks = jQuery.attrHooks[ name ];
+
+ if ( !hooks ) {
+ // Use boolHook for boolean attributes
+ if ( rboolean.test( name ) ) {
+ hooks = boolHook;
+
+ // Use nodeHook if available( IE6/7 )
+ } else if ( nodeHook ) {
+ hooks = nodeHook;
+ }
+ }
+ }
+
+ if ( value !== undefined ) {
+
+ if ( value === null ) {
+ jQuery.removeAttr( elem, name );
+ return undefined;
+
+ } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ elem.setAttribute( name, "" + value );
+ return value;
+ }
+
+ } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
+ return ret;
+
+ } else {
+
+ ret = elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return ret === null ?
+ undefined :
+ ret;
+ }
+ },
+
+ removeAttr: function( elem, name ) {
+ var propName;
+ if ( elem.nodeType === 1 ) {
+ name = jQuery.attrFix[ name ] || name;
+
+ jQuery.attr( elem, name, "" );
+ elem.removeAttribute( name );
+
+ // Set corresponding property to false for boolean attributes
+ if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
+ elem[ propName ] = false;
+ }
+ }
+ },
+
+ attrHooks: {
+ type: {
+ set: function( elem, value ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+ // Setting the type on a radio button after the value resets the value in IE6-9
+ // Reset value to it's default in case type is set after value
+ // This is for element creation
+ var val = elem.value;
+ elem.setAttribute( "type", value );
+ if ( val ) {
+ elem.value = val;
+ }
+ return value;
+ }
+ }
+ },
+ // Use the value property for back compat
+ // Use the nodeHook for button elements in IE6/7 (#1954)
+ value: {
+ get: function( elem, name ) {
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
+ return nodeHook.get( elem, name );
+ }
+ return name in elem ?
+ elem.value :
+ null;
+ },
+ set: function( elem, value, name ) {
+ if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
+ return nodeHook.set( elem, value, name );
+ }
+ // Does not return so that setAttribute is also used
+ elem.value = value;
+ }
+ }
+ },
+
+ propFix: {
+ tabindex: "tabIndex",
+ readonly: "readOnly",
+ "for": "htmlFor",
+ "class": "className",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ cellpadding: "cellPadding",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ usemap: "useMap",
+ frameborder: "frameBorder",
+ contenteditable: "contentEditable"
+ },
+
+ prop: function( elem, name, value ) {
+ var nType = elem.nodeType;
+
+ // don't get/set properties on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return undefined;
+ }
+
+ var ret, hooks,
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ if ( notxml ) {
+ // Fix name and attach hooks
+ name = jQuery.propFix[ name ] || name;
+ hooks = jQuery.propHooks[ name ];
+ }
+
+ if ( value !== undefined ) {
+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ return (elem[ name ] = value);
+ }
+
+ } else {
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+ return ret;
+
+ } else {
+ return elem[ name ];
+ }
+ }
+ },
+
+ propHooks: {
+ tabIndex: {
+ get: function( elem ) {
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ var attributeNode = elem.getAttributeNode("tabindex");
+
+ return attributeNode && attributeNode.specified ?
+ parseInt( attributeNode.value, 10 ) :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+ }
+ }
+});
+
+// Add the tabindex propHook to attrHooks for back-compat
+jQuery.attrHooks.tabIndex = jQuery.propHooks.tabIndex;
+
+// Hook for boolean attributes
+boolHook = {
+ get: function( elem, name ) {
+ // Align boolean attributes with corresponding properties
+ // Fall back to attribute presence where some booleans are not supported
+ var attrNode;
+ return jQuery.prop( elem, name ) === true || ( attrNode = elem.getAttributeNode( name ) ) && attrNode.nodeValue !== false ?
+ name.toLowerCase() :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ var propName;
+ if ( value === false ) {
+ // Remove boolean attributes when set to false
+ jQuery.removeAttr( elem, name );
+ } else {
+ // value is true since we know at this point it's type boolean and not false
+ // Set boolean attributes to the same name and set the DOM property
+ propName = jQuery.propFix[ name ] || name;
+ if ( propName in elem ) {
+ // Only set the IDL specifically if it already exists on the element
+ elem[ propName ] = true;
+ }
+
+ elem.setAttribute( name, name.toLowerCase() );
+ }
+ return name;
+ }
+};
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !jQuery.support.getSetAttribute ) {
+
+ // Use this for any attribute in IE6/7
+ // This fixes almost every IE6/7 issue
+ nodeHook = jQuery.valHooks.button = {
+ get: function( elem, name ) {
+ var ret;
+ ret = elem.getAttributeNode( name );
+ // Return undefined if nodeValue is empty string
+ return ret && ret.nodeValue !== "" ?
+ ret.nodeValue :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ // Set the existing or create a new attribute node
+ var ret = elem.getAttributeNode( name );
+ if ( !ret ) {
+ ret = document.createAttribute( name );
+ elem.setAttributeNode( ret );
+ }
+ return (ret.nodeValue = value + "");
+ }
+ };
+
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+ // This is for removals
+ jQuery.each([ "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ set: function( elem, value ) {
+ if ( value === "" ) {
+ elem.setAttribute( name, "auto" );
+ return value;
+ }
+ }
+ });
+ });
+}
+
+
+// Some attributes require a special call on IE
+if ( !jQuery.support.hrefNormalized ) {
+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ get: function( elem ) {
+ var ret = elem.getAttribute( name, 2 );
+ return ret === null ? undefined : ret;
+ }
+ });
+ });
+}
+
+if ( !jQuery.support.style ) {
+ jQuery.attrHooks.style = {
+ get: function( elem ) {
+ // Return undefined in the case of empty string
+ // Normalize to lowercase since IE uppercases css property names
+ return elem.style.cssText.toLowerCase() || undefined;
+ },
+ set: function( elem, value ) {
+ return (elem.style.cssText = "" + value);
+ }
+ };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+ get: function( elem ) {
+ var parent = elem.parentNode;
+
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ return null;
+ }
+ });
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+ jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = {
+ get: function( elem ) {
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+ };
+ });
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+ set: function( elem, value ) {
+ if ( jQuery.isArray( value ) ) {
+ return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
+ }
+ }
+ });
+});
+
+
+
+
+var rnamespaces = /\.(.*)$/,
+ rformElems = /^(?:textarea|input|select)$/i,
+ rperiod = /\./g,
+ rspaces = / /g,
+ rescape = /[^\w\s.|`]/g,
+ fcleanup = function( nm ) {
+ return nm.replace(rescape, "\\$&");
+ };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function( elem, types, handler, data ) {
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ if ( handler === false ) {
+ handler = returnFalse;
+ } else if ( !handler ) {
+ // Fixes bug #7229. Fix recommended by jdalton
+ return;
+ }
+
+ var handleObjIn, handleObj;
+
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ }
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure
+ var elemData = jQuery._data( elem );
+
+ // If no elemData is found then we must be trying to bind to one of the
+ // banned noData elements
+ if ( !elemData ) {
+ return;
+ }
+
+ var events = elemData.events,
+ eventHandle = elemData.handle;
+
+ if ( !events ) {
+ elemData.events = events = {};
+ }
+
+ if ( !eventHandle ) {
+ elemData.handle = eventHandle = function( e ) {
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+ }
+
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native events in IE.
+ eventHandle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ var type, i = 0, namespaces;
+
+ while ( (type = types[ i++ ]) ) {
+ handleObj = handleObjIn ?
+ jQuery.extend({}, handleObjIn) :
+ { handler: handler, data: data };
+
+ // Namespaced event handlers
+ if ( type.indexOf(".") > -1 ) {
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+ } else {
+ namespaces = [];
+ handleObj.namespace = "";
+ }
+
+ handleObj.type = type;
+ if ( !handleObj.guid ) {
+ handleObj.guid = handler.guid;
+ }
+
+ // Get the current list of functions bound to this event
+ var handlers = events[ type ],
+ special = jQuery.event.special[ type ] || {};
+
+ // Init the event handler queue
+ if ( !handlers ) {
+ handlers = events[ type ] = [];
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers.push( handleObj );
+
+ // Keep track of which events have been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, pos ) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ if ( handler === false ) {
+ handler = returnFalse;
+ }
+
+ var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
+ events = elemData && elemData.events;
+
+ if ( !elemData || !events ) {
+ return;
+ }
+
+ // types is actually an event object here
+ if ( types && types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Unbind all events for the element
+ if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+ types = types || "";
+
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types );
+ }
+
+ return;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ while ( (type = types[ i++ ]) ) {
+ origType = type;
+ handleObj = null;
+ all = type.indexOf(".") < 0;
+ namespaces = [];
+
+ if ( !all ) {
+ // Namespaced event handlers
+ namespaces = type.split(".");
+ type = namespaces.shift();
+
+ namespace = new RegExp("(^|\\.)" +
+ jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ eventType = events[ type ];
+
+ if ( !eventType ) {
+ continue;
+ }
+
+ if ( !handler ) {
+ for ( j = 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ jQuery.event.remove( elem, origType, handleObj.handler, j );
+ eventType.splice( j--, 1 );
+ }
+ }
+
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+
+ for ( j = pos || 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( handler.guid === handleObj.guid ) {
+ // remove the given handler for the given type
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ if ( pos == null ) {
+ eventType.splice( j--, 1 );
+ }
+
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+
+ if ( pos != null ) {
+ break;
+ }
+ }
+ }
+
+ // remove generic event handler if no more handlers exist
+ if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ ret = null;
+ delete events[ type ];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ var handle = elemData.handle;
+ if ( handle ) {
+ handle.elem = null;
+ }
+
+ delete elemData.events;
+ delete elemData.handle;
+
+ if ( jQuery.isEmptyObject( elemData ) ) {
+ jQuery.removeData( elem, undefined, true );
+ }
+ }
+ },
+
+ // Events that are safe to short-circuit if no handlers are attached.
+ // Native DOM events should not be added, they may have inline handlers.
+ customEvent: {
+ "getData": true,
+ "setData": true,
+ "changeData": true
+ },
+
+ trigger: function( event, data, elem, onlyHandlers ) {
+ // Event object or event type
+ var type = event.type || event,
+ namespaces = [],
+ exclusive;
+
+ if ( type.indexOf("!") >= 0 ) {
+ // Exclusive events trigger only for the exact event (no namespaces)
+ type = type.slice(0, -1);
+ exclusive = true;
+ }
+
+ if ( type.indexOf(".") >= 0 ) {
+ // Namespaced trigger; create a regexp to match event type in handle()
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ namespaces.sort();
+ }
+
+ if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
+ // No jQuery handlers for this event type, and it can't have inline handlers
+ return;
+ }
+
+ // Caller can pass in an Event, Object, or just an event type string
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[ jQuery.expando ] ? event :
+ // Object literal
+ new jQuery.Event( type, event ) :
+ // Just the event type (string)
+ new jQuery.Event( type );
+
+ event.type = type;
+ event.exclusive = exclusive;
+ event.namespace = namespaces.join(".");
+ event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
+
+ // triggerHandler() and global events don't bubble or run the default action
+ if ( onlyHandlers || !elem ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // TODO: Stop taunting the data cache; remove global events and always attach to document
+ jQuery.each( jQuery.cache, function() {
+ // internalKey variable is just used to make it easier to find
+ // and potentially change this stuff later; currently it just
+ // points to jQuery.expando
+ var internalKey = jQuery.expando,
+ internalCache = this[ internalKey ];
+ if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
+ jQuery.event.trigger( event, data, internalCache.handle.elem );
+ }
+ });
+ return;
+ }
+
+ // Don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // Clean up the event in case it is being reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone any incoming data and prepend the event, creating the handler arg list
+ data = data != null ? jQuery.makeArray( data ) : [];
+ data.unshift( event );
+
+ var cur = elem,
+ // IE doesn't like method names with a colon (#3533, #8272)
+ ontype = type.indexOf(":") < 0 ? "on" + type : "";
+
+ // Fire event on the current element, then bubble up the DOM tree
+ do {
+ var handle = jQuery._data( cur, "handle" );
+
+ event.currentTarget = cur;
+ if ( handle ) {
+ handle.apply( cur, data );
+ }
+
+ // Trigger an inline bound script
+ if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
+ event.result = false;
+ event.preventDefault();
+ }
+
+ // Bubble up to document, then to window
+ cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
+ } while ( cur && !event.isPropagationStopped() );
+
+ // If nobody prevented the default action, do it now
+ if ( !event.isDefaultPrevented() ) {
+ var old,
+ special = jQuery.event.special[ type ] || {};
+
+ if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
+ !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
+
+ // Call a native DOM method on the target with the same name name as the event.
+ // Can't use an .isFunction)() check here because IE6/7 fails that test.
+ // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
+ try {
+ if ( ontype && elem[ type ] ) {
+ // Don't re-trigger an onFOO event when we call its FOO() method
+ old = elem[ ontype ];
+
+ if ( old ) {
+ elem[ ontype ] = null;
+ }
+
+ jQuery.event.triggered = type;
+ elem[ type ]();
+ }
+ } catch ( ieError ) {}
+
+ if ( old ) {
+ elem[ ontype ] = old;
+ }
+
+ jQuery.event.triggered = undefined;
+ }
+ }
+
+ return event.result;
+ },
+
+ handle: function( event ) {
+ event = jQuery.event.fix( event || window.event );
+ // Snapshot the handlers list since a called handler may add/remove events.
+ var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
+ run_all = !event.exclusive && !event.namespace,
+ args = Array.prototype.slice.call( arguments, 0 );
+
+ // Use the fix-ed Event rather than the (read-only) native event
+ args[0] = event;
+ event.currentTarget = this;
+
+ for ( var j = 0, l = handlers.length; j < l; j++ ) {
+ var handleObj = handlers[ j ];
+
+ // Triggered event must 1) be non-exclusive and have no namespace, or
+ // 2) have namespace(s) a subset or equal to those in the bound event.
+ if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handleObj.handler;
+ event.data = handleObj.data;
+ event.handleObj = handleObj;
+
+ var ret = handleObj.handler.apply( this, args );
+
+ if ( ret !== undefined ) {
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+ return event.result;
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function( event ) {
+ if ( event[ jQuery.expando ] ) {
+ return event;
+ }
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ) {
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target ) {
+ // Fixes #1925 where srcElement might not be defined either
+ event.target = event.srcElement || document;
+ }
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement ) {
+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+ }
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var eventDocument = event.target.ownerDocument || document,
+ doc = eventDocument.documentElement,
+ body = eventDocument.body;
+
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
+ event.which = event.charCode != null ? event.charCode : event.keyCode;
+ }
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button !== undefined ) {
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+ }
+
+ return event;
+ },
+
+ // Deprecated, use jQuery.guid instead
+ guid: 1E8,
+
+ // Deprecated, use jQuery.proxy instead
+ proxy: jQuery.proxy,
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: jQuery.bindReady,
+ teardown: jQuery.noop
+ },
+
+ live: {
+ add: function( handleObj ) {
+ jQuery.event.add( this,
+ liveConvert( handleObj.origType, handleObj.selector ),
+ jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
+ },
+
+ remove: function( handleObj ) {
+ jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
+ }
+ },
+
+ beforeunload: {
+ setup: function( data, namespaces, eventHandle ) {
+ // We only want to do this special case on windows
+ if ( jQuery.isWindow( this ) ) {
+ this.onbeforeunload = eventHandle;
+ }
+ },
+
+ teardown: function( namespaces, eventHandle ) {
+ if ( this.onbeforeunload === eventHandle ) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ }
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle, false );
+ }
+ } :
+ function( elem, type, handle ) {
+ if ( elem.detachEvent ) {
+ elem.detachEvent( "on" + type, handle );
+ }
+ };
+
+jQuery.Event = function( src, props ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !this.preventDefault ) {
+ return new jQuery.Event( src, props );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
+ src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if ( props ) {
+ jQuery.extend( this, props );
+ }
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = jQuery.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+ return false;
+}
+function returnTrue() {
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+
+ // otherwise set the returnValue property of the original event to false (IE)
+ } else {
+ e.returnValue = false;
+ }
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+
+ // Check if mouse(over|out) are still within the same parent element
+ var related = event.relatedTarget,
+ inside = false,
+ eventType = event.type;
+
+ event.type = event.data;
+
+ if ( related !== this ) {
+
+ if ( related ) {
+ inside = jQuery.contains( this, related );
+ }
+
+ if ( !inside ) {
+
+ jQuery.event.handle.apply( this, arguments );
+
+ event.type = eventType;
+ }
+ }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+ event.type = event.data;
+ jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ setup: function( data ) {
+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+ },
+ teardown: function( data ) {
+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+ }
+ };
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+ jQuery.event.special.submit = {
+ setup: function( data, namespaces ) {
+ if ( !jQuery.nodeName( this, "form" ) ) {
+ jQuery.event.add(this, "click.specialSubmit", function( e ) {
+ // Avoid triggering error on non-existent type attribute in IE VML (#7071)
+ var elem = e.target,
+ type = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.type : "";
+
+ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+ trigger( "submit", this, arguments );
+ }
+ });
+
+ jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+ var elem = e.target,
+ type = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.type : "";
+
+ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+ trigger( "submit", this, arguments );
+ }
+ });
+
+ } else {
+ return false;
+ }
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialSubmit" );
+ }
+ };
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+ var changeFilters,
+
+ getVal = function( elem ) {
+ var type = jQuery.nodeName( elem, "input" ) ? elem.type : "",
+ val = elem.value;
+
+ if ( type === "radio" || type === "checkbox" ) {
+ val = elem.checked;
+
+ } else if ( type === "select-multiple" ) {
+ val = elem.selectedIndex > -1 ?
+ jQuery.map( elem.options, function( elem ) {
+ return elem.selected;
+ }).join("-") :
+ "";
+
+ } else if ( jQuery.nodeName( elem, "select" ) ) {
+ val = elem.selectedIndex;
+ }
+
+ return val;
+ },
+
+ testChange = function testChange( e ) {
+ var elem = e.target, data, val;
+
+ if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
+ return;
+ }
+
+ data = jQuery._data( elem, "_change_data" );
+ val = getVal(elem);
+
+ // the current data will be also retrieved by beforeactivate
+ if ( e.type !== "focusout" || elem.type !== "radio" ) {
+ jQuery._data( elem, "_change_data", val );
+ }
+
+ if ( data === undefined || val === data ) {
+ return;
+ }
+
+ if ( data != null || val ) {
+ e.type = "change";
+ e.liveFired = undefined;
+ jQuery.event.trigger( e, arguments[1], elem );
+ }
+ };
+
+ jQuery.event.special.change = {
+ filters: {
+ focusout: testChange,
+
+ beforedeactivate: testChange,
+
+ click: function( e ) {
+ var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
+
+ if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
+ testChange.call( this, e );
+ }
+ },
+
+ // Change has to be called before submit
+ // Keydown will be called before keypress, which is used in submit-event delegation
+ keydown: function( e ) {
+ var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
+
+ if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+ type === "select-multiple" ) {
+ testChange.call( this, e );
+ }
+ },
+
+ // Beforeactivate happens also before the previous element is blurred
+ // with this event you can't trigger a change event, but you can store
+ // information
+ beforeactivate: function( e ) {
+ var elem = e.target;
+ jQuery._data( elem, "_change_data", getVal(elem) );
+ }
+ },
+
+ setup: function( data, namespaces ) {
+ if ( this.type === "file" ) {
+ return false;
+ }
+
+ for ( var type in changeFilters ) {
+ jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+ }
+
+ return rformElems.test( this.nodeName );
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialChange" );
+
+ return rformElems.test( this.nodeName );
+ }
+ };
+
+ changeFilters = jQuery.event.special.change.filters;
+
+ // Handle when the input is .focus()'d
+ changeFilters.focus = changeFilters.beforeactivate;
+}
+
+function trigger( type, elem, args ) {
+ // Piggyback on a donor event to simulate a different one.
+ // Fake originalEvent to avoid donor's stopPropagation, but if the
+ // simulated event prevents default then we do the same on the donor.
+ // Don't pass args or remember liveFired; they apply to the donor event.
+ var event = jQuery.extend( {}, args[ 0 ] );
+ event.type = type;
+ event.originalEvent = {};
+ event.liveFired = undefined;
+ jQuery.event.handle.call( elem, event );
+ if ( event.isDefaultPrevented() ) {
+ args[ 0 ].preventDefault();
+ }
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+ // Attach a single capturing handler while someone wants focusin/focusout
+ var attaches = 0;
+
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ if ( attaches++ === 0 ) {
+ document.addEventListener( orig, handler, true );
+ }
+ },
+ teardown: function() {
+ if ( --attaches === 0 ) {
+ document.removeEventListener( orig, handler, true );
+ }
+ }
+ };
+
+ function handler( donor ) {
+ // Donor event is always a native one; fix it and switch its type.
+ // Let focusin/out handler cancel the donor focus/blur event.
+ var e = jQuery.event.fix( donor );
+ e.type = fix;
+ e.originalEvent = {};
+ jQuery.event.trigger( e, null, e.target );
+ if ( e.isDefaultPrevented() ) {
+ donor.preventDefault();
+ }
+ }
+ });
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+ jQuery.fn[ name ] = function( type, data, fn ) {
+ var handler;
+
+ // Handle object literals
+ if ( typeof type === "object" ) {
+ for ( var key in type ) {
+ this[ name ](key, data, type[key], fn);
+ }
+ return this;
+ }
+
+ if ( arguments.length === 2 || data === false ) {
+ fn = data;
+ data = undefined;
+ }
+
+ if ( name === "one" ) {
+ handler = function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ };
+ handler.guid = fn.guid || jQuery.guid++;
+ } else {
+ handler = fn;
+ }
+
+ if ( type === "unload" && name !== "one" ) {
+ this.one( type, data, fn );
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.add( this[i], type, handler, data );
+ }
+ }
+
+ return this;
+ };
+});
+
+jQuery.fn.extend({
+ unbind: function( type, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" && !type.preventDefault ) {
+ for ( var key in type ) {
+ this.unbind(key, type[key]);
+ }
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.remove( this[i], type, fn );
+ }
+ }
+
+ return this;
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.live( types, data, fn, selector );
+ },
+
+ undelegate: function( selector, types, fn ) {
+ if ( arguments.length === 0 ) {
+ return this.unbind( "live" );
+
+ } else {
+ return this.die( types, null, fn, selector );
+ }
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if ( this[0] ) {
+ return jQuery.event.trigger( type, data, this[0], true );
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments,
+ guid = fn.guid || jQuery.guid++,
+ i = 0,
+ toggler = function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ };
+
+ // link all the functions, so any of them can unbind this click handler
+ toggler.guid = guid;
+ while ( i < args.length ) {
+ args[ i++ ].guid = guid;
+ }
+
+ return this.click( toggler );
+ },
+
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+});
+
+var liveMap = {
+ focus: "focusin",
+ blur: "focusout",
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+ jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+ var type, i = 0, match, namespaces, preType,
+ selector = origSelector || this.selector,
+ context = origSelector ? this : jQuery( this.context );
+
+ if ( typeof types === "object" && !types.preventDefault ) {
+ for ( var key in types ) {
+ context[ name ]( key, data, types[key], selector );
+ }
+
+ return this;
+ }
+
+ if ( name === "die" && !types &&
+ origSelector && origSelector.charAt(0) === "." ) {
+
+ context.unbind( origSelector );
+
+ return this;
+ }
+
+ if ( data === false || jQuery.isFunction( data ) ) {
+ fn = data || returnFalse;
+ data = undefined;
+ }
+
+ types = (types || "").split(" ");
+
+ while ( (type = types[ i++ ]) != null ) {
+ match = rnamespaces.exec( type );
+ namespaces = "";
+
+ if ( match ) {
+ namespaces = match[0];
+ type = type.replace( rnamespaces, "" );
+ }
+
+ if ( type === "hover" ) {
+ types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+ continue;
+ }
+
+ preType = type;
+
+ if ( liveMap[ type ] ) {
+ types.push( liveMap[ type ] + namespaces );
+ type = type + namespaces;
+
+ } else {
+ type = (liveMap[ type ] || type) + namespaces;
+ }
+
+ if ( name === "live" ) {
+ // bind live handler
+ for ( var j = 0, l = context.length; j < l; j++ ) {
+ jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
+ { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+ }
+
+ } else {
+ // unbind live handler
+ context.unbind( "live." + liveConvert( type, selector ), fn );
+ }
+ }
+
+ return this;
+ };
+});
+
+function liveHandler( event ) {
+ var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
+ elems = [],
+ selectors = [],
+ events = jQuery._data( this, "events" );
+
+ // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
+ if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
+ return;
+ }
+
+ if ( event.namespace ) {
+ namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ event.liveFired = this;
+
+ var live = events.live.slice(0);
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+ selectors.push( handleObj.selector );
+
+ } else {
+ live.splice( j--, 1 );
+ }
+ }
+
+ match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+ for ( i = 0, l = match.length; i < l; i++ ) {
+ close = match[i];
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
+ elem = close.elem;
+ related = null;
+
+ // Those two events require additional checking
+ if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+ event.type = handleObj.preType;
+ related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+
+ // Make sure not to accidentally match a child element with the same selector
+ if ( related && jQuery.contains( elem, related ) ) {
+ related = elem;
+ }
+ }
+
+ if ( !related || related !== elem ) {
+ elems.push({ elem: elem, handleObj: handleObj, level: close.level });
+ }
+ }
+ }
+ }
+
+ for ( i = 0, l = elems.length; i < l; i++ ) {
+ match = elems[i];
+
+ if ( maxLevel && match.level > maxLevel ) {
+ break;
+ }
+
+ event.currentTarget = match.elem;
+ event.data = match.handleObj.data;
+ event.handleObj = match.handleObj;
+
+ ret = match.handleObj.origHandler.apply( match.elem, arguments );
+
+ if ( ret === false || event.isPropagationStopped() ) {
+ maxLevel = match.level;
+
+ if ( ret === false ) {
+ stop = false;
+ }
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+
+ return stop;
+}
+
+function liveConvert( type, selector ) {
+ return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( data, fn ) {
+ if ( fn == null ) {
+ fn = data;
+ data = null;
+ }
+
+ return arguments.length > 0 ?
+ this.bind( name, data, fn ) :
+ this.trigger( name );
+ };
+
+ if ( jQuery.attrFn ) {
+ jQuery.attrFn[ name ] = true;
+ }
+});
+
+
+
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true,
+ rBackslash = /\\/g,
+ rNonWord = /\W/;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function() {
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function( selector, context, results, seed ) {
+ results = results || [];
+ context = context || document;
+
+ var origContext = context;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var m, set, checkSet, extra, ret, cur, pop, i,
+ prune = true,
+ contextXML = Sizzle.isXML( context ),
+ parts = [],
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ do {
+ chunker.exec( "" );
+ m = chunker.exec( soFar );
+
+ if ( m ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+ } while ( m );
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] ) {
+ selector += parts.shift();
+ }
+
+ set = posProcess( selector, set );
+ }
+ }
+
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+
+ ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set )[0] :
+ ret.set[0];
+ }
+
+ if ( context ) {
+ ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+
+ set = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set ) :
+ ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray( set );
+
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ cur = parts.pop();
+ pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ Sizzle.error( cur || selector );
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+
+ } else if ( context && context.nodeType === 1 ) {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+
+ } else {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function( results ) {
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[ i - 1 ] ) {
+ results.splice( i--, 1 );
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function( expr, set ) {
+ return Sizzle( expr, null, null, set );
+};
+
+Sizzle.matchesSelector = function( node, expr ) {
+ return Sizzle( expr, null, null, [node] ).length > 0;
+};
+
+Sizzle.find = function( expr, context, isXML ) {
+ var set;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var match,
+ type = Expr.order[i];
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice( 1, 1 );
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace( rBackslash, "" );
+ set = Expr.find[ type ]( match, context, isXML );
+
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = typeof context.getElementsByTagName !== "undefined" ?
+ context.getElementsByTagName( "*" ) :
+ [];
+ }
+
+ return { set: set, expr: expr };
+};
+
+Sizzle.filter = function( expr, set, inplace, not ) {
+ var match, anyFound,
+ old = expr,
+ result = [],
+ curLoop = set,
+ isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+ var found, item,
+ filter = Expr.filter[ type ],
+ left = match[1];
+
+ anyFound = false;
+
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) === "\\" ) {
+ continue;
+ }
+
+ if ( curLoop === result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+
+ } else {
+ curLoop[i] = false;
+ }
+
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr === old ) {
+ if ( anyFound == null ) {
+ Sizzle.error( expr );
+
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+ throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+ },
+
+ leftMatch: {},
+
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+
+ attrHandle: {
+ href: function( elem ) {
+ return elem.getAttribute( "href" );
+ },
+ type: function( elem ) {
+ return elem.getAttribute( "type" );
+ }
+ },
+
+ relative: {
+ "+": function(checkSet, part){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !rNonWord.test( part ),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag ) {
+ part = part.toLowerCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+
+ ">": function( checkSet, part ) {
+ var elem,
+ isPartStr = typeof part === "string",
+ i = 0,
+ l = checkSet.length;
+
+ if ( isPartStr && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+ }
+ }
+
+ } else {
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+
+ "": function(checkSet, part, isXML){
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
+ },
+
+ "~": function( checkSet, part, isXML ) {
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
+ }
+ },
+
+ find: {
+ ID: function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ },
+
+ NAME: function( match, context ) {
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [],
+ results = context.getElementsByName( match[1] );
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+
+ TAG: function( match, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( match[1] );
+ }
+ }
+ },
+ preFilter: {
+ CLASS: function( match, curLoop, inplace, result, not, isXML ) {
+ match = " " + match[1].replace( rBackslash, "" ) + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
+ if ( !inplace ) {
+ result.push( elem );
+ }
+
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ ID: function( match ) {
+ return match[1].replace( rBackslash, "" );
+ },
+
+ TAG: function( match, curLoop ) {
+ return match[1].replace( rBackslash, "" ).toLowerCase();
+ },
+
+ CHILD: function( match ) {
+ if ( match[1] === "nth" ) {
+ if ( !match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ match[2] = match[2].replace(/^\+|\s*/g, '');
+
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+ else if ( match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+
+ ATTR: function( match, curLoop, inplace, result, not, isXML ) {
+ var name = match[1] = match[1].replace( rBackslash, "" );
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ // Handle if an un-quoted value was used
+ match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+
+ PSEUDO: function( match, curLoop, inplace, result, not ) {
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+
+ return false;
+ }
+
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+
+ POS: function( match ) {
+ match.unshift( true );
+
+ return match;
+ }
+ },
+
+ filters: {
+ enabled: function( elem ) {
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+
+ disabled: function( elem ) {
+ return elem.disabled === true;
+ },
+
+ checked: function( elem ) {
+ return elem.checked === true;
+ },
+
+ selected: function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ parent: function( elem ) {
+ return !!elem.firstChild;
+ },
+
+ empty: function( elem ) {
+ return !elem.firstChild;
+ },
+
+ has: function( elem, i, match ) {
+ return !!Sizzle( match[3], elem ).length;
+ },
+
+ header: function( elem ) {
+ return (/h\d/i).test( elem.nodeName );
+ },
+
+ text: function( elem ) {
+ var attr = elem.getAttribute( "type" ), type = elem.type;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
+ },
+
+ radio: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
+ },
+
+ checkbox: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
+ },
+
+ file: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
+ },
+
+ password: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
+ },
+
+ submit: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && "submit" === elem.type;
+ },
+
+ image: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
+ },
+
+ reset: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && "reset" === elem.type;
+ },
+
+ button: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && "button" === elem.type || name === "button";
+ },
+
+ input: function( elem ) {
+ return (/input|select|textarea|button/i).test( elem.nodeName );
+ },
+
+ focus: function( elem ) {
+ return elem === elem.ownerDocument.activeElement;
+ }
+ },
+ setFilters: {
+ first: function( elem, i ) {
+ return i === 0;
+ },
+
+ last: function( elem, i, match, array ) {
+ return i === array.length - 1;
+ },
+
+ even: function( elem, i ) {
+ return i % 2 === 0;
+ },
+
+ odd: function( elem, i ) {
+ return i % 2 === 1;
+ },
+
+ lt: function( elem, i, match ) {
+ return i < match[3] - 0;
+ },
+
+ gt: function( elem, i, match ) {
+ return i > match[3] - 0;
+ },
+
+ nth: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ },
+
+ eq: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ }
+ },
+ filter: {
+ PSEUDO: function( elem, match, i, array ) {
+ var name = match[1],
+ filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
+
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var j = 0, l = not.length; j < l; j++ ) {
+ if ( not[j] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ } else {
+ Sizzle.error( name );
+ }
+ },
+
+ CHILD: function( elem, match ) {
+ var type = match[1],
+ node = elem;
+
+ switch ( type ) {
+ case "only":
+ case "first":
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ if ( type === "first" ) {
+ return true;
+ }
+
+ node = elem;
+
+ case "last":
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ case "nth":
+ var first = match[2],
+ last = match[3];
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+
+ if ( first === 0 ) {
+ return diff === 0;
+
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ }
+ },
+
+ ID: function( elem, match ) {
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+
+ TAG: function( elem, match ) {
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+ },
+
+ CLASS: function( elem, match ) {
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+
+ ATTR: function( elem, match ) {
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value !== check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+
+ POS: function( elem, match, i, array ) {
+ var name = match[2],
+ filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS,
+ fescape = function(all, num){
+ return "\\" + (num - 0 + 1);
+ };
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
+}
+
+var makeArray = function( array, results ) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch( e ) {
+ makeArray = function( array, results ) {
+ var i = 0,
+ ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+
+ } else {
+ for ( ; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder, siblingCheck;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+ };
+
+} else {
+ sortOrder = function( a, b ) {
+ // The nodes are identical, we can exit early
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
+ } else if ( a.sourceIndex && b.sourceIndex ) {
+ return a.sourceIndex - b.sourceIndex;
+ }
+
+ var al, bl,
+ ap = [],
+ bp = [],
+ aup = a.parentNode,
+ bup = b.parentNode,
+ cur = aup;
+
+ // If the nodes are siblings (or identical) we can do a quick check
+ if ( aup === bup ) {
+ return siblingCheck( a, b );
+
+ // If no parents were found then the nodes are disconnected
+ } else if ( !aup ) {
+ return -1;
+
+ } else if ( !bup ) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while ( cur ) {
+ ap.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while ( cur ) {
+ bp.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for ( var i = 0; i < al && i < bl; i++ ) {
+ if ( ap[i] !== bp[i] ) {
+ return siblingCheck( ap[i], bp[i] );
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ?
+ siblingCheck( a, bp[i], -1 ) :
+ siblingCheck( ap[i], b, 1 );
+ };
+
+ siblingCheck = function( a, b, ret ) {
+ if ( a === b ) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while ( cur ) {
+ if ( cur === b ) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+ };
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+Sizzle.getText = function( elems ) {
+ var ret = "", elem;
+
+ for ( var i = 0; elems[i]; i++ ) {
+ elem = elems[i];
+
+ // Get the text from text nodes and CDATA nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+ ret += elem.nodeValue;
+
+ // Traverse everything else, except comment nodes
+ } else if ( elem.nodeType !== 8 ) {
+ ret += Sizzle.getText( elem.childNodes );
+ }
+ }
+
+ return ret;
+};
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"),
+ id = "script" + (new Date()).getTime(),
+ root = document.documentElement;
+
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( document.getElementById( id ) ) {
+ Expr.find.ID = function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+
+ return m ?
+ m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
+ [m] :
+ undefined :
+ [];
+ }
+ };
+
+ Expr.filter.ID = function( elem, match ) {
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+
+ // release memory in IE
+ root = form = null;
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function( match, context ) {
+ var results = context.getElementsByTagName( match[1] );
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+
+ Expr.attrHandle.href = function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ };
+ }
+
+ // release memory in IE
+ div = null;
+})();
+
+if ( document.querySelectorAll ) {
+ (function(){
+ var oldSizzle = Sizzle,
+ div = document.createElement("div"),
+ id = "__sizzle__";
+
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function( query, context, extra, seed ) {
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && !Sizzle.isXML(context) ) {
+ // See if we find a selector to speed up
+ var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
+
+ if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
+ // Speed-up: Sizzle("TAG")
+ if ( match[1] ) {
+ return makeArray( context.getElementsByTagName( query ), extra );
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
+ return makeArray( context.getElementsByClassName( match[2] ), extra );
+ }
+ }
+
+ if ( context.nodeType === 9 ) {
+ // Speed-up: Sizzle("body")
+ // The body element only exists once, optimize finding it
+ if ( query === "body" && context.body ) {
+ return makeArray( [ context.body ], extra );
+
+ // Speed-up: Sizzle("#ID")
+ } else if ( match && match[3] ) {
+ var elem = context.getElementById( match[3] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id === match[3] ) {
+ return makeArray( [ elem ], extra );
+ }
+
+ } else {
+ return makeArray( [], extra );
+ }
+ }
+
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(qsaError) {}
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ var oldContext = context,
+ old = context.getAttribute( "id" ),
+ nid = old || id,
+ hasParent = context.parentNode,
+ relativeHierarchySelector = /^\s*[+~]/.test( query );
+
+ if ( !old ) {
+ context.setAttribute( "id", nid );
+ } else {
+ nid = nid.replace( /'/g, "\\$&" );
+ }
+ if ( relativeHierarchySelector && hasParent ) {
+ context = context.parentNode;
+ }
+
+ try {
+ if ( !relativeHierarchySelector || hasParent ) {
+ return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
+ }
+
+ } catch(pseudoError) {
+ } finally {
+ if ( !old ) {
+ oldContext.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ // release memory in IE
+ div = null;
+ })();
+}
+
+(function(){
+ var html = document.documentElement,
+ matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
+
+ if ( matches ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9 fails this)
+ var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
+ pseudoWorks = false;
+
+ try {
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( document.documentElement, "[test!='']:sizzle" );
+
+ } catch( pseudoError ) {
+ pseudoWorks = true;
+ }
+
+ Sizzle.matchesSelector = function( node, expr ) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+ if ( !Sizzle.isXML( node ) ) {
+ try {
+ if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
+ var ret = matches.call( node, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || !disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9, so check for that
+ node.document && node.document.nodeType !== 11 ) {
+ return ret;
+ }
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle(expr, null, null, [node]).length > 0;
+ };
+ }
+})();
+
+(function(){
+ var div = document.createElement("div");
+
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 ) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function( match, context, isXML ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ // release memory in IE
+ div = null;
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName.toLowerCase() === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+if ( document.documentElement.contains ) {
+ Sizzle.contains = function( a, b ) {
+ return a !== b && (a.contains ? a.contains(b) : true);
+ };
+
+} else if ( document.documentElement.compareDocumentPosition ) {
+ Sizzle.contains = function( a, b ) {
+ return !!(a.compareDocumentPosition(b) & 16);
+ };
+
+} else {
+ Sizzle.contains = function() {
+ return false;
+ };
+}
+
+Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function( selector, context ) {
+ var match,
+ tmpSet = [],
+ later = "",
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})();
+
+
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/,
+ isSimple = /^.[^:#\[\.,]*$/,
+ slice = Array.prototype.slice,
+ POS = jQuery.expr.match.POS,
+ // methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var self = this,
+ i, l;
+
+ if ( typeof selector !== "string" ) {
+ return jQuery( selector ).filter(function() {
+ for ( i = 0, l = self.length; i < l; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ });
+ }
+
+ var ret = this.pushStack( "", "find", selector ),
+ length, n, r;
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ length = ret.length;
+ jQuery.find( selector, this[i], ret );
+
+ if ( i > 0 ) {
+ // Make sure that the results are unique
+ for ( n = length; n < ret.length; n++ ) {
+ for ( r = 0; r < length; r++ ) {
+ if ( ret[r] === ret[n] ) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has: function( target ) {
+ var targets = jQuery( target );
+ return this.filter(function() {
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector, false), "not", selector);
+ },
+
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
+ },
+
+ is: function( selector ) {
+ return !!selector && ( typeof selector === "string" ?
+ jQuery.filter( selector, this ).length > 0 :
+ this.filter( selector ).length > 0 );
+ },
+
+ closest: function( selectors, context ) {
+ var ret = [], i, l, cur = this[0];
+
+ // Array
+ if ( jQuery.isArray( selectors ) ) {
+ var match, selector,
+ matches = {},
+ level = 1;
+
+ if ( cur && selectors.length ) {
+ for ( i = 0, l = selectors.length; i < l; i++ ) {
+ selector = selectors[i];
+
+ if ( !matches[ selector ] ) {
+ matches[ selector ] = POS.test( selector ) ?
+ jQuery( selector, context || this.context ) :
+ selector;
+ }
+ }
+
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ for ( selector in matches ) {
+ match = matches[ selector ];
+
+ if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
+ ret.push({ selector: selector, elem: cur, level: level });
+ }
+ }
+
+ cur = cur.parentNode;
+ level++;
+ }
+ }
+
+ return ret;
+ }
+
+ // String
+ var pos = POS.test( selectors ) || typeof selectors !== "string" ?
+ jQuery( selectors, context || this.context ) :
+ 0;
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ cur = this[i];
+
+ while ( cur ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+ ret.push( cur );
+ break;
+
+ } else {
+ cur = cur.parentNode;
+ if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
+ break;
+ }
+ }
+ }
+ }
+
+ ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
+
+ return this.pushStack( ret, "closest", selectors );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
+ }
+
+ // index in selector
+ if ( typeof elem === "string" ) {
+ return jQuery.inArray( this[0], jQuery( elem ) );
+ }
+
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ var set = typeof selector === "string" ?
+ jQuery( selector, context ) :
+ jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+ all :
+ jQuery.unique( all ) );
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return jQuery.nth( elem, 2, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return jQuery.nth( elem, 2, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( elem.parentNode.firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.makeArray( elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until ),
+ // The variable 'args' was introduced in
+ // https://github.com/jquery/jquery/commit/52a0238
+ // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
+ // http://code.google.com/p/v8/issues/detail?id=1050
+ args = slice.call(arguments);
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, name, args.join(",") );
+ };
+});
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 ?
+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+ jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ var matched = [],
+ cur = elem[ dir ];
+
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function( cur, result, dir, elem ) {
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] ) {
+ if ( cur.nodeType === 1 && ++num === result ) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+
+ // Can't pass null or undefined to indexOf in Firefox 4
+ // Set to 0 to skip string check
+ qualifier = qualifier || 0;
+
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ var retVal = !!qualifier.call( elem, i, elem );
+ return retVal === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return (elem === qualifier) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem, i ) {
+ return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+ });
+}
+
+
+
+
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&#?\w+;/,
+ rnocache = /<(?:script|object|embed|option|style)/i,
+ // checked="checked" or checked
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+ rscriptType = /\/(java|ecma)script/i,
+ rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ area: [ 1, "<map>", "</map>" ],
+ _default: [ 0, "", "" ]
+ };
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+ text: function( text ) {
+ if ( jQuery.isFunction(text) ) {
+ return this.each(function(i) {
+ var self = jQuery( this );
+
+ self.text( text.call(this, i, self.text()) );
+ });
+ }
+
+ if ( typeof text !== "object" && text !== undefined ) {
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+ }
+
+ return jQuery.text( this );
+ },
+
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append( this );
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ),
+ contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function() {
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this );
+ });
+ } else if ( arguments.length ) {
+ var set = jQuery(arguments[0]);
+ set.push.apply( set, this.toArray() );
+ return this.pushStack( set, "before", arguments );
+ }
+ },
+
+ after: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ } else if ( arguments.length ) {
+ var set = this.pushStack( this, "after", arguments );
+ set.push.apply( set, jQuery(arguments[0]).toArray() );
+ return set;
+ }
+ },
+
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+ if ( !keepData && elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ jQuery.cleanData( [ elem ] );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+ }
+ }
+
+ return this;
+ },
+
+ empty: function() {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+ }
+
+ return this;
+ },
+
+ clone: function( dataAndEvents, deepDataAndEvents ) {
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+ return this.map( function () {
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+ });
+ },
+
+ html: function( value ) {
+ if ( value === undefined ) {
+ return this[0] && this[0].nodeType === 1 ?
+ this[0].innerHTML.replace(rinlinejQuery, "") :
+ null;
+
+ // See if we can take a shortcut and just use innerHTML
+ } else if ( typeof value === "string" && !rnocache.test( value ) &&
+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+ value = value.replace(rxhtmlTag, "<$1></$2>");
+
+ try {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( this[i].nodeType === 1 ) {
+ jQuery.cleanData( this[i].getElementsByTagName("*") );
+ this[i].innerHTML = value;
+ }
+ }
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {
+ this.empty().append( value );
+ }
+
+ } else if ( jQuery.isFunction( value ) ) {
+ this.each(function(i){
+ var self = jQuery( this );
+
+ self.html( value.call(this, i, self.html()) );
+ });
+
+ } else {
+ this.empty().append( value );
+ }
+
+ return this;
+ },
+
+ replaceWith: function( value ) {
+ if ( this[0] && this[0].parentNode ) {
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this), old = self.html();
+ self.replaceWith( value.call( this, i, old ) );
+ });
+ }
+
+ if ( typeof value !== "string" ) {
+ value = jQuery( value ).detach();
+ }
+
+ return this.each(function() {
+ var next = this.nextSibling,
+ parent = this.parentNode;
+
+ jQuery( this ).remove();
+
+ if ( next ) {
+ jQuery(next).before( value );
+ } else {
+ jQuery(parent).append( value );
+ }
+ });
+ } else {
+ return this.length ?
+ this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
+ this;
+ }
+ },
+
+ detach: function( selector ) {
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+ var results, first, fragment, parent,
+ value = args[0],
+ scripts = [];
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+ return this.each(function() {
+ jQuery(this).domManip( args, table, callback, true );
+ });
+ }
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ args[0] = value.call(this, i, table ? self.html() : undefined);
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( this[0] ) {
+ parent = value && value.parentNode;
+
+ // If we're in a fragment, just use that instead of building a new one
+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+ results = { fragment: parent };
+
+ } else {
+ results = jQuery.buildFragment( args, this, scripts );
+ }
+
+ fragment = results.fragment;
+
+ if ( fragment.childNodes.length === 1 ) {
+ first = fragment = fragment.firstChild;
+ } else {
+ first = fragment.firstChild;
+ }
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+
+ for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
+ callback.call(
+ table ?
+ root(this[i], first) :
+ this[i],
+ // Make sure that we do not leak memory by inadvertently discarding
+ // the original fragment (which might have attached data) instead of
+ // using it; in addition, use the original fragment object for the last
+ // item instead of first because it can end up being emptied incorrectly
+ // in certain situations (Bug #8070).
+ // Fragments from the fragment cache must always be cloned and never used
+ // in place.
+ results.cacheable || (l > 1 && i < lastIndex) ?
+ jQuery.clone( fragment, true, true ) :
+ fragment
+ );
+ }
+ }
+
+ if ( scripts.length ) {
+ jQuery.each( scripts, evalScript );
+ }
+ }
+
+ return this;
+ }
+});
+
+function root( elem, cur ) {
+ return jQuery.nodeName(elem, "table") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+}
+
+function cloneCopyEvent( src, dest ) {
+
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+ return;
+ }
+
+ var internalKey = jQuery.expando,
+ oldData = jQuery.data( src ),
+ curData = jQuery.data( dest, oldData );
+
+ // Switch to use the internal data object, if it exists, for the next
+ // stage of data copying
+ if ( (oldData = oldData[ internalKey ]) ) {
+ var events = oldData.events;
+ curData = curData[ internalKey ] = jQuery.extend({}, oldData);
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( var type in events ) {
+ for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
+ jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
+ }
+ }
+ }
+ }
+}
+
+function cloneFixAttributes( src, dest ) {
+ var nodeName;
+
+ // We do not need to do anything for non-Elements
+ if ( dest.nodeType !== 1 ) {
+ return;
+ }
+
+ // clearAttributes removes the attributes, which we don't want,
+ // but also removes the attachEvent events, which we *do* want
+ if ( dest.clearAttributes ) {
+ dest.clearAttributes();
+ }
+
+ // mergeAttributes, in contrast, only merges back on the
+ // original attributes, not the events
+ if ( dest.mergeAttributes ) {
+ dest.mergeAttributes( src );
+ }
+
+ nodeName = dest.nodeName.toLowerCase();
+
+ // IE6-8 fail to clone children inside object elements that use
+ // the proprietary classid attribute value (rather than the type
+ // attribute) to identify the type of content to display
+ if ( nodeName === "object" ) {
+ dest.outerHTML = src.outerHTML;
+
+ } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
+ // IE6-8 fails to persist the checked state of a cloned checkbox
+ // or radio button. Worse, IE6-7 fail to give the cloned element
+ // a checked appearance if the defaultChecked value isn't also set
+ if ( src.checked ) {
+ dest.defaultChecked = dest.checked = src.checked;
+ }
+
+ // IE6-7 get confused and end up setting the value of a cloned
+ // checkbox/radio button to an empty string instead of "on"
+ if ( dest.value !== src.value ) {
+ dest.value = src.value;
+ }
+
+ // IE6-8 fails to return the selected option to the default selected
+ // state when cloning options
+ } else if ( nodeName === "option" ) {
+ dest.selected = src.defaultSelected;
+
+ // IE6-8 fails to set the defaultValue to the correct value when
+ // cloning other types of input fields
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
+ dest.defaultValue = src.defaultValue;
+ }
+
+ // Event data gets referenced instead of copied if the expando
+ // gets copied too
+ dest.removeAttribute( jQuery.expando );
+}
+
+jQuery.buildFragment = function( args, nodes, scripts ) {
+ var fragment, cacheable, cacheresults, doc;
+
+ // nodes may contain either an explicit document object,
+ // a jQuery collection or context object.
+ // If nodes[0] contains a valid object to assign to doc
+ if ( nodes && nodes[0] ) {
+ doc = nodes[0].ownerDocument || nodes[0];
+ }
+
+ // Ensure that an attr object doesn't incorrectly stand in as a document object
+ // Chrome and Firefox seem to allow this to occur and will throw exception
+ // Fixes #8950
+ if ( !doc.createDocumentFragment ) {
+ doc = document;
+ }
+
+ // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
+ // Cloning options loses the selected state, so don't cache them
+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+ if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+ args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+ cacheable = true;
+
+ cacheresults = jQuery.fragments[ args[0] ];
+ if ( cacheresults && cacheresults !== 1 ) {
+ fragment = cacheresults;
+ }
+ }
+
+ if ( !fragment ) {
+ fragment = doc.createDocumentFragment();
+ jQuery.clean( args, doc, fragment, scripts );
+ }
+
+ if ( cacheable ) {
+ jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+ }
+
+ return { fragment: fragment, cacheable: cacheable };
+};
+
+jQuery.fragments = {};
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [],
+ insert = jQuery( selector ),
+ parent = this.length === 1 && this[0].parentNode;
+
+ if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+ insert[ original ]( this[0] );
+ return this;
+
+ } else {
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery( insert[i] )[ original ]( elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, insert.selector );
+ }
+ };
+});
+
+function getAll( elem ) {
+ if ( "getElementsByTagName" in elem ) {
+ return elem.getElementsByTagName( "*" );
+
+ } else if ( "querySelectorAll" in elem ) {
+ return elem.querySelectorAll( "*" );
+
+ } else {
+ return [];
+ }
+}
+
+// Used in clean, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+ if ( elem.type === "checkbox" || elem.type === "radio" ) {
+ elem.defaultChecked = elem.checked;
+ }
+}
+// Finds all inputs and passes them to fixDefaultChecked
+function findInputs( elem ) {
+ if ( jQuery.nodeName( elem, "input" ) ) {
+ fixDefaultChecked( elem );
+ } else if ( "getElementsByTagName" in elem ) {
+ jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
+ }
+}
+
+jQuery.extend({
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+ var clone = elem.cloneNode(true),
+ srcElements,
+ destElements,
+ i;
+
+ if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+ // IE copies events bound via attachEvent when using cloneNode.
+ // Calling detachEvent on the clone will also remove the events
+ // from the original. In order to get around this, we use some
+ // proprietary methods to clear the events. Thanks to MooTools
+ // guys for this hotness.
+
+ cloneFixAttributes( elem, clone );
+
+ // Using Sizzle here is crazy slow, so we use getElementsByTagName
+ // instead
+ srcElements = getAll( elem );
+ destElements = getAll( clone );
+
+ // Weird iteration because IE will replace the length property
+ // with an element if you are cloning the body and one of the
+ // elements on the page has a name or id of "length"
+ for ( i = 0; srcElements[i]; ++i ) {
+ // Ensure that the destination node is not null; Fixes #9587
+ if ( destElements[i] ) {
+ cloneFixAttributes( srcElements[i], destElements[i] );
+ }
+ }
+ }
+
+ // Copy the events from the original to the clone
+ if ( dataAndEvents ) {
+ cloneCopyEvent( elem, clone );
+
+ if ( deepDataAndEvents ) {
+ srcElements = getAll( elem );
+ destElements = getAll( clone );
+
+ for ( i = 0; srcElements[i]; ++i ) {
+ cloneCopyEvent( srcElements[i], destElements[i] );
+ }
+ }
+ }
+
+ srcElements = destElements = null;
+
+ // Return the cloned set
+ return clone;
+ },
+
+ clean: function( elems, context, fragment, scripts ) {
+ var checkScriptType;
+
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" ) {
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+ }
+
+ var ret = [], j;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( typeof elem === "number" ) {
+ elem += "";
+ }
+
+ if ( !elem ) {
+ continue;
+ }
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" ) {
+ if ( !rhtml.test( elem ) ) {
+ elem = context.createTextNode( elem );
+ } else {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(rxhtmlTag, "<$1></$2>");
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+ wrap = wrapMap[ tag ] || wrapMap._default,
+ depth = wrap[0],
+ div = context.createElement("div");
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( depth-- ) {
+ div = div.lastChild;
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = rtbody.test(elem),
+ tbody = tag === "table" && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( j = tbody.length - 1; j >= 0 ; --j ) {
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+ }
+ }
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+ }
+
+ elem = div.childNodes;
+ }
+ }
+
+ // Resets defaultChecked for any radios and checkboxes
+ // about to be appended to the DOM in IE 6/7 (#8060)
+ var len;
+ if ( !jQuery.support.appendChecked ) {
+ if ( elem[0] && typeof (len = elem.length) === "number" ) {
+ for ( j = 0; j < len; j++ ) {
+ findInputs( elem[j] );
+ }
+ } else {
+ findInputs( elem );
+ }
+ }
+
+ if ( elem.nodeType ) {
+ ret.push( elem );
+ } else {
+ ret = jQuery.merge( ret, elem );
+ }
+ }
+
+ if ( fragment ) {
+ checkScriptType = function( elem ) {
+ return !elem.type || rscriptType.test( elem.type );
+ };
+ for ( i = 0; ret[i]; i++ ) {
+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+
+ } else {
+ if ( ret[i].nodeType === 1 ) {
+ var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
+
+ ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
+ }
+ fragment.appendChild( ret[i] );
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ cleanData: function( elems ) {
+ var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
+ deleteExpando = jQuery.support.deleteExpando;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ continue;
+ }
+
+ id = elem[ jQuery.expando ];
+
+ if ( id ) {
+ data = cache[ id ] && cache[ id ][ internalKey ];
+
+ if ( data && data.events ) {
+ for ( var type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ // This is a shortcut to avoid jQuery.event.remove's overhead
+ } else {
+ jQuery.removeEvent( elem, type, data.handle );
+ }
+ }
+
+ // Null the DOM reference to avoid IE6/7/8 leak (#7054)
+ if ( data.handle ) {
+ data.handle.elem = null;
+ }
+ }
+
+ if ( deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ delete cache[ id ];
+ }
+ }
+ }
+});
+
+function evalScript( i, elem ) {
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+
+
+
+var ralpha = /alpha\([^)]*\)/i,
+ ropacity = /opacity=([^)]*)/,
+ // fixed for IE9, see #8346
+ rupper = /([A-Z]|^ms)/g,
+ rnumpx = /^-?\d+(?:px)?$/i,
+ rnum = /^-?\d/,
+ rrelNum = /^([\-+])=([\-+.\de]+)/,
+
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+ cssWidth = [ "Left", "Right" ],
+ cssHeight = [ "Top", "Bottom" ],
+ curCSS,
+
+ getComputedStyle,
+ currentStyle;
+
+jQuery.fn.css = function( name, value ) {
+ // Setting 'undefined' is a no-op
+ if ( arguments.length === 2 && value === undefined ) {
+ return this;
+ }
+
+ return jQuery.access( this, name, value, true, function( elem, name, value ) {
+ return value !== undefined ?
+ jQuery.style( elem, name, value ) :
+ jQuery.css( elem, name );
+ });
+};
+
+jQuery.extend({
+ // Add in style property hooks for overriding the default
+ // behavior of getting and setting a style property
+ cssHooks: {
+ opacity: {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ // We should always get a number back from opacity
+ var ret = curCSS( elem, "opacity", "opacity" );
+ return ret === "" ? "1" : ret;
+
+ } else {
+ return elem.style.opacity;
+ }
+ }
+ }
+ },
+
+ // Exclude the following css properties to add px
+ cssNumber: {
+ "fillOpacity": true,
+ "fontWeight": true,
+ "lineHeight": true,
+ "opacity": true,
+ "orphans": true,
+ "widows": true,
+ "zIndex": true,
+ "zoom": true
+ },
+
+ // Add in properties whose names you wish to fix before
+ // setting or getting the value
+ cssProps: {
+ // normalize float css property
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+ },
+
+ // Get and set the style property on a DOM Node
+ style: function( elem, name, value, extra ) {
+ // Don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+ return;
+ }
+
+ // Make sure that we're working with the right name
+ var ret, type, origName = jQuery.camelCase( name ),
+ style = elem.style, hooks = jQuery.cssHooks[ origName ];
+
+ name = jQuery.cssProps[ origName ] || origName;
+
+ // Check if we're setting a value
+ if ( value !== undefined ) {
+ type = typeof value;
+
+ // convert relative number strings (+= or -=) to relative numbers. #7345
+ if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+ value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
+ // Fixes bug #9237
+ type = "number";
+ }
+
+ // Make sure that NaN and null values aren't set. See: #7116
+ if ( value == null || type === "number" && isNaN( value ) ) {
+ return;
+ }
+
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+ value += "px";
+ }
+
+ // If a hook was provided, use that value, otherwise just set the specified value
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+ // Fixes bug #5509
+ try {
+ style[ name ] = value;
+ } catch(e) {}
+ }
+
+ } else {
+ // If a hook was provided get the non-computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+ return ret;
+ }
+
+ // Otherwise just get the value from the style object
+ return style[ name ];
+ }
+ },
+
+ css: function( elem, name, extra ) {
+ var ret, hooks;
+
+ // Make sure that we're working with the right name
+ name = jQuery.camelCase( name );
+ hooks = jQuery.cssHooks[ name ];
+ name = jQuery.cssProps[ name ] || name;
+
+ // cssFloat needs a special treatment
+ if ( name === "cssFloat" ) {
+ name = "float";
+ }
+
+ // If a hook was provided get the computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
+ return ret;
+
+ // Otherwise, if a way to get the computed value exists, use that
+ } else if ( curCSS ) {
+ return curCSS( elem, name );
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+ }
+});
+
+// DEPRECATED, Use jQuery.css() instead
+jQuery.curCSS = jQuery.css;
+
+jQuery.each(["height", "width"], function( i, name ) {
+ jQuery.cssHooks[ name ] = {
+ get: function( elem, computed, extra ) {
+ var val;
+
+ if ( computed ) {
+ if ( elem.offsetWidth !== 0 ) {
+ return getWH( elem, name, extra );
+ } else {
+ jQuery.swap( elem, cssShow, function() {
+ val = getWH( elem, name, extra );
+ });
+ }
+
+ return val;
+ }
+ },
+
+ set: function( elem, value ) {
+ if ( rnumpx.test( value ) ) {
+ // ignore negative width and height values #1599
+ value = parseFloat( value );
+
+ if ( value >= 0 ) {
+ return value + "px";
+ }
+
+ } else {
+ return value;
+ }
+ }
+ };
+});
+
+if ( !jQuery.support.opacity ) {
+ jQuery.cssHooks.opacity = {
+ get: function( elem, computed ) {
+ // IE uses filters for opacity
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+ ( parseFloat( RegExp.$1 ) / 100 ) + "" :
+ computed ? "1" : "";
+ },
+
+ set: function( elem, value ) {
+ var style = elem.style,
+ currentStyle = elem.currentStyle,
+ opacity = jQuery.isNaN( value ) ? "" : "alpha(opacity=" + value * 100 + ")",
+ filter = currentStyle && currentStyle.filter || style.filter || "";
+
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+ if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
+
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
+ // style.removeAttribute is IE Only, but so apparently is this code path...
+ style.removeAttribute( "filter" );
+
+ // if there there is no filter style applied in a css rule, we are done
+ if ( currentStyle && !currentStyle.filter ) {
+ return;
+ }
+ }
+
+ // otherwise, set new filter values
+ style.filter = ralpha.test( filter ) ?
+ filter.replace( ralpha, opacity ) :
+ filter + " " + opacity;
+ }
+ };
+}
+
+jQuery(function() {
+ // This hook cannot be added until DOM ready because the support test
+ // for it is not run until after DOM ready
+ if ( !jQuery.support.reliableMarginRight ) {
+ jQuery.cssHooks.marginRight = {
+ get: function( elem, computed ) {
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ // Work around by temporarily setting element display to inline-block
+ var ret;
+ jQuery.swap( elem, { "display": "inline-block" }, function() {
+ if ( computed ) {
+ ret = curCSS( elem, "margin-right", "marginRight" );
+ } else {
+ ret = elem.style.marginRight;
+ }
+ });
+ return ret;
+ }
+ };
+ }
+});
+
+if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ getComputedStyle = function( elem, name ) {
+ var ret, defaultView, computedStyle;
+
+ name = name.replace( rupper, "-$1" ).toLowerCase();
+
+ if ( !(defaultView = elem.ownerDocument.defaultView) ) {
+ return undefined;
+ }
+
+ if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+ ret = computedStyle.getPropertyValue( name );
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+ ret = jQuery.style( elem, name );
+ }
+ }
+
+ return ret;
+ };
+}
+
+if ( document.documentElement.currentStyle ) {
+ currentStyle = function( elem, name ) {
+ var left,
+ ret = elem.currentStyle && elem.currentStyle[ name ],
+ rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
+ style = elem.style;
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+ // Remember the original values
+ left = style.left;
+
+ // Put in the new values to get a computed value out
+ if ( rsLeft ) {
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ }
+ style.left = name === "fontSize" ? "1em" : (ret || 0);
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ if ( rsLeft ) {
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret === "" ? "auto" : ret;
+ };
+}
+
+curCSS = getComputedStyle || currentStyle;
+
+function getWH( elem, name, extra ) {
+
+ // Start with offset property
+ var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+ which = name === "width" ? cssWidth : cssHeight;
+
+ if ( val > 0 ) {
+ if ( extra !== "border" ) {
+ jQuery.each( which, function() {
+ if ( !extra ) {
+ val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
+ }
+ if ( extra === "margin" ) {
+ val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
+ } else {
+ val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
+ }
+ });
+ }
+
+ return val + "px";
+ }
+
+ // Fall back to computed then uncomputed css if necessary
+ val = curCSS( elem, name, name );
+ if ( val < 0 || val == null ) {
+ val = elem.style[ name ] || 0;
+ }
+ // Normalize "", auto, and prepare for extra
+ val = parseFloat( val ) || 0;
+
+ // Add padding, border, margin
+ if ( extra ) {
+ jQuery.each( which, function() {
+ val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
+ if ( extra !== "padding" ) {
+ val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
+ }
+ if ( extra === "margin" ) {
+ val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
+ }
+ });
+ }
+
+ return val + "px";
+}
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ var width = elem.offsetWidth,
+ height = elem.offsetHeight;
+
+ return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+
+
+
+
+var r20 = /%20/g,
+ rbracket = /\[\]$/,
+ rCRLF = /\r?\n/g,
+ rhash = /#.*$/,
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+ rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+ // #7653, #8125, #8152: local protocol detection
+ rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
+ rnoContent = /^(?:GET|HEAD)$/,
+ rprotocol = /^\/\//,
+ rquery = /\?/,
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+ rselectTextarea = /^(?:select|textarea)/i,
+ rspacesAjax = /\s+/,
+ rts = /([?&])_=[^&]*/,
+ rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
+
+ // Keep a copy of the old load method
+ _load = jQuery.fn.load,
+
+ /* Prefilters
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+ * 2) These are called:
+ * - BEFORE asking for a transport
+ * - AFTER param serialization (s.data is a string if s.processData is true)
+ * 3) key is the dataType
+ * 4) the catchall symbol "*" can be used
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+ */
+ prefilters = {},
+
+ /* Transports bindings
+ * 1) key is the dataType
+ * 2) the catchall symbol "*" can be used
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
+ */
+ transports = {},
+
+ // Document location
+ ajaxLocation,
+
+ // Document location segments
+ ajaxLocParts,
+
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+ allTypes = ["*/"] + ["*"];
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+ ajaxLocation = location.href;
+} catch( e ) {
+ // Use the href attribute of an A element
+ // since IE will modify it given document.location
+ ajaxLocation = document.createElement( "a" );
+ ajaxLocation.href = "";
+ ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+ // dataTypeExpression is optional and defaults to "*"
+ return function( dataTypeExpression, func ) {
+
+ if ( typeof dataTypeExpression !== "string" ) {
+ func = dataTypeExpression;
+ dataTypeExpression = "*";
+ }
+
+ if ( jQuery.isFunction( func ) ) {
+ var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
+ i = 0,
+ length = dataTypes.length,
+ dataType,
+ list,
+ placeBefore;
+
+ // For each dataType in the dataTypeExpression
+ for(; i < length; i++ ) {
+ dataType = dataTypes[ i ];
+ // We control if we're asked to add before
+ // any existing element
+ placeBefore = /^\+/.test( dataType );
+ if ( placeBefore ) {
+ dataType = dataType.substr( 1 ) || "*";
+ }
+ list = structure[ dataType ] = structure[ dataType ] || [];
+ // then we add to the structure accordingly
+ list[ placeBefore ? "unshift" : "push" ]( func );
+ }
+ }
+ };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
+ dataType /* internal */, inspected /* internal */ ) {
+
+ dataType = dataType || options.dataTypes[ 0 ];
+ inspected = inspected || {};
+
+ inspected[ dataType ] = true;
+
+ var list = structure[ dataType ],
+ i = 0,
+ length = list ? list.length : 0,
+ executeOnly = ( structure === prefilters ),
+ selection;
+
+ for(; i < length && ( executeOnly || !selection ); i++ ) {
+ selection = list[ i ]( options, originalOptions, jqXHR );
+ // If we got redirected to another dataType
+ // we try there if executing only and not done already
+ if ( typeof selection === "string" ) {
+ if ( !executeOnly || inspected[ selection ] ) {
+ selection = undefined;
+ } else {
+ options.dataTypes.unshift( selection );
+ selection = inspectPrefiltersOrTransports(
+ structure, options, originalOptions, jqXHR, selection, inspected );
+ }
+ }
+ }
+ // If we're only executing or nothing was selected
+ // we try the catchall dataType if not done already
+ if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
+ selection = inspectPrefiltersOrTransports(
+ structure, options, originalOptions, jqXHR, "*", inspected );
+ }
+ // unnecessary when only executing (prefilters)
+ // but it'll be ignored by the caller in that case
+ return selection;
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+ var key, deep,
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
+ for( key in src ) {
+ if ( src[ key ] !== undefined ) {
+ ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
+ }
+ }
+ if ( deep ) {
+ jQuery.extend( true, target, deep );
+ }
+}
+
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" && _load ) {
+ return _load.apply( this, arguments );
+
+ // Don't do a request if no elements are being requested
+ } else if ( !this.length ) {
+ return this;
+ }
+
+ var off = url.indexOf( " " );
+ if ( off >= 0 ) {
+ var selector = url.slice( off, url.length );
+ url = url.slice( 0, off );
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params ) {
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = undefined;
+
+ // Otherwise, build a param string
+ } else if ( typeof params === "object" ) {
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+ type = "POST";
+ }
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ // Complete callback (responseText is used internally)
+ complete: function( jqXHR, status, responseText ) {
+ // Store the response as specified by the jqXHR object
+ responseText = jqXHR.responseText;
+ // If successful, inject the HTML into all the matched elements
+ if ( jqXHR.isResolved() ) {
+ // #4825: Get the actual response in case
+ // a dataFilter is present in ajaxSettings
+ jqXHR.done(function( r ) {
+ responseText = r;
+ });
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(responseText.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ responseText );
+ }
+
+ if ( callback ) {
+ self.each( callback, [ responseText, status, jqXHR ] );
+ }
+ }
+ });
+
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param( this.serializeArray() );
+ },
+
+ serializeArray: function() {
+ return this.map(function(){
+ return this.elements ? jQuery.makeArray( this.elements ) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
+ rinput.test( this.type ) );
+ })
+ .map(function( i, elem ){
+ var val = jQuery( this ).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray( val ) ?
+ jQuery.map( val, function( val, i ){
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }) :
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
+ jQuery.fn[ o ] = function( f ){
+ return this.bind( o, f );
+ };
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+ jQuery[ method ] = function( url, data, callback, type ) {
+ // shift arguments if data argument was omitted
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = undefined;
+ }
+
+ return jQuery.ajax({
+ type: method,
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ };
+});
+
+jQuery.extend({
+
+ getScript: function( url, callback ) {
+ return jQuery.get( url, undefined, callback, "script" );
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get( url, data, callback, "json" );
+ },
+
+ // Creates a full fledged settings object into target
+ // with both ajaxSettings and settings fields.
+ // If target is omitted, writes into ajaxSettings.
+ ajaxSetup: function( target, settings ) {
+ if ( settings ) {
+ // Building a settings object
+ ajaxExtend( target, jQuery.ajaxSettings );
+ } else {
+ // Extending ajaxSettings
+ settings = target;
+ target = jQuery.ajaxSettings;
+ }
+ ajaxExtend( target, settings );
+ return target;
+ },
+
+ ajaxSettings: {
+ url: ajaxLocation,
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ dataType: null,
+ username: null,
+ password: null,
+ cache: null,
+ traditional: false,
+ headers: {},
+ */
+
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ text: "text/plain",
+ json: "application/json, text/javascript",
+ "*": allTypes
+ },
+
+ contents: {
+ xml: /xml/,
+ html: /html/,
+ json: /json/
+ },
+
+ responseFields: {
+ xml: "responseXML",
+ text: "responseText"
+ },
+
+ // List of data converters
+ // 1) key format is "source_type destination_type" (a single space in-between)
+ // 2) the catchall symbol "*" can be used for source_type
+ converters: {
+
+ // Convert anything to text
+ "* text": window.String,
+
+ // Text to html (true = no transformation)
+ "text html": true,
+
+ // Evaluate text as a json expression
+ "text json": jQuery.parseJSON,
+
+ // Parse text as xml
+ "text xml": jQuery.parseXML
+ },
+
+ // For options that shouldn't be deep extended:
+ // you can add your own custom options here if
+ // and when you create one that shouldn't be
+ // deep extended (see ajaxExtend)
+ flatOptions: {
+ context: true,
+ url: true
+ }
+ },
+
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+ // Main method
+ ajax: function( url, options ) {
+
+ // If url is an object, simulate pre-1.5 signature
+ if ( typeof url === "object" ) {
+ options = url;
+ url = undefined;
+ }
+
+ // Force options to be an object
+ options = options || {};
+
+ var // Create the final options object
+ s = jQuery.ajaxSetup( {}, options ),
+ // Callbacks context
+ callbackContext = s.context || s,
+ // Context for global events
+ // It's the callbackContext if one was provided in the options
+ // and if it's a DOM node or a jQuery collection
+ globalEventContext = callbackContext !== s &&
+ ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
+ jQuery( callbackContext ) : jQuery.event,
+ // Deferreds
+ deferred = jQuery.Deferred(),
+ completeDeferred = jQuery._Deferred(),
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
+ // ifModified key
+ ifModifiedKey,
+ // Headers (they are sent all at once)
+ requestHeaders = {},
+ requestHeadersNames = {},
+ // Response headers
+ responseHeadersString,
+ responseHeaders,
+ // transport
+ transport,
+ // timeout handle
+ timeoutTimer,
+ // Cross-domain detection vars
+ parts,
+ // The jqXHR state
+ state = 0,
+ // To know if global events are to be dispatched
+ fireGlobals,
+ // Loop variable
+ i,
+ // Fake xhr
+ jqXHR = {
+
+ readyState: 0,
+
+ // Caches the header
+ setRequestHeader: function( name, value ) {
+ if ( !state ) {
+ var lname = name.toLowerCase();
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+ requestHeaders[ name ] = value;
+ }
+ return this;
+ },
+
+ // Raw string
+ getAllResponseHeaders: function() {
+ return state === 2 ? responseHeadersString : null;
+ },
+
+ // Builds headers hashtable if needed
+ getResponseHeader: function( key ) {
+ var match;
+ if ( state === 2 ) {
+ if ( !responseHeaders ) {
+ responseHeaders = {};
+ while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+ }
+ }
+ match = responseHeaders[ key.toLowerCase() ];
+ }
+ return match === undefined ? null : match;
+ },
+
+ // Overrides response content-type header
+ overrideMimeType: function( type ) {
+ if ( !state ) {
+ s.mimeType = type;
+ }
+ return this;
+ },
+
+ // Cancel the request
+ abort: function( statusText ) {
+ statusText = statusText || "abort";
+ if ( transport ) {
+ transport.abort( statusText );
+ }
+ done( 0, statusText );
+ return this;
+ }
+ };
+
+ // Callback for when everything is done
+ // It is defined here because jslint complains if it is declared
+ // at the end of the function (which would be more logical and readable)
+ function done( status, nativeStatusText, responses, headers ) {
+
+ // Called once
+ if ( state === 2 ) {
+ return;
+ }
+
+ // State is "done" now
+ state = 2;
+
+ // Clear timeout if it exists
+ if ( timeoutTimer ) {
+ clearTimeout( timeoutTimer );
+ }
+
+ // Dereference transport for early garbage collection
+ // (no matter how long the jqXHR object will be used)
+ transport = undefined;
+
+ // Cache response headers
+ responseHeadersString = headers || "";
+
+ // Set readyState
+ jqXHR.readyState = status > 0 ? 4 : 0;
+
+ var isSuccess,
+ success,
+ error,
+ statusText = nativeStatusText,
+ response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
+ lastModified,
+ etag;
+
+ // If successful, handle type chaining
+ if ( status >= 200 && status < 300 || status === 304 ) {
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+
+ if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
+ jQuery.lastModified[ ifModifiedKey ] = lastModified;
+ }
+ if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
+ jQuery.etag[ ifModifiedKey ] = etag;
+ }
+ }
+
+ // If not modified
+ if ( status === 304 ) {
+
+ statusText = "notmodified";
+ isSuccess = true;
+
+ // If we have data
+ } else {
+
+ try {
+ success = ajaxConvert( s, response );
+ statusText = "success";
+ isSuccess = true;
+ } catch(e) {
+ // We have a parsererror
+ statusText = "parsererror";
+ error = e;
+ }
+ }
+ } else {
+ // We extract error from statusText
+ // then normalize statusText and status for non-aborts
+ error = statusText;
+ if( !statusText || status ) {
+ statusText = "error";
+ if ( status < 0 ) {
+ status = 0;
+ }
+ }
+ }
+
+ // Set data for the fake xhr object
+ jqXHR.status = status;
+ jqXHR.statusText = "" + ( nativeStatusText || statusText );
+
+ // Success/Error
+ if ( isSuccess ) {
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+ } else {
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+ }
+
+ // Status-dependent callbacks
+ jqXHR.statusCode( statusCode );
+ statusCode = undefined;
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
+ [ jqXHR, s, isSuccess ? success : error ] );
+ }
+
+ // Complete
+ completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+ // Handle the global AJAX counter
+ if ( !( --jQuery.active ) ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+ }
+
+ // Attach deferreds
+ deferred.promise( jqXHR );
+ jqXHR.success = jqXHR.done;
+ jqXHR.error = jqXHR.fail;
+ jqXHR.complete = completeDeferred.done;
+
+ // Status-dependent callbacks
+ jqXHR.statusCode = function( map ) {
+ if ( map ) {
+ var tmp;
+ if ( state < 2 ) {
+ for( tmp in map ) {
+ statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
+ }
+ } else {
+ tmp = map[ jqXHR.status ];
+ jqXHR.then( tmp, tmp );
+ }
+ }
+ return this;
+ };
+
+ // Remove hash character (#7531: and string promotion)
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+ // We also use the url parameter if available
+ s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+ // Extract dataTypes list
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
+
+ // Determine if a cross-domain request is in order
+ if ( s.crossDomain == null ) {
+ parts = rurl.exec( s.url.toLowerCase() );
+ s.crossDomain = !!( parts &&
+ ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
+ );
+ }
+
+ // Convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Apply prefilters
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+ // If request was aborted inside a prefiler, stop there
+ if ( state === 2 ) {
+ return false;
+ }
+
+ // We can fire global events as of now if asked to
+ fireGlobals = s.global;
+
+ // Uppercase the type
+ s.type = s.type.toUpperCase();
+
+ // Determine if request has content
+ s.hasContent = !rnoContent.test( s.type );
+
+ // Watch for a new set of requests
+ if ( fireGlobals && jQuery.active++ === 0 ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // More options handling for requests with no content
+ if ( !s.hasContent ) {
+
+ // If data is available, append data to url
+ if ( s.data ) {
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
+ // #9682: remove data so that it's not used in an eventual retry
+ delete s.data;
+ }
+
+ // Get ifModifiedKey before adding the anti-cache parameter
+ ifModifiedKey = s.url;
+
+ // Add anti-cache in url if needed
+ if ( s.cache === false ) {
+
+ var ts = jQuery.now(),
+ // try replacing _= if it is there
+ ret = s.url.replace( rts, "$1_=" + ts );
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
+ }
+ }
+
+ // Set the correct header, if data is being sent
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ ifModifiedKey = ifModifiedKey || s.url;
+ if ( jQuery.lastModified[ ifModifiedKey ] ) {
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
+ }
+ if ( jQuery.etag[ ifModifiedKey ] ) {
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
+ }
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ jqXHR.setRequestHeader(
+ "Accept",
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+ s.accepts[ "*" ]
+ );
+
+ // Check for headers option
+ for ( i in s.headers ) {
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
+ }
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+ // Abort if not done already
+ jqXHR.abort();
+ return false;
+
+ }
+
+ // Install callbacks on deferreds
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
+ jqXHR[ i ]( s[ i ] );
+ }
+
+ // Get transport
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+ // If no transport, we auto-abort
+ if ( !transport ) {
+ done( -1, "No Transport" );
+ } else {
+ jqXHR.readyState = 1;
+ // Send global event
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+ }
+ // Timeout
+ if ( s.async && s.timeout > 0 ) {
+ timeoutTimer = setTimeout( function(){
+ jqXHR.abort( "timeout" );
+ }, s.timeout );
+ }
+
+ try {
+ state = 1;
+ transport.send( requestHeaders, done );
+ } catch (e) {
+ // Propagate exception as error if not done
+ if ( state < 2 ) {
+ done( -1, e );
+ // Simply rethrow otherwise
+ } else {
+ jQuery.error( e );
+ }
+ }
+ }
+
+ return jqXHR;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a, traditional ) {
+ var s = [],
+ add = function( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction( value ) ? value() : value;
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+ };
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( var prefix in a ) {
+ buildParams( prefix, a[ prefix ], traditional, add );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join( "&" ).replace( r20, "+" );
+ }
+});
+
+function buildParams( prefix, obj, traditional, add ) {
+ if ( jQuery.isArray( obj ) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || rbracket.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+
+ } else {
+ // If array item is non-scalar (array or object), encode its
+ // numeric index to resolve deserialization ambiguity issues.
+ // Note that rack (as of 1.0.0) can't currently deserialize
+ // nested arrays properly, and attempting to do so may cause
+ // a server error. Possible fixes are to modify rack's
+ // deserialization algorithm or to provide an option or flag
+ // to force array serialization to be shallow.
+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
+ }
+ });
+
+ } else if ( !traditional && obj != null && typeof obj === "object" ) {
+ // Serialize object item.
+ for ( var name in obj ) {
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+ }
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+}
+
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {}
+
+});
+
+/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+ var contents = s.contents,
+ dataTypes = s.dataTypes,
+ responseFields = s.responseFields,
+ ct,
+ type,
+ finalDataType,
+ firstDataType;
+
+ // Fill responseXXX fields
+ for( type in responseFields ) {
+ if ( type in responses ) {
+ jqXHR[ responseFields[type] ] = responses[ type ];
+ }
+ }
+
+ // Remove auto dataType and get content-type in the process
+ while( dataTypes[ 0 ] === "*" ) {
+ dataTypes.shift();
+ if ( ct === undefined ) {
+ ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
+ }
+ }
+
+ // Check if we're dealing with a known content-type
+ if ( ct ) {
+ for ( type in contents ) {
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
+ dataTypes.unshift( type );
+ break;
+ }
+ }
+ }
+
+ // Check to see if we have a response for the expected dataType
+ if ( dataTypes[ 0 ] in responses ) {
+ finalDataType = dataTypes[ 0 ];
+ } else {
+ // Try convertible dataTypes
+ for ( type in responses ) {
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+ finalDataType = type;
+ break;
+ }
+ if ( !firstDataType ) {
+ firstDataType = type;
+ }
+ }
+ // Or just use first one
+ finalDataType = finalDataType || firstDataType;
+ }
+
+ // If we found a dataType
+ // We add the dataType to the list if needed
+ // and return the corresponding response
+ if ( finalDataType ) {
+ if ( finalDataType !== dataTypes[ 0 ] ) {
+ dataTypes.unshift( finalDataType );
+ }
+ return responses[ finalDataType ];
+ }
+}
+
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
+
+ // Apply the dataFilter if provided
+ if ( s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
+
+ var dataTypes = s.dataTypes,
+ converters = {},
+ i,
+ key,
+ length = dataTypes.length,
+ tmp,
+ // Current and previous dataTypes
+ current = dataTypes[ 0 ],
+ prev,
+ // Conversion expression
+ conversion,
+ // Conversion function
+ conv,
+ // Conversion functions (transitive conversion)
+ conv1,
+ conv2;
+
+ // For each dataType in the chain
+ for( i = 1; i < length; i++ ) {
+
+ // Create converters map
+ // with lowercased keys
+ if ( i === 1 ) {
+ for( key in s.converters ) {
+ if( typeof key === "string" ) {
+ converters[ key.toLowerCase() ] = s.converters[ key ];
+ }
+ }
+ }
+
+ // Get the dataTypes
+ prev = current;
+ current = dataTypes[ i ];
+
+ // If current is auto dataType, update it to prev
+ if( current === "*" ) {
+ current = prev;
+ // If no auto and dataTypes are actually different
+ } else if ( prev !== "*" && prev !== current ) {
+
+ // Get the converter
+ conversion = prev + " " + current;
+ conv = converters[ conversion ] || converters[ "* " + current ];
+
+ // If there is no direct converter, search transitively
+ if ( !conv ) {
+ conv2 = undefined;
+ for( conv1 in converters ) {
+ tmp = conv1.split( " " );
+ if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
+ conv2 = converters[ tmp[1] + " " + current ];
+ if ( conv2 ) {
+ conv1 = converters[ conv1 ];
+ if ( conv1 === true ) {
+ conv = conv2;
+ } else if ( conv2 === true ) {
+ conv = conv1;
+ }
+ break;
+ }
+ }
+ }
+ }
+ // If we found no converter, dispatch an error
+ if ( !( conv || conv2 ) ) {
+ jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
+ }
+ // If found converter is not an equivalence
+ if ( conv !== true ) {
+ // Convert with 1 or 2 converters accordingly
+ response = conv ? conv( response ) : conv2( conv1(response) );
+ }
+ }
+ }
+ return response;
+}
+
+
+
+
+var jsc = jQuery.now(),
+ jsre = /(\=)\?(&|$)|\?\?/i;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+ jsonp: "callback",
+ jsonpCallback: function() {
+ return jQuery.expando + "_" + ( jsc++ );
+ }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+ var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
+ ( typeof s.data === "string" );
+
+ if ( s.dataTypes[ 0 ] === "jsonp" ||
+ s.jsonp !== false && ( jsre.test( s.url ) ||
+ inspectData && jsre.test( s.data ) ) ) {
+
+ var responseContainer,
+ jsonpCallback = s.jsonpCallback =
+ jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
+ previous = window[ jsonpCallback ],
+ url = s.url,
+ data = s.data,
+ replace = "$1" + jsonpCallback + "$2";
+
+ if ( s.jsonp !== false ) {
+ url = url.replace( jsre, replace );
+ if ( s.url === url ) {
+ if ( inspectData ) {
+ data = data.replace( jsre, replace );
+ }
+ if ( s.data === data ) {
+ // Add callback manually
+ url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
+ }
+ }
+ }
+
+ s.url = url;
+ s.data = data;
+
+ // Install callback
+ window[ jsonpCallback ] = function( response ) {
+ responseContainer = [ response ];
+ };
+
+ // Clean-up function
+ jqXHR.always(function() {
+ // Set callback back to previous value
+ window[ jsonpCallback ] = previous;
+ // Call if it was a function and we have a response
+ if ( responseContainer && jQuery.isFunction( previous ) ) {
+ window[ jsonpCallback ]( responseContainer[ 0 ] );
+ }
+ });
+
+ // Use data converter to retrieve json after script execution
+ s.converters["script json"] = function() {
+ if ( !responseContainer ) {
+ jQuery.error( jsonpCallback + " was not called" );
+ }
+ return responseContainer[ 0 ];
+ };
+
+ // force json dataType
+ s.dataTypes[ 0 ] = "json";
+
+ // Delegate to script
+ return "script";
+ }
+});
+
+
+
+
+// Install script dataType
+jQuery.ajaxSetup({
+ accepts: {
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+ },
+ contents: {
+ script: /javascript|ecmascript/
+ },
+ converters: {
+ "text script": function( text ) {
+ jQuery.globalEval( text );
+ return text;
+ }
+ }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+ if ( s.cache === undefined ) {
+ s.cache = false;
+ }
+ if ( s.crossDomain ) {
+ s.type = "GET";
+ s.global = false;
+ }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+ // This transport only deals with cross domain requests
+ if ( s.crossDomain ) {
+
+ var script,
+ head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
+
+ return {
+
+ send: function( _, callback ) {
+
+ script = document.createElement( "script" );
+
+ script.async = "async";
+
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ script.src = s.url;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+
+ // Remove the script
+ if ( head && script.parentNode ) {
+ head.removeChild( script );
+ }
+
+ // Dereference the script
+ script = undefined;
+
+ // Callback if not abort
+ if ( !isAbort ) {
+ callback( 200, "success" );
+ }
+ }
+ };
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709 and #4378).
+ head.insertBefore( script, head.firstChild );
+ },
+
+ abort: function() {
+ if ( script ) {
+ script.onload( 0, 1 );
+ }
+ }
+ };
+ }
+});
+
+
+
+
+var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+ xhrOnUnloadAbort = window.ActiveXObject ? function() {
+ // Abort all pending requests
+ for ( var key in xhrCallbacks ) {
+ xhrCallbacks[ key ]( 0, 1 );
+ }
+ } : false,
+ xhrId = 0,
+ xhrCallbacks;
+
+// Functions to create xhrs
+function createStandardXHR() {
+ try {
+ return new window.XMLHttpRequest();
+ } catch( e ) {}
+}
+
+function createActiveXHR() {
+ try {
+ return new window.ActiveXObject( "Microsoft.XMLHTTP" );
+ } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+ /* Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+ function() {
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
+ } :
+ // For all other browsers, use the standard XMLHttpRequest object
+ createStandardXHR;
+
+// Determine support properties
+(function( xhr ) {
+ jQuery.extend( jQuery.support, {
+ ajax: !!xhr,
+ cors: !!xhr && ( "withCredentials" in xhr )
+ });
+})( jQuery.ajaxSettings.xhr() );
+
+// Create transport if the browser can provide an xhr
+if ( jQuery.support.ajax ) {
+
+ jQuery.ajaxTransport(function( s ) {
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( !s.crossDomain || jQuery.support.cors ) {
+
+ var callback;
+
+ return {
+ send: function( headers, complete ) {
+
+ // Get a new xhr
+ var xhr = s.xhr(),
+ handle,
+ i;
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
+ } else {
+ xhr.open( s.type, s.url, s.async );
+ }
+
+ // Apply custom fields if provided
+ if ( s.xhrFields ) {
+ for ( i in s.xhrFields ) {
+ xhr[ i ] = s.xhrFields[ i ];
+ }
+ }
+
+ // Override mime type if needed
+ if ( s.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( s.mimeType );
+ }
+
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+ headers[ "X-Requested-With" ] = "XMLHttpRequest";
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+ } catch( _ ) {}
+
+ // Do send the request
+ // This may raise an exception which is actually
+ // handled in jQuery.ajax (so no try/catch here)
+ xhr.send( ( s.hasContent && s.data ) || null );
+
+ // Listener
+ callback = function( _, isAbort ) {
+
+ var status,
+ statusText,
+ responseHeaders,
+ responses,
+ xml;
+
+ // Firefox throws exceptions when accessing properties
+ // of an xhr when a network error occured
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+ try {
+
+ // Was never called and is aborted or complete
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = undefined;
+
+ // Do not keep as active anymore
+ if ( handle ) {
+ xhr.onreadystatechange = jQuery.noop;
+ if ( xhrOnUnloadAbort ) {
+ delete xhrCallbacks[ handle ];
+ }
+ }
+
+ // If it's an abort
+ if ( isAbort ) {
+ // Abort it manually if needed
+ if ( xhr.readyState !== 4 ) {
+ xhr.abort();
+ }
+ } else {
+ status = xhr.status;
+ responseHeaders = xhr.getAllResponseHeaders();
+ responses = {};
+ xml = xhr.responseXML;
+
+ // Construct response list
+ if ( xml && xml.documentElement /* #4958 */ ) {
+ responses.xml = xml;
+ }
+ responses.text = xhr.responseText;
+
+ // Firefox throws an exception when accessing
+ // statusText for faulty cross-domain requests
+ try {
+ statusText = xhr.statusText;
+ } catch( e ) {
+ // We normalize with Webkit giving an empty statusText
+ statusText = "";
+ }
+
+ // Filter status for non standard behaviors
+
+ // If the request is local and we have data: assume a success
+ // (success with no data won't get notified, that's the best we
+ // can do given current implementations)
+ if ( !status && s.isLocal && !s.crossDomain ) {
+ status = responses.text ? 200 : 404;
+ // IE - #1450: sometimes returns 1223 when it should be 204
+ } else if ( status === 1223 ) {
+ status = 204;
+ }
+ }
+ }
+ } catch( firefoxAccessException ) {
+ if ( !isAbort ) {
+ complete( -1, firefoxAccessException );
+ }
+ }
+
+ // Call complete if needed
+ if ( responses ) {
+ complete( status, statusText, responses, responseHeaders );
+ }
+ };
+
+ // if we're in sync mode or it's in cache
+ // and has been retrieved directly (IE6 & IE7)
+ // we need to manually fire the callback
+ if ( !s.async || xhr.readyState === 4 ) {
+ callback();
+ } else {
+ handle = ++xhrId;
+ if ( xhrOnUnloadAbort ) {
+ // Create the active xhrs callbacks list if needed
+ // and attach the unload handler
+ if ( !xhrCallbacks ) {
+ xhrCallbacks = {};
+ jQuery( window ).unload( xhrOnUnloadAbort );
+ }
+ // Add to list of active xhrs callbacks
+ xhrCallbacks[ handle ] = callback;
+ }
+ xhr.onreadystatechange = callback;
+ }
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback(0,1);
+ }
+ }
+ };
+ }
+ });
+}
+
+
+
+
+var elemdisplay = {},
+ iframe, iframeDoc,
+ rfxtypes = /^(?:toggle|show|hide)$/,
+ rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ],
+ fxNow;
+
+jQuery.fn.extend({
+ show: function( speed, easing, callback ) {
+ var elem, display;
+
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("show", 3), speed, easing, callback);
+
+ } else {
+ for ( var i = 0, j = this.length; i < j; i++ ) {
+ elem = this[i];
+
+ if ( elem.style ) {
+ display = elem.style.display;
+
+ // Reset the inline display of this element to learn if it is
+ // being hidden by cascaded rules or not
+ if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
+ display = elem.style.display = "";
+ }
+
+ // Set elements which have been overridden with display: none
+ // in a stylesheet to whatever the default browser style is
+ // for such an element
+ if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
+ jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
+ }
+ }
+ }
+
+ // Set the display of most of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ elem = this[i];
+
+ if ( elem.style ) {
+ display = elem.style.display;
+
+ if ( display === "" || display === "none" ) {
+ elem.style.display = jQuery._data(elem, "olddisplay") || "";
+ }
+ }
+ }
+
+ return this;
+ }
+ },
+
+ hide: function( speed, easing, callback ) {
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("hide", 3), speed, easing, callback);
+
+ } else {
+ for ( var i = 0, j = this.length; i < j; i++ ) {
+ if ( this[i].style ) {
+ var display = jQuery.css( this[i], "display" );
+
+ if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
+ jQuery._data( this[i], "olddisplay", display );
+ }
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ if ( this[i].style ) {
+ this[i].style.display = "none";
+ }
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2, callback ) {
+ var bool = typeof fn === "boolean";
+
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+ this._toggle.apply( this, arguments );
+
+ } else if ( fn == null || bool ) {
+ this.each(function() {
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ });
+
+ } else {
+ this.animate(genFx("toggle", 3), fn, fn2, callback);
+ }
+
+ return this;
+ },
+
+ fadeTo: function( speed, to, easing, callback ) {
+ return this.filter(":hidden").css("opacity", 0).show().end()
+ .animate({opacity: to}, speed, easing, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ if ( jQuery.isEmptyObject( prop ) ) {
+ return this.each( optall.complete, [ false ] );
+ }
+
+ // Do not change referenced properties as per-property easing will be lost
+ prop = jQuery.extend( {}, prop );
+
+ return this[ optall.queue === false ? "each" : "queue" ](function() {
+ // XXX 'this' does not always have a nodeName when running the
+ // test suite
+
+ if ( optall.queue === false ) {
+ jQuery._mark( this );
+ }
+
+ var opt = jQuery.extend( {}, optall ),
+ isElement = this.nodeType === 1,
+ hidden = isElement && jQuery(this).is(":hidden"),
+ name, val, p,
+ display, e,
+ parts, start, end, unit;
+
+ // will store per property easing and be used to determine when an animation is complete
+ opt.animatedProperties = {};
+
+ for ( p in prop ) {
+
+ // property name normalization
+ name = jQuery.camelCase( p );
+ if ( p !== name ) {
+ prop[ name ] = prop[ p ];
+ delete prop[ p ];
+ }
+
+ val = prop[ name ];
+
+ // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
+ if ( jQuery.isArray( val ) ) {
+ opt.animatedProperties[ name ] = val[ 1 ];
+ val = prop[ name ] = val[ 0 ];
+ } else {
+ opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
+ }
+
+ if ( val === "hide" && hidden || val === "show" && !hidden ) {
+ return opt.complete.call( this );
+ }
+
+ if ( isElement && ( name === "height" || name === "width" ) ) {
+ // Make sure that nothing sneaks out
+ // Record all 3 overflow attributes because IE does not
+ // change the overflow attribute when overflowX and
+ // overflowY are set to the same value
+ opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+
+ // Set display property to inline-block for height/width
+ // animations on inline elements that are having width/height
+ // animated
+ if ( jQuery.css( this, "display" ) === "inline" &&
+ jQuery.css( this, "float" ) === "none" ) {
+ if ( !jQuery.support.inlineBlockNeedsLayout ) {
+ this.style.display = "inline-block";
+
+ } else {
+ display = defaultDisplay( this.nodeName );
+
+ // inline-level elements accept inline-block;
+ // block-level elements need to be inline with layout
+ if ( display === "inline" ) {
+ this.style.display = "inline-block";
+
+ } else {
+ this.style.display = "inline";
+ this.style.zoom = 1;
+ }
+ }
+ }
+ }
+ }
+
+ if ( opt.overflow != null ) {
+ this.style.overflow = "hidden";
+ }
+
+ for ( p in prop ) {
+ e = new jQuery.fx( this, opt, p );
+ val = prop[ p ];
+
+ if ( rfxtypes.test(val) ) {
+ e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
+
+ } else {
+ parts = rfxnum.exec( val );
+ start = e.cur();
+
+ if ( parts ) {
+ end = parseFloat( parts[2] );
+ unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
+
+ // We need to compute starting value
+ if ( unit !== "px" ) {
+ jQuery.style( this, p, (end || 1) + unit);
+ start = ((end || 1) / e.cur()) * start;
+ jQuery.style( this, p, start + unit);
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] ) {
+ end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
+ }
+
+ e.custom( start, end, unit );
+
+ } else {
+ e.custom( start, val, "" );
+ }
+ }
+ }
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function( clearQueue, gotoEnd ) {
+ if ( clearQueue ) {
+ this.queue([]);
+ }
+
+ this.each(function() {
+ var timers = jQuery.timers,
+ i = timers.length;
+ // clear marker counters if we know they won't be
+ if ( !gotoEnd ) {
+ jQuery._unmark( true, this );
+ }
+ while ( i-- ) {
+ if ( timers[i].elem === this ) {
+ if (gotoEnd) {
+ // force the next step to be the last
+ timers[i](true);
+ }
+
+ timers.splice(i, 1);
+ }
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if ( !gotoEnd ) {
+ this.dequeue();
+ }
+
+ return this;
+ }
+
+});
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+ setTimeout( clearFxNow, 0 );
+ return ( fxNow = jQuery.now() );
+}
+
+function clearFxNow() {
+ fxNow = undefined;
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, num ) {
+ var obj = {};
+
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+ obj[ this ] = type;
+ });
+
+ return obj;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" },
+ fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return this.animate( props, speed, easing, callback );
+ };
+});
+
+jQuery.extend({
+ speed: function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function( noUnmark ) {
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+
+ if ( opt.queue !== false ) {
+ jQuery.dequeue( this );
+ } else if ( noUnmark !== false ) {
+ jQuery._unmark( this );
+ }
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ) {
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ options.orig = options.orig || {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+ // Simple function for setting a style value
+ update: function() {
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+ },
+
+ // Get the current size
+ cur: function() {
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+ return this.elem[ this.prop ];
+ }
+
+ var parsed,
+ r = jQuery.css( this.elem, this.prop );
+ // Empty strings, null, undefined and "auto" are converted to 0,
+ // complex values such as "rotate(1rad)" are returned as is,
+ // simple values such as "10px" are parsed to Float.
+ return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
+ },
+
+ // Start an animation from one number to another
+ custom: function( from, to, unit ) {
+ var self = this,
+ fx = jQuery.fx;
+
+ this.startTime = fxNow || createFxNow();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ function t( gotoEnd ) {
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval( fx.tick, fx.interval );
+ }
+ },
+
+ // Simple 'show' function
+ show: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery( this.elem ).show();
+ },
+
+ // Simple 'hide' function
+ hide: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function( gotoEnd ) {
+ var t = fxNow || createFxNow(),
+ done = true,
+ elem = this.elem,
+ options = this.options,
+ i, n;
+
+ if ( gotoEnd || t >= options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ options.animatedProperties[ this.prop ] = true;
+
+ for ( i in options.animatedProperties ) {
+ if ( options.animatedProperties[i] !== true ) {
+ done = false;
+ }
+ }
+
+ if ( done ) {
+ // Reset the overflow
+ if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
+
+ jQuery.each( [ "", "X", "Y" ], function (index, value) {
+ elem.style[ "overflow" + value ] = options.overflow[index];
+ });
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( options.hide ) {
+ jQuery(elem).hide();
+ }
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( options.hide || options.show ) {
+ for ( var p in options.animatedProperties ) {
+ jQuery.style( elem, p, options.orig[p] );
+ }
+ }
+
+ // Execute the complete function
+ options.complete.call( elem );
+ }
+
+ return false;
+
+ } else {
+ // classical easing cannot be used with an Infinity duration
+ if ( options.duration == Infinity ) {
+ this.now = t;
+ } else {
+ n = t - this.startTime;
+ this.state = n / options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
+ this.now = this.start + ((this.end - this.start) * this.pos);
+ }
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+};
+
+jQuery.extend( jQuery.fx, {
+ tick: function() {
+ for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
+ if ( !timers[i]() ) {
+ timers.splice(i--, 1);
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ },
+
+ interval: 13,
+
+ stop: function() {
+ clearInterval( timerId );
+ timerId = null;
+ },
+
+ speeds: {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+
+ step: {
+ opacity: function( fx ) {
+ jQuery.style( fx.elem, "opacity", fx.now );
+ },
+
+ _default: function( fx ) {
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+ fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+ } else {
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+
+// Try to restore the default display value of an element
+function defaultDisplay( nodeName ) {
+
+ if ( !elemdisplay[ nodeName ] ) {
+
+ var body = document.body,
+ elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
+ display = elem.css( "display" );
+
+ elem.remove();
+
+ // If the simple way fails,
+ // get element's real default display by attaching it to a temp iframe
+ if ( display === "none" || display === "" ) {
+ // No iframe to use yet, so create it
+ if ( !iframe ) {
+ iframe = document.createElement( "iframe" );
+ iframe.frameBorder = iframe.width = iframe.height = 0;
+ }
+
+ body.appendChild( iframe );
+
+ // Create a cacheable copy of the iframe document on first call.
+ // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
+ // document to it; WebKit & Firefox won't allow reusing the iframe document.
+ if ( !iframeDoc || !iframe.createElement ) {
+ iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
+ iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
+ iframeDoc.close();
+ }
+
+ elem = iframeDoc.createElement( nodeName );
+
+ iframeDoc.body.appendChild( elem );
+
+ display = jQuery.css( elem, "display" );
+
+ body.removeChild( iframe );
+ }
+
+ // Store the correct default display
+ elemdisplay[ nodeName ] = display;
+ }
+
+ return elemdisplay[ nodeName ];
+}
+
+
+
+
+var rtable = /^t(?:able|d|h)$/i,
+ rroot = /^(?:body|html)$/i;
+
+if ( "getBoundingClientRect" in document.documentElement ) {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0], box;
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ try {
+ box = elem.getBoundingClientRect();
+ } catch(e) {}
+
+ var doc = elem.ownerDocument,
+ docElem = doc.documentElement;
+
+ // Make sure we're not dealing with a disconnected DOM node
+ if ( !box || !jQuery.contains( docElem, elem ) ) {
+ return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
+ }
+
+ var body = doc.body,
+ win = getWindow(doc),
+ clientTop = docElem.clientTop || body.clientTop || 0,
+ clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
+ scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
+ top = box.top + scrollTop - clientTop,
+ left = box.left + scrollLeft - clientLeft;
+
+ return { top: top, left: left };
+ };
+
+} else {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ jQuery.offset.initialize();
+
+ var computedStyle,
+ offsetParent = elem.offsetParent,
+ prevOffsetParent = elem,
+ doc = elem.ownerDocument,
+ docElem = doc.documentElement,
+ body = doc.body,
+ defaultView = doc.defaultView,
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+ top = elem.offsetTop,
+ left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ break;
+ }
+
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+ top -= elem.scrollTop;
+ left -= elem.scrollLeft;
+
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevOffsetParent = offsetParent;
+ offsetParent = elem.offsetParent;
+ }
+
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+ top += body.offsetTop;
+ left += body.offsetLeft;
+ }
+
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ top += Math.max( docElem.scrollTop, body.scrollTop );
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
+ }
+
+ return { top: top, left: left };
+ };
+}
+
+jQuery.offset = {
+ initialize: function() {
+ var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
+ html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+ jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+ container.innerHTML = html;
+ body.insertBefore( container, body.firstChild );
+ innerDiv = container.firstChild;
+ checkDiv = innerDiv.firstChild;
+ td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ checkDiv.style.position = "fixed";
+ checkDiv.style.top = "20px";
+
+ // safari subtracts parent border width here which is 5px
+ this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+ checkDiv.style.position = checkDiv.style.top = "";
+
+ innerDiv.style.overflow = "hidden";
+ innerDiv.style.position = "relative";
+
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+ body.removeChild( container );
+ jQuery.offset.initialize = jQuery.noop;
+ },
+
+ bodyOffset: function( body ) {
+ var top = body.offsetTop,
+ left = body.offsetLeft;
+
+ jQuery.offset.initialize();
+
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+ top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
+ left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
+ }
+
+ return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options, i ) {
+ var position = jQuery.css( elem, "position" );
+
+ // set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curCSSTop = jQuery.css( elem, "top" ),
+ curCSSLeft = jQuery.css( elem, "left" ),
+ calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+ props = {}, curPosition = {}, curTop, curLeft;
+
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ curTop = curPosition.top;
+ curLeft = curPosition.left;
+ } else {
+ curTop = parseFloat( curCSSTop ) || 0;
+ curLeft = parseFloat( curCSSLeft ) || 0;
+ }
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ if (options.top != null) {
+ props.top = (options.top - curOffset.top) + curTop;
+ }
+ if (options.left != null) {
+ props.left = (options.left - curOffset.left) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ if ( !this[0] ) {
+ return null;
+ }
+
+ var elem = this[0],
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
+ offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
+ parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.body;
+ while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function( val ) {
+ var elem, win;
+
+ if ( val === undefined ) {
+ elem = this[ 0 ];
+
+ if ( !elem ) {
+ return null;
+ }
+
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery( win ).scrollLeft(),
+ i ? val : jQuery( win ).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ };
+});
+
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+
+
+
+
+// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn[ "inner" + name ] = function() {
+ var elem = this[0];
+ return elem && elem.style ?
+ parseFloat( jQuery.css( elem, type, "padding" ) ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn[ "outer" + name ] = function( margin ) {
+ var elem = this[0];
+ return elem && elem.style ?
+ parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ if ( jQuery.isWindow( elem ) ) {
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
+ var docElemProp = elem.document.documentElement[ "client" + name ],
+ body = elem.document.body;
+ return elem.document.compatMode === "CSS1Compat" && docElemProp ||
+ body && body[ "client" + name ] || docElemProp;
+
+ // Get document width or height
+ } else if ( elem.nodeType === 9 ) {
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ return Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ );
+
+ // Get or set width or height on the element
+ } else if ( size === undefined ) {
+ var orig = jQuery.css( elem, type ),
+ ret = parseFloat( orig );
+
+ return jQuery.isNaN( ret ) ? orig : ret;
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ } else {
+ return this.css( type, typeof size === "string" ? size : size + "px" );
+ }
+ };
+
+});
+
+
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+})(window); \ No newline at end of file
diff --git a/lib/scripts/jquery/jquery.min.js b/lib/scripts/jquery/jquery.min.js
new file mode 100644
index 000000000..3684c36b5
--- /dev/null
+++ b/lib/scripts/jquery/jquery.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */
+(function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function bZ(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bY(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bA.test(a)?d(a,e):bY(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)bY(a+"["+e+"]",b[e],c,d);else d(a,b)}function bX(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bW(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bP,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bW(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bW(a,c,d,e,"*",g));return l}function bV(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bL),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function by(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bt:bu;if(d>0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bf(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function V(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(Q.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(w,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.4",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:H?function(a){return a==null?"":H.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?F.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(!b)return-1;if(I)return I.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=G.call(arguments,2),g=function(){return a.apply(c,f.concat(G.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){J["[object "+b+"]"]=b.toLowerCase()}),A=e.uaMatch(z),A.browser&&(e.browser[A.browser]=!0,e.browser.version=A.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?C=function(){c.removeEventListener("DOMContentLoaded",C,!1),e.ready()}:c.attachEvent&&(C=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",C),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),h&&f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g+"With"](this===b?d:this,[h])}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i=f.expando,j=typeof c=="string",k=a.nodeType,l=k?f.cache:a,m=k?a[f.expando]:a[f.expando]&&f.expando;if((!m||e&&m&&l[m]&&!l[m][i])&&j&&d===b)return;m||(k?a[f.expando]=m=++f.uuid:m=f.expando),l[m]||(l[m]={},k||(l[m].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?l[m][i]=f.extend(l[m][i],c):l[m]=f.extend(l[m],c);g=l[m],e&&(g[i]||(g[i]={}),g=g[i]),d!==b&&(g[f.camelCase(c)]=d);if(c==="events"&&!g[c])return g[i]&&g[i].events;j?(h=g[c],h==null&&(h=g[f.camelCase(c)])):h=g;return h}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e=f.expando,g=a.nodeType,h=g?f.cache:a,i=g?a[f.expando]:f.expando;if(!h[i])return;if(b){d=c?h[i][e]:h[i];if(d){d[b]||(b=f.camelCase(b)),delete d[b];if(!l(d))return}}if(c){delete h[i][e];if(!l(h[i]))return}var j=h[i][e];f.support.deleteExpando||!h.setInterval?delete h[i]:h[i]=null,j?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=j):g&&(f.support.deleteExpando?delete a[f.expando]:a.removeAttribute?a.removeAttribute(f.expando):a[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,l.done(m);m();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,u,v;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(o);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(o);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(n," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h<i;h++){var j=e[h];if(j.selected&&(f.support.optDisabled?!j.disabled:j.getAttribute("disabled")===null)&&(!j.parentNode.disabled||!f.nodeName(j.parentNode,"optgroup"))){b=f(j).val();if(g)return b;d.push(b)}}if(g&&!d.length&&e.length)return f(e[c]).val();return d},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=v:u&&(i=u)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.attr(a,b,""),a.removeAttribute(b),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(u&&f.nodeName(a,"button"))return u.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(u&&f.nodeName(a,"button"))return u.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==null?g:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabIndex=f.propHooks.tabIndex,v={get:function(a,c){var d;return f.prop(a,c)===!0||(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(u=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=/\.(.*)$/,x=/^(?:textarea|input|select)$/i,y=/\./g,z=/ /g,A=/[^\w\s.|`]/g,B=function(a){return a.replace(A,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=C;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=C);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),B).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete
+t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,M(a.origType,a.selector),f.extend({},a,{handler:L,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,M(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?D:C):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=D;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=D;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=D,this.stopPropagation()},isDefaultPrevented:C,isPropagationStopped:C,isImmediatePropagationStopped:C};var E=function(a){var b=a.relatedTarget,c=!1,d=a.type;a.type=a.data,b!==this&&(b&&(c=f.contains(this,b)),c||(f.event.handle.apply(this,arguments),a.type=d))},F=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?F:E,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?F:E)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=f.nodeName(b,"input")||f.nodeName(b,"button")?b.type:"";(c==="submit"||c==="image")&&f(b).closest("form").length&&J("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=f.nodeName(b,"input")||f.nodeName(b,"button")?b.type:"";(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&J("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var G,H=function(a){var b=f.nodeName(a,"input")?a.type:"",c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},I=function(c){var d=c.target,e,g;if(!!x.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=H(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:I,beforedeactivate:I,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&I.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&I.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",H(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in G)f.event.add(this,c+".specialChange",G[c]);return x.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return x.test(this.nodeName)}},G=f.event.special.change.filters,G.focus=G.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var K={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||C,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=w.exec(h),k="",j&&(k=j[0],h=h.replace(w,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,K[h]?(a.push(K[h]+k),h=h+k):h=(K[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+M(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+M(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){if(a===b){g=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var N=/Until$/,O=/^(?:parents|prevUntil|prevAll)/,P=/,/,Q=/^.[^:#\[\.,]*$/,R=Array.prototype.slice,S=f.expr.match.POS,T={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(V(this,a,!1),"not",a)},filter:function(a){return this.pushStack(V(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=S.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=S.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(U(c[0])||U(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=R.call(arguments);N.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!T[a]?f.unique(e):e,(this.length>1||P.test(d))&&O.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|object|embed|option|style)/i,bb=/checked\s*(?:[^=]|=\s*.checked.)/i,bc=/\/(java|ecma)script/i,bd=/^\s*<!(?:\[CDATA\[|\-\-)/,be={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!be[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bb.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bf(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bl)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i;b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!ba.test(a[0])&&(f.support.checkClone||!bb.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean
+(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)g[h]&&bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=be[l]||be._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bk(k[i]);else bk(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||bc.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bm=/alpha\([^)]*\)/i,bn=/opacity=([^)]*)/,bo=/([A-Z]|^ms)/g,bp=/^-?\d+(?:px)?$/i,bq=/^-?\d/,br=/^([\-+])=([\-+.\de]+)/,bs={position:"absolute",visibility:"hidden",display:"block"},bt=["Left","Right"],bu=["Top","Bottom"],bv,bw,bx;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bv(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=br.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bv)return bv(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return by(a,b,d);f.swap(a,bs,function(){e=by(a,b,d)});return e}},set:function(a,b){if(!bp.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bm,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bv(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bw=function(a,c){var d,e,g;c=c.replace(bo,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bx=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bp.test(d)&&bq.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bv=bw||bx,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bz=/%20/g,bA=/\[\]$/,bB=/\r?\n/g,bC=/#.*$/,bD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bE=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bF=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bG=/^(?:GET|HEAD)$/,bH=/^\/\//,bI=/\?/,bJ=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bK=/^(?:select|textarea)/i,bL=/\s+/,bM=/([?&])_=[^&]*/,bN=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bO=f.fn.load,bP={},bQ={},bR,bS,bT=["*/"]+["*"];try{bR=e.href}catch(bU){bR=c.createElement("a"),bR.href="",bR=bR.href}bS=bN.exec(bR.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bO)return bO.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bJ,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bK.test(this.nodeName)||bE.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bB,"\r\n")}}):{name:b.name,value:c.replace(bB,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?bX(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),bX(a,b);return a},ajaxSettings:{url:bR,isLocal:bF.test(bS[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bT},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bV(bP),ajaxTransport:bV(bQ),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?bZ(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=b$(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bD.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bC,"").replace(bH,bS[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bL),d.crossDomain==null&&(r=bN.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bS[1]&&r[2]==bS[2]&&(r[3]||(r[1]==="http:"?80:443))==(bS[3]||(bS[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bW(bP,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bG.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bI.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bM,"$1_="+x);d.url=y+(y===d.url?(bI.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bT+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bW(bQ,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bz,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cq("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cr(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cq("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cq("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=cr(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block"))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],cj.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=ck.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[i]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cq("show",1),slideUp:cq("hide",1),slideToggle:cq("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function g(a){return d.step(a)}var d=this,e=f.fx;this.startTime=cn||co(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,g.elem=this.elem,g()&&f.timers.push(g)&&!cl&&(cl=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=cn||co(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b<a.length;++b)a[b]()||a.splice(b--,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cl),cl=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cs=/^t(?:able|d|h)$/i,ct=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cu(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cs.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=ct.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!ct.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cu(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cu(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNaN(j)?i:j}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file
diff --git a/lib/scripts/jquery/update.sh b/lib/scripts/jquery/update.sh
new file mode 100755
index 000000000..fde46f4d7
--- /dev/null
+++ b/lib/scripts/jquery/update.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# This script loads the latest jQuery and jQuery-UI 1.* versions from Google's CDN
+#
+# It also loads the 'smoothness' jQuery-UI theme and all referenced images.
+#
+# @author Andreas Gohr <andi@splitbrain.org>
+# @link https://code.google.com/apis/libraries/devguide.html#jquery
+
+# load jQuery
+wget -nv https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js -O jquery.min.js
+wget -nv https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js -O jquery.js
+
+# load jQuery-UI
+wget -nv https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js -O jquery-ui.min.js
+wget -nv https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.js -O jquery-ui.js
+
+# load the smoothness theme
+mkdir -p jquery-ui-theme/images
+wget -nv https://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/smoothness/jquery-ui.css -O 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 https://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/smoothness/$img -O jquery-ui-theme/$img
+done
+
+# remove font family declarations from smoothness CSS
+sed -i "s/font-family:[^;]*; \?//" jquery-ui-theme/smoothness.css
diff --git a/lib/scripts/linkwiz.js b/lib/scripts/linkwiz.js
new file mode 100644
index 000000000..5075a0ab8
--- /dev/null
+++ b/lib/scripts/linkwiz.js
@@ -0,0 +1,308 @@
+/**
+ * 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
+ 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');
+
+ // attach event handlers
+ jQuery('#link__wiz_close').click(dw_linkwiz.hide);
+ dw_linkwiz.$entry.keyup(dw_linkwiz.onEntry);
+ jQuery(dw_linkwiz.result).delegate('a', 'click', 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){
+ 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 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 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 = getSelection(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+3;
+
+ link = '[['+link+'|';
+ if(stxt) {
+ link += stxt;
+ }
+ link += ']]';
+
+ pasteText(sel,link,{startofs: so, endofs: 2});
+ dw_linkwiz.hide();
+
+ // reset the entry to the parent namespace
+ dw_linkwiz.$entry.val(dw_linkwiz.$entry.val().replace(/[^:]*$/, ''));
+ },
+
+ /**
+ * 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 = getSelection(dw_linkwiz.textArea);
+ dw_linkwiz.$wiz.show();
+ dw_linkwiz.$entry.focus();
+ dw_linkwiz.autocomplete();
+ },
+
+ /**
+ * 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/lib/scripts/locktimer.js b/lib/scripts/locktimer.js
new file mode 100644
index 000000000..96f963c08
--- /dev/null
+++ b/lib/scripts/locktimer.js
@@ -0,0 +1,126 @@
+/**
+ * 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: '',
+
+ /**
+ * Initialize the lock timer
+ *
+ * @param int timeout Length of timeout in seconds
+ * @param string msg Deprecated; The expiry message
+ * @param bool draft Whether to save drafts
+ * @param string edid Optional; ID of an edit object which has to be present
+ */
+ init: function(timeout,msg,draft,edid){
+ var $edit;
+
+ switch (arguments.length) {
+ case 4:
+ DEPRECATED('Setting the locktimer expiry message is deprecated');
+ dw_locktimer.msg = msg;
+ break;
+ case 3:
+ edid = draft;
+ case 2:
+ draft = msg;
+ }
+ 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 input[name=id]').val();
+ if(!dw_locktimer.pageid) {
+ return;
+ }
+
+ // register refresh event
+ $edit.keypress(dw_locktimer.refresh);
+ // start timer
+ dw_locktimer.reset();
+ },
+
+ /**
+ * (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 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 textarea[name=wikitext]').length > 0){
+ params += jQuery('#dw__editform').find('input[name=prefix], ' +
+ 'textarea[name=wikitext], ' +
+ 'input[name=suffix], ' +
+ 'input[name=date]').serialize();
+ }
+
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ params,
+ dw_locktimer.refreshed,
+ 'html'
+ );
+ dw_locktimer.lasttime = now;
+ },
+
+ /**
+ * Callback. Resets the warning timer
+ */
+ refreshed: function(data){
+ var error = data.charAt(0);
+ data = data.substring(1);
+
+ jQuery('#draft__status').html(data);
+ if(error != '1') {
+ return; // locking failed
+ }
+ dw_locktimer.reset();
+ }
+};
diff --git a/lib/scripts/media.js b/lib/scripts/media.js
new file mode 100644
index 000000000..841baa93f
--- /dev/null
+++ b/lib/scripts/media.js
@@ -0,0 +1,940 @@
+/**
+ * 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');
+
+ dw_mediamanager.prepare_content($content);
+
+ dw_mediamanager.attachoptions();
+ dw_mediamanager.initpopup();
+
+ // add the action to autofill the "upload as" field
+ $content.delegate('#upload__file', 'change', dw_mediamanager.suggest)
+ // Attach the image selector action to all links
+ .delegate('a.select', 'click', dw_mediamanager.select)
+ // Attach deletion confirmation dialog to the delete buttons
+ .delegate('#media__content a.btn_media_delete', 'click',
+ dw_mediamanager.confirmattach)
+ .delegate('#mediamanager__done_form', 'submit', 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.delegate('a', 'click', 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
+ jQuery('#mediamanager__page div.filelist').delegate('ul.tabs a', 'click', dw_mediamanager.list)
+ // loading file details
+ .delegate('div.panelContent a', 'click', dw_mediamanager.details)
+ // search form
+ .delegate('#dw__mediasearch', 'submit', dw_mediamanager.list)
+ // "upload as" field autofill
+ .delegate('#upload__file', 'change', dw_mediamanager.suggest)
+ // uploaded images
+ .delegate('.qq-upload-file a', 'click', dw_mediamanager.details);
+
+ // changing opened tab in the file details panel
+ jQuery('#mediamanager__page div.file').delegate('ul.tabs a', 'click', dw_mediamanager.details)
+ // "update new version" button
+ .delegate('#mediamanager__btn_update', 'submit', dw_mediamanager.list)
+ // revisions form
+ .delegate('#page__revisions', 'submit', dw_mediamanager.details)
+ .delegate('#page__revisions a', 'click', dw_mediamanager.details)
+ // meta edit form
+ .delegate('#mediamanager__save_meta', 'submit', dw_mediamanager.details)
+ // delete button
+ .delegate('#mediamanager__btn_delete', 'submit', dw_mediamanager.details)
+ // "restore this version" button
+ .delegate('#mediamanager__btn_restore', 'submit', dw_mediamanager.details)
+ // less/more recent buttons in media revisions form
+ .delegate('.btn_newer, .btn_older', 'submit', dw_mediamanager.details);
+
+ dw_mediamanager.update_resizable();
+ dw_mediamanager.layout_width = jQuery("#mediamanager__page").width();
+ jQuery(window).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('input[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.buttonset();
+
+ // Change handlers
+ $listType.children('input').change(function (event) {
+ 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])
+ .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, alignleft, alignright, edid, s;
+
+ // set syntax options
+ dw_mediamanager.$popup.dialog('close');
+
+ opts = '';
+ alignleft = '';
+ alignright = '';
+
+ 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);
+
+ if (s && s >= 1 && s < 4) {
+ opts += (opts.length)?'&':'?';
+ opts += dw_mediamanager.size + '00';
+ if (dw_mediamanager.ext === 'swf') {
+ switch (s) {
+ case 1:
+ opts += 'x62';
+ break;
+ case 2:
+ opts += 'x123';
+ break;
+ case 3:
+ opts += 'x185';
+ break;
+ }
+ }
+ }
+ if (dw_mediamanager.align !== '1') {
+ alignleft = dw_mediamanager.align === '2' ? '' : ' ';
+ alignright = dw_mediamanager.align === '4' ? '' : ' ';
+ }
+ }
+ }
+ edid = String.prototype.match.call(document.location, /&edid=([^&]+)/);
+ opener.insertTags(edid ? edid[1] : 'wiki__text',
+ '{{'+alignleft+id+opts+alignright+'|','}}','');
+
+ 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('input[value="Apply"]')[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/loading.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 () {
+ $resizables = dw_mediamanager.$resizables();
+
+ $resizables.resizable({
+ handles: 'e',
+ resize: function(event, ui){
+ var widthFull = jQuery('#mediamanager__page').width();
+ var widthResizables = 0;
+ $resizables.each(function() {
+ widthResizables += jQuery(this).width();
+ });
+ var $filePanel = jQuery('#mediamanager__page 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);
+ $resizables.resizable( "option", "maxWidth", maxWidth );
+
+ // width of file panel in % = 100% - width of resizables in %
+ // this calculates with 99.99 and not 100 to overcome rounding errors
+ var relWidthNonResizable = 99.99 - (100 * widthResizables / widthFull);
+ // set width of file panel
+ $filePanel.width(relWidthNonResizable+'%');
+
+ // FIXME: please fix without browser sniffing
+ if (!jQuery.browser.webkit) {
+ $resizables.each(function() {
+ w = jQuery(this).width();
+ w = (99.99 * w / widthFull);
+ w += "%";
+ jQuery(this).width(w);
+ });
+ }
+
+ dw_mediamanager.opacity_slider();
+ dw_mediamanager.portions_slider();
+ }
+ });
+
+ dw_mediamanager.resize();
+ },
+
+ resize: function () {
+ var $contents = jQuery('#mediamanager__page 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;
+
+ $form = jQuery('#mediamanager__form_diffview');
+ if (!$form.length) return;
+
+ $label = jQuery(document.createElement('label'));
+ $label.append('<span>'+LANG.media_diff+'</span> ');
+ $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 () {
+ $select = jQuery('#mediamanager__difftype');
+ $content = jQuery('#mediamanager__diff');
+
+ 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 $slider = jQuery( "#mediamanager__diff div.slider" );
+ if (!$slider.length) return;
+
+ var $image = jQuery('#mediamanager__diff 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.bind("slide", function(event, ui) {
+ jQuery('#mediamanager__diff 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 $image1 = jQuery('#mediamanager__diff div.imageDiff.portions div.image1 img');
+ var $image2 = jQuery('#mediamanager__diff div.imageDiff.portions div.image2 img');
+ if (!$image1.length || !$image2.length) return;
+
+ var $div = jQuery("#mediamanager__diff");
+ if (!$div.length) return;
+
+ $div.width('100%');
+ $image2.parent().width('97%');
+ $image1.width('100%');
+ $image2.width('100%');
+
+ if ($image1.width() < $div.width()) {
+ $div.width($image1.width());
+ }
+
+ $image2.parent().width('50%');
+ $image2.width($image1.width());
+ $image1.width($image1.width());
+
+ var $slider = jQuery("#mediamanager__diff 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.bind("slide", function(event, ui) {
+ jQuery('#mediamanager__diff 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();
+ },
+
+ /**
+ * shows the popup for a image link
+ */
+ select: function(event){
+ var $link, id, dot, ext;
+
+ event.preventDefault();
+
+ $link = jQuery(this);
+ id = $link.attr('name').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.
+ jQuery('#media__sendbtn').unbind().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');
+
+ jQuery('#media__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])
+ .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 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;
+ }
+};
+
+// moved from helpers.js temporarily here
+/**
+ * Very simplistic Flash plugin check, probably works for Flash 8 and higher only
+ *
+ */
+function hasFlash(version){
+ var ver = 0, axo;
+ try{
+ if(navigator.plugins !== null && navigator.plugins.length > 0){
+ ver = navigator.plugins["Shockwave Flash"].description.split(' ')[2].split('.')[0];
+ }else{
+ axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+ ver = axo.GetVariable("$version").split(' ')[1].split(',')[0];
+ }
+ }catch(e){ }
+
+ return ver >= version;
+}
+
+jQuery(dw_mediamanager.init);
diff --git a/lib/scripts/page.js b/lib/scripts/page.js
new file mode 100644
index 000000000..5da4a9cc0
--- /dev/null
+++ b/lib/scripts/page.js
@@ -0,0 +1,141 @@
+/**
+ * Page behaviours
+ *
+ * This class adds various behaviours to the rendered page
+ */
+dw_page = {
+ /**
+ * initialize page behaviours
+ */
+ init: function(){
+ dw_page.sectionHighlight();
+ jQuery('a.fn_top').mouseover(dw_page.footnoteDisplay);
+ dw_page.initTocToggle();
+ },
+
+ /**
+ * Highlight the section when hovering over the appropriate section edit button
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ sectionHighlight: function() {
+ jQuery('form.btn_secedit')
+ .mouseover(function(){
+ var $tgt = jQuery(this).parent(),
+ nr = $tgt.attr('class').match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2];
+
+ // Walk the DOM tree up (first previous siblings, then parents)
+ // until boundary element
+ while($tgt.length > 0 && !$tgt.hasClass('sectionedit' + nr)) {
+ // $.last gives the DOM-ordered last element:
+ // prev if present, else parent.
+ $tgt = $tgt.prev().add($tgt.parent()).last();
+ $tgt.addClass('section_highlight');
+ }
+ })
+ .mouseout(function(){
+ jQuery('.section_highlight').removeClass('section_highlight');
+ });
+ },
+
+ /**
+ * 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')
+ .mouseleave(function () {jQuery(this).hide();});
+ 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>
+ */
+ footnoteDisplay: function () {
+ var content = jQuery(jQuery(this).attr('href')) // Footnote text anchor
+ .closest('div.fn').html();
+
+ if (content === null){
+ return;
+ }
+
+ // strip the leading content anchors and their comma separators
+ content = content.replace(/((^|\s*,\s*)<sup>.*?<\/sup>)+\s*/gi, '');
+
+ // prefix ids on any elements with "insitu__" to ensure they remain unique
+ content = content.replace(/\bid=(['"])([^"']+)\1/gi,'id="insitu__$2');
+
+ // now put the content into the wrapper
+ dw_page.insituPopup(this, 'insitu__fn').html(content).show();
+ },
+
+ /**
+ * Adds the toggle switch to the TOC
+ */
+ initTocToggle: function() {
+ var $header, $clicky, $toc, $tocul, setClicky;
+ $header = jQuery('#toc__header');
+ if(!$header.length) {
+ return;
+ }
+ $toc = jQuery('#toc__inside');
+ $tocul = $toc.children('ul.toc');
+
+ setClicky = function(hiding){
+ if(hiding){
+ $clicky.html('<span>+</span>');
+ $clicky[0].className = 'toc_open';
+ }else{
+ $clicky.html('<span>&minus;</span>');
+ $clicky[0].className = 'toc_close';
+ }
+ };
+
+ $clicky = jQuery(document.createElement('span'))
+ .attr('id','toc__toggle');
+ $header.css('cursor','pointer')
+ .click(function () {
+ var hidden;
+
+ // Assert that $toc instantly takes the whole TOC space
+ $toc.css('height', $toc.height()).show();
+
+ hidden = $tocul.stop(true, true).is(':hidden');
+
+ setClicky(!hidden);
+
+ // Start animation and assure that $toc is hidden/visible
+ $tocul.dw_toggle(hidden, function () {
+ $toc.toggle(hidden);
+ });
+ })
+ .prepend($clicky);
+
+ setClicky();
+ }
+};
+
+jQuery(dw_page.init);
diff --git a/lib/scripts/qsearch.js b/lib/scripts/qsearch.js
new file mode 100644
index 000000000..a309f9e29
--- /dev/null
+++ b/lib/scripts/qsearch.js
@@ -0,0 +1,146 @@
+/**
+ * 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>
+ */
+
+var dw_qsearch = {
+
+ $inObj: null,
+ $outObj: null,
+ timer: null,
+
+ /**
+ * initialize the quick search
+ *
+ * Attaches the event handlers
+ *
+ * @param input element (jQuery selector/DOM obj)
+ * @param output element (jQuery selector/DOM obj)
+ */
+ init: function (input, output) {
+ var do_qsearch;
+
+ dw_qsearch.$inObj = jQuery(input);
+ dw_qsearch.$outObj = jQuery(output);
+
+ // objects found?
+ if (dw_qsearch.$inObj.length === 0 ||
+ dw_qsearch.$outObj.length === 0) {
+ return;
+ }
+
+ // attach eventhandler to search field
+ do_qsearch = function () {
+ dw_qsearch.clear_results();
+ var value = dw_qsearch.$inObj.val();
+ if (value === '') {
+ return;
+ }
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'qsearch',
+ q: encodeURI(value)
+ },
+ dw_qsearch.onCompletion,
+ 'html'
+ );
+ };
+
+ dw_qsearch.$inObj.keyup(
+ function() {
+ if(dw_qsearch.timer){
+ window.clearTimeout(dw_qsearch.timer);
+ dw_qsearch.timer = null;
+ }
+ dw_qsearch.clear_results();
+ dw_qsearch.timer = window.setTimeout(do_qsearch, 500);
+ }
+ );
+
+ // attach eventhandler to output field
+ dw_qsearch.$outObj.click(dw_qsearch.clear_results);
+ },
+
+ /**
+ * Empty and hide the output div
+ */
+ clear_results: function(){
+ 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;
+
+ if (data === '') { return; }
+
+ dw_qsearch.$outObj
+ .html(data)
+ .show()
+ .css('white-space', 'nowrap');
+
+ // shorten namespaces if too long
+ max = dw_qsearch.$outObj[0].clientWidth;
+ $links = dw_qsearch.$outObj.find('a');
+ too_big = (document.documentElement.dir === 'rtl')
+ ? function (l) { return l.offsetLeft < 0; }
+ : 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.innerText.indexOf('(');
+ nsR = this.innerText.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.innerText = substr_replace(this.innerText,
+ replace, start, length);
+
+ eli = this.innerText.indexOf('…');
+ nsL = this.innerText.indexOf('(');
+ nsR = this.innerText.indexOf(')');
+ }
+ });
+ }
+};
+
+jQuery(function () {
+ dw_qsearch.init('#qsearch__in','#qsearch__out');
+});
diff --git a/lib/scripts/script.js b/lib/scripts/script.js
new file mode 100644
index 000000000..5fddb0431
--- /dev/null
+++ b/lib/scripts/script.js
@@ -0,0 +1,63 @@
+// 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);
+}
+
+/**
+ * Prints a animated gif to show the search is performed
+ *
+ * Because we need to modify the DOM here before the document is loaded
+ * and parsed completely we have to rely on document.write()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function showLoadBar(){
+
+ document.write('<img src="'+DOKU_BASE+'lib/images/loading.gif" '+
+ 'width="150" height="12" alt="..." />');
+
+ /* this does not work reliable in IE
+ obj = $(id);
+
+ if(obj){
+ obj.innerHTML = '<img src="'+DOKU_BASE+'lib/images/loading.gif" '+
+ 'width="150" height="12" alt="..." />';
+ obj.style.display="block";
+ }
+ */
+}
+
+/**
+ * Disables the animated gif to show the search is done
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function hideLoadBar(id){
+ jQuery('#' + id).hide();
+}
+
+/**
+ * Handler to close all open Popups
+ */
+function closePopups(){
+ jQuery('div.JSpopup').hide();
+}
+
+jQuery(function () {
+ jQuery(document).click(closePopups);
+});
diff --git a/lib/scripts/textselection.js b/lib/scripts/textselection.js
new file mode 100644
index 000000000..bd80e9341
--- /dev/null
+++ b/lib/scripts/textselection.js
@@ -0,0 +1,233 @@
+/**
+ * Text selection related functions.
+ */
+
+/**
+ * selection prototype
+ *
+ * Object that capsulates the selection in a textarea. Returned by getSelection.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function selection_class(){
+ this.start = 0;
+ this.end = 0;
+ this.obj = null;
+ this.rangeCopy = 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 getSelection(textArea) {
+ var sel = new selection_class();
+
+ sel.obj = textArea;
+ sel.start = textArea.value.length;
+ sel.end = textArea.value.length;
+ textArea.focus();
+ if(document.getSelection) { // Mozilla et al.
+ sel.start = textArea.selectionStart;
+ sel.end = textArea.selectionEnd;
+ sel.scroll = textArea.scrollTop;
+ } else if(document.selection) { // MSIE
+ /*
+ * This huge lump of code is neccessary to work around two MSIE bugs:
+ *
+ * 1. Selections trim newlines at the end of the code
+ * 2. Selections count newlines as two characters
+ */
+
+ // The current selection
+ sel.rangeCopy = document.selection.createRange().duplicate();
+ if (textArea.tagName === 'INPUT') {
+ var before_range = textArea.createTextRange();
+ before_range.expand('textedit'); // Selects all the text
+ } else {
+ var before_range = document.body.createTextRange();
+ before_range.moveToElementText(textArea); // Selects all the text
+ }
+ before_range.setEndPoint("EndToStart", sel.rangeCopy); // Moves the end where we need it
+
+ var before_finished = false, selection_finished = false;
+ var before_text, selection_text;
+ // Load the text values we need to compare
+ before_text = before_range.text;
+ selection_text = sel.rangeCopy.text;
+
+ sel.start = before_text.length;
+ sel.end = sel.start + selection_text.length;
+
+ // Check each range for trimmed newlines by shrinking the range by 1 character and seeing
+ // if the text property has changed. If it has not changed then we know that IE has trimmed
+ // a \r\n from the end.
+ do {
+ if (!before_finished) {
+ if (before_range.compareEndPoints("StartToEnd", before_range) == 0) {
+ before_finished = true;
+ } else {
+ before_range.moveEnd("character", -1);
+ if (before_range.text == before_text) {
+ sel.start += 2;
+ sel.end += 2;
+ } else {
+ before_finished = true;
+ }
+ }
+ }
+ if (!selection_finished) {
+ if (sel.rangeCopy.compareEndPoints("StartToEnd", sel.rangeCopy) == 0) {
+ selection_finished = true;
+ } else {
+ sel.rangeCopy.moveEnd("character", -1);
+ if (sel.rangeCopy.text == selection_text) {
+ sel.end += 2;
+ } else {
+ selection_finished = true;
+ }
+ }
+ }
+ } while ((!before_finished || !selection_finished));
+
+
+ // count number of newlines in str to work around stupid IE selection bug
+ var countNL = function(str) {
+ var m = str.split("\r\n");
+ if (!m || !m.length) return 0;
+ return m.length-1;
+ };
+ sel.fix = countNL(sel.obj.value.substring(0,sel.start));
+
+ }
+ return sel;
+}
+
+/**
+ * Set the selection
+ *
+ * You need to get a selection object via getSelection() 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 object selection - a selection object as returned by getSelection()
+ */
+function setSelection(selection){
+ if(document.getSelection){ // FF
+ // what a pleasure in FF ;)
+ selection.obj.setSelectionRange(selection.start,selection.end);
+ if(selection.scroll) selection.obj.scrollTop = selection.scroll;
+ } else if(document.selection) { // IE
+ selection.rangeCopy.collapse(true);
+ selection.rangeCopy.moveStart('character',selection.start - selection.fix);
+ selection.rangeCopy.moveEnd('character',selection.end - selection.start);
+ selection.rangeCopy.select();
+ }
+}
+
+/**
+ * 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 objct selecttion - selection object returned by getSelection
+ * @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 bool 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;
+
+ setSelection(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 = getSelection(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 = getSelection(txtarea);
+ pasteText(selection,text,{nosel: true});
+}
+
diff --git a/lib/scripts/toolbar.js b/lib/scripts/toolbar.js
new file mode 100644
index 000000000..04d30c1a6
--- /dev/null
+++ b/lib/scripts/toolbar.js
@@ -0,0 +1,255 @@
+// 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.bind('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]) ){
+ if(window[actionFunc]($btn, val, edid)){
+ $toolbar.append($btn);
+ }
+ 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.title || props.sample;
+ 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.title || props.sample,
+ opts,
+ selection = getSelection(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++);
+ createPicker(pickerid, props, edid);
+
+ $btn.click(
+ function() {
+ pickerToggle(pickerid,$btn);
+ return false;
+ }
+ );
+
+ return true;
+}
+
+/**
+ * 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(){
+ dw_linkwiz.toggle();
+ return false;
+ });
+ return true;
+}
+
+
+/**
+ * Show/Hide a previosly created picker window
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function pickerToggle(pickerid,$btn){
+ var $picker = jQuery('#' + pickerid),
+ pos = $btn.offset();
+ $picker.toggleClass('a11y')
+ .offset({left: pos.left+3, 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);
+});
diff --git a/lib/scripts/tree.js b/lib/scripts/tree.js
new file mode 100644
index 000000000..96763053d
--- /dev/null
+++ b/lib/scripts/tree.js
@@ -0,0 +1,93 @@
+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.delegate(this.toggle_selector, 'click', this,
+ this.toggle);
+ },
+
+ /**
+ * 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');
+ $listitem.toggleClass('open closed');
+ dw_tree.toggle_display($clicky, opening);
+
+ // 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);
+ }
+ 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"/>');
+ $listitem.append($sublist);
+
+ timeout = window.setTimeout(
+ bind(show_sublist, '<li><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/lib/scripts/tw-sack.js b/lib/scripts/tw-sack.js
new file mode 100644
index 000000000..cc988f5be
--- /dev/null
+++ b/lib/scripts/tw-sack.js
@@ -0,0 +1,139 @@
+/* Simple AJAX Code-Kit (SACK) */
+/* ©2005 Gregory Wild-Smith */
+/* www.twilightuniverse.com */
+/* Software licenced under a modified X11 licence, see documentation or authors website for more details */
+
+function sack(file){
+ this.AjaxFailedAlert = "Your browser does not support the enhanced functionality of this website, and therefore you will have an experience that differs from the intended one.\n";
+ this.requestFile = file;
+ this.method = "POST";
+ this.URLString = "";
+ this.encodeURIString = true;
+ this.execute = false;
+ this.asynchronous = true;
+
+ this.onLoading = function() { };
+ this.onLoaded = function() { };
+ this.onInteractive = function() { };
+ this.onCompletion = function() { };
+ this.afterCompletion = function() { };
+
+ this.createAJAX = function() {
+ try {
+ this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
+ } catch (e) {
+ try {
+ this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch (err) {
+ this.xmlhttp = null;
+ }
+ }
+ if(!this.xmlhttp && typeof XMLHttpRequest != "undefined"){
+ this.xmlhttp = new XMLHttpRequest();
+ }
+ if (!this.xmlhttp){
+ this.failed = true;
+ }
+ };
+
+ this.setVar = function(name, value){
+ if (this.URLString.length < 3){
+ this.URLString = name + "=" + value;
+ } else {
+ this.URLString += "&" + name + "=" + value;
+ }
+ };
+
+ this.encVar = function(name, value){
+ var varString = encodeURIComponent(name) + "=" + encodeURIComponent(value);
+ return varString;
+ };
+
+ this.encodeURLString = function(string){
+ varArray = string.split('&');
+ for (i = 0; i < varArray.length; i++){
+ urlVars = varArray[i].split('=');
+ if (urlVars[0].indexOf('amp;') != -1){
+ urlVars[0] = urlVars[0].substring(4);
+ }
+ varArray[i] = this.encVar(urlVars[0],urlVars[1]);
+ }
+ return varArray.join('&');
+ };
+
+ this.runResponse = function(){
+ eval(this.response);
+ };
+
+ this.runAJAX = function(urlstring){
+ DEPRECATED('Please use jQuery.post() or any other of jQuery\'s AJAX methods.');
+
+ this.responseStatus = new Array(2);
+ if(this.failed && this.AjaxFailedAlert){
+ alert(this.AjaxFailedAlert);
+ } else {
+ if (urlstring){
+ if (this.URLString.length){
+ this.URLString = this.URLString + "&" + urlstring;
+ } else {
+ this.URLString = urlstring;
+ }
+ }
+ if (this.encodeURIString){
+ var timeval = new Date().getTime();
+ this.URLString = this.encodeURLString(this.URLString);
+ this.setVar("rndval", timeval);
+ }
+ if (this.element) { this.elementObj = document.getElementById(this.element); }
+ if (this.xmlhttp) {
+ var self = this;
+ if (this.method == "GET") {
+ var totalurlstring = this.requestFile + "?" + this.URLString;
+ this.xmlhttp.open(this.method, totalurlstring, this.asynchronous);
+ } else {
+ this.xmlhttp.open(this.method, this.requestFile, this.asynchronous);
+ }
+ if (this.method == "POST"){
+ try {
+ this.xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
+ } catch (e) {}
+ }
+
+ this.xmlhttp.onreadystatechange = function() {
+ switch (self.xmlhttp.readyState){
+ case 1:
+ self.onLoading();
+ break;
+ case 2:
+ self.onLoaded();
+ break;
+ case 3:
+ self.onInteractive();
+ break;
+ case 4:
+ self.response = self.xmlhttp.responseText;
+ self.responseXML = self.xmlhttp.responseXML;
+ self.responseStatus[0] = self.xmlhttp.status;
+ self.responseStatus[1] = self.xmlhttp.statusText;
+ self.onCompletion();
+ if(self.execute){ self.runResponse(); }
+ if (self.elementObj) {
+ var elemNodeName = self.elementObj.nodeName;
+ elemNodeName.toLowerCase();
+ if (elemNodeName == "input" || elemNodeName == "select" || elemNodeName == "option" || elemNodeName == "textarea"){
+ self.elementObj.value = self.response;
+ } else {
+ self.elementObj.innerHTML = self.response;
+ }
+ }
+ self.afterCompletion();
+ self.URLString = "";
+ break;
+ }
+ };
+ this.xmlhttp.send(this.URLString);
+ }
+ }
+ };
+this.createAJAX();
+}
diff --git a/lib/styles/all.css b/lib/styles/all.css
new file mode 100644
index 000000000..5d7eb7d14
--- /dev/null
+++ b/lib/styles/all.css
@@ -0,0 +1,65 @@
+/**
+ * Basic 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; }
+
+/* underline */
+em.u {
+ font-style: normal;
+ text-decoration: underline;
+}
+em em.u {
+ font-style: italic;
+}
diff --git a/lib/styles/feed.css b/lib/styles/feed.css
new file mode 100644
index 000000000..44b72d770
--- /dev/null
+++ b/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/lib/styles/index.html b/lib/styles/index.html
new file mode 100644
index 000000000..d614603ac
--- /dev/null
+++ b/lib/styles/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<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/lib/styles/print.css b/lib/styles/print.css
new file mode 100644
index 000000000..76bc6d3bc
--- /dev/null
+++ b/lib/styles/print.css
@@ -0,0 +1,23 @@
+/**
+ * Basic 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 {
+ display: none;
+}
+
+/* section edit button */
+.secedit {
+ display: none;
+}
+
+/* modal windows */
+.JSpopup,
+#link__wiz {
+ display: none;
+}
diff --git a/lib/styles/screen.css b/lib/styles/screen.css
new file mode 100644
index 000000000..101ed3529
--- /dev/null
+++ b/lib/styles/screen.css
@@ -0,0 +1,103 @@
+/**
+ * Basic 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: .5em 0;
+ border-bottom: 1px solid;
+ font-size: 90%;
+ margin: 0;
+ padding-left: 3em;
+ overflow: hidden;
+}
+
+div.error {
+ background-color: #fcc;
+ background-image: url(../images/error.png);
+ border-bottom-color: #faa;
+}
+
+div.info {
+ background-color: #ccf;
+ background-image: url(../images/info.png);
+ border-bottom-color: #aaf;
+}
+
+div.success {
+ background-color: #cfc;
+ background-image: url(../images/success.png);
+ border-bottom-color: #afa;
+}
+
+div.notify {
+ background-color: #ffc;
+ background-image: url(../images/notify.png);
+ border-bottom-color: #ffa;
+}
+
+/* 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: -10000px !important;
+ top: auto !important;
+ width: 1px !important;
+ height: 1px !important;
+ overflow: hidden !important;
+}
+
+/* syntax highlighting code */
+.code .br0 { color: #66cc66; }
+.code .co0 { color: #808080; font-style: italic; }
+.code .co1 { color: #808080; font-style: italic; }
+.code .co2 { color: #808080; font-style: italic; }
+.code .co3 { color: #808080; }
+.code .coMULTI { color: #808080; font-style: italic; }
+.code .es0 { color: #000099; font-weight: bold; }
+.code .kw1 { color: #b1b100; }
+.code .kw2 { color: #000000; font-weight: bold; }
+.code .kw3 { color: #000066; }
+.code .kw4 { color: #993333; }
+.code .kw5 { color: #0000ff; }
+.code .me1 { color: #006600; }
+.code .me2 { color: #006600; }
+.code .nu0 { color: #cc66cc; }
+.code .re0 { color: #0000ff; }
+.code .re1 { color: #0000ff; }
+.code .re2 { color: #0000ff; }
+.code .re3 { color: #ff3333; font-weight:bold; }
+.code .re4 { color: #009999; }
+.code .st0 { color: #ff0000; }
+.code .sy0 { color: #66cc66; }
diff --git a/lib/tpl/default/_admin.css b/lib/tpl/default/_admin.css
new file mode 100644
index 000000000..6c8066ba6
--- /dev/null
+++ b/lib/tpl/default/_admin.css
@@ -0,0 +1,48 @@
+#admin__version {
+ clear:left;
+ float: right;
+ color: __text_neu__;
+}
+
+.dokuwiki ul.admin_tasks {
+ font-size: 115%;
+ float: left;
+ width: 40%;
+ list-style-type: none;
+}
+
+.dokuwiki ul.admin_tasks li {
+ line-height: 22px;
+ padding-left: 35px;
+ margin: 1em 0;
+ background: transparent none no-repeat scroll 0 0;
+ text-align: left;
+}
+
+.dokuwiki ul.admin_tasks li div.li {
+ font-weight: bold;
+}
+
+.dokuwiki ul.admin_tasks li.admin_acl {
+ background-image: url(../../images/admin/acl.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_usermanager {
+ background-image: url(../../images/admin/usermanager.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_plugin {
+ background-image: url(../../images/admin/plugin.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_config {
+ background-image: url(../../images/admin/config.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_revert {
+ background-image: url(../../images/admin/revert.png);
+}
+
+.dokuwiki ul.admin_tasks li.admin_popularity {
+ background-image: url(../../images/admin/popularity.png);
+}
diff --git a/lib/tpl/default/_fileuploader.css b/lib/tpl/default/_fileuploader.css
new file mode 100644
index 000000000..d06bfd519
--- /dev/null
+++ b/lib/tpl/default/_fileuploader.css
@@ -0,0 +1,111 @@
+
+.qq-uploader {
+ position: relative;
+ width: 100%;
+}
+
+.qq-uploader .error {
+ color: #f00;
+ background-color: #fff;
+}
+
+/* select file button */
+
+.qq-upload-button {
+ display: inline-block;
+ border: 1px solid __border__;
+ color: __text__;
+ background: __background__ url(images/buttonshadow.png) repeat-x bottom;
+ text-decoration: none;
+ font-size: 100%;
+ cursor: pointer;
+ margin: 1px 1px 5px;
+ padding: 0.125em 0.4em;
+}
+
+* html .qq-upload-button,
+*+html .qq-upload-button {
+ display: inline;
+}
+
+.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: __background_neu__;
+ color: __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: __background_alt__;
+}
+
+/* list of files to upload */
+
+div.qq-uploader ul {
+ margin: 0;
+ list-style: none;
+}
+
+.qq-uploader li {
+ margin-bottom: 5px;
+ color: __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/lib/tpl/default/_linkwiz.css b/lib/tpl/default/_linkwiz.css
new file mode 100644
index 000000000..ca8812867
--- /dev/null
+++ b/lib/tpl/default/_linkwiz.css
@@ -0,0 +1,40 @@
+#link__wiz {
+}
+
+#link__wiz_result {
+ background-color: __background__;
+ width: 293px;
+ height: 193px;
+ overflow: auto;
+ border: 1px solid __border__;
+ margin: 3px auto;
+ text-align: left;
+}
+
+#link__wiz_result div.type_u {
+ padding: 3px 3px 3px 22px;
+ background: transparent url(../../images/up.png) 3px 3px no-repeat;
+}
+
+#link__wiz_result div.type_f {
+ padding: 3px 3px 3px 22px;
+ background: transparent url(../../images/page.png) 3px 3px no-repeat;
+}
+
+#link__wiz_result div.type_d {
+ padding: 3px 3px 3px 22px;
+ background: transparent url(../../images/ns.png) 3px 3px no-repeat;
+}
+
+#link__wiz_result div.even {
+ background-color: __background_neu__;
+}
+
+#link__wiz_result div.selected {
+ background-color: __background_alt__;
+}
+
+#link__wiz_result span {
+ display: block;
+ color: __text_neu__;
+}
diff --git a/lib/tpl/default/_mediamanager.css b/lib/tpl/default/_mediamanager.css
new file mode 100644
index 000000000..68fa2e97f
--- /dev/null
+++ b/lib/tpl/default/_mediamanager.css
@@ -0,0 +1,432 @@
+
+/*____________ Layout ____________*/
+
+#mediamanager__page h1 {
+ margin: 0 0 .5em;
+}
+
+#mediamanager__page {
+ min-width: 800px;
+ width: 100%;
+ text-align: left;
+}
+
+#mediamanager__page .panel {
+ float: left;
+}
+
+#mediamanager__page .namespaces {
+ width: 15%;
+ min-width: 120px;
+}
+#mediamanager__page .filelist {
+ width: 50%;
+ min-width: 400px;
+}
+#mediamanager__page .file {
+ width: 35%;
+ min-width: 280px;
+}
+
+#mediamanager__page .panelHeader {
+ background-color: __background_alt__;
+ margin: 0 10px 10px 0;
+ padding: 10px 10px 8px;
+ text-align: left;
+ min-height: 20px;
+ overflow: hidden;
+}
+
+#mediamanager__page .panelContent {
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding: 0;
+ margin: 0 10px 10px 0;
+ position: relative;
+}
+
+#mediamanager__page .file .panelHeader,
+#mediamanager__page .file .panelContent {
+ margin-right: 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: __background_alt__;
+}
+
+
+/*____________ Namespaces tree ____________*/
+
+#mediamanager__page .namespaces h2 {
+ font-size: 1em;
+ display: inline-block;
+ border-width: 0;
+ padding: .3em .8em;
+ margin: 0 .3em 0 0;
+ border-radius: .5em .5em 0 0;
+ font-weight: normal;
+ background-color: __background_alt__;
+ color: __text__;
+ line-height: 1.5em;
+}
+* html #mediamanager__page .namespaces h2,
+*+html #mediamanager__page .namespaces h2 {
+ display: inline;
+}
+
+#mediamanager__page .namespaces ul {
+ margin-left: .2em;
+ list-style: none;
+}
+#mediamanager__page .namespaces ul ul {
+ margin-left: 1em;
+}
+
+#mediamanager__page .namespaces ul .selected {
+ background-color: __highlight__;
+ font-weight: bold;
+}
+
+/*____________ Panel header ____________*/
+
+#mediamanager__page .panelHeader h3 {
+ float: left;
+ font-weight: normal;
+ font-size: 1em;
+ padding: 0;
+ margin: 0 0 3px;
+}
+
+#mediamanager__page .panelHeader form.options {
+ float: right;
+ margin-top: -3px;
+}
+
+#mediamanager__page .panelHeader ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+#mediamanager__page .panelHeader ul li {
+ color: __text__;
+ float: left;
+ line-height: 1;
+ padding-left: 3px;
+}
+
+#mediamanager__page .panelHeader ul li.listType {
+ padding-left: 30px;
+ background: url('../../images/icon-list.png') 3px 1px no-repeat;
+}
+#mediamanager__page .panelHeader ul li.sortBy {
+ padding-left: 30px;
+ background: url('../../images/icon-sort.png') 3px 1px no-repeat;
+}
+
+#mediamanager__page .panelHeader form.options .ui-buttonset label{
+ font-size: 90%;
+ margin-right: -0.4em;
+}
+#mediamanager__page .panelHeader form.options .ui-buttonset .ui-button-text {
+ padding: .4em .7em;
+ line-height: 1;
+}
+
+/*____________ File list ____________*/
+
+#mediamanager__page .filelist ul {
+ padding: 0;
+ margin: 0;
+}
+
+#mediamanager__page .filelist .panelContent ul li:hover {
+ background-color: __background_alt__;
+}
+
+#mediamanager__page .filelist li dt a {
+ vertical-align: middle;
+ display: table-cell;
+ overflow: hidden;
+}
+* html #mediamanager__page .filelist .thumbs li dt a,
+*+html #mediamanager__page .filelist .thumbs li dt a {
+ display: block;
+}
+* html #mediamanager__page .filelist .rows li dt a,
+*+html #mediamanager__page .filelist .rows li dt a {
+ display: inline;
+}
+
+/* thumbs */
+
+#mediamanager__page .filelist .thumbs li {
+ width: 100px;
+ min-height: 130px;
+ display: inline-block;
+ display: -moz-inline-stack;
+ /* 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: __background_neu__;
+ color: __text__;
+ padding: 5px;
+ vertical-align: top;
+ text-align: center;
+ position: relative;
+ line-height: 1.2;
+}
+* html #mediamanager__page .filelist .thumbs li,
+*+html #mediamanager__page .filelist .thumbs li {
+ display: inline;
+ zoom: 1;
+}
+
+#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;
+ 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;
+}
+
+/* rows */
+
+#mediamanager__page .filelist .rows li {
+ list-style: none;
+ display: block;
+ position: relative;
+ max-height: 50px;
+ margin: 0;
+ margin-bottom: 3px;
+ background-color: __background__;
+ color: __text__;
+ overflow: hidden;
+}
+
+#mediamanager__page .filelist .rows li:nth-child(2n+1) {
+ background-color: __background_neu__;
+}
+
+#mediamanager__page .filelist .rows li dt {
+ float: left;
+ width: 10%;
+ height: 40px;
+ text-align: center;
+}
+
+#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;
+ float: left;
+ margin-left: 1%;
+ white-space: nowrap;
+}
+
+#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 panel ____________*/
+
+#mediamanager__page div.upload {
+ padding-bottom: 0.5em;
+}
+
+#media__content #mediamanager__uploader {
+ border-bottom: 1px solid __border__;
+ padding-bottom: 0.5em;
+}
+
+/*____________ File preview ____________*/
+
+#mediamanager__page .file ul.actions {
+ text-align: center;
+ margin: 0 0 5px;
+ list-style: none;
+}
+#mediamanager__page .file ul.actions li {
+ display: inline;
+}
+
+#mediamanager__page .file div.image {
+ margin-bottom: 5px;
+ text-align: center;
+}
+
+#mediamanager__page .file div.image img {
+ width: 100%;
+}
+
+#mediamanager__page .file dl {
+}
+#mediamanager__page .file dl dt {
+ font-weight: bold;
+ display: block;
+ background-color: __background_alt__;
+}
+#mediamanager__page .file dl dd {
+ display: block;
+ background-color: __background_neu__;
+}
+
+
+/*____________ 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 input.button {
+ width: auto;
+}
+
+#mediamanager__page form.meta textarea.edit {
+ height: 6em;
+ width: 95%;
+ min-width: 95%;
+ max-width: 95%;
+}
+
+/*____________ Revisions form ____________*/
+
+#mediamanager__page #page__revisions ul {
+ margin-left: 10px;
+ list-style-type: none;
+}
+
+#mediamanager__page #page__revisions ul li div.li div {
+ font-size: 90%;
+ color: __text_neu__;
+ padding-left: 18px;
+}
+
+#mediamanager__page #page__revisions ul li div.li input {
+ position: relative;
+ top: 1px;
+}
+
+/* File diff */
+
+#mediamanager__diff table {
+ table-layout: fixed;
+}
+
+#mediamanager__diff td,
+#mediamanager__diff th {
+ width: 48%;
+ margin: 0 5px 10px 0;
+ padding: 0;
+ vertical-align: top;
+ text-align: left;
+}
+
+#mediamanager__diff th {
+ font-weight: normal;
+}
+#mediamanager__diff th a {
+ font-weight: bold;
+}
+#mediamanager__diff th span {
+ font-size: 90%;
+}
+
+#mediamanager__diff dl dd strong{
+ background-color: __highlight__;
+ color: __text__;
+ font-weight: normal;
+}
+
+/* Image diff */
+
+#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 .image1,
+#mediamanager__diff .imageDiff .image2 {
+ width: 97%;
+}
+#mediamanager__diff .imageDiff .image2 {
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+#mediamanager__diff .imageDiff.opacity .image2 {
+ -moz-opacity: 0.5;
+ -khtml-opacity: 0.5;
+ opacity: 0.5;
+}
+
+#mediamanager__diff .imageDiff.portions .image2 {
+ border-right: 1px solid red;
+ overflow: hidden;
+}
+
+#mediamanager__diff .imageDiff img {
+ width: 100%;
+}
+
diff --git a/lib/tpl/default/_mediaoptions.css b/lib/tpl/default/_mediaoptions.css
new file mode 100644
index 000000000..81e87aa8e
--- /dev/null
+++ b/lib/tpl/default/_mediaoptions.css
@@ -0,0 +1,18 @@
+
+#media__popup_content p {
+ margin: 0 0 .5em;
+}
+
+#media__popup_content label {
+ float: left;
+ width: 9em;
+}
+
+#media__popup_content .button {
+ margin-right: 1px;
+ cursor: pointer;
+}
+
+#media__popup_content input.button {
+ margin-left: 9em;
+}
diff --git a/lib/tpl/default/_subscription.css b/lib/tpl/default/_subscription.css
new file mode 100644
index 000000000..0792c8c21
--- /dev/null
+++ b/lib/tpl/default/_subscription.css
@@ -0,0 +1,21 @@
+/**
+ * Styles for the subscription page
+ */
+
+form#subscribe__form {
+ display: block;
+ width: 300px;
+ text-align: center;
+}
+
+form#subscribe__form fieldset {
+ text-align: left;
+ margin: 0.5em 0;
+}
+
+form#subscribe__form label {
+ display:block;
+ margin: 0 0.5em 0.5em;
+}
+
+
diff --git a/lib/tpl/default/_tabs.css b/lib/tpl/default/_tabs.css
new file mode 100644
index 000000000..8bfb676a0
--- /dev/null
+++ b/lib/tpl/default/_tabs.css
@@ -0,0 +1,37 @@
+
+.dokuwiki ul.tabs {
+ padding: 0;
+ margin: 0;
+ overflow: hidden;
+}
+.dokuwiki ul.tabs li {
+ float: left;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+.dokuwiki ul.tabs li strong,
+.dokuwiki ul.tabs li a {
+ float: left;
+ padding: .3em .8em;
+ margin: 0 .3em 0 0;
+ background-color: __background_neu__;
+ color: __text__;
+ border-radius: .5em .5em 0 0;
+}
+.dokuwiki ul.tabs li strong {
+ font-weight: normal;
+}
+
+.dokuwiki ul.tabs li a:link,
+.dokuwiki ul.tabs li a:visited {
+}
+.dokuwiki ul.tabs li a:hover,
+.dokuwiki ul.tabs li a:active,
+.dokuwiki ul.tabs li a:focus,
+.dokuwiki ul.tabs li strong {
+ background-color: __background_alt__;
+ color: __text__;
+ text-decoration: none;
+}
diff --git a/lib/tpl/default/design.css b/lib/tpl/default/design.css
new file mode 100644
index 000000000..a94f814aa
--- /dev/null
+++ b/lib/tpl/default/design.css
@@ -0,0 +1,851 @@
+/**
+ * Design elements for default Template
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+
+/* -------------- general elements --------------- */
+
+* { padding: 0; margin: 0; }
+
+body {
+ font: 80% "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ background-color: __background__;
+ color: __text__;
+}
+
+/* the document */
+div.dokuwiki div.page {
+ margin: 4px 2em 0 1em;
+ text-align: justify;
+}
+
+div.dokuwiki table {
+ font-size: 100%;
+}
+
+div.dokuwiki tr,
+div.dokuwiki td,
+div.dokuwiki th {
+}
+
+div.dokuwiki img {
+ border: 0;
+}
+
+div.dokuwiki p,
+div.dokuwiki blockquote,
+div.dokuwiki table,
+div.dokuwiki pre {
+ margin: 0 0 1.0em 0;
+}
+
+div.dokuwiki hr {
+ border: 0px;
+ border-top: 1px solid __border__;
+ text-align: center;
+ height: 0px;
+}
+
+div.dokuwiki div.nothing {
+ text-align: center;
+ margin: 2em;
+}
+
+/* ---------------- forms ------------------------ */
+
+div.dokuwiki form {
+ border: none;
+ display: inline;
+}
+
+div.dokuwiki label.block {
+ display: block;
+ text-align: right;
+ font-weight: bold;
+}
+
+div.dokuwiki label.simple {
+ display: block;
+ text-align: left;
+ font-weight: normal;
+}
+
+div.dokuwiki label.block input.edit {
+ width: 50%;
+}
+
+div.dokuwiki fieldset {
+ width: 300px;
+ text-align: center;
+ border: 1px solid __border__;
+ padding: 0.5em;
+ margin: auto;
+}
+
+div.dokuwiki textarea.edit {
+ font-family: monospace, serif;
+ /* second generic font fixes problem with font-size, see
+ http://meyerweb.com/eric/thoughts/2010/02/12/fixed-monospace-sizing/ */
+ font-size: 100%;
+ color: __text__;
+ background-color: __background__;
+ border: 1px solid __border__;
+ padding: 0.3em 0 0 0.3em;
+ /* should just be "width: 100%", but IE8 doesn't like it, see FS#1910 + FS#1667 */
+ width: 700px;
+ min-width: 100%;
+ max-width: 100%;
+}
+
+/* nice alphatransparency background except for IE <7 */
+html>body div.dokuwiki textarea.edit {
+ background: __background__ url(images/inputshadow.png) repeat-x top;
+}
+
+div.dokuwiki input.edit,
+div.dokuwiki select.edit {
+ font-size: 100%;
+ border: 1px solid __border__;
+ color: __text__;
+ background-color: __background__;
+ vertical-align: middle;
+ margin: 1px;
+ padding: 0.20em 0.3em;
+ display: inline;
+}
+
+/* nice alphatransparency background except for IE <7 */
+html>body div.dokuwiki input.edit,
+html>body div.dokuwiki select.edit {
+ background: __background__ url(images/inputshadow.png) repeat-x top;
+}
+
+div.dokuwiki select.edit {
+ padding: 0.1em 0;
+}
+
+div.dokuwiki input.missing {
+ font-size: 100%;
+ border: 1px solid __border__;
+ color: __text__;
+ background-color: #ffcccc;
+ vertical-align: middle;
+ margin: 1px;
+ padding: 0.20em 0.3em;
+ display: inline;
+}
+
+/* disabled style - not understood by IE */
+div.dokuwiki textarea.edit[disabled],
+div.dokuwiki textarea.edit[readonly],
+div.dokuwiki input.edit[disabled],
+div.dokuwiki input.edit[readonly],
+div.dokuwiki input.button[disabled],
+div.dokuwiki select.edit[disabled] {
+ background-color: __background_neu__!important;
+ color: __text_neu__!important;
+}
+
+/* edit form */
+div.dokuwiki div.toolbar,
+div.dokuwiki div#wiki__editbar {
+ margin: 2px 0;
+ text-align: left;
+}
+div.dokuwiki div#size__ctl {
+ float: right;
+ width: 60px;
+ height: 2.7em;
+}
+div.dokuwiki #size__ctl img {
+ cursor: pointer;
+}
+div.dokuwiki div#wiki__editbar div.editButtons {
+ float: left;
+ padding: 0 1.0em 0.7em 0;
+}
+div.dokuwiki div#wiki__editbar div.summary {
+ float: left;
+}
+div.dokuwiki .nowrap {
+ white-space: nowrap;
+}
+div.dokuwiki div#draft__status {
+ float: right;
+ color: __text_alt__;
+}
+
+div.dokuwiki div.license {
+ padding: 0.5em;
+ font-size: 90%;
+ text-align: center;
+}
+
+div.dokuwiki form#dw__editform div.license {
+ clear: left;
+ font-size: 90%;
+}
+
+/* --------- buttons ------------------- */
+
+div.dokuwiki input.button,
+div.dokuwiki button.button {
+ border: 1px solid __border__;
+ color: __text__;
+ background-color: __background__;
+ vertical-align: middle;
+ text-decoration: none;
+ font-size: 100%;
+ cursor: pointer;
+ margin: 1px;
+ padding: 0.125em 0.4em;
+}
+
+/* nice alphatransparency background except for IE <7 */
+html>body div.dokuwiki input.button,
+html>body div.dokuwiki button.button {
+ background: __background__ url(images/buttonshadow.png) repeat-x bottom;
+}
+
+* html div.dokuwiki input.button,
+* html div.dokuwiki button.button {
+ height: 1.8em;
+}
+
+div.dokuwiki div.secedit input.button {
+ border: 1px solid __border__;
+ color: __text__;
+ background-color: __background__;
+ vertical-align: middle;
+ text-decoration: none;
+ margin: 0;
+ padding: 0;
+ font-size: 10px;
+ cursor: pointer;
+ float: right;
+ display: inline;
+}
+
+/* ----------- page navigator ------------- */
+
+div.dokuwiki div.pagenav {
+ margin: 1em 0 0 0;
+}
+
+div.dokuwiki div.pagenav-prev {
+ text-align: right;
+ float: left;
+ width: 49%
+}
+
+div.dokuwiki div.pagenav-next {
+ text-align: left;
+ float: right;
+ width: 49%
+}
+
+/* ----------- type of recent changes select -------- */
+
+div.dokuwiki form#dw__recent select {
+ margin-bottom: 10px;
+}
+
+/* --------------- Links ------------------ */
+
+div.dokuwiki a:link,
+div.dokuwiki a:visited {
+ color: __extern__;
+ text-decoration: none;
+}
+div.dokuwiki a:hover,
+div.dokuwiki a:active {
+ color: __text__;
+ text-decoration: underline;
+}
+
+div.dokuwiki h1 a,
+div.dokuwiki h2 a,
+div.dokuwiki h3 a,
+div.dokuwiki h4 a,
+div.dokuwiki h5 a,
+div.dokuwiki a.nolink {
+ color: __text__ !important;
+ text-decoration: none !important;
+}
+
+/* external link */
+div.dokuwiki a.urlextern {
+ background: transparent url(images/link_icon.gif) 0px 1px no-repeat;
+ padding: 1px 0px 1px 16px;
+}
+
+/* windows share */
+div.dokuwiki a.windows {
+ background: transparent url(images/windows.gif) 0px 1px no-repeat;
+ padding: 1px 0px 1px 16px;
+}
+
+/* interwiki link (icon are set by dokuwiki) */
+div.dokuwiki a.interwiki {
+}
+
+/* link to some embedded media */
+div.dokuwiki a.media {
+}
+
+div.dokuwiki a.urlextern:link,
+div.dokuwiki a.windows:link,
+div.dokuwiki a.interwiki:link {
+ color: __extern__;
+}
+
+div.dokuwiki a.urlextern:visited,
+div.dokuwiki a.windows:visited,
+div.dokuwiki a.interwiki:visited {
+ color: purple;
+}
+div.dokuwiki a.urlextern:hover,
+div.dokuwiki a.urlextern:active,
+div.dokuwiki a.windows:hover,
+div.dokuwiki a.windows:active,
+div.dokuwiki a.interwiki:hover,
+div.dokuwiki a.interwiki:active {
+ color: __text__;
+}
+
+/* email link */
+div.dokuwiki a.mail {
+ background: transparent url(images/mail_icon.gif) 0px 1px no-repeat;
+ padding: 1px 0px 1px 16px;
+}
+
+/* existing wikipage */
+div.dokuwiki a.wikilink1 {
+ color: __existing__ !important;
+}
+
+/* not existing wikipage */
+div.dokuwiki a.wikilink2 {
+ color: __missing__ !important;
+ text-decoration: none !important;
+ border-bottom: dashed 1px __missing__ !important;
+}
+
+/* ------------- Page elements ----------------- */
+
+div.dokuwiki div.preview {
+ background-color: __background_neu__;
+ margin: 0 0 0 2em;
+ padding: 4px;
+ border: 1px dashed __text__;
+}
+
+div.dokuwiki div.breadcrumbs {
+ background-color: __background_neu__;
+ color: __text_neu__;
+ font-size: 80%;
+ padding: 0 0 0 4px;
+}
+
+div.dokuwiki span.user {
+ color: __text_other__;
+ font-size: 90%;
+}
+
+div.dokuwiki li.minor {
+ color: __text_neu__;
+ font-style: italic;
+}
+
+/* embedded images */
+div.dokuwiki img.media {
+ margin: 3px;
+}
+
+div.dokuwiki img.medialeft {
+ border: 0;
+ float: left;
+ margin: 0 1.5em 0 0;
+}
+
+div.dokuwiki img.mediaright {
+ border: 0;
+ float: right;
+ margin: 0 0 0 1.5em;
+}
+
+div.dokuwiki img.mediacenter {
+ border: 0;
+ display: block;
+ margin: 0 auto;
+}
+
+/* smileys */
+div.dokuwiki img.middle {
+ vertical-align: middle;
+}
+
+div.dokuwiki acronym {
+ cursor: help;
+ border-bottom: 1px dotted __text__;
+}
+
+/* general headline setup */
+div.dokuwiki h1,
+div.dokuwiki h2,
+div.dokuwiki h3,
+div.dokuwiki h4,
+div.dokuwiki h5 {
+ color: __text__;
+ background-color: inherit;
+ font-size: 100%;
+ font-weight: normal;
+ margin: 0 0 1em 0;
+ padding: 0.5em 0 0 0;
+ border-bottom: 1px solid __border__;
+ clear: left;
+}
+
+/* special headlines */
+div.dokuwiki h1 {font-size: 160%; margin-left: 0px; font-weight: bold;}
+div.dokuwiki h2 {font-size: 150%; margin-left: 20px;}
+div.dokuwiki h3 {font-size: 140%; margin-left: 40px; border-bottom: none; font-weight: bold;}
+div.dokuwiki h4 {font-size: 120%; margin-left: 60px; border-bottom: none; font-weight: bold;}
+div.dokuwiki h5 {font-size: 100%; margin-left: 80px; border-bottom: none; font-weight: bold;}
+
+/* indent different sections */
+div.dokuwiki div.level1 { margin-left: 3px; }
+div.dokuwiki div.level2 { margin-left: 23px; }
+div.dokuwiki div.level3 { margin-left: 43px; }
+div.dokuwiki div.level4 { margin-left: 63px; }
+div.dokuwiki div.level5 { margin-left: 83px; }
+
+/* unordered lists */
+div.dokuwiki ul {
+ line-height: 1.5em;
+ list-style-type: square;
+ list-style-image: none;
+ margin: 0 0 1em 3.5em;
+ color: __text_alt__;
+}
+
+/* ordered lists */
+div.dokuwiki ol {
+ line-height: 1.5em;
+ list-style-image: none;
+ margin: 0 0 1em 3.5em;
+ color: __text_alt__;
+ font-weight: bold;
+}
+
+/* no bottom gap in between and smaller left margin for nested lists */
+div.dokuwiki li ul,
+div.dokuwiki li ol {
+ margin: 0 0 0 1.5em;
+}
+
+/* the list items overriding the ul/ol definition */
+div.dokuwiki .li {
+ color: __text__;
+ font-weight: normal;
+}
+
+div.dokuwiki ol { list-style-type: decimal; }
+div.dokuwiki ol ol { list-style-type: upper-roman; }
+div.dokuwiki ol ol ol { list-style-type: lower-alpha; }
+div.dokuwiki ol ol ol ol { list-style-type: lower-greek; }
+
+div.dokuwiki li.open {
+ list-style-image: url(images/open.gif);
+ /*list-style-type: circle;*/
+}
+
+div.dokuwiki li.closed {
+ list-style-image: url(images/closed.gif);
+ /*list-style-type: disc;*/
+}
+
+div.dokuwiki blockquote {
+ border-left: 2px solid __border__;
+ padding-left: 3px;
+}
+
+div.dokuwiki pre,
+div.dokuwiki code {
+ font-family: monospace, serif;
+ /* second generic font fixes problem with font-size, see
+ http://meyerweb.com/eric/thoughts/2010/02/12/fixed-monospace-sizing/ */
+ font-size: 100%;
+}
+div.dokuwiki pre {
+ padding: 0.5em;
+ border: 1px dashed __border__;
+ color: __text__;
+ overflow: auto;
+}
+
+/* code blocks by indention */
+div.dokuwiki pre.pre {
+ background-color: __background_other__;
+}
+
+/* code blocks by code tag */
+div.dokuwiki pre.code {
+ background-color: __background_other__;
+}
+
+/* code blocks by file tag */
+div.dokuwiki pre.file {
+ background-color: __background_alt__;
+}
+
+/* filenames for file and code blocks */
+div.dokuwiki dl.file,
+div.dokuwiki dl.code {
+ margin-top: 2em;
+ margin-bottom: 2.5em;
+}
+
+div.dokuwiki dl.file dt,
+div.dokuwiki dl.code dt {
+ border: 1px dashed __border__;
+ display: inline;
+ padding: 0.1em 1em;
+ margin-left: 2em;
+}
+
+div.dokuwiki dl.code dt a,
+div.dokuwiki dl.file dt a {
+ color: __text__;
+}
+
+div.dokuwiki dl.code dt {
+ background-color: __background_other__;
+ border-bottom: 1px solid __background_other__;
+}
+
+div.dokuwiki dl.file dt {
+ background-color: __background_alt__;
+ border-bottom: 1px solid __background_alt__;
+}
+
+
+/* inline tables */
+div.dokuwiki table.inline {
+ background-color: __background__;
+ border-spacing: 0px;
+ border-collapse: collapse;
+}
+
+div.dokuwiki table.inline th {
+ padding: 3px;
+ border: 1px solid __border__;
+ background-color: __background_alt__;
+}
+
+div.dokuwiki table.inline td {
+ padding: 3px;
+ border: 1px solid __border__;
+}
+
+/* ---------- table of contents ------------------- */
+
+div.dokuwiki div.toc {
+ margin: 1.2em 0 0 2em;
+ float: right;
+ width: 200px;
+ font-size: 80%;
+ clear: both;
+}
+
+div.dokuwiki div.tocheader {
+ border: 1px solid __border__;
+ background-color: __background_alt__;
+ text-align: left;
+ font-weight: bold;
+ padding: 3px;
+ margin-bottom: 2px;
+}
+
+div.dokuwiki span.toc_open,
+div.dokuwiki span.toc_close {
+ border: 0.4em solid __background_alt__;
+ float: right;
+ display: block;
+ margin: 0.4em 3px 0 0;
+}
+
+div.dokuwiki span.toc_open span,
+div.dokuwiki span.toc_close span {
+ display: none;
+}
+
+div.dokuwiki span.toc_open {
+ margin-top: 0.4em;
+ border-top: 0.4em solid __text__;
+}
+
+div.dokuwiki span.toc_close {
+ margin-top: 0;
+ border-bottom: 0.4em solid __text__;
+}
+
+div.dokuwiki #toc__inside {
+ border: 1px solid __border__;
+ background-color: __background__;
+ text-align: left;
+ padding: 0.5em 0 0.7em 0;
+}
+
+div.dokuwiki ul.toc {
+ list-style-type: none;
+ list-style-image: none;
+ line-height: 1.2em;
+ padding-left: 1em;
+ margin: 0;
+}
+
+div.dokuwiki ul.toc li {
+ background: transparent url(images/tocdot2.gif) 0 0.6em no-repeat;
+ padding-left: 0.4em;
+}
+
+div.dokuwiki ul.toc li.clear {
+ background-image: none;
+ padding-left: 0.4em;
+}
+
+div.dokuwiki a.toc:link,
+div.dokuwiki a.toc:visited {
+ color: __extern__;
+}
+
+div.dokuwiki a.toc:hover,
+div.dokuwiki a.toc:active {
+ color: __text__;
+}
+
+/* ---------------------------- Diff rendering --------------------------*/
+div.dokuwiki table.diff {
+ background-color: __background__;
+ width: 100%;
+}
+div.dokuwiki td.diff-blockheader {
+ font-weight: bold;
+}
+div.dokuwiki table.diff th {
+ border-bottom: 1px solid __border__;
+ font-size: 110%;
+ width: 50%;
+ font-weight: normal;
+ text-align: left;
+}
+div.dokuwiki table.diff th a {
+ font-weight: bold;
+}
+div.dokuwiki table.diff th span.user {
+ color: __text__;
+ font-size: 80%;
+}
+div.dokuwiki table.diff th span.sum {
+ font-size: 80%;
+ font-weight: bold;
+}
+div.dokuwiki table.diff th.minor {
+ font-style: italic;
+}
+div.dokuwiki table.diff td {
+ font-family: monospace;
+ font-size: 100%;
+}
+div.dokuwiki td.diff-addedline,
+div.dokuwiki span.diff-addedline {
+ background-color: #ddffdd;
+}
+div.dokuwiki td.diff-deletedline,
+div.dokuwiki span.diff-deletedline {
+ background-color: #ffffbb;
+}
+div.dokuwiki td.diff-context {
+ background-color: __background_neu__;
+}
+div.dokuwiki table.diff td.diff-addedline strong,
+div.dokuwiki table.diff td.diff-deletedline strong {
+ color: red;
+}
+
+/* --------------------- footnotes -------------------------------- */
+
+div.dokuwiki div.footnotes {
+ clear: both;
+ border-top: 1px solid __border__;
+ padding-left: 1em;
+ margin-top: 1em;
+}
+
+div.dokuwiki div.fn {
+ font-size: 90%;
+}
+
+div.dokuwiki a.fn_bot {
+ font-weight: bold;
+}
+
+/* insitu-footnotes */
+div.insitu-footnote {
+ font-size: 80%;
+ line-height: 1.2em;
+ border: 1px solid __border__;
+ background-color: __background_other__;
+ text-align: left;
+ padding: 4px;
+ max-width: 40%; /* IE's width is handled in javascript */
+ min-width: 5em;
+}
+
+/* overcome IE issue with one line code or file boxes which require h. scrolling */
+* html .insitu-footnote pre.code,
+* html .insitu-footnote pre.file {
+ padding-bottom: 18px;
+}
+
+/* --------------- search result formating --------------- */
+div.dokuwiki .search_result {
+ margin-bottom: 6px;
+ padding: 0 10px 0 30px;
+}
+
+div.dokuwiki .search_snippet {
+ color: __text_other__;
+ font-size: 12px;
+ margin-left: 20px;
+}
+
+div.dokuwiki .search_sep {
+ color: __text__;
+}
+
+div.dokuwiki .search_hit {
+ color: __text__;
+ background-color: __highlight__;
+}
+div.dokuwiki strong.search_hit {
+ font-weight: normal;
+}
+
+div.dokuwiki div.search_quickresult {
+ margin: 0 0 15px 30px;
+ padding: 0 10px 10px 0;
+ border-bottom: 1px dashed __border__;
+}
+div.dokuwiki div.search_quickresult h3 {
+ margin: 0 0 1.0em 0;
+ font-size: 1em;
+ font-weight: bold;
+}
+
+div.dokuwiki ul.search_quickhits {
+ margin: 0 0 0.5em 1.0em;
+}
+
+div.dokuwiki ul.search_quickhits li {
+ margin: 0 1.0em 0 1.0em;
+ float: left;
+ width: 30%;
+}
+
+div.dokuwiki .section_highlight {
+ background-color: __background_alt__ !important;
+}
+
+/* ------------------ Additional ---------------------- */
+
+div.footerinc {
+ text-align: center;
+}
+.footerinc a img {
+ opacity: 0.5;
+ border: 0;
+}
+
+.footerinc a:hover img {
+ opacity: 1;
+}
+
+/* ---------- AJAX quicksearch ----------- */
+
+div.dokuwiki div.ajax_qsearch {
+ position: absolute;
+ right: 237px;;
+ width: 200px;
+ opacity: 0.9;
+ display: none;
+ font-size: 80%;
+ line-height: 1.2em;
+ border: 1px solid __border__;
+ background-color: __background_other__;
+ text-align: left;
+ padding: 4px;
+}
+
+/* --------- Toolbar -------------------- */
+button.toolbutton {
+ background-color: __background__;
+ padding: 0px;
+ margin: 0 1px 0 0;
+ border: 1px solid __border__;
+ cursor: pointer;
+}
+
+/* nice alphatransparency background except for IE <7 */
+html>body button.toolbutton {
+ background: __background__ url(images/buttonshadow.png) repeat-x bottom;
+}
+
+div.picker {
+ width: 250px;
+ border: 1px solid __border__;
+ background-color: __background_alt__;
+}
+
+div.pk_hl {
+ width: 125px;
+}
+
+button.pickerbutton {
+ padding: 0px;
+ margin: 0 1px 1px 0;
+ border: 0;
+ background-color: transparent;
+ font-size: 80%;
+ cursor: pointer;
+}
+
+/* --------------- Image Details ----------------- */
+
+div.dokuwiki div.img_big {
+ float: left;
+ margin-right: 0.5em;
+}
+
+div.dokuwiki dl.img_tags dt {
+ font-weight: bold;
+ background-color: __background_alt__;
+}
+div.dokuwiki dl.img_tags dd {
+ background-color: __background_neu__;
+}
+
+div.dokuwiki div.imagemeta {
+ color: __text_neu__;
+ font-size: 70%;
+ line-height: 95%;
+}
+
+div.dokuwiki div.imagemeta img.thumb {
+ float: left;
+ margin-right: 0.1em;
+}
+
diff --git a/lib/tpl/default/detail.php b/lib/tpl/default/detail.php
new file mode 100644
index 000000000..503c0ef71
--- /dev/null
+++ b/lib/tpl/default/detail.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * DokuWiki Image Detail Template
+ *
+ * This is the template for displaying image details
+ *
+ * You should leave the doctype at the very top - It should
+ * always be the very first line of a document.
+ *
+ * @link http://dokuwiki.org/templates
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>" lang="<?php echo $conf['lang']?>" dir="ltr">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>
+ <?php echo hsc(tpl_img_getTag('IPTC.Headline',$IMG))?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+
+ <?php tpl_metaheaders()?>
+
+ <link rel="shortcut icon" href="<?php echo DOKU_TPL?>images/favicon.ico" />
+</head>
+
+<body>
+<div class="dokuwiki">
+ <?php html_msgarea()?>
+
+ <div class="page">
+ <?php if($ERROR){ print $ERROR; }else{ ?>
+
+ <h1><?php echo hsc(tpl_img_getTag('IPTC.Headline',$IMG))?></h1>
+
+ <div class="img_big">
+ <?php tpl_img(900,700) ?>
+ </div>
+
+ <div class="img_detail">
+ <p class="img_caption">
+ <?php print nl2br(hsc(tpl_img_getTag('simple.title'))); ?>
+ </p>
+
+ <p>&larr; <?php echo $lang['img_backto']?> <?php tpl_pagelink($ID)?></p>
+ <?php
+ $imgNS = getNS($IMG);
+ $authNS = auth_quickaclcheck("$imgNS:*");
+ if ($authNS >= AUTH_UPLOAD) {
+ echo '<p><a href="'.media_managerURL(array('ns' => $imgNS, 'image' => $IMG)).'">'.$lang['img_manager'].'</a></p>';
+ }
+ ?>
+
+ <dl class="img_tags">
+ <?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 //Comment in for Debug// dbg(tpl_img_getTag('Simple.Raw'));?>
+ </div>
+
+ <?php } ?>
+ </div>
+</div>
+</body>
+</html>
+
diff --git a/lib/tpl/default/footer.html b/lib/tpl/default/footer.html
new file mode 100644
index 000000000..38aab7216
--- /dev/null
+++ b/lib/tpl/default/footer.html
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Example footer include
+ *
+ * This file shows you how to use the include hooks. However I recommend to
+ * create your own complete new template instead.
+ */
+
+$tgt = ($conf['target']['extern']) ? 'target="'.$conf['target']['extern'].'"' : '';
+?>
+
+<div class="footerinc">
+
+ <a <?php echo $tgt?> href="<?php echo DOKU_BASE; ?>feed.php" title="Recent changes RSS feed"><img src="<?php echo DOKU_TPL; ?>images/button-rss.png" width="80" height="15" alt="Recent changes RSS feed" /></a>
+
+ <?php
+ $lic = license_img('button');
+ if($lic){
+ ?>
+ <a <?php echo $tgt?> href="<?php echo $license[$conf['license']]['url']?>" rel="license" title="<?php echo $license[$conf['license']]['name']?>"><img src="<?php echo DOKU_BASE.$lic ?>" width="80" height="15" alt="" /></a>
+ <?php } ?>
+
+ <a <?php echo $tgt?> href="http://www.dokuwiki.org/donate" title="Donate"><img src="<?php echo DOKU_TPL; ?>images/button-donate.gif" alt="Donate" width="80" height="15" /></a>
+
+ <a <?php echo $tgt?> href="http://www.php.net" title="Powered by PHP"><img src="<?php echo DOKU_TPL; ?>images/button-php.gif" width="80" height="15" alt="Powered by PHP" /></a>
+
+ <a <?php echo $tgt?> href="http://validator.w3.org/check/referer" title="Valid XHTML 1.0"><img src="<?php echo DOKU_TPL; ?>images/button-xhtml.png" width="80" height="15" alt="Valid XHTML 1.0" /></a>
+
+ <a <?php echo $tgt?> href="http://jigsaw.w3.org/css-validator/check/referer?profile=css3" title="Valid CSS"><img src="<?php echo DOKU_TPL; ?>images/button-css.png" width="80" height="15" alt="Valid CSS" /></a>
+
+ <a <?php echo $tgt?> href="http://dokuwiki.org/" title="Driven by DokuWiki"><img src="<?php echo DOKU_TPL; ?>images/button-dw.png" width="80" height="15" alt="Driven by DokuWiki" /></a>
+
+<?php
+if ($conf['allowdebug']) {
+ echo '<!-- page made in '.round(delta_time(DOKU_START_TIME), 3).' seconds -->';
+}
+?>
+
+
+</div>
+<?php include(dirname(__FILE__).'/dwtb.html') ?>
diff --git a/lib/tpl/default/images/UWEB.png b/lib/tpl/default/images/UWEB.png
new file mode 100644
index 000000000..292ade4ed
--- /dev/null
+++ b/lib/tpl/default/images/UWEB.png
Binary files differ
diff --git a/lib/tpl/default/images/UWEBshadow.png b/lib/tpl/default/images/UWEBshadow.png
new file mode 100644
index 000000000..8c4e5f829
--- /dev/null
+++ b/lib/tpl/default/images/UWEBshadow.png
Binary files differ
diff --git a/lib/tpl/default/images/apple-touch-icon.png b/lib/tpl/default/images/apple-touch-icon.png
new file mode 100644
index 000000000..45fa4e7b0
--- /dev/null
+++ b/lib/tpl/default/images/apple-touch-icon.png
Binary files differ
diff --git a/lib/tpl/default/images/bullet.gif b/lib/tpl/default/images/bullet.gif
new file mode 100644
index 000000000..b43de48a4
--- /dev/null
+++ b/lib/tpl/default/images/bullet.gif
Binary files differ
diff --git a/lib/tpl/default/images/button-cc.gif b/lib/tpl/default/images/button-cc.gif
new file mode 100644
index 000000000..c7a403a9e
--- /dev/null
+++ b/lib/tpl/default/images/button-cc.gif
Binary files differ
diff --git a/lib/tpl/default/images/button-css.png b/lib/tpl/default/images/button-css.png
new file mode 100644
index 000000000..706325e1c
--- /dev/null
+++ b/lib/tpl/default/images/button-css.png
Binary files differ
diff --git a/lib/tpl/default/images/button-donate.gif b/lib/tpl/default/images/button-donate.gif
new file mode 100644
index 000000000..bba284e21
--- /dev/null
+++ b/lib/tpl/default/images/button-donate.gif
Binary files differ
diff --git a/lib/tpl/default/images/button-dw.png b/lib/tpl/default/images/button-dw.png
new file mode 100644
index 000000000..97272d968
--- /dev/null
+++ b/lib/tpl/default/images/button-dw.png
Binary files differ
diff --git a/lib/tpl/default/images/button-php.gif b/lib/tpl/default/images/button-php.gif
new file mode 100644
index 000000000..19aefb08f
--- /dev/null
+++ b/lib/tpl/default/images/button-php.gif
Binary files differ
diff --git a/lib/tpl/default/images/button-rss.png b/lib/tpl/default/images/button-rss.png
new file mode 100644
index 000000000..f2438043f
--- /dev/null
+++ b/lib/tpl/default/images/button-rss.png
Binary files differ
diff --git a/lib/tpl/default/images/button-xhtml.png b/lib/tpl/default/images/button-xhtml.png
new file mode 100644
index 000000000..ec686442c
--- /dev/null
+++ b/lib/tpl/default/images/button-xhtml.png
Binary files differ
diff --git a/lib/tpl/default/images/buttonshadow.png b/lib/tpl/default/images/buttonshadow.png
new file mode 100644
index 000000000..b96ebf759
--- /dev/null
+++ b/lib/tpl/default/images/buttonshadow.png
Binary files differ
diff --git a/lib/tpl/default/images/closed.gif b/lib/tpl/default/images/closed.gif
new file mode 100644
index 000000000..8414d4d69
--- /dev/null
+++ b/lib/tpl/default/images/closed.gif
Binary files differ
diff --git a/lib/tpl/default/images/favicon.ico b/lib/tpl/default/images/favicon.ico
new file mode 100644
index 000000000..8b9616abb
--- /dev/null
+++ b/lib/tpl/default/images/favicon.ico
Binary files differ
diff --git a/lib/tpl/default/images/inputshadow.png b/lib/tpl/default/images/inputshadow.png
new file mode 100644
index 000000000..480044986
--- /dev/null
+++ b/lib/tpl/default/images/inputshadow.png
Binary files differ
diff --git a/lib/tpl/default/images/link_icon.gif b/lib/tpl/default/images/link_icon.gif
new file mode 100644
index 000000000..d0a92f2fa
--- /dev/null
+++ b/lib/tpl/default/images/link_icon.gif
Binary files differ
diff --git a/lib/tpl/default/images/mail_icon.gif b/lib/tpl/default/images/mail_icon.gif
new file mode 100644
index 000000000..437d28fe1
--- /dev/null
+++ b/lib/tpl/default/images/mail_icon.gif
Binary files differ
diff --git a/lib/tpl/default/images/open.gif b/lib/tpl/default/images/open.gif
new file mode 100644
index 000000000..f5d5c7e56
--- /dev/null
+++ b/lib/tpl/default/images/open.gif
Binary files differ
diff --git a/lib/tpl/default/images/resizecol.png b/lib/tpl/default/images/resizecol.png
new file mode 100644
index 000000000..f0111507c
--- /dev/null
+++ b/lib/tpl/default/images/resizecol.png
Binary files differ
diff --git a/lib/tpl/default/images/tocdot2.gif b/lib/tpl/default/images/tocdot2.gif
new file mode 100644
index 000000000..e2b5f15cb
--- /dev/null
+++ b/lib/tpl/default/images/tocdot2.gif
Binary files differ
diff --git a/lib/tpl/default/images/windows.gif b/lib/tpl/default/images/windows.gif
new file mode 100644
index 000000000..64dfeb6fb
--- /dev/null
+++ b/lib/tpl/default/images/windows.gif
Binary files differ
diff --git a/lib/tpl/default/layout.css b/lib/tpl/default/layout.css
new file mode 100644
index 000000000..ded2d87a2
--- /dev/null
+++ b/lib/tpl/default/layout.css
@@ -0,0 +1,79 @@
+/**
+ * Tableless Layout for default template
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author moraes <moraes@tipos.com.br>
+ */
+
+/* -------------- top row --------------- */
+div.dokuwiki .header {
+ padding: 3px 0 0 2px;
+}
+
+div.dokuwiki .pagename {
+ float: left;
+ font-size: 200%;
+ font-weight: bolder;
+ color: __background_alt__;
+ text-align: left;
+ vertical-align: middle;
+}
+
+div.dokuwiki .pagename a {
+ color: __extern__ !important;
+ text-decoration: none !important;
+}
+
+div.dokuwiki .logo {
+ float: right;
+ font-size: 220%;
+ font-weight: bolder;
+ text-align: right;
+ vertical-align: middle;
+}
+
+div.dokuwiki .logo a {
+ color: __background_alt__ !important;
+ text-decoration: none !important;
+ font-variant: small-caps;
+ letter-spacing: 2pt;
+}
+
+/* --------------- top and bottom bar ---------------- */
+div.dokuwiki .bar {
+ border-top: 1px solid __border__;
+ border-bottom: 1px solid __border__;
+ background: __background_alt__;
+ padding: 0.1em 0.15em;
+ clear: both;
+}
+
+div.dokuwiki .bar-left {
+ float: left;
+}
+
+div.dokuwiki .bar-right {
+ float: right;
+ text-align: right;
+}
+
+div.dokuwiki #bar__bottom {
+ margin-bottom: 3px;
+}
+
+/* ------------- File Metadata ----------------------- */
+
+div.dokuwiki div.meta {
+ clear: both;
+ margin-top: 1em;
+ color: __text_alt__;
+ font-size: 70%;
+}
+
+div.dokuwiki div.meta div.user {
+ float: left;
+}
+
+div.dokuwiki div.meta div.doc {
+ text-align: right;
+}
diff --git a/lib/tpl/default/main.php b/lib/tpl/default/main.php
new file mode 100644
index 000000000..3e85c58f2
--- /dev/null
+++ b/lib/tpl/default/main.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * DokuWiki Default Template
+ *
+ * This is the template you need to change for the overall look
+ * of DokuWiki.
+ *
+ * You should leave the doctype at the very top - It should
+ * always be the very first line of a document.
+ *
+ * @link http://dokuwiki.org/templates
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>"
+ lang="<?php echo $conf['lang']?>" dir="<?php echo $lang['direction']?>">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>
+ <?php tpl_pagetitle()?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+
+ <?php tpl_metaheaders()?>
+ <?php echo tpl_favicon(array('favicon', 'mobile')) ?>
+
+ <?php /*old includehook*/ @include(dirname(__FILE__).'/meta.html')?>
+</head>
+
+<body>
+<?php /*old includehook*/ @include(dirname(__FILE__).'/topheader.html')?>
+<div class="dokuwiki">
+ <?php html_msgarea()?>
+
+ <div class="stylehead">
+
+ <div class="header">
+ <div class="pagename">
+ [[<?php tpl_link(wl($ID,'do=backlink'),tpl_pagetitle($ID,true),'title="'.$lang['btn_backlink'].'"')?>]]
+ </div>
+ <div class="logo">
+ <?php tpl_link(wl(),$conf['title'],'name="dokuwiki__top" id="dokuwiki__top" accesskey="h" title="[H]"')?>
+ </div>
+
+ <div class="clearer"></div>
+ </div>
+
+ <?php /*old includehook*/ @include(dirname(__FILE__).'/header.html')?>
+
+ <div class="bar" id="bar__top">
+ <div class="bar-left" id="bar__topleft">
+ <?php tpl_button('edit')?>
+ <?php tpl_button('history')?>
+ </div>
+
+ <div class="bar-right" id="bar__topright">
+ <?php tpl_button('recent')?>
+ <?php tpl_searchform()?>&nbsp;
+ </div>
+
+ <div class="clearer"></div>
+ </div>
+
+ <?php if($conf['breadcrumbs']){?>
+ <div class="breadcrumbs">
+ <?php tpl_breadcrumbs()?>
+ <?php //tpl_youarehere() //(some people prefer this)?>
+ </div>
+ <?php }?>
+
+ <?php if($conf['youarehere']){?>
+ <div class="breadcrumbs">
+ <?php tpl_youarehere() ?>
+ </div>
+ <?php }?>
+
+ </div>
+ <?php tpl_flush()?>
+
+ <?php /*old includehook*/ @include(dirname(__FILE__).'/pageheader.html')?>
+
+ <div class="page">
+ <!-- wikipage start -->
+ <?php tpl_content()?>
+ <!-- wikipage stop -->
+ </div>
+
+ <div class="clearer"></div>
+
+ <?php tpl_flush()?>
+
+ <div class="stylefoot">
+
+ <div class="meta">
+ <div class="user">
+ <?php tpl_userinfo()?>
+ </div>
+ <div class="doc">
+ <?php tpl_pageinfo()?>
+ </div>
+ </div>
+
+ <?php /*old includehook*/ @include(dirname(__FILE__).'/pagefooter.html')?>
+
+ <div class="bar" id="bar__bottom">
+ <div class="bar-left" id="bar__bottomleft">
+ <?php tpl_button('edit')?>
+ <?php tpl_button('history')?>
+ <?php tpl_button('revert')?>
+ </div>
+ <div class="bar-right" id="bar__bottomright">
+ <?php tpl_button('subscribe')?>
+ <?php tpl_button('media')?>
+ <?php tpl_button('admin')?>
+ <?php tpl_button('profile')?>
+ <?php tpl_button('login')?>
+ <?php tpl_button('index')?>
+ <?php tpl_button('top')?>&nbsp;
+ </div>
+ <div class="clearer"></div>
+ </div>
+
+ </div>
+
+ <?php tpl_license(false);?>
+
+</div>
+<?php /*old includehook*/ @include(dirname(__FILE__).'/footer.html')?>
+
+<div class="no"><?php /* provide DokuWiki housekeeping, required in all templates */ tpl_indexerWebBug()?></div>
+</body>
+</html>
diff --git a/lib/tpl/default/media.css b/lib/tpl/default/media.css
new file mode 100644
index 000000000..37369fe2f
--- /dev/null
+++ b/lib/tpl/default/media.css
@@ -0,0 +1,213 @@
+/**
+ * The CSS in here controls the appearance of the media manager
+ */
+
+#media__manager {
+ height: 100%;
+ overflow: hidden;
+}
+
+#media__left {
+ width: 30%;
+ border-right: solid 1px __border__;
+
+ height: 100%;
+ overflow: auto;
+ position: absolute;
+ left: 0;
+}
+
+#media__right {
+ width: 69.7%;
+
+ height: 100%;
+ overflow: auto;
+ position: absolute;
+ right: 0;
+}
+
+#media__manager h1 {
+ margin: 0;
+ padding: 0;
+ margin-bottom: 0.5em;
+}
+
+#media__manager a.select {
+ cursor: pointer;
+}
+
+/* --- Tree formatting --- */
+
+#media__tree img {
+ float: left;
+ padding: 0.5em 0.3em 0 0;
+}
+
+#media__tree ul {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: 1.5em;
+}
+
+#media__tree li {
+ clear: left;
+ list-style-type: none;
+ list-style-image: none;
+}
+*+html #media__tree li,
+* html #media__tree li {
+ border: 1px solid __background__;
+}/* I don't understand this, but this fixes a style bug in IE;
+it's dirty, so any "real" fixes are welcome */
+
+/* --- options --- */
+
+#media__opts {
+ padding-left: 1em;
+ margin-bottom: 0.5em;
+}
+
+#media__opts input {
+ float: left;
+ display: block;
+ margin-top: 4px;
+ position: absolute;
+}
+*+html #media__opts input,
+* html #media__opts input {
+ position: static;
+}
+
+#media__opts label {
+ display: block;
+ float: left;
+ margin-left: 20px;
+ margin-bottom: 4px;
+}
+*+html #media__opts label,
+* html #media__opts label {
+ margin-left: 10px;
+}
+
+#media__opts br {
+ clear: left;
+}
+
+/* --- file list --- */
+
+#media__content img.load {
+ margin: 1em auto;
+}
+
+#media__content #scroll__here {
+ border: 1px dashed __border__;
+}
+
+#media__content .odd {
+ background-color: __background_other__;
+ padding: 0.4em;
+}
+
+#media__content .even {
+ padding: 0.4em;
+}
+
+#media__content a.mediafile {
+ margin-right: 1.5em;
+ font-weight: bold;
+}
+
+#media__content div.detail {
+ padding: 0.3em 0 0.3em 2em;
+}
+
+#media__content div.detail div.thumb {
+ float: left;
+ width: 130px;
+ text-align: center;
+ margin-right: 0.4em;
+}
+
+
+#media__content img.btn {
+ vertical-align: text-bottom;
+}
+
+#media__content div.example {
+ color: __text_neu__;
+ margin-left: 1em;
+}
+
+/* --- upload form --- */
+
+#media__content div.upload {
+ font-size: 90%;
+ padding: 0 0.5em 0.5em 0.5em;
+}
+
+#media__content #mediamanager__uploader {
+ display: block;
+ border-bottom: solid 1px __border__;
+ padding: 0 0.5em 1em 0.5em;
+}
+
+#media__content form#dw__upload {
+ border-bottom: 0;
+}
+
+#media__content form#dw__upload fieldset {
+ padding: 0;
+ margin: 0;
+ border: none;
+ width: auto;
+}
+#media__content form#dw__upload p {
+ text-align: left;
+ padding: 0.25em 0;
+ margin: 0;
+ line-height: 1.0em;
+}
+#media__content form#dw__upload label.check {
+ float: none;
+ width: auto;
+ margin-left: 11.5em;
+}
+
+/* --- meta edit form --- */
+
+#media__content form.meta {
+ display: block;
+ padding: 0 0 1em 0;
+}
+
+#media__content form.meta label {
+ display: block;
+ width: 25%;
+ float: left;
+ font-weight: bold;
+ margin-left: 1em;
+ clear: left;
+}
+
+#media__content form.meta .edit {
+ font: 100% "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ float: left;
+ width: 70%;
+ padding-right: 0;
+ padding-left: 0.2em;
+ margin: 2px;
+}
+
+#media__content form.meta textarea.edit {
+ height: 8em;
+}
+
+#media__content form.meta div.metafield {
+ clear: left;
+}
+
+#media__content form.meta div.buttons {
+ clear: left;
+ margin-left: 20%;
+ padding-left: 1em;
+}
diff --git a/lib/tpl/default/mediamanager.php b/lib/tpl/default/mediamanager.php
new file mode 100644
index 000000000..7b7fe8675
--- /dev/null
+++ b/lib/tpl/default/mediamanager.php
@@ -0,0 +1,44 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?php
+/**
+ * DokuWiki Default Template
+ *
+ * This is the template for the media manager popup
+ *
+ * You should leave the doctype at the very top - It should
+ * always be the very first line of a document.
+ *
+ * @link http://dokuwiki.org/templates
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+?>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>" lang="<?php echo $conf['lang']?>" dir="ltr">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>
+ <?php echo hsc($lang['mediaselect'])?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+ <?php tpl_metaheaders()?>
+ <link rel="shortcut icon" href="<?php echo DOKU_TPL?>images/favicon.ico" />
+</head>
+
+<body>
+<div id="media__manager" class="dokuwiki">
+ <div id="media__left">
+ <?php html_msgarea()?>
+ <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 id="media__right">
+ <?php tpl_mediaContent() ?>
+ </div>
+</div>
+</body>
+</html>
diff --git a/lib/tpl/default/print.css b/lib/tpl/default/print.css
new file mode 100644
index 000000000..45b60aad2
--- /dev/null
+++ b/lib/tpl/default/print.css
@@ -0,0 +1,228 @@
+
+body {
+ font: 10pt "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ background-color: White;
+ color: Black;
+}
+
+table {
+ font-size: 100%;
+ padding: 0;
+ margin: 0;
+}
+
+tr,td,th { padding: 0; margin: 0; }
+
+img { border: 0; }
+
+a {
+ color: #000000;
+ text-decoration: none;
+ background: none !important;
+}
+
+a.interwiki {
+ padding-left: 0px !important;
+}
+
+
+div.meta {
+ clear: both;
+ margin-top: 1em;
+ font-size: 70%;
+ text-align: right;
+}
+
+div.breadcrumbs {
+ display: none;
+}
+
+
+/* --------------------- Text formating -------------------------------- */
+
+/* external link */
+a.urlextern:after {
+ content: " [" attr(href) "]";
+ font-size: 90%;
+}
+
+/* interwiki link */
+a.interwiki:after {
+ content: " [" attr(href) "]";
+ font-size: 90%;
+}
+
+/* email link */
+a.mail:after {
+ content: " [" attr(href) "]";
+ font-size: 90%;
+}
+
+/* existing wikilink */
+a.wikilink1 { text-decoration: underline; }
+
+/* the document */
+div.page {
+ text-align: justify;
+}
+
+/* general headline setup */
+h1, h2, h3, h4, h5 {
+ color: Black;
+ background-color: transparent;
+ font-family: "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ font-size: 100%;
+ font-weight: normal;
+ margin-left: 0;
+ margin-right: 0;
+ margin-top: 0;
+ margin-bottom: 1em;
+ padding-left: 0;
+ padding-right: 0;
+ padding-top: 0.5em;
+ padding-bottom: 0;
+ border-bottom: 1px solid #000000;
+ clear: left;
+}
+
+/* special headlines */
+h1 { font-size: 160%; font-weight: bold; }
+h2 { font-size: 150%; }
+h3 { font-size: 140%; border-bottom: none; }
+h4 { font-size: 120%; border-bottom: none; }
+h5 { font-size: 100%; border-bottom: none; }
+
+/* embedded images */
+img.media {
+ margin: 3px;
+}
+
+/* the styles for media images are already in
+ lib/styles/all.css, these are additional styles */
+img.medialeft {
+ margin: 0 1.5em 0 0;
+}
+img.mediaright {
+ margin: 0 0 0 1.5em;
+}
+img.mediacenter {
+}
+
+/* unordered lists */
+ul {
+ line-height: 1.5em;
+ list-style-type: square;
+ margin: 0 0 1em 3.5em;
+ padding: 0;
+}
+
+/* ordered lists */
+ol {
+ line-height: 1.5em;
+ margin: 0 0 1em 3.5em;
+ padding: 0;
+ font-weight: normal;
+}
+
+div.dokuwiki li ul {
+ margin-bottom: 0;
+}
+div.dokuwiki li ol {
+ margin-bottom: 0;
+}
+
+div.dokuwiki ol { list-style-type: decimal; }
+div.dokuwiki ol ol { list-style-type: upper-roman; }
+div.dokuwiki ol ol ol { list-style-type: lower-alpha; }
+div.dokuwiki ol ol ol ol { list-style-type: lower-greek; }
+
+/* the list items overriding the ol definition */
+span.li {
+ font-weight: normal;
+}
+
+pre {
+ font-family: monospace;
+}
+
+/* code blocks by indention */
+pre.pre {
+ font-size: 8pt;
+ padding: 0.5em;
+ border: 1px dashed #000000;
+ color: Black;
+ overflow: visible;
+}
+
+/* code blocks by code tag */
+pre.code {
+ font-size: 8pt;
+ padding: 0.5em;
+ border: 1px dashed #000000;
+ color: Black;
+ overflow: visible;
+}
+
+/* inline code words */
+code {
+ font-size: 120%;
+}
+
+/* code blocks by file tag */
+pre.file {
+ font-size: 8pt;
+ padding: 0.5em;
+ border: 1px dotted #000000;
+ color: Black;
+ overflow: visible;
+}
+
+/* footnotes */
+div.footnotes {
+ clear: both;
+ border-top: 1px solid #000000;
+ padding-left: 1em;
+ margin-top: 1em;
+}
+
+div.fn {
+ font-size: 90%;
+}
+
+a.fn_top {
+ vertical-align: super;
+ font-size: 80%;
+}
+
+a.fn_bot {
+ vertical-align: super;
+ font-size: 80%;
+ font-weight: bold;
+}
+
+acronym {
+ border: 0;
+}
+
+/* ---------- inline tables ------------------- */
+
+table.inline {
+ font-size: 80%;
+ background-color: #ffffff;
+ border-spacing: 0px;
+ border-collapse: collapse;
+}
+
+table.inline th {
+ padding: 3px;
+ border: 1px solid #000000;
+ border-bottom: 2px solid #000000;
+}
+
+table.inline td {
+ padding: 3px;
+ border: 1px solid #000000;
+}
+
+.toc, .footerinc, .header, .bar, .user { display: none; }
+
diff --git a/lib/tpl/default/rtl.css b/lib/tpl/default/rtl.css
new file mode 100644
index 000000000..82c85839b
--- /dev/null
+++ b/lib/tpl/default/rtl.css
@@ -0,0 +1,154 @@
+/**
+ * Layout and design corrections for right-to-left languages
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Dotan Kamber <kamberd@yahoo.com>
+ */
+
+.bar-left {
+ float: right;
+ text-align: right;
+}
+
+.bar-right {
+ float: left;
+ text-align: left;
+}
+
+.pagename {
+ float: right;
+ text-align: right;
+}
+
+.logo {
+ float: left;
+ text-align: left;
+}
+
+label {
+ text-align: left;
+}
+
+label.simple {
+ text-align: right;
+}
+
+div.meta div.user {
+ float: right;
+}
+
+div.meta div.doc {
+ text-align: left;
+}
+
+/* ------------------ Design corrections --------------------------------- */
+
+div.dokuwiki ul,
+div.dokuwiki ol {
+ margin: 0.5em 3.5em 0.5em 0;
+}
+div.dokuwiki li ul,
+div.dokuwiki li ol {
+ margin: 0.5em 1.5em 0.5em 0;
+}
+
+div.dokuwiki a.urlextern,
+div.dokuwiki a.interwiki,
+div.dokuwiki a.windows,
+div.dokuwiki a.mail {
+ /* should work but doesn't - so we just disable icons here*/
+ /*
+ background-position: right 1px;
+ padding-right: 16px;
+ */
+ background-image: none !important;
+ padding: 0px 0px 0px 0px;
+}
+
+div.dokuwiki div.secedit input.button {
+ float: left;
+}
+
+/* headlines */
+div.dokuwiki h1, div.dokuwiki h2, div.dokuwiki h3, div.dokuwiki h4, div.dokuwiki h5 {
+ clear: right;
+}
+
+/* special headlines */
+div.dokuwiki h1 { margin-left: 0px; margin-right: 0px; }
+div.dokuwiki h2 { margin-left: 0px; margin-right: 20px; }
+div.dokuwiki h3 { margin-left: 0px; margin-right: 40px; }
+div.dokuwiki h4 { margin-left: 0px; margin-right: 60px; }
+div.dokuwiki h5 { margin-left: 0px; margin-right: 80px; }
+
+/* indent different sections */
+div.dokuwiki div.level1 { margin-left: 0px; margin-right: 3px; }
+div.dokuwiki div.level2 { margin-left: 0px; margin-right: 23px; }
+div.dokuwiki div.level3 { margin-left: 0px; margin-right: 43px; }
+div.dokuwiki div.level4 { margin-left: 0px; margin-right: 63px; }
+div.dokuwiki div.level5 { margin-left: 0px; margin-right: 83px; }
+
+/* TOC control */
+div.dokuwiki div.toc {
+ float: left;
+}
+
+div.dokuwiki div.tocheader {
+ text-align: right;
+}
+
+div.dokuwiki #toc__inside {
+ text-align: right;
+}
+
+div.dokuwiki ul.toc {
+ padding: 0;
+ padding-right: 1em;
+}
+
+div.dokuwiki ul.toc li {
+ background-position: right 0.6em;
+ padding-right: 0.4em;
+ direction: rtl;
+}
+
+div.dokuwiki ul.toc li.clear {
+ padding-right: 0.4em;
+}
+
+div.dokuwiki .code {
+ direction: ltr;
+ text-align: left;
+}
+div.dokuwiki blockquote {
+ border-left: 0;
+ padding-left: 0;
+ border-right: 2px solid __border__;
+ padding-right: 3px;
+}
+
+/* Admin corrections */
+#admin__version {
+ clear: right;
+ float: left;
+}
+
+.dokuwiki ul.admin_tasks {
+ float: right;
+}
+
+.dokuwiki ul.admin_tasks li {
+ padding-left: 0px;
+ padding-right: 35px;
+ background: transparent none no-repeat scroll right 0;
+ text-align: right;
+}
+
+/* Search corrections */
+div.dokuwiki ul.search_quickhits li {
+ float: right;
+}
+
+div#qsearch__out {
+ text-align: right;
+}
diff --git a/lib/tpl/default/style.ini b/lib/tpl/default/style.ini
new file mode 100644
index 000000000..7d27381c9
--- /dev/null
+++ b/lib/tpl/default/style.ini
@@ -0,0 +1,72 @@
+; Please see http://www.php.net/manual/en/function.parse-ini-file.php
+; for limitations of the ini format used here
+
+; Define the stylesheets your template uses here. The second value
+; defines for which output media the style should be loaded. Currently
+; print, screen and rtl are supported. rtl styles are loaded additionally
+; to screen styles if a right-to-left language is selected (eg. hebrew)
+[stylesheets]
+layout.css = screen
+design.css = screen
+style.css = screen
+
+media.css = screen
+_mediaoptions.css = screen
+_admin.css = screen
+_linkwiz.css = screen
+_subscription.css = screen
+_mediamanager.css = screen
+_tabs.css = screen
+_fileuploader.css = screen
+
+rtl.css = rtl
+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.
+[replacements]
+
+;--------------------------------------------------------------------------
+;------ guaranteed dokuwiki color placeholders that every plugin can use
+; main text and background colors
+__text__ = "#000"
+__background__ = "#fff"
+; alternative text and background colors
+__text_alt__ = "#638c9c"
+__background_alt__ = "#dee7ec"
+; neutral text and background colors
+__text_neu__ = "#666"
+__background_neu__ = "#f5f5f5"
+; border color
+__border__ = "#8cacbb"
+;--------------------------------------------------------------------------
+
+; other text and background colors
+__text_other__ = "#ccc"
+__background_other__ = "#f7f9fa"
+
+; these are used for links
+__extern__ = "#436976"
+__existing__ = "#090"
+__missing__ = "#f30"
+
+; highlighting search snippets
+__highlight__ = "#ff9"
+
+
+;--------------------------------------------------------------------------
+;------ for keeping old templates and plugins compatible to the old pattern
+; (to be deleted at the next or after next release)
+__white__ = "#fff"
+__lightgray__ = "#f5f5f5"
+__mediumgray__ = "#ccc"
+__darkgray__ = "#666"
+__black__ = "#000"
+
+; these are the shades of blue
+__lighter__ = "#f7f9fa"
+__light__ = "#eef3f8"
+__medium__ = "#dee7ec"
+__dark__ = "#8cacbb"
+__darker__ = "#638c9c"
diff --git a/lib/tpl/index.php b/lib/tpl/index.php
new file mode 100644
index 000000000..0273e5678
--- /dev/null
+++ b/lib/tpl/index.php
@@ -0,0 +1,68 @@
+<?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>
+ */
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+if(!defined('NOSESSION')) define('NOSESSION',1);
+require_once(DOKU_INC.'inc/init.php');
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Template Replacements</title>
+ <style type="text/css">
+ 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
+$ini = @parse_ini_file($conf['template'].'/style.ini',true);
+if ($ini) {
+ echo '<table>';
+ echo "<caption>".htmlspecialchars($conf['template'])."'s style.ini</caption>";
+ foreach($ini['replacements'] as $key => $val){
+ echo '<tr>';
+ echo '<td>'.htmlspecialchars($key).'</td>';
+ echo '<td>'.htmlspecialchars($val).'</td>';
+ echo '<td>';
+ if(preg_match('/^#[0-f]{3,6}$/i',$val)){
+ echo '<div class="color" style="background-color:'.$val.';">&nbsp;</div>';
+ }
+ echo '</td>';
+ echo '</tr>';
+ }
+ echo '</table>';
+} else {
+ echo "<p>Non-existent template: <strong>".htmlspecialchars($conf['template'])."</strong></p>";
+}
+?>
+</body>
+</html>