marked 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/component.json +1 -1
- package/doc/broken.md +426 -0
- package/doc/todo.md +2 -0
- package/lib/marked.js +28 -13
- package/package.json +1 -1
package/component.json
CHANGED
package/doc/broken.md
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
# Markdown is broken
|
|
2
|
+
|
|
3
|
+
I have a lot of scraps of markdown engine oddities that I've collected over the
|
|
4
|
+
years. What you see below is slightly messy, but it's what I've managed to
|
|
5
|
+
cobble together to illustrate the differences between markdown engines, and
|
|
6
|
+
why, if there ever is a markdown specification, it has to be absolutely
|
|
7
|
+
thorough. There are a lot more of these little differences I have documented
|
|
8
|
+
elsewhere. I know I will find them lingering on my disk one day, but until
|
|
9
|
+
then, I'll continue to add whatever strange nonsensical things I find.
|
|
10
|
+
|
|
11
|
+
Some of these examples may only mention a particular engine compared to marked.
|
|
12
|
+
However, the examples with markdown.pl could easily be swapped out for
|
|
13
|
+
discount, upskirt, or markdown.js, and you would very easily see even more
|
|
14
|
+
inconsistencies.
|
|
15
|
+
|
|
16
|
+
A lot of this was written when I was very unsatisfied with the inconsistencies
|
|
17
|
+
between markdown engines. Please excuse the frustration noticeable in my
|
|
18
|
+
writing.
|
|
19
|
+
|
|
20
|
+
## Examples of markdown's "stupid" list parsing
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
$ markdown.pl
|
|
24
|
+
|
|
25
|
+
* item1
|
|
26
|
+
|
|
27
|
+
* item2
|
|
28
|
+
|
|
29
|
+
text
|
|
30
|
+
^D
|
|
31
|
+
<ul>
|
|
32
|
+
<li><p>item1</p>
|
|
33
|
+
|
|
34
|
+
<ul>
|
|
35
|
+
<li>item2</li>
|
|
36
|
+
</ul>
|
|
37
|
+
|
|
38
|
+
<p><p>text</p></li>
|
|
39
|
+
</ul></p>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
$ marked
|
|
45
|
+
* item1
|
|
46
|
+
|
|
47
|
+
* item2
|
|
48
|
+
|
|
49
|
+
text
|
|
50
|
+
^D
|
|
51
|
+
<ul>
|
|
52
|
+
<li><p>item1</p>
|
|
53
|
+
<ul>
|
|
54
|
+
<li>item2</li>
|
|
55
|
+
</ul>
|
|
56
|
+
<p>text</p>
|
|
57
|
+
</li>
|
|
58
|
+
</ul>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Which looks correct to you?
|
|
62
|
+
|
|
63
|
+
- - -
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
$ markdown.pl
|
|
67
|
+
* hello
|
|
68
|
+
> world
|
|
69
|
+
^D
|
|
70
|
+
<p><ul>
|
|
71
|
+
<li>hello</p>
|
|
72
|
+
|
|
73
|
+
<blockquote>
|
|
74
|
+
<p>world</li>
|
|
75
|
+
</ul></p>
|
|
76
|
+
</blockquote>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
$ marked
|
|
81
|
+
* hello
|
|
82
|
+
> world
|
|
83
|
+
^D
|
|
84
|
+
<ul>
|
|
85
|
+
<li>hello<blockquote>
|
|
86
|
+
<p>world</p>
|
|
87
|
+
</blockquote>
|
|
88
|
+
</li>
|
|
89
|
+
</ul>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Again, which looks correct to you?
|
|
93
|
+
|
|
94
|
+
- - -
|
|
95
|
+
|
|
96
|
+
EXAMPLE:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
$ markdown.pl
|
|
100
|
+
* hello
|
|
101
|
+
* world
|
|
102
|
+
* hi
|
|
103
|
+
code
|
|
104
|
+
^D
|
|
105
|
+
<ul>
|
|
106
|
+
<li>hello
|
|
107
|
+
<ul>
|
|
108
|
+
<li>world</li>
|
|
109
|
+
<li>hi
|
|
110
|
+
code</li>
|
|
111
|
+
</ul></li>
|
|
112
|
+
</ul>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The code isn't a code block even though it's after the bullet margin. I know,
|
|
116
|
+
lets give it two more spaces, effectively making it 8 spaces past the bullet.
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
$ markdown.pl
|
|
120
|
+
* hello
|
|
121
|
+
* world
|
|
122
|
+
* hi
|
|
123
|
+
code
|
|
124
|
+
^D
|
|
125
|
+
<ul>
|
|
126
|
+
<li>hello
|
|
127
|
+
<ul>
|
|
128
|
+
<li>world</li>
|
|
129
|
+
<li>hi
|
|
130
|
+
code</li>
|
|
131
|
+
</ul></li>
|
|
132
|
+
</ul>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
And, it's still not a code block. Did you also notice that the 3rd item isn't
|
|
136
|
+
even its own list? Markdown screws that up too because of its indentation
|
|
137
|
+
unaware parsing.
|
|
138
|
+
|
|
139
|
+
- - -
|
|
140
|
+
|
|
141
|
+
Let's look at some more examples of markdown's list parsing:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
$ markdown.pl
|
|
145
|
+
|
|
146
|
+
* item1
|
|
147
|
+
|
|
148
|
+
* item2
|
|
149
|
+
|
|
150
|
+
text
|
|
151
|
+
^D
|
|
152
|
+
<ul>
|
|
153
|
+
<li><p>item1</p>
|
|
154
|
+
|
|
155
|
+
<ul>
|
|
156
|
+
<li>item2</li>
|
|
157
|
+
</ul>
|
|
158
|
+
|
|
159
|
+
<p><p>text</p></li>
|
|
160
|
+
</ul></p>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Misnested tags.
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
$ marked
|
|
168
|
+
* item1
|
|
169
|
+
|
|
170
|
+
* item2
|
|
171
|
+
|
|
172
|
+
text
|
|
173
|
+
^D
|
|
174
|
+
<ul>
|
|
175
|
+
<li><p>item1</p>
|
|
176
|
+
<ul>
|
|
177
|
+
<li>item2</li>
|
|
178
|
+
</ul>
|
|
179
|
+
<p>text</p>
|
|
180
|
+
</li>
|
|
181
|
+
</ul>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Which looks correct to you?
|
|
185
|
+
|
|
186
|
+
- - -
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
$ markdown.pl
|
|
190
|
+
* hello
|
|
191
|
+
> world
|
|
192
|
+
^D
|
|
193
|
+
<p><ul>
|
|
194
|
+
<li>hello</p>
|
|
195
|
+
|
|
196
|
+
<blockquote>
|
|
197
|
+
<p>world</li>
|
|
198
|
+
</ul></p>
|
|
199
|
+
</blockquote>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
More misnested tags.
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
$ marked
|
|
207
|
+
* hello
|
|
208
|
+
> world
|
|
209
|
+
^D
|
|
210
|
+
<ul>
|
|
211
|
+
<li>hello<blockquote>
|
|
212
|
+
<p>world</p>
|
|
213
|
+
</blockquote>
|
|
214
|
+
</li>
|
|
215
|
+
</ul>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Again, which looks correct to you?
|
|
219
|
+
|
|
220
|
+
- - -
|
|
221
|
+
|
|
222
|
+
# Why quality matters - Part 2
|
|
223
|
+
|
|
224
|
+
``` bash
|
|
225
|
+
$ markdown.pl
|
|
226
|
+
* hello
|
|
227
|
+
> world
|
|
228
|
+
^D
|
|
229
|
+
<p><ul>
|
|
230
|
+
<li>hello</p>
|
|
231
|
+
|
|
232
|
+
<blockquote>
|
|
233
|
+
<p>world</li>
|
|
234
|
+
</ul></p>
|
|
235
|
+
</blockquote>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
``` bash
|
|
239
|
+
$ sundown # upskirt
|
|
240
|
+
* hello
|
|
241
|
+
> world
|
|
242
|
+
^D
|
|
243
|
+
<ul>
|
|
244
|
+
<li>hello
|
|
245
|
+
> world</li>
|
|
246
|
+
</ul>
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
``` bash
|
|
250
|
+
$ marked
|
|
251
|
+
* hello
|
|
252
|
+
> world
|
|
253
|
+
^D
|
|
254
|
+
<ul><li>hello <blockquote><p>world</p></blockquote></li></ul>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Which looks correct to you?
|
|
258
|
+
|
|
259
|
+
- - -
|
|
260
|
+
|
|
261
|
+
See: https://github.com/evilstreak/markdown-js/issues/23
|
|
262
|
+
|
|
263
|
+
``` bash
|
|
264
|
+
$ markdown.pl # upskirt/markdown.js/discount
|
|
265
|
+
* hello
|
|
266
|
+
var a = 1;
|
|
267
|
+
* world
|
|
268
|
+
^D
|
|
269
|
+
<ul>
|
|
270
|
+
<li>hello
|
|
271
|
+
var a = 1;</li>
|
|
272
|
+
<li>world</li>
|
|
273
|
+
</ul>
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
``` bash
|
|
277
|
+
$ marked
|
|
278
|
+
* hello
|
|
279
|
+
var a = 1;
|
|
280
|
+
* world
|
|
281
|
+
^D
|
|
282
|
+
<ul><li>hello
|
|
283
|
+
<pre>code>var a = 1;</code></pre></li>
|
|
284
|
+
<li>world</li></ul>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Which looks more reasonable? Why shouldn't code blocks be able to appear in
|
|
288
|
+
list items in a sane way?
|
|
289
|
+
|
|
290
|
+
- - -
|
|
291
|
+
|
|
292
|
+
``` bash
|
|
293
|
+
$ markdown.js
|
|
294
|
+
<div>hello</div>
|
|
295
|
+
|
|
296
|
+
<span>hello</span>
|
|
297
|
+
^D
|
|
298
|
+
<p><div>hello</div></p>
|
|
299
|
+
|
|
300
|
+
<p><span>hello</span></p>
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
``` bash
|
|
304
|
+
$ marked
|
|
305
|
+
<div>hello</div>
|
|
306
|
+
|
|
307
|
+
<span>hello</span>
|
|
308
|
+
^D
|
|
309
|
+
<div>hello</div>
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
<p><span>hello</span>
|
|
313
|
+
</p>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
- - -
|
|
317
|
+
|
|
318
|
+
See: https://github.com/evilstreak/markdown-js/issues/27
|
|
319
|
+
|
|
320
|
+
``` bash
|
|
321
|
+
$ markdown.js
|
|
322
|
+
[](/link)
|
|
323
|
+
^D
|
|
324
|
+
<p><a href="/image)](/link">](/link)
|
|
330
|
+
^D
|
|
331
|
+
<p><a href="/link"><img src="/image" alt="an image"></a>
|
|
332
|
+
</p>
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
- - -
|
|
336
|
+
|
|
337
|
+
See: https://github.com/evilstreak/markdown-js/issues/24
|
|
338
|
+
|
|
339
|
+
``` bash
|
|
340
|
+
$ markdown.js
|
|
341
|
+
> a
|
|
342
|
+
|
|
343
|
+
> b
|
|
344
|
+
|
|
345
|
+
> c
|
|
346
|
+
^D
|
|
347
|
+
<blockquote><p>a</p><p>bundefined> c</p></blockquote>
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
``` bash
|
|
351
|
+
$ marked
|
|
352
|
+
> a
|
|
353
|
+
|
|
354
|
+
> b
|
|
355
|
+
|
|
356
|
+
> c
|
|
357
|
+
^D
|
|
358
|
+
<blockquote><p>a
|
|
359
|
+
|
|
360
|
+
</p></blockquote>
|
|
361
|
+
<blockquote><p>b
|
|
362
|
+
|
|
363
|
+
</p></blockquote>
|
|
364
|
+
<blockquote><p>c
|
|
365
|
+
</p></blockquote>
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
- - -
|
|
369
|
+
|
|
370
|
+
``` bash
|
|
371
|
+
$ markdown.pl
|
|
372
|
+
* hello
|
|
373
|
+
* world
|
|
374
|
+
how
|
|
375
|
+
|
|
376
|
+
are
|
|
377
|
+
you
|
|
378
|
+
|
|
379
|
+
* today
|
|
380
|
+
* hi
|
|
381
|
+
^D
|
|
382
|
+
<ul>
|
|
383
|
+
<li><p>hello</p>
|
|
384
|
+
|
|
385
|
+
<ul>
|
|
386
|
+
<li>world
|
|
387
|
+
how</li>
|
|
388
|
+
</ul>
|
|
389
|
+
|
|
390
|
+
<p>are
|
|
391
|
+
you</p>
|
|
392
|
+
|
|
393
|
+
<ul>
|
|
394
|
+
<li>today</li>
|
|
395
|
+
</ul></li>
|
|
396
|
+
<li>hi</li>
|
|
397
|
+
</ul>
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
``` bash
|
|
401
|
+
$ marked
|
|
402
|
+
* hello
|
|
403
|
+
* world
|
|
404
|
+
how
|
|
405
|
+
|
|
406
|
+
are
|
|
407
|
+
you
|
|
408
|
+
|
|
409
|
+
* today
|
|
410
|
+
* hi
|
|
411
|
+
^D
|
|
412
|
+
<ul>
|
|
413
|
+
<li><p>hello</p>
|
|
414
|
+
<ul>
|
|
415
|
+
<li><p>world
|
|
416
|
+
how</p>
|
|
417
|
+
<p>are
|
|
418
|
+
you</p>
|
|
419
|
+
</li>
|
|
420
|
+
<li><p>today</p>
|
|
421
|
+
</li>
|
|
422
|
+
</ul>
|
|
423
|
+
</li>
|
|
424
|
+
<li>hi</li>
|
|
425
|
+
</ul>
|
|
426
|
+
```
|
package/doc/todo.md
ADDED
package/lib/marked.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* marked - a markdown parser
|
|
3
|
-
* Copyright (c) 2011-
|
|
3
|
+
* Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
|
|
4
4
|
* https://github.com/chjj/marked
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -18,8 +18,8 @@ var block = {
|
|
|
18
18
|
heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
|
|
19
19
|
nptable: noop,
|
|
20
20
|
lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
|
|
21
|
-
blockquote: /^( *>[^\n]+(\n[^\n]+)*\n*)+/,
|
|
22
|
-
list: /^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
|
|
21
|
+
blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
|
|
22
|
+
list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
|
|
23
23
|
html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,
|
|
24
24
|
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
|
|
25
25
|
table: noop,
|
|
@@ -35,7 +35,12 @@ block.item = replace(block.item, 'gm')
|
|
|
35
35
|
|
|
36
36
|
block.list = replace(block.list)
|
|
37
37
|
(/bull/g, block.bullet)
|
|
38
|
-
('hr',
|
|
38
|
+
('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
|
|
39
|
+
('def', '\\n+(?=' + block.def.source + ')')
|
|
40
|
+
();
|
|
41
|
+
|
|
42
|
+
block.blockquote = replace(block.blockquote)
|
|
43
|
+
('def', block.def)
|
|
39
44
|
();
|
|
40
45
|
|
|
41
46
|
block._tag = '(?!(?:'
|
|
@@ -141,7 +146,7 @@ Lexer.prototype.lex = function(src) {
|
|
|
141
146
|
* Lexing
|
|
142
147
|
*/
|
|
143
148
|
|
|
144
|
-
Lexer.prototype.token = function(src, top) {
|
|
149
|
+
Lexer.prototype.token = function(src, top, bq) {
|
|
145
150
|
var src = src.replace(/^ +$/gm, '')
|
|
146
151
|
, next
|
|
147
152
|
, loose
|
|
@@ -264,7 +269,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
264
269
|
// Pass `top` to keep the current
|
|
265
270
|
// "toplevel" state. This is exactly
|
|
266
271
|
// how markdown.pl works.
|
|
267
|
-
this.token(cap, top);
|
|
272
|
+
this.token(cap, top, true);
|
|
268
273
|
|
|
269
274
|
this.tokens.push({
|
|
270
275
|
type: 'blockquote_end'
|
|
@@ -333,7 +338,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
333
338
|
});
|
|
334
339
|
|
|
335
340
|
// Recurse.
|
|
336
|
-
this.token(item, false);
|
|
341
|
+
this.token(item, false, bq);
|
|
337
342
|
|
|
338
343
|
this.tokens.push({
|
|
339
344
|
type: 'list_item_end'
|
|
@@ -361,7 +366,7 @@ Lexer.prototype.token = function(src, top) {
|
|
|
361
366
|
}
|
|
362
367
|
|
|
363
368
|
// def
|
|
364
|
-
if (top && (cap = this.rules.def.exec(src))) {
|
|
369
|
+
if ((!bq && top) && (cap = this.rules.def.exec(src))) {
|
|
365
370
|
src = src.substring(cap[0].length);
|
|
366
371
|
this.tokens.links[cap[1].toLowerCase()] = {
|
|
367
372
|
href: cap[2],
|
|
@@ -584,7 +589,7 @@ InlineLexer.prototype.output = function(src) {
|
|
|
584
589
|
}
|
|
585
590
|
|
|
586
591
|
// url (gfm)
|
|
587
|
-
if (cap = this.rules.url.exec(src)) {
|
|
592
|
+
if (!this.inLink && (cap = this.rules.url.exec(src))) {
|
|
588
593
|
src = src.substring(cap[0].length);
|
|
589
594
|
text = escape(cap[1]);
|
|
590
595
|
href = text;
|
|
@@ -594,6 +599,11 @@ InlineLexer.prototype.output = function(src) {
|
|
|
594
599
|
|
|
595
600
|
// tag
|
|
596
601
|
if (cap = this.rules.tag.exec(src)) {
|
|
602
|
+
if (!this.inLink && /^<a /i.test(cap[0])) {
|
|
603
|
+
this.inLink = true;
|
|
604
|
+
} else if (this.inLink && /^<\/a>/i.test(cap[0])) {
|
|
605
|
+
this.inLink = false;
|
|
606
|
+
}
|
|
597
607
|
src = src.substring(cap[0].length);
|
|
598
608
|
out += this.options.sanitize
|
|
599
609
|
? escape(cap[0])
|
|
@@ -604,10 +614,12 @@ InlineLexer.prototype.output = function(src) {
|
|
|
604
614
|
// link
|
|
605
615
|
if (cap = this.rules.link.exec(src)) {
|
|
606
616
|
src = src.substring(cap[0].length);
|
|
617
|
+
this.inLink = true;
|
|
607
618
|
out += this.outputLink(cap, {
|
|
608
619
|
href: cap[2],
|
|
609
620
|
title: cap[3]
|
|
610
621
|
});
|
|
622
|
+
this.inLink = false;
|
|
611
623
|
continue;
|
|
612
624
|
}
|
|
613
625
|
|
|
@@ -622,7 +634,9 @@ InlineLexer.prototype.output = function(src) {
|
|
|
622
634
|
src = cap[0].substring(1) + src;
|
|
623
635
|
continue;
|
|
624
636
|
}
|
|
637
|
+
this.inLink = true;
|
|
625
638
|
out += this.outputLink(cap, link);
|
|
639
|
+
this.inLink = false;
|
|
626
640
|
continue;
|
|
627
641
|
}
|
|
628
642
|
|
|
@@ -785,7 +799,7 @@ Renderer.prototype.heading = function(text, level, raw) {
|
|
|
785
799
|
};
|
|
786
800
|
|
|
787
801
|
Renderer.prototype.hr = function() {
|
|
788
|
-
return '<hr>\n';
|
|
802
|
+
return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
|
|
789
803
|
};
|
|
790
804
|
|
|
791
805
|
Renderer.prototype.list = function(body, ordered) {
|
|
@@ -838,7 +852,7 @@ Renderer.prototype.codespan = function(text) {
|
|
|
838
852
|
};
|
|
839
853
|
|
|
840
854
|
Renderer.prototype.br = function() {
|
|
841
|
-
return '<br>';
|
|
855
|
+
return this.options.xhtml ? '<br/>' : '<br>';
|
|
842
856
|
};
|
|
843
857
|
|
|
844
858
|
Renderer.prototype.del = function(text) {
|
|
@@ -871,7 +885,7 @@ Renderer.prototype.image = function(href, title, text) {
|
|
|
871
885
|
if (title) {
|
|
872
886
|
out += ' title="' + title + '"';
|
|
873
887
|
}
|
|
874
|
-
out += '>';
|
|
888
|
+
out += this.options.xhtml ? '/>' : '>';
|
|
875
889
|
return out;
|
|
876
890
|
};
|
|
877
891
|
|
|
@@ -1218,7 +1232,8 @@ marked.defaults = {
|
|
|
1218
1232
|
langPrefix: 'lang-',
|
|
1219
1233
|
smartypants: false,
|
|
1220
1234
|
headerPrefix: '',
|
|
1221
|
-
renderer: new Renderer
|
|
1235
|
+
renderer: new Renderer,
|
|
1236
|
+
xhtml: false
|
|
1222
1237
|
};
|
|
1223
1238
|
|
|
1224
1239
|
/**
|