69 | Editing is enabled. Use the "Save changes" button below the editor to commit modifications to this file.
70 |
71 |
72 |
73 |
83 |
84 |
85 |
170 |
171 |
--------------------------------------------------------------------------------
/library/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | "tags": ["wiki", "wikitten", "personal wiki"],
3 | "author": "Victor Stanciu",
4 | "maintainer": "Eduardo Fernandes"
5 | ---
6 |
7 | # Hello there! Welcome to your personal wiki!
8 |
9 | `Wikitten` is a small, fast, PHP wiki that [I][1] made because I really needed a place to store my notes, snippets, ideas, and so on. I've tried a lot of personal wikis and note-taking applications in the past, but since I have peculiar needs, none of them really suited me, so I rolled my own.
10 |
11 | [1]: https://github.com/devaneando/wikitten
12 |
13 | The page you are looking at right now is part of the actual wiki, and is written using the [Markdown](http://daringfireball.net/projects/markdown/syntax) syntax. If you're not familiar with Markdown go ahead, press the `Toggle source` button in the upper right corner, or check out the [sample document](Sample%20Markdown%20document.md) in the sidebar. By the way, if you're reading the source, noticed how I linked to another page within the wiki?
14 |
15 | Now, there are other Markdown-powered wikis out there, and I've tried some of them, but I wanted something that I could use to store my code snippets too, so `syntax highlighting` was a must. Expand the `Code snippets` folder in the sidebar and take a look at some of the supported file types. I also needed something light enough that I could sync on Dropbox, because I access my notes and snippets on multiple machines.
16 |
17 | ## Requirements
18 |
19 | - PHP `5.3+`
20 | - The Apache webserver (with `mod_rewrite`)
21 |
22 | or
23 |
24 | - PHP `5.4`
25 | - Inbuilt webserver `php -S 0.0.0.0:8000 routing.php`
26 |
27 | or
28 |
29 | - PHP `7.0+`
30 | - Inbuilt webserver `php -S 0.0.0.0:8000 routing.php`
31 |
32 | ### Installation
33 |
34 | - [Download](https://github.com/devaneando/Wikitten/archive/master.zip) the latest version or clone the [repository on GitHub](https://github.com/devaneando/Wikitten)
35 | - After extracting the archive, drop the files somewhere in your DocumentRoot, or make a separate Apache [VirtualHost](http://httpd.apache.org/docs/2.2/mod/core.html#virtualhost).
36 | - That's it. There's a `library` directory in the installation folder. Everything you place in there will be rendered by the wiki. If there's an `index.md` file (such as the one you are reading now) in that folder, it will be served by default when accessing the wiki.
37 |
38 | ### Docker
39 |
40 | You can also run the wiki using [Docker](https://github.com/devaneando/Wikitten/wiki/Docker-instructions)
41 |
42 | ### Configure Wikitten
43 |
44 | You are able to configure Wikitten by using the config file.
45 | First, copy the `config.php.example` to `config.php` and you are ready to change the settings.
46 | Some options are disabled with a comment but can be enabled by removing `//` from the option line.
47 |
48 | - `define('APP_NAME', 'My Wiki');` - Set the Wiki title
49 | - `define('DEFAULT_FILE', 'index.md');` - Choose the file that should be loaded as the homepage, must be located in library folder
50 | - `define('LIBRARY', '/path/to/wiki/library');` - Set a custom path to the library
51 | - `define('ENABLE_EDITING', true);` - Enable the in-page editing of any files
52 | - `define('USE_PAGE_METADATA', true);` - Enable the JSON Front Matter (meta data), see below for more details
53 | - `define('USE_DARK_THEME', true);` - Enable the dark theme (see below for a screenshot)
54 | - `define('USE_WIKITTEN_LOGO', false);` - Disable the Wikitten logo on the left bottom
55 | - `define('ACCESS_USER', 'Wikitten');` - Will required to log in with to view the documents
56 | - `define('ACCESS_PASSWORD', 'Wikitten');` - Will required to log in with to view the documents
57 | - `define('EXTERNAL_LINK_TARGET', '_blank');` - Will append `target="_blank"` to all external links in markdown documents. If you want to disable this, just change the value to `self`.
58 | - `define('INTERNAL_WIKI_LINK', true);`- Will change markdown links to behave like a wiki so if you click a link to another markdown document, it will open in Wikitten in its real path.
59 |
60 | ### JSON Front Matter (meta data)
61 |
62 | Wikitten content can also be tagged using a simple but powerful JSON Front Matter system, akin to [Jekyll's YAML Front Matter](https://github.com/mojombo/jekyll/wiki/YAML-Front-Matter). Defining a custom title, tags, or other
63 | relevant data for a specific page is just a matter of adding a special header at the start of your files, like so:
64 |
65 | ---
66 | "title": "My Custom Page Title",
67 | "tags": ["my", "custom", "tags"],
68 | "author": "Bob"
69 | ---
70 |
71 | # Hello, world!
72 |
73 | This is my cool wiki page.
74 |
75 | Wikitten will intelligently grab this data, and use it for things like meta keywords, the
76 | page title, and maybe eventually search indexing. All the information provided in this
77 | header is passed as-is to the views, so future components and plugins may also make use of it.
78 |
79 | **Note:** The JSON header is expected to be a JSON hash, but to simplify things, Wikitten lets you leave out the starting an ending `{ }` brackets if you want. Everything else in the JSON syntax still applies:
80 |
81 | - Strings (i.e: `title` must be written within double quotes: `"title"`)
82 | - Values must be seperated with a comma character, even if its the only value in a line.
83 |
84 | ### Dark Theme
85 |
86 | If you are working until midnight it can be a pain to look at bright white backgrounds. That's why Wikitten offers a Dark Theme which can be enabled in the config.php file with the `define('USE_DARK_THEME', true);` option.
87 |
88 | It looks like this:
89 | 
90 |
91 | ### Customize CSS
92 |
93 | You can add a new Markdown Style by creating your custom file in the `static/css/custom-styles/` folder.
94 |
95 | The css must address to the `#render` element as shown in the `static/css/custom-styles/github.css` file.
96 |
97 | You can use the `static/css/custom-styles/github.css` file as basis to create a new customized one.
98 |
99 | After having your custom file, edit the `config.php` file and define your custom file name in `CUSTOM_MARKDOWN_STYLESHEET`.
100 |
101 | ```php
102 | // Enable a custom stylesheet
103 | define('CUSTOM_MARKDOWN_STYLESHEET', 'github.css');
104 | ```
105 |
106 | **Attention!!!** Do not use the full path to the file. Use only the filename.
107 |
108 | ### Roadmap
109 |
110 | Some of the features I plan to implement next:
111 |
112 | - [Pastebin](http://pastebin.com/) API integration. I think it would be cool to share snippets on Pastebin (or a similar service) with a single click
113 | - Creating / updating files directly through the web interface. Other wikis place great accent on creating and editing pages in the browser, but since I have my trusty code editor open non-stop anyway, I prefer to update my files manually for now.
114 | - Search in files
115 |
116 | ### Special thanks go to:
117 |
118 | - [Michel Fortin](http://michelf.ca/home/), for the [PHP Markdown parser](http://michelf.ca/projects/php-markdown/).
119 | - [Marijn Haverbeke](http://marijnhaverbeke.nl/), for [CodeMirror](http://codemirror.net/), a JavaScript code editor.
120 | - Twitter, for the [Bootstrap](http://twitter.github.com/bootstrap/) CSS framework.
121 | - All Vectors, for the [free cat vector](http://www.allvectors.com/cats-vector/) silhouette I used in making the logo.
122 | - [Sindre Sorhus](https://sindresorhus.com/) for the Github flavored [Markdown Style](https://github.com/sindresorhus/github-markdown-css).
123 |
--------------------------------------------------------------------------------
/library/Sample HTML document.html:
--------------------------------------------------------------------------------
1 |
This is a sample HTML document. Unlike Markdown documents, HTML is simply displayed as-is, so make sure you don't add tags that would interfere with the HTML of the wiki itself.
2 |
3 |
This is 2nd level heading
4 |
This is a test paragraph.
5 |
This is 3rd level heading
6 |
This is a test paragraph.
7 |
This is 4th level heading
8 |
This is a test paragraph.
9 |
This is 5th level heading
10 |
This is a test paragraph.
11 |
This is 6th level heading
12 |
This is a test paragraph.
13 |
Basic block level elements
14 |
This is a normal paragraph (p element). To add some length to it, let us mention that this page was primarily written for testing the effect of user style sheets. You can use it for various other purposes as well, like just checking how your browser displays various HTML elements.
15 |
This is another paragraph. I think it needs to be added that the set of elements tested is not exhaustive in any sense. I have selected those elements for which it can make sense to write user style sheet rules, in my opionion.
16 |
This is a div element. Authors may use such elements instead of paragraph markup for various reasons. (End of div.)
17 |
18 |
This is a block quotation containing a single paragraph. Well, not quite, since this is not really quoted text, but I hope you understand the point. After all, this page does not use HTML markup very normally anyway.
19 |
20 |
Lists
21 |
This is a paragraph before an unnumbered list (ul). Note that the spacing between a paragraph and a list before or after that is hard to tune in a user style sheet. You can't guess which paragraphs are logically related to a list, e.g. as a "list header".
22 |
23 |
One.
24 |
Two.
25 |
Three. Well, probably this list item should be longer. Note that for short items lists look better if they are compactly presented, whereas for long items, it would be better to have more vertical spacing between items.
26 |
Four. This is the last item in this list. Let us terminate the list now without making any more fuss about it.
27 |
28 |
This is a paragraph before a numbered list (ol). Note that the spacing between a paragraph and a list before or after that is hard to tune in a user style sheet. You can't guess which paragraphs are logically related to a list, e.g. as a "list header".
29 |
30 |
One.
31 |
Two.
32 |
Three. Well, probably this list item should be longer. Note that if items are short, lists look better if they are compactly presented, whereas for long items, it would be better to have more vertical spacing between items.
33 |
Four. This is the last item in this list. Let us terminate the list now without making any more fuss about it.
34 |
35 |
This is a paragraph before a definition list (dl). In principle, such a list should consist of terms and associated definitions. But many authors use dl elements for fancy "layout" things. Usually the effect is not too bad, if you design user style sheet rules for dl which are suitable for real definition lists.
36 |
recursion
see recursion
recursion, indirect
see indirect recursion
indirect recursion
see recursion, indirect
term
a word or other expression taken into specific use in a well-defined meaning, which is often defined rather rigorously, even formally, and may differ quite a lot from an everyday meaning
37 |
Text-level markup
38 |
39 |
CSS (an abbreviation; abbr markup used)
40 |
radar (an acronym; acronym markup used)
41 |
bolded (b markup used - just bolding with unspecified semantics)
42 |
big thing (big markup used)
43 |
large size (font size=6 markup used)
44 |
Courier font (font face=Courier markup used)
45 |
red text (font color=red markup used)
46 |
Origin of Species (a book title; cite markup used)
an octet is an entity consisting of eight bits (dfn markup used for the term being defined)
50 |
this is very simple (em markup used for emphasizing a word)
51 |
Homo sapiens (should appear in italics; i markup used)
52 |
here we have some inserted text (ins markup used)
53 |
type yes when prompted for an answer (kbd markup used for text indicating keyboard input)
54 |
Hello! (q markup used for quotation)
55 |
He said: She said Hello! (a quotation inside a quotation)
56 |
you may get the message Core dumped at times (samp markup used for sample output)
57 |
this is not that important (small markup used)
58 |
overstruck (strike markup used; note: s is a nonstandard synonym for strike)
59 |
this is highlighted text (strong markup used)
60 |
In order to test how subscripts and superscripts (sub and sup markup) work inside running text, we need some dummy text around constructs like x1 and H2O (where subscripts occur). So here is some fill so that you will (hopefully) see whether and how badly the subscripts and superscripts mess up vertical spacing between lines. Now superscripts: Mlle, 1st, and then some mathematical notations: ex, sin2x, and some nested superscripts (exponents) too: ex2 and f(x)g(x)a+b+c (where 2 and a+b+c should appear as exponents of exponents).
61 |
text in monospace font (tt markup used)
62 |
underlined text (u markup used)
63 |
the command catfilename displays the file specified by the filename (var markup used to indicate a word as a variable).
64 |
65 |
Some of the elements tested above are typically displayed in a monospace font, often using the same presentation for all of them. This tests whether that is the case on your browser:
This is a text paragraph that contains some inline links. Generally, inline links (as opposite to e.g. links lists) are problematic from the usability perspective, but they may have use as “incidental”, less relevant links.
78 |
Tables
79 |
The first row and the first column contain table header cells (th elements) only; other cells are data cells (td elements), with align="right" attributes:
80 |
81 |
82 |
83 |
Country
Total area
Land area
84 |
85 |
86 |
Denmark
87 |
43,070
88 |
42,370
89 |
90 |
91 |
Finland
92 |
337,030
93 |
305,470
94 |
95 |
96 |
Iceland
97 |
103,000
98 |
100,250
99 |
100 |
101 |
Norway
102 |
324,220
103 |
307,860
104 |
105 |
106 |
Sweden
107 |
449,964
108 |
410,928
109 |
110 |
111 |
--------------------------------------------------------------------------------
/plugins/PasteBin.php:
--------------------------------------------------------------------------------
1 | label array
85 | *
86 | * @var array
87 | */
88 | public static $pastePrivacyTypes = array(
89 | self::PASTE_PRIVACY_PUBLIC => 'Public',
90 | self::PASTE_PRIVACY_UNLISTED => 'Unlisted',
91 | self::PASTE_PRIVACY_PRIVATE => 'Private',
92 | );
93 |
94 | /**
95 | * API paste expire date type => label array
96 | *
97 | * @var array
98 | */
99 | public static $pasteExpireTypes = array(
100 | self::PASTE_EXPIRE_NEVER => 'Never',
101 | self::PASTE_EXPIRE_10M => '10 Minutes',
102 | self::PASTE_EXPIRE_1H => '1 Hour',
103 | self::PASTE_EXPIRE_1D => '1 Day',
104 | self::PASTE_EXPIRE_1W => '1 Week',
105 | self::PASTE_EXPIRE_2W => '2 Weeks',
106 | self::PASTE_EXPIRE_1M => '1 Month',
107 | );
108 |
109 | /**
110 | * Default options to be used when making cURL requests.
111 | *
112 | * @var array
113 | */
114 | public static $curlOptions = array(
115 | CURLOPT_CONNECTTIMEOUT => 10,
116 | CURLOPT_RETURNTRANSFER => true,
117 | CURLOPT_TIMEOUT => 60,
118 | CURLOPT_VERBOSE => 1,
119 | CURLOPT_NOBODY => 0,
120 | CURLOPT_ENCODING => 'UTF-8',
121 | );
122 |
123 |
124 | /**
125 | * Instantiate a new PasteBin object.
126 | *
127 | * @param string $_apiKey
128 | */
129 | public function __construct($_apiKey = false)
130 | {
131 | if ($_apiKey) {
132 | $this->setApiKey($_apiKey);
133 | }
134 | }
135 |
136 | /**
137 | * Set the API key used to make requests.
138 | *
139 | * @param string $_apiKey
140 | */
141 | public function setApiKey($_apiKey)
142 | {
143 | $this->apiDevKey = $_apiKey;
144 | }
145 |
146 | /**
147 | * Get the API key.
148 | *
149 | * @return string
150 | */
151 | public function getApiKey()
152 | {
153 | return $this->apiDevKey;
154 | }
155 |
156 | /**
157 | * Return last call error, whether it was a cURL error or API error.
158 | * If no error exists, false is returned.
159 | *
160 | * @return string|boolean
161 | */
162 | public function getError()
163 | {
164 | if ($this->curlError) {
165 | return $this->curlError;
166 | } elseif ($this->apiError) {
167 | return $this->apiError;
168 | }
169 |
170 | return false;
171 | }
172 |
173 | /**
174 | * Create a new Paste. If everything is OK the return value will be the
175 | * URL of the newly created Paste. If there was an error when the request
176 | * was sent, the return value will be false. Check the error message if
177 | * this is the case.
178 | *
179 | * @param string $_code
180 | * @param string $_visibility
181 | * @param string $_name
182 | * @param string $_expire
183 | * @param string $_format
184 | * @return string|boolean The URL for the newly created Paste
185 | */
186 | public function createPaste($_code, $_visibility = false, $_name = false,
187 | $_expire = false, $_format = false)
188 | {
189 | $params = array(
190 | self::API_FIELD_OPTION => self::API_OPTION_CREATE,
191 | self::API_FIELD_DEV_KEY => $this->getApiKey(),
192 | self::API_FIELD_PASTE_CODE => $_code,
193 | self::API_FIELD_PASTE_PRIVATE => $this->_preparePrivateValue($_visibility),
194 | self::API_FIELD_PASTE_NAME => (string)$_name,
195 | self::API_FIELD_PASTE_EXPIRE_DATE => $this->_prepareExpireValue($_expire),
196 | self::API_FIELD_PASTE_FORMAT => $this->_prepareFormatValue($_format),
197 | );
198 |
199 | return $this->_makePostRequest(self::API_POST_URL, $params);
200 | }
201 |
202 | /**
203 | * Make a cURL request using the POST method.
204 | *
205 | * @param string $_url
206 | * @param array $_params
207 | * @return string|boolean
208 | */
209 | protected function _makePostRequest($_url, $_params)
210 | {
211 | return $this->_makeRequest($_url, $_params, 'post');
212 | }
213 |
214 | /**
215 | * Make a cURL request by specifying the url, params and the method.
216 | *
217 | * @param string $_url
218 | * @param array $_params
219 | * @param string $_type
220 | * @return string|boolean
221 | */
222 | protected function _makeRequest($_url, $_params, $_type = 'get')
223 | {
224 | $ch = $this->_prepareRequest($_url, $_type, $_params);
225 |
226 | $result = curl_exec($ch);
227 | if (!$result) {
228 | $this->curlError = curl_error($ch);
229 | return false;
230 | }
231 |
232 | curl_close($ch);
233 |
234 | return $this->_parseResponse($result);
235 | }
236 |
237 | /**
238 | * Prepare the cURL request based on the http method type.
239 | *
240 | * @param string $_type
241 | * @return cURL handle
242 | */
243 | protected function _prepareRequest($_url, $_type, $_params = array())
244 | {
245 | $ch = $this->_initRequest();
246 | if ($ch) {
247 | curl_setopt($ch, CURLOPT_URL, $_url);
248 |
249 | switch (strtolower($_type)) {
250 | case 'post':
251 | curl_setopt($ch, CURLOPT_POST, 1);
252 |
253 | $postfields = $this->_encodeParams($_params);
254 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
255 | break;
256 |
257 | case 'get':
258 | default:
259 | // this is set as default, but just to be sure
260 | curl_setopt($ch, CURLOPT_HTTPGET, 1);
261 | }
262 | }
263 |
264 | return $ch;
265 | }
266 |
267 | /**
268 | * Prepare request params to be sent through cURL.
269 | *
270 | * @param array $_params
271 | * @return string
272 | */
273 | protected function _encodeParams(array $_params)
274 | {
275 | $data = array();
276 | foreach ($_params as $label => $value) {
277 | $data[] = $label .'=' . urlencode($value);
278 | }
279 |
280 | return implode('&', $data);
281 | }
282 |
283 | /**
284 | * Test if the privacy value is among valid ones,
285 | * else return the default value.
286 | *
287 | * @param string $_value
288 | * @return string
289 | */
290 | protected function _preparePrivateValue($_value)
291 | {
292 | if (in_array($_value, array_keys(self::$pastePrivacyTypes))) {
293 | return $_value;
294 | }
295 |
296 | // default unlisted
297 | return self::PASTE_PRIVACY_UNLISTED;
298 | }
299 |
300 | /**
301 | * Test if the expire date value is among the valid ones,
302 | * else return the default value.
303 | *
304 | * @param string $_value
305 | * @return string
306 | */
307 | protected function _prepareExpireValue($_value)
308 | {
309 | if (in_array($_value, array_keys(self::$pasteExpireTypes))) {
310 | return $_value;
311 | }
312 |
313 | // default 10 minutes
314 | return self::PASTE_EXPIRE_10M;
315 | }
316 |
317 | /**
318 | * Set proper format of the code.
319 | *
320 | * @param string $_value
321 | * @return string
322 | */
323 | protected function _prepareFormatValue($_value)
324 | {
325 | return $_value ? $_value : 'text';
326 | }
327 |
328 | /**
329 | * Initiates the cURL request used by other methods to send cURL requests.
330 | *
331 | * @return cURL handle|false
332 | */
333 | protected function _initRequest()
334 | {
335 | $ch = curl_init();
336 | curl_setopt_array($ch, self::$curlOptions);
337 |
338 | return $ch;
339 | }
340 |
341 | /**
342 | * Interpret the response received from the API.
343 | * Check if there is an error returned or not.
344 | *
345 | * @param string $_response
346 | * @return boolean|string
347 | */
348 | protected function _parseResponse($_response)
349 | {
350 | if (preg_match('/Bad API request, (.*)/', $_response, $match)) {
351 | $this->apiError = ucfirst($match[1]);
352 | return false;
353 | }
354 |
355 | return $_response;
356 | }
357 | }
358 |
--------------------------------------------------------------------------------
/static/js/prettify.js:
--------------------------------------------------------------------------------
1 | !function(){var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
2 | (function(){function S(a){function d(e){var b=e.charCodeAt(0);if(b!==92)return b;var a=e.charAt(1);return(b=r[a])?b:"0"<=a&&a<="7"?parseInt(e.substring(1),8):a==="u"||a==="x"?parseInt(e.substring(2),16):e.charCodeAt(1)}function g(e){if(e<32)return(e<16?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);return e==="\\"||e==="-"||e==="]"||e==="^"?"\\"+e:e}function b(e){var b=e.substring(1,e.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),e=[],a=
3 | b[0]==="^",c=["["];a&&c.push("^");for(var a=a?1:0,f=b.length;a122||(l<65||h>90||e.push([Math.max(65,h)|32,Math.min(l,90)|32]),l<97||h>122||e.push([Math.max(97,h)&-33,Math.min(l,122)&-33]))}}e.sort(function(e,a){return e[0]-a[0]||a[1]-e[1]});b=[];f=[];for(a=0;ah[0]&&(h[1]+1>h[0]&&c.push("-"),c.push(g(h[1])));c.push("]");return c.join("")}function s(e){for(var a=e.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),c=a.length,d=[],f=0,h=0;f=2&&e==="["?a[f]=b(l):e!=="\\"&&(a[f]=l.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var x=0,m=!1,j=!1,k=0,c=a.length;k=5&&"lang-"===w.substring(0,5))&&!(t&&typeof t[1]==="string"))f=!1,w="src";f||(r[z]=w)}h=c;c+=z.length;if(f){f=t[1];var l=z.indexOf(f),B=l+f.length;t[2]&&(B=z.length-t[2].length,l=B-f.length);w=w.substring(5);H(j+h,z.substring(0,l),g,k);H(j+h+l,f,I(w,f),k);H(j+h+B,z.substring(B),g,k)}else k.push(j+h,w)}a.g=k}var b={},s;(function(){for(var g=a.concat(d),j=[],k={},c=0,i=g.length;c=0;)b[n.charAt(e)]=r;r=r[1];n=""+r;k.hasOwnProperty(n)||(j.push(r),k[n]=q)}j.push(/[\S\s]/);s=S(j)})();var x=d.length;return g}function v(a){var d=[],g=[];a.tripleQuotedStrings?d.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?d.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
10 | q,"'\"`"]):d.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&g.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var b=a.hashComments;b&&(a.cStyleComments?(b>1?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),g.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,q])):d.push(["com",
11 | /^#[^\n\r]*/,q,"#"]));a.cStyleComments&&(g.push(["com",/^\/\/[^\n\r]*/,q]),g.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));if(b=a.regexLiterals){var s=(b=b>1?"":"\n\r")?".":"[\\S\\s]";g.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+("/(?=[^/*"+b+"])(?:[^/\\x5B\\x5C"+b+"]|\\x5C"+s+"|\\x5B(?:[^\\x5C\\x5D"+b+"]|\\x5C"+
12 | s+")*(?:\\x5D|$))+/")+")")])}(b=a.types)&&g.push(["typ",b]);b=(""+a.keywords).replace(/^ | $/g,"");b.length&&g.push(["kwd",RegExp("^(?:"+b.replace(/[\s,]+/g,"|")+")\\b"),q]);d.push(["pln",/^\s+/,q," \r\n\t\u00a0"]);b="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(b+="(?!s*/)");g.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,
13 | q],["pun",RegExp(b),q]);return C(d,g)}function J(a,d,g){function b(a){var c=a.nodeType;if(c==1&&!x.test(a.className))if("br"===a.nodeName)s(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)b(a);else if((c==3||c==4)&&g){var d=a.nodeValue,i=d.match(m);if(i)c=d.substring(0,i.index),a.nodeValue=c,(d=d.substring(i.index+i[0].length))&&a.parentNode.insertBefore(j.createTextNode(d),a.nextSibling),s(a),c||a.parentNode.removeChild(a)}}function s(a){function b(a,c){var d=
14 | c?a.cloneNode(!1):a,e=a.parentNode;if(e){var e=b(e,1),g=a.nextSibling;e.appendChild(d);for(var i=g;i;i=g)g=i.nextSibling,e.appendChild(i)}return d}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),d;(d=a.parentNode)&&d.nodeType===1;)a=d;c.push(a)}for(var x=/(?:^|\s)nocode(?:\s|$)/,m=/\r\n?|\n/,j=a.ownerDocument,k=j.createElement("li");a.firstChild;)k.appendChild(a.firstChild);for(var c=[k],i=0;i=0;){var b=d[g];F.hasOwnProperty(b)?D.console&&console.warn("cannot override language handler %s",b):F[b]=a}}function I(a,d){if(!a||!F.hasOwnProperty(a))a=/^\s*=l&&(b+=2);g>=B&&(r+=2)}}finally{if(f)f.style.display=h}}catch(u){D.console&&console.log(u&&u.stack||u)}}var D=window,y=["break,continue,do,else,for,if,return,while"],E=[[y,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],M=[E,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],N=[E,"abstract,assert,boolean,byte,extends,final,finally,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],
19 | O=[N,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,internal,into,is,let,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var,virtual,where"],E=[E,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],P=[y,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
20 | Q=[y,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],W=[y,"as,assert,const,copy,drop,enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv,pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"],y=[y,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],R=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,
21 | V=/\S/,X=v({keywords:[M,O,E,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",P,Q,y],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),F={};p(X,["default-code"]);p(C([],[["pln",/^[^]+/],["dec",/^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",
22 | /^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^