Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
T
todomvc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Eugene Shen
todomvc
Commits
e659901d
Commit
e659901d
authored
Jan 02, 2012
by
Sindre Sorhus
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Switched from jQuery-tmpl to handlebars.js
Since jQuery-tmpl is depricated
parent
fb92c298
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
1570 additions
and
18 deletions
+1570
-18
todo-example/jquery/index.html
todo-example/jquery/index.html
+18
-15
todo-example/jquery/js/app.js
todo-example/jquery/js/app.js
+2
-3
todo-example/jquery/js/handlebars-1.0.0.beta.6.js
todo-example/jquery/js/handlebars-1.0.0.beta.6.js
+1550
-0
No files found.
todo-example/jquery/index.html
View file @
e659901d
<!doctype html>
<html>
<html
lang=
"en"
>
<head>
<meta
charset=
"utf-8"
>
<title>
jQuery
</title>
<link
rel=
"stylesheet"
href=
"css/app.css"
>
<script
src=
"js/json2.js"
></script>
<script
src=
"js/jquery.min.js"
></script>
<script
src=
"js/
jquery.tmpl
.js"
></script>
<script
src=
"js/
handlebars-1.0.0.beta.6
.js"
></script>
<script
src=
"js/app.js"
></script>
<script
type=
"text/x-jquery-tmpl"
id=
"todo-template"
>
<
li
class
=
"
item {{if done}}done{{/if}}
"
data
-
id
=
"
${id}
"
>
<
div
class
=
"
view
"
title
=
"
Double click to edit...
"
>
<
input
type
=
"
checkbox
"
{{
if
done
}}
checked
=
"
checked
"
{{
/if}}>
<
span
>
$
{
title
}
<
/span
>
<
a
class
=
"
destroy
"
><
/a
>
<
/div
>
<
div
class
=
"
edit
"
>
<
input
type
=
"
text
"
value
=
"
${title}
"
>
<
/div
>
<
/li
>
</script>
</head>
<body>
<div
id=
"todoapp"
>
...
...
@@ -32,11 +21,25 @@
<div
class=
"count"
></div>
</footer>
</div>
<div
id=
'instructions'
>
<div
id=
"instructions"
>
Double-click to edit a todo.
</div>
<div
id=
"credits"
>
Created by
<a
href=
"http://sindresorhus.com"
>
Sindre Sorhus
</a>
.
</div>
<script
type=
"text/x-handlebars-template"
id=
"todo-template"
>
{{
#
this
}}
<
li
class
=
"
item {{#if done}}done{{/if}}
"
data
-
id
=
"
{{id}}
"
>
<
div
class
=
"
view
"
title
=
"
Double click to edit...
"
>
<
input
type
=
"
checkbox
"
{{
#
if
done
}}
checked
=
"
checked
"
{{
/if}}
>
<
span
>
{{
title
}}
<
/span
>
<
a
class
=
"
destroy
"
><
/a
>
<
/div
>
<
div
class
=
"
edit
"
>
<
input
type
=
"
text
"
value
=
"
{{title}}
"
>
<
/div
>
<
/li
>
{{
/
this
}}
</script>
</body>
</html>
\ No newline at end of file
todo-example/jquery/js/app.js
View file @
e659901d
...
...
@@ -33,7 +33,7 @@ jQuery(function($) {
this
.
render
();
},
cacheElements
:
function
()
{
this
.
$template
=
$
(
'
#todo-template
'
);
this
.
template
=
Handlebars
.
compile
(
$
(
'
#todo-template
'
).
html
()
);
this
.
$todoApp
=
$
(
'
#todoapp
'
);
this
.
$todoList
=
this
.
$todoApp
.
find
(
'
.items
'
);
this
.
$footer
=
this
.
$todoApp
.
find
(
'
footer
'
);
...
...
@@ -60,8 +60,7 @@ jQuery(function($) {
list
.
on
(
'
click
'
,
'
.destroy
'
,
this
.
destroy
);
},
render
:
function
()
{
var
html
=
this
.
$template
.
tmpl
(
this
.
todos
);
this
.
$todoList
.
html
(
html
);
this
.
$todoList
.
html
(
this
.
template
(
this
.
todos
)
);
this
.
renderFooter
();
this
.
store
(
this
.
todos
);
},
...
...
todo-example/jquery/js/handlebars-1.0.0.beta.6.js
0 → 100644
View file @
e659901d
// lib/handlebars/base.js
var
Handlebars
=
{};
Handlebars
.
VERSION
=
"
1.0.beta.6
"
;
Handlebars
.
helpers
=
{};
Handlebars
.
partials
=
{};
Handlebars
.
registerHelper
=
function
(
name
,
fn
,
inverse
)
{
if
(
inverse
)
{
fn
.
not
=
inverse
;
}
this
.
helpers
[
name
]
=
fn
;
};
Handlebars
.
registerPartial
=
function
(
name
,
str
)
{
this
.
partials
[
name
]
=
str
;
};
Handlebars
.
registerHelper
(
'
helperMissing
'
,
function
(
arg
)
{
if
(
arguments
.
length
===
2
)
{
return
undefined
;
}
else
{
throw
new
Error
(
"
Could not find property '
"
+
arg
+
"
'
"
);
}
});
var
toString
=
Object
.
prototype
.
toString
,
functionType
=
"
[object Function]
"
;
Handlebars
.
registerHelper
(
'
blockHelperMissing
'
,
function
(
context
,
options
)
{
var
inverse
=
options
.
inverse
||
function
()
{},
fn
=
options
.
fn
;
var
ret
=
""
;
var
type
=
toString
.
call
(
context
);
if
(
type
===
functionType
)
{
context
=
context
.
call
(
this
);
}
if
(
context
===
true
)
{
return
fn
(
this
);
}
else
if
(
context
===
false
||
context
==
null
)
{
return
inverse
(
this
);
}
else
if
(
type
===
"
[object Array]
"
)
{
if
(
context
.
length
>
0
)
{
for
(
var
i
=
0
,
j
=
context
.
length
;
i
<
j
;
i
++
)
{
ret
=
ret
+
fn
(
context
[
i
]);
}
}
else
{
ret
=
inverse
(
this
);
}
return
ret
;
}
else
{
return
fn
(
context
);
}
});
Handlebars
.
registerHelper
(
'
each
'
,
function
(
context
,
options
)
{
var
fn
=
options
.
fn
,
inverse
=
options
.
inverse
;
var
ret
=
""
;
if
(
context
&&
context
.
length
>
0
)
{
for
(
var
i
=
0
,
j
=
context
.
length
;
i
<
j
;
i
++
)
{
ret
=
ret
+
fn
(
context
[
i
]);
}
}
else
{
ret
=
inverse
(
this
);
}
return
ret
;
});
Handlebars
.
registerHelper
(
'
if
'
,
function
(
context
,
options
)
{
var
type
=
toString
.
call
(
context
);
if
(
type
===
functionType
)
{
context
=
context
.
call
(
this
);
}
if
(
!
context
||
Handlebars
.
Utils
.
isEmpty
(
context
))
{
return
options
.
inverse
(
this
);
}
else
{
return
options
.
fn
(
this
);
}
});
Handlebars
.
registerHelper
(
'
unless
'
,
function
(
context
,
options
)
{
var
fn
=
options
.
fn
,
inverse
=
options
.
inverse
;
options
.
fn
=
inverse
;
options
.
inverse
=
fn
;
return
Handlebars
.
helpers
[
'
if
'
].
call
(
this
,
context
,
options
);
});
Handlebars
.
registerHelper
(
'
with
'
,
function
(
context
,
options
)
{
return
options
.
fn
(
context
);
});
Handlebars
.
registerHelper
(
'
log
'
,
function
(
context
)
{
Handlebars
.
log
(
context
);
});
;
// lib/handlebars/compiler/parser.js
/* Jison generated parser */
var
handlebars
=
(
function
(){
var
parser
=
{
trace
:
function
trace
()
{
},
yy
:
{},
symbols_
:
{
"
error
"
:
2
,
"
root
"
:
3
,
"
program
"
:
4
,
"
EOF
"
:
5
,
"
statements
"
:
6
,
"
simpleInverse
"
:
7
,
"
statement
"
:
8
,
"
openInverse
"
:
9
,
"
closeBlock
"
:
10
,
"
openBlock
"
:
11
,
"
mustache
"
:
12
,
"
partial
"
:
13
,
"
CONTENT
"
:
14
,
"
COMMENT
"
:
15
,
"
OPEN_BLOCK
"
:
16
,
"
inMustache
"
:
17
,
"
CLOSE
"
:
18
,
"
OPEN_INVERSE
"
:
19
,
"
OPEN_ENDBLOCK
"
:
20
,
"
path
"
:
21
,
"
OPEN
"
:
22
,
"
OPEN_UNESCAPED
"
:
23
,
"
OPEN_PARTIAL
"
:
24
,
"
params
"
:
25
,
"
hash
"
:
26
,
"
param
"
:
27
,
"
STRING
"
:
28
,
"
INTEGER
"
:
29
,
"
BOOLEAN
"
:
30
,
"
hashSegments
"
:
31
,
"
hashSegment
"
:
32
,
"
ID
"
:
33
,
"
EQUALS
"
:
34
,
"
pathSegments
"
:
35
,
"
SEP
"
:
36
,
"
$accept
"
:
0
,
"
$end
"
:
1
},
terminals_
:
{
2
:
"
error
"
,
5
:
"
EOF
"
,
14
:
"
CONTENT
"
,
15
:
"
COMMENT
"
,
16
:
"
OPEN_BLOCK
"
,
18
:
"
CLOSE
"
,
19
:
"
OPEN_INVERSE
"
,
20
:
"
OPEN_ENDBLOCK
"
,
22
:
"
OPEN
"
,
23
:
"
OPEN_UNESCAPED
"
,
24
:
"
OPEN_PARTIAL
"
,
28
:
"
STRING
"
,
29
:
"
INTEGER
"
,
30
:
"
BOOLEAN
"
,
33
:
"
ID
"
,
34
:
"
EQUALS
"
,
36
:
"
SEP
"
},
productions_
:
[
0
,[
3
,
2
],[
4
,
3
],[
4
,
1
],[
4
,
0
],[
6
,
1
],[
6
,
2
],[
8
,
3
],[
8
,
3
],[
8
,
1
],[
8
,
1
],[
8
,
1
],[
8
,
1
],[
11
,
3
],[
9
,
3
],[
10
,
3
],[
12
,
3
],[
12
,
3
],[
13
,
3
],[
13
,
4
],[
7
,
2
],[
17
,
3
],[
17
,
2
],[
17
,
2
],[
17
,
1
],[
25
,
2
],[
25
,
1
],[
27
,
1
],[
27
,
1
],[
27
,
1
],[
27
,
1
],[
26
,
1
],[
31
,
2
],[
31
,
1
],[
32
,
3
],[
32
,
3
],[
32
,
3
],[
32
,
3
],[
21
,
1
],[
35
,
3
],[
35
,
1
]],
performAction
:
function
anonymous
(
yytext
,
yyleng
,
yylineno
,
yy
,
yystate
,
$$
,
_$
)
{
var
$0
=
$$
.
length
-
1
;
switch
(
yystate
)
{
case
1
:
return
$$
[
$0
-
1
]
break
;
case
2
:
this
.
$
=
new
yy
.
ProgramNode
(
$$
[
$0
-
2
],
$$
[
$0
])
break
;
case
3
:
this
.
$
=
new
yy
.
ProgramNode
(
$$
[
$0
])
break
;
case
4
:
this
.
$
=
new
yy
.
ProgramNode
([])
break
;
case
5
:
this
.
$
=
[
$$
[
$0
]]
break
;
case
6
:
$$
[
$0
-
1
].
push
(
$$
[
$0
]);
this
.
$
=
$$
[
$0
-
1
]
break
;
case
7
:
this
.
$
=
new
yy
.
InverseNode
(
$$
[
$0
-
2
],
$$
[
$0
-
1
],
$$
[
$0
])
break
;
case
8
:
this
.
$
=
new
yy
.
BlockNode
(
$$
[
$0
-
2
],
$$
[
$0
-
1
],
$$
[
$0
])
break
;
case
9
:
this
.
$
=
$$
[
$0
]
break
;
case
10
:
this
.
$
=
$$
[
$0
]
break
;
case
11
:
this
.
$
=
new
yy
.
ContentNode
(
$$
[
$0
])
break
;
case
12
:
this
.
$
=
new
yy
.
CommentNode
(
$$
[
$0
])
break
;
case
13
:
this
.
$
=
new
yy
.
MustacheNode
(
$$
[
$0
-
1
][
0
],
$$
[
$0
-
1
][
1
])
break
;
case
14
:
this
.
$
=
new
yy
.
MustacheNode
(
$$
[
$0
-
1
][
0
],
$$
[
$0
-
1
][
1
])
break
;
case
15
:
this
.
$
=
$$
[
$0
-
1
]
break
;
case
16
:
this
.
$
=
new
yy
.
MustacheNode
(
$$
[
$0
-
1
][
0
],
$$
[
$0
-
1
][
1
])
break
;
case
17
:
this
.
$
=
new
yy
.
MustacheNode
(
$$
[
$0
-
1
][
0
],
$$
[
$0
-
1
][
1
],
true
)
break
;
case
18
:
this
.
$
=
new
yy
.
PartialNode
(
$$
[
$0
-
1
])
break
;
case
19
:
this
.
$
=
new
yy
.
PartialNode
(
$$
[
$0
-
2
],
$$
[
$0
-
1
])
break
;
case
20
:
break
;
case
21
:
this
.
$
=
[[
$$
[
$0
-
2
]].
concat
(
$$
[
$0
-
1
]),
$$
[
$0
]]
break
;
case
22
:
this
.
$
=
[[
$$
[
$0
-
1
]].
concat
(
$$
[
$0
]),
null
]
break
;
case
23
:
this
.
$
=
[[
$$
[
$0
-
1
]],
$$
[
$0
]]
break
;
case
24
:
this
.
$
=
[[
$$
[
$0
]],
null
]
break
;
case
25
:
$$
[
$0
-
1
].
push
(
$$
[
$0
]);
this
.
$
=
$$
[
$0
-
1
];
break
;
case
26
:
this
.
$
=
[
$$
[
$0
]]
break
;
case
27
:
this
.
$
=
$$
[
$0
]
break
;
case
28
:
this
.
$
=
new
yy
.
StringNode
(
$$
[
$0
])
break
;
case
29
:
this
.
$
=
new
yy
.
IntegerNode
(
$$
[
$0
])
break
;
case
30
:
this
.
$
=
new
yy
.
BooleanNode
(
$$
[
$0
])
break
;
case
31
:
this
.
$
=
new
yy
.
HashNode
(
$$
[
$0
])
break
;
case
32
:
$$
[
$0
-
1
].
push
(
$$
[
$0
]);
this
.
$
=
$$
[
$0
-
1
]
break
;
case
33
:
this
.
$
=
[
$$
[
$0
]]
break
;
case
34
:
this
.
$
=
[
$$
[
$0
-
2
],
$$
[
$0
]]
break
;
case
35
:
this
.
$
=
[
$$
[
$0
-
2
],
new
yy
.
StringNode
(
$$
[
$0
])]
break
;
case
36
:
this
.
$
=
[
$$
[
$0
-
2
],
new
yy
.
IntegerNode
(
$$
[
$0
])]
break
;
case
37
:
this
.
$
=
[
$$
[
$0
-
2
],
new
yy
.
BooleanNode
(
$$
[
$0
])]
break
;
case
38
:
this
.
$
=
new
yy
.
IdNode
(
$$
[
$0
])
break
;
case
39
:
$$
[
$0
-
2
].
push
(
$$
[
$0
]);
this
.
$
=
$$
[
$0
-
2
];
break
;
case
40
:
this
.
$
=
[
$$
[
$0
]]
break
;
}
},
table
:
[{
3
:
1
,
4
:
2
,
5
:[
2
,
4
],
6
:
3
,
8
:
4
,
9
:
5
,
11
:
6
,
12
:
7
,
13
:
8
,
14
:[
1
,
9
],
15
:[
1
,
10
],
16
:[
1
,
12
],
19
:[
1
,
11
],
22
:[
1
,
13
],
23
:[
1
,
14
],
24
:[
1
,
15
]},{
1
:[
3
]},{
5
:[
1
,
16
]},{
5
:[
2
,
3
],
7
:
17
,
8
:
18
,
9
:
5
,
11
:
6
,
12
:
7
,
13
:
8
,
14
:[
1
,
9
],
15
:[
1
,
10
],
16
:[
1
,
12
],
19
:[
1
,
19
],
20
:[
2
,
3
],
22
:[
1
,
13
],
23
:[
1
,
14
],
24
:[
1
,
15
]},{
5
:[
2
,
5
],
14
:[
2
,
5
],
15
:[
2
,
5
],
16
:[
2
,
5
],
19
:[
2
,
5
],
20
:[
2
,
5
],
22
:[
2
,
5
],
23
:[
2
,
5
],
24
:[
2
,
5
]},{
4
:
20
,
6
:
3
,
8
:
4
,
9
:
5
,
11
:
6
,
12
:
7
,
13
:
8
,
14
:[
1
,
9
],
15
:[
1
,
10
],
16
:[
1
,
12
],
19
:[
1
,
11
],
20
:[
2
,
4
],
22
:[
1
,
13
],
23
:[
1
,
14
],
24
:[
1
,
15
]},{
4
:
21
,
6
:
3
,
8
:
4
,
9
:
5
,
11
:
6
,
12
:
7
,
13
:
8
,
14
:[
1
,
9
],
15
:[
1
,
10
],
16
:[
1
,
12
],
19
:[
1
,
11
],
20
:[
2
,
4
],
22
:[
1
,
13
],
23
:[
1
,
14
],
24
:[
1
,
15
]},{
5
:[
2
,
9
],
14
:[
2
,
9
],
15
:[
2
,
9
],
16
:[
2
,
9
],
19
:[
2
,
9
],
20
:[
2
,
9
],
22
:[
2
,
9
],
23
:[
2
,
9
],
24
:[
2
,
9
]},{
5
:[
2
,
10
],
14
:[
2
,
10
],
15
:[
2
,
10
],
16
:[
2
,
10
],
19
:[
2
,
10
],
20
:[
2
,
10
],
22
:[
2
,
10
],
23
:[
2
,
10
],
24
:[
2
,
10
]},{
5
:[
2
,
11
],
14
:[
2
,
11
],
15
:[
2
,
11
],
16
:[
2
,
11
],
19
:[
2
,
11
],
20
:[
2
,
11
],
22
:[
2
,
11
],
23
:[
2
,
11
],
24
:[
2
,
11
]},{
5
:[
2
,
12
],
14
:[
2
,
12
],
15
:[
2
,
12
],
16
:[
2
,
12
],
19
:[
2
,
12
],
20
:[
2
,
12
],
22
:[
2
,
12
],
23
:[
2
,
12
],
24
:[
2
,
12
]},{
17
:
22
,
21
:
23
,
33
:[
1
,
25
],
35
:
24
},{
17
:
26
,
21
:
23
,
33
:[
1
,
25
],
35
:
24
},{
17
:
27
,
21
:
23
,
33
:[
1
,
25
],
35
:
24
},{
17
:
28
,
21
:
23
,
33
:[
1
,
25
],
35
:
24
},{
21
:
29
,
33
:[
1
,
25
],
35
:
24
},{
1
:[
2
,
1
]},{
6
:
30
,
8
:
4
,
9
:
5
,
11
:
6
,
12
:
7
,
13
:
8
,
14
:[
1
,
9
],
15
:[
1
,
10
],
16
:[
1
,
12
],
19
:[
1
,
11
],
22
:[
1
,
13
],
23
:[
1
,
14
],
24
:[
1
,
15
]},{
5
:[
2
,
6
],
14
:[
2
,
6
],
15
:[
2
,
6
],
16
:[
2
,
6
],
19
:[
2
,
6
],
20
:[
2
,
6
],
22
:[
2
,
6
],
23
:[
2
,
6
],
24
:[
2
,
6
]},{
17
:
22
,
18
:[
1
,
31
],
21
:
23
,
33
:[
1
,
25
],
35
:
24
},{
10
:
32
,
20
:[
1
,
33
]},{
10
:
34
,
20
:[
1
,
33
]},{
18
:[
1
,
35
]},{
18
:[
2
,
24
],
21
:
40
,
25
:
36
,
26
:
37
,
27
:
38
,
28
:[
1
,
41
],
29
:[
1
,
42
],
30
:[
1
,
43
],
31
:
39
,
32
:
44
,
33
:[
1
,
45
],
35
:
24
},{
18
:[
2
,
38
],
28
:[
2
,
38
],
29
:[
2
,
38
],
30
:[
2
,
38
],
33
:[
2
,
38
],
36
:[
1
,
46
]},{
18
:[
2
,
40
],
28
:[
2
,
40
],
29
:[
2
,
40
],
30
:[
2
,
40
],
33
:[
2
,
40
],
36
:[
2
,
40
]},{
18
:[
1
,
47
]},{
18
:[
1
,
48
]},{
18
:[
1
,
49
]},{
18
:[
1
,
50
],
21
:
51
,
33
:[
1
,
25
],
35
:
24
},{
5
:[
2
,
2
],
8
:
18
,
9
:
5
,
11
:
6
,
12
:
7
,
13
:
8
,
14
:[
1
,
9
],
15
:[
1
,
10
],
16
:[
1
,
12
],
19
:[
1
,
11
],
20
:[
2
,
2
],
22
:[
1
,
13
],
23
:[
1
,
14
],
24
:[
1
,
15
]},{
14
:[
2
,
20
],
15
:[
2
,
20
],
16
:[
2
,
20
],
19
:[
2
,
20
],
22
:[
2
,
20
],
23
:[
2
,
20
],
24
:[
2
,
20
]},{
5
:[
2
,
7
],
14
:[
2
,
7
],
15
:[
2
,
7
],
16
:[
2
,
7
],
19
:[
2
,
7
],
20
:[
2
,
7
],
22
:[
2
,
7
],
23
:[
2
,
7
],
24
:[
2
,
7
]},{
21
:
52
,
33
:[
1
,
25
],
35
:
24
},{
5
:[
2
,
8
],
14
:[
2
,
8
],
15
:[
2
,
8
],
16
:[
2
,
8
],
19
:[
2
,
8
],
20
:[
2
,
8
],
22
:[
2
,
8
],
23
:[
2
,
8
],
24
:[
2
,
8
]},{
14
:[
2
,
14
],
15
:[
2
,
14
],
16
:[
2
,
14
],
19
:[
2
,
14
],
20
:[
2
,
14
],
22
:[
2
,
14
],
23
:[
2
,
14
],
24
:[
2
,
14
]},{
18
:[
2
,
22
],
21
:
40
,
26
:
53
,
27
:
54
,
28
:[
1
,
41
],
29
:[
1
,
42
],
30
:[
1
,
43
],
31
:
39
,
32
:
44
,
33
:[
1
,
45
],
35
:
24
},{
18
:[
2
,
23
]},{
18
:[
2
,
26
],
28
:[
2
,
26
],
29
:[
2
,
26
],
30
:[
2
,
26
],
33
:[
2
,
26
]},{
18
:[
2
,
31
],
32
:
55
,
33
:[
1
,
56
]},{
18
:[
2
,
27
],
28
:[
2
,
27
],
29
:[
2
,
27
],
30
:[
2
,
27
],
33
:[
2
,
27
]},{
18
:[
2
,
28
],
28
:[
2
,
28
],
29
:[
2
,
28
],
30
:[
2
,
28
],
33
:[
2
,
28
]},{
18
:[
2
,
29
],
28
:[
2
,
29
],
29
:[
2
,
29
],
30
:[
2
,
29
],
33
:[
2
,
29
]},{
18
:[
2
,
30
],
28
:[
2
,
30
],
29
:[
2
,
30
],
30
:[
2
,
30
],
33
:[
2
,
30
]},{
18
:[
2
,
33
],
33
:[
2
,
33
]},{
18
:[
2
,
40
],
28
:[
2
,
40
],
29
:[
2
,
40
],
30
:[
2
,
40
],
33
:[
2
,
40
],
34
:[
1
,
57
],
36
:[
2
,
40
]},{
33
:[
1
,
58
]},{
14
:[
2
,
13
],
15
:[
2
,
13
],
16
:[
2
,
13
],
19
:[
2
,
13
],
20
:[
2
,
13
],
22
:[
2
,
13
],
23
:[
2
,
13
],
24
:[
2
,
13
]},{
5
:[
2
,
16
],
14
:[
2
,
16
],
15
:[
2
,
16
],
16
:[
2
,
16
],
19
:[
2
,
16
],
20
:[
2
,
16
],
22
:[
2
,
16
],
23
:[
2
,
16
],
24
:[
2
,
16
]},{
5
:[
2
,
17
],
14
:[
2
,
17
],
15
:[
2
,
17
],
16
:[
2
,
17
],
19
:[
2
,
17
],
20
:[
2
,
17
],
22
:[
2
,
17
],
23
:[
2
,
17
],
24
:[
2
,
17
]},{
5
:[
2
,
18
],
14
:[
2
,
18
],
15
:[
2
,
18
],
16
:[
2
,
18
],
19
:[
2
,
18
],
20
:[
2
,
18
],
22
:[
2
,
18
],
23
:[
2
,
18
],
24
:[
2
,
18
]},{
18
:[
1
,
59
]},{
18
:[
1
,
60
]},{
18
:[
2
,
21
]},{
18
:[
2
,
25
],
28
:[
2
,
25
],
29
:[
2
,
25
],
30
:[
2
,
25
],
33
:[
2
,
25
]},{
18
:[
2
,
32
],
33
:[
2
,
32
]},{
34
:[
1
,
57
]},{
21
:
61
,
28
:[
1
,
62
],
29
:[
1
,
63
],
30
:[
1
,
64
],
33
:[
1
,
25
],
35
:
24
},{
18
:[
2
,
39
],
28
:[
2
,
39
],
29
:[
2
,
39
],
30
:[
2
,
39
],
33
:[
2
,
39
],
36
:[
2
,
39
]},{
5
:[
2
,
19
],
14
:[
2
,
19
],
15
:[
2
,
19
],
16
:[
2
,
19
],
19
:[
2
,
19
],
20
:[
2
,
19
],
22
:[
2
,
19
],
23
:[
2
,
19
],
24
:[
2
,
19
]},{
5
:[
2
,
15
],
14
:[
2
,
15
],
15
:[
2
,
15
],
16
:[
2
,
15
],
19
:[
2
,
15
],
20
:[
2
,
15
],
22
:[
2
,
15
],
23
:[
2
,
15
],
24
:[
2
,
15
]},{
18
:[
2
,
34
],
33
:[
2
,
34
]},{
18
:[
2
,
35
],
33
:[
2
,
35
]},{
18
:[
2
,
36
],
33
:[
2
,
36
]},{
18
:[
2
,
37
],
33
:[
2
,
37
]}],
defaultActions
:
{
16
:[
2
,
1
],
37
:[
2
,
23
],
53
:[
2
,
21
]},
parseError
:
function
parseError
(
str
,
hash
)
{
throw
new
Error
(
str
);
},
parse
:
function
parse
(
input
)
{
var
self
=
this
,
stack
=
[
0
],
vstack
=
[
null
],
lstack
=
[],
table
=
this
.
table
,
yytext
=
""
,
yylineno
=
0
,
yyleng
=
0
,
recovering
=
0
,
TERROR
=
2
,
EOF
=
1
;
this
.
lexer
.
setInput
(
input
);
this
.
lexer
.
yy
=
this
.
yy
;
this
.
yy
.
lexer
=
this
.
lexer
;
if
(
typeof
this
.
lexer
.
yylloc
==
"
undefined
"
)
this
.
lexer
.
yylloc
=
{};
var
yyloc
=
this
.
lexer
.
yylloc
;
lstack
.
push
(
yyloc
);
if
(
typeof
this
.
yy
.
parseError
===
"
function
"
)
this
.
parseError
=
this
.
yy
.
parseError
;
function
popStack
(
n
)
{
stack
.
length
=
stack
.
length
-
2
*
n
;
vstack
.
length
=
vstack
.
length
-
n
;
lstack
.
length
=
lstack
.
length
-
n
;
}
function
lex
()
{
var
token
;
token
=
self
.
lexer
.
lex
()
||
1
;
if
(
typeof
token
!==
"
number
"
)
{
token
=
self
.
symbols_
[
token
]
||
token
;
}
return
token
;
}
var
symbol
,
preErrorSymbol
,
state
,
action
,
a
,
r
,
yyval
=
{},
p
,
len
,
newState
,
expected
;
while
(
true
)
{
state
=
stack
[
stack
.
length
-
1
];
if
(
this
.
defaultActions
[
state
])
{
action
=
this
.
defaultActions
[
state
];
}
else
{
if
(
symbol
==
null
)
symbol
=
lex
();
action
=
table
[
state
]
&&
table
[
state
][
symbol
];
}
if
(
typeof
action
===
"
undefined
"
||
!
action
.
length
||
!
action
[
0
])
{
if
(
!
recovering
)
{
expected
=
[];
for
(
p
in
table
[
state
])
if
(
this
.
terminals_
[
p
]
&&
p
>
2
)
{
expected
.
push
(
"
'
"
+
this
.
terminals_
[
p
]
+
"
'
"
);
}
var
errStr
=
""
;
if
(
this
.
lexer
.
showPosition
)
{
errStr
=
"
Parse error on line
"
+
(
yylineno
+
1
)
+
"
:
\n
"
+
this
.
lexer
.
showPosition
()
+
"
\n
Expecting
"
+
expected
.
join
(
"
,
"
)
+
"
, got '
"
+
this
.
terminals_
[
symbol
]
+
"
'
"
;
}
else
{
errStr
=
"
Parse error on line
"
+
(
yylineno
+
1
)
+
"
: Unexpected
"
+
(
symbol
==
1
?
"
end of input
"
:
"
'
"
+
(
this
.
terminals_
[
symbol
]
||
symbol
)
+
"
'
"
);
}
this
.
parseError
(
errStr
,
{
text
:
this
.
lexer
.
match
,
token
:
this
.
terminals_
[
symbol
]
||
symbol
,
line
:
this
.
lexer
.
yylineno
,
loc
:
yyloc
,
expected
:
expected
});
}
}
if
(
action
[
0
]
instanceof
Array
&&
action
.
length
>
1
)
{
throw
new
Error
(
"
Parse Error: multiple actions possible at state:
"
+
state
+
"
, token:
"
+
symbol
);
}
switch
(
action
[
0
])
{
case
1
:
stack
.
push
(
symbol
);
vstack
.
push
(
this
.
lexer
.
yytext
);
lstack
.
push
(
this
.
lexer
.
yylloc
);
stack
.
push
(
action
[
1
]);
symbol
=
null
;
if
(
!
preErrorSymbol
)
{
yyleng
=
this
.
lexer
.
yyleng
;
yytext
=
this
.
lexer
.
yytext
;
yylineno
=
this
.
lexer
.
yylineno
;
yyloc
=
this
.
lexer
.
yylloc
;
if
(
recovering
>
0
)
recovering
--
;
}
else
{
symbol
=
preErrorSymbol
;
preErrorSymbol
=
null
;
}
break
;
case
2
:
len
=
this
.
productions_
[
action
[
1
]][
1
];
yyval
.
$
=
vstack
[
vstack
.
length
-
len
];
yyval
.
_$
=
{
first_line
:
lstack
[
lstack
.
length
-
(
len
||
1
)].
first_line
,
last_line
:
lstack
[
lstack
.
length
-
1
].
last_line
,
first_column
:
lstack
[
lstack
.
length
-
(
len
||
1
)].
first_column
,
last_column
:
lstack
[
lstack
.
length
-
1
].
last_column
};
r
=
this
.
performAction
.
call
(
yyval
,
yytext
,
yyleng
,
yylineno
,
this
.
yy
,
action
[
1
],
vstack
,
lstack
);
if
(
typeof
r
!==
"
undefined
"
)
{
return
r
;
}
if
(
len
)
{
stack
=
stack
.
slice
(
0
,
-
1
*
len
*
2
);
vstack
=
vstack
.
slice
(
0
,
-
1
*
len
);
lstack
=
lstack
.
slice
(
0
,
-
1
*
len
);
}
stack
.
push
(
this
.
productions_
[
action
[
1
]][
0
]);
vstack
.
push
(
yyval
.
$
);
lstack
.
push
(
yyval
.
_$
);
newState
=
table
[
stack
[
stack
.
length
-
2
]][
stack
[
stack
.
length
-
1
]];
stack
.
push
(
newState
);
break
;
case
3
:
return
true
;
}
}
return
true
;
}
};
/* Jison generated lexer */
var
lexer
=
(
function
(){
var
lexer
=
({
EOF
:
1
,
parseError
:
function
parseError
(
str
,
hash
)
{
if
(
this
.
yy
.
parseError
)
{
this
.
yy
.
parseError
(
str
,
hash
);
}
else
{
throw
new
Error
(
str
);
}
},
setInput
:
function
(
input
)
{
this
.
_input
=
input
;
this
.
_more
=
this
.
_less
=
this
.
done
=
false
;
this
.
yylineno
=
this
.
yyleng
=
0
;
this
.
yytext
=
this
.
matched
=
this
.
match
=
''
;
this
.
conditionStack
=
[
'
INITIAL
'
];
this
.
yylloc
=
{
first_line
:
1
,
first_column
:
0
,
last_line
:
1
,
last_column
:
0
};
return
this
;
},
input
:
function
()
{
var
ch
=
this
.
_input
[
0
];
this
.
yytext
+=
ch
;
this
.
yyleng
++
;
this
.
match
+=
ch
;
this
.
matched
+=
ch
;
var
lines
=
ch
.
match
(
/
\n
/
);
if
(
lines
)
this
.
yylineno
++
;
this
.
_input
=
this
.
_input
.
slice
(
1
);
return
ch
;
},
unput
:
function
(
ch
)
{
this
.
_input
=
ch
+
this
.
_input
;
return
this
;
},
more
:
function
()
{
this
.
_more
=
true
;
return
this
;
},
pastInput
:
function
()
{
var
past
=
this
.
matched
.
substr
(
0
,
this
.
matched
.
length
-
this
.
match
.
length
);
return
(
past
.
length
>
20
?
'
...
'
:
''
)
+
past
.
substr
(
-
20
).
replace
(
/
\n
/g
,
""
);
},
upcomingInput
:
function
()
{
var
next
=
this
.
match
;
if
(
next
.
length
<
20
)
{
next
+=
this
.
_input
.
substr
(
0
,
20
-
next
.
length
);
}
return
(
next
.
substr
(
0
,
20
)
+
(
next
.
length
>
20
?
'
...
'
:
''
)).
replace
(
/
\n
/g
,
""
);
},
showPosition
:
function
()
{
var
pre
=
this
.
pastInput
();
var
c
=
new
Array
(
pre
.
length
+
1
).
join
(
"
-
"
);
return
pre
+
this
.
upcomingInput
()
+
"
\n
"
+
c
+
"
^
"
;
},
next
:
function
()
{
if
(
this
.
done
)
{
return
this
.
EOF
;
}
if
(
!
this
.
_input
)
this
.
done
=
true
;
var
token
,
match
,
col
,
lines
;
if
(
!
this
.
_more
)
{
this
.
yytext
=
''
;
this
.
match
=
''
;
}
var
rules
=
this
.
_currentRules
();
for
(
var
i
=
0
;
i
<
rules
.
length
;
i
++
)
{
match
=
this
.
_input
.
match
(
this
.
rules
[
rules
[
i
]]);
if
(
match
)
{
lines
=
match
[
0
].
match
(
/
\n
.*/g
);
if
(
lines
)
this
.
yylineno
+=
lines
.
length
;
this
.
yylloc
=
{
first_line
:
this
.
yylloc
.
last_line
,
last_line
:
this
.
yylineno
+
1
,
first_column
:
this
.
yylloc
.
last_column
,
last_column
:
lines
?
lines
[
lines
.
length
-
1
].
length
-
1
:
this
.
yylloc
.
last_column
+
match
[
0
].
length
}
this
.
yytext
+=
match
[
0
];
this
.
match
+=
match
[
0
];
this
.
matches
=
match
;
this
.
yyleng
=
this
.
yytext
.
length
;
this
.
_more
=
false
;
this
.
_input
=
this
.
_input
.
slice
(
match
[
0
].
length
);
this
.
matched
+=
match
[
0
];
token
=
this
.
performAction
.
call
(
this
,
this
.
yy
,
this
,
rules
[
i
],
this
.
conditionStack
[
this
.
conditionStack
.
length
-
1
]);
if
(
token
)
return
token
;
else
return
;
}
}
if
(
this
.
_input
===
""
)
{
return
this
.
EOF
;
}
else
{
this
.
parseError
(
'
Lexical error on line
'
+
(
this
.
yylineno
+
1
)
+
'
. Unrecognized text.
\n
'
+
this
.
showPosition
(),
{
text
:
""
,
token
:
null
,
line
:
this
.
yylineno
});
}
},
lex
:
function
lex
()
{
var
r
=
this
.
next
();
if
(
typeof
r
!==
'
undefined
'
)
{
return
r
;
}
else
{
return
this
.
lex
();
}
},
begin
:
function
begin
(
condition
)
{
this
.
conditionStack
.
push
(
condition
);
},
popState
:
function
popState
()
{
return
this
.
conditionStack
.
pop
();
},
_currentRules
:
function
_currentRules
()
{
return
this
.
conditions
[
this
.
conditionStack
[
this
.
conditionStack
.
length
-
1
]].
rules
;
},
topState
:
function
()
{
return
this
.
conditionStack
[
this
.
conditionStack
.
length
-
2
];
},
pushState
:
function
begin
(
condition
)
{
this
.
begin
(
condition
);
}});
lexer
.
performAction
=
function
anonymous
(
yy
,
yy_
,
$avoiding_name_collisions
,
YY_START
)
{
var
YYSTATE
=
YY_START
switch
(
$avoiding_name_collisions
)
{
case
0
:
if
(
yy_
.
yytext
.
slice
(
-
1
)
!==
"
\\
"
)
this
.
begin
(
"
mu
"
);
if
(
yy_
.
yytext
.
slice
(
-
1
)
===
"
\\
"
)
yy_
.
yytext
=
yy_
.
yytext
.
substr
(
0
,
yy_
.
yyleng
-
1
),
this
.
begin
(
"
emu
"
);
if
(
yy_
.
yytext
)
return
14
;
break
;
case
1
:
return
14
;
break
;
case
2
:
this
.
popState
();
return
14
;
break
;
case
3
:
return
24
;
break
;
case
4
:
return
16
;
break
;
case
5
:
return
20
;
break
;
case
6
:
return
19
;
break
;
case
7
:
return
19
;
break
;
case
8
:
return
23
;
break
;
case
9
:
return
23
;
break
;
case
10
:
yy_
.
yytext
=
yy_
.
yytext
.
substr
(
3
,
yy_
.
yyleng
-
5
);
this
.
popState
();
return
15
;
break
;
case
11
:
return
22
;
break
;
case
12
:
return
34
;
break
;
case
13
:
return
33
;
break
;
case
14
:
return
33
;
break
;
case
15
:
return
36
;
break
;
case
16
:
/*ignore whitespace*/
break
;
case
17
:
this
.
popState
();
return
18
;
break
;
case
18
:
this
.
popState
();
return
18
;
break
;
case
19
:
yy_
.
yytext
=
yy_
.
yytext
.
substr
(
1
,
yy_
.
yyleng
-
2
).
replace
(
/
\\
"/g
,
'
"
'
);
return
28
;
break
;
case
20
:
return
30
;
break
;
case
21
:
return
30
;
break
;
case
22
:
return
29
;
break
;
case
23
:
return
33
;
break
;
case
24
:
yy_
.
yytext
=
yy_
.
yytext
.
substr
(
1
,
yy_
.
yyleng
-
2
);
return
33
;
break
;
case
25
:
return
'
INVALID
'
;
break
;
case
26
:
return
5
;
break
;
}
};
lexer
.
rules
=
[
/^
[^\x
00
]
*
?(?=(\{\{))
/
,
/^
[^\x
00
]
+/
,
/^
[^\x
00
]{2,}?(?=(\{\{))
/
,
/^
\{\{
>/
,
/^
\{\{
#/
,
/^
\{\{\/
/
,
/^
\{\{\^
/
,
/^
\{\{\s
*else
\b
/
,
/^
\{\{\{
/
,
/^
\{\{
&/
,
/^
\{\{
!
[\s\S]
*
?\}\}
/
,
/^
\{\{
/
,
/^=/
,
/^
\.(?=[
}
])
/
,
/^
\.\.
/
,
/^
[\/
.
]
/
,
/^
\s
+/
,
/^
\}\}\}
/
,
/^
\}\}
/
,
/^"
(\\[
"
]
|
[^
"
])
*"/
,
/^true
(?=[
}
\s])
/
,
/^false
(?=[
}
\s])
/
,
/^
[
0-9
]
+
(?=[
}
\s])
/
,
/^
[
a-zA-Z0-9_$-
]
+
(?=[
=}
\s\/
.
])
/
,
/^
\[[^\]]
*
\]
/
,
/^./
,
/^$/
];
lexer
.
conditions
=
{
"
mu
"
:{
"
rules
"
:[
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
],
"
inclusive
"
:
false
},
"
emu
"
:{
"
rules
"
:[
2
],
"
inclusive
"
:
false
},
"
INITIAL
"
:{
"
rules
"
:[
0
,
1
,
26
],
"
inclusive
"
:
true
}};
return
lexer
;})()
parser
.
lexer
=
lexer
;
return
parser
;
})();
if
(
typeof
require
!==
'
undefined
'
&&
typeof
exports
!==
'
undefined
'
)
{
exports
.
parser
=
handlebars
;
exports
.
parse
=
function
()
{
return
handlebars
.
parse
.
apply
(
handlebars
,
arguments
);
}
exports
.
main
=
function
commonjsMain
(
args
)
{
if
(
!
args
[
1
])
throw
new
Error
(
'
Usage:
'
+
args
[
0
]
+
'
FILE
'
);
if
(
typeof
process
!==
'
undefined
'
)
{
var
source
=
require
(
'
fs
'
).
readFileSync
(
require
(
'
path
'
).
join
(
process
.
cwd
(),
args
[
1
]),
"
utf8
"
);
}
else
{
var
cwd
=
require
(
"
file
"
).
path
(
require
(
"
file
"
).
cwd
());
var
source
=
cwd
.
join
(
args
[
1
]).
read
({
charset
:
"
utf-8
"
});
}
return
exports
.
parser
.
parse
(
source
);
}
if
(
typeof
module
!==
'
undefined
'
&&
require
.
main
===
module
)
{
exports
.
main
(
typeof
process
!==
'
undefined
'
?
process
.
argv
.
slice
(
1
)
:
require
(
"
system
"
).
args
);
}
};
;
// lib/handlebars/compiler/base.js
Handlebars
.
Parser
=
handlebars
;
Handlebars
.
parse
=
function
(
string
)
{
Handlebars
.
Parser
.
yy
=
Handlebars
.
AST
;
return
Handlebars
.
Parser
.
parse
(
string
);
};
Handlebars
.
print
=
function
(
ast
)
{
return
new
Handlebars
.
PrintVisitor
().
accept
(
ast
);
};
Handlebars
.
logger
=
{
DEBUG
:
0
,
INFO
:
1
,
WARN
:
2
,
ERROR
:
3
,
level
:
3
,
// override in the host environment
log
:
function
(
level
,
str
)
{}
};
Handlebars
.
log
=
function
(
level
,
str
)
{
Handlebars
.
logger
.
log
(
level
,
str
);
};
;
// lib/handlebars/compiler/ast.js
(
function
()
{
Handlebars
.
AST
=
{};
Handlebars
.
AST
.
ProgramNode
=
function
(
statements
,
inverse
)
{
this
.
type
=
"
program
"
;
this
.
statements
=
statements
;
if
(
inverse
)
{
this
.
inverse
=
new
Handlebars
.
AST
.
ProgramNode
(
inverse
);
}
};
Handlebars
.
AST
.
MustacheNode
=
function
(
params
,
hash
,
unescaped
)
{
this
.
type
=
"
mustache
"
;
this
.
id
=
params
[
0
];
this
.
params
=
params
.
slice
(
1
);
this
.
hash
=
hash
;
this
.
escaped
=
!
unescaped
;
};
Handlebars
.
AST
.
PartialNode
=
function
(
id
,
context
)
{
this
.
type
=
"
partial
"
;
// TODO: disallow complex IDs
this
.
id
=
id
;
this
.
context
=
context
;
};
var
verifyMatch
=
function
(
open
,
close
)
{
if
(
open
.
original
!==
close
.
original
)
{
throw
new
Handlebars
.
Exception
(
open
.
original
+
"
doesn't match
"
+
close
.
original
);
}
};
Handlebars
.
AST
.
BlockNode
=
function
(
mustache
,
program
,
close
)
{
verifyMatch
(
mustache
.
id
,
close
);
this
.
type
=
"
block
"
;
this
.
mustache
=
mustache
;
this
.
program
=
program
;
};
Handlebars
.
AST
.
InverseNode
=
function
(
mustache
,
program
,
close
)
{
verifyMatch
(
mustache
.
id
,
close
);
this
.
type
=
"
inverse
"
;
this
.
mustache
=
mustache
;
this
.
program
=
program
;
};
Handlebars
.
AST
.
ContentNode
=
function
(
string
)
{
this
.
type
=
"
content
"
;
this
.
string
=
string
;
};
Handlebars
.
AST
.
HashNode
=
function
(
pairs
)
{
this
.
type
=
"
hash
"
;
this
.
pairs
=
pairs
;
};
Handlebars
.
AST
.
IdNode
=
function
(
parts
)
{
this
.
type
=
"
ID
"
;
this
.
original
=
parts
.
join
(
"
.
"
);
var
dig
=
[],
depth
=
0
;
for
(
var
i
=
0
,
l
=
parts
.
length
;
i
<
l
;
i
++
)
{
var
part
=
parts
[
i
];
if
(
part
===
"
..
"
)
{
depth
++
;
}
else
if
(
part
===
"
.
"
||
part
===
"
this
"
)
{
this
.
isScoped
=
true
;
}
else
{
dig
.
push
(
part
);
}
}
this
.
parts
=
dig
;
this
.
string
=
dig
.
join
(
'
.
'
);
this
.
depth
=
depth
;
this
.
isSimple
=
(
dig
.
length
===
1
)
&&
(
depth
===
0
);
};
Handlebars
.
AST
.
StringNode
=
function
(
string
)
{
this
.
type
=
"
STRING
"
;
this
.
string
=
string
;
};
Handlebars
.
AST
.
IntegerNode
=
function
(
integer
)
{
this
.
type
=
"
INTEGER
"
;
this
.
integer
=
integer
;
};
Handlebars
.
AST
.
BooleanNode
=
function
(
bool
)
{
this
.
type
=
"
BOOLEAN
"
;
this
.
bool
=
bool
;
};
Handlebars
.
AST
.
CommentNode
=
function
(
comment
)
{
this
.
type
=
"
comment
"
;
this
.
comment
=
comment
;
};
})();;
// lib/handlebars/utils.js
Handlebars
.
Exception
=
function
(
message
)
{
var
tmp
=
Error
.
prototype
.
constructor
.
apply
(
this
,
arguments
);
for
(
var
p
in
tmp
)
{
if
(
tmp
.
hasOwnProperty
(
p
))
{
this
[
p
]
=
tmp
[
p
];
}
}
this
.
message
=
tmp
.
message
;
};
Handlebars
.
Exception
.
prototype
=
new
Error
;
// Build out our basic SafeString type
Handlebars
.
SafeString
=
function
(
string
)
{
this
.
string
=
string
;
};
Handlebars
.
SafeString
.
prototype
.
toString
=
function
()
{
return
this
.
string
.
toString
();
};
(
function
()
{
var
escape
=
{
"
<
"
:
"
<
"
,
"
>
"
:
"
>
"
,
'
"
'
:
"
"
"
,
"
'
"
:
"
'
"
,
"
`
"
:
"
`
"
};
var
badChars
=
/&
(?!\w
+;
)
|
[
<>"'`
]
/g
;
var
possible
=
/
[
&<>"'`
]
/
;
var
escapeChar
=
function
(
chr
)
{
return
escape
[
chr
]
||
"
&
"
;
};
Handlebars
.
Utils
=
{
escapeExpression
:
function
(
string
)
{
// don't escape SafeStrings, since they're already safe
if
(
string
instanceof
Handlebars
.
SafeString
)
{
return
string
.
toString
();
}
else
if
(
string
==
null
||
string
===
false
)
{
return
""
;
}
if
(
!
possible
.
test
(
string
))
{
return
string
;
}
return
string
.
replace
(
badChars
,
escapeChar
);
},
isEmpty
:
function
(
value
)
{
if
(
typeof
value
===
"
undefined
"
)
{
return
true
;
}
else
if
(
value
===
null
)
{
return
true
;
}
else
if
(
value
===
false
)
{
return
true
;
}
else
if
(
Object
.
prototype
.
toString
.
call
(
value
)
===
"
[object Array]
"
&&
value
.
length
===
0
)
{
return
true
;
}
else
{
return
false
;
}
}
};
})();;
// lib/handlebars/compiler/compiler.js
Handlebars
.
Compiler
=
function
()
{};
Handlebars
.
JavaScriptCompiler
=
function
()
{};
(
function
(
Compiler
,
JavaScriptCompiler
)
{
Compiler
.
OPCODE_MAP
=
{
appendContent
:
1
,
getContext
:
2
,
lookupWithHelpers
:
3
,
lookup
:
4
,
append
:
5
,
invokeMustache
:
6
,
appendEscaped
:
7
,
pushString
:
8
,
truthyOrFallback
:
9
,
functionOrFallback
:
10
,
invokeProgram
:
11
,
invokePartial
:
12
,
push
:
13
,
assignToHash
:
15
,
pushStringParam
:
16
};
Compiler
.
MULTI_PARAM_OPCODES
=
{
appendContent
:
1
,
getContext
:
1
,
lookupWithHelpers
:
2
,
lookup
:
1
,
invokeMustache
:
3
,
pushString
:
1
,
truthyOrFallback
:
1
,
functionOrFallback
:
1
,
invokeProgram
:
3
,
invokePartial
:
1
,
push
:
1
,
assignToHash
:
1
,
pushStringParam
:
1
};
Compiler
.
DISASSEMBLE_MAP
=
{};
for
(
var
prop
in
Compiler
.
OPCODE_MAP
)
{
var
value
=
Compiler
.
OPCODE_MAP
[
prop
];
Compiler
.
DISASSEMBLE_MAP
[
value
]
=
prop
;
}
Compiler
.
multiParamSize
=
function
(
code
)
{
return
Compiler
.
MULTI_PARAM_OPCODES
[
Compiler
.
DISASSEMBLE_MAP
[
code
]];
};
Compiler
.
prototype
=
{
compiler
:
Compiler
,
disassemble
:
function
()
{
var
opcodes
=
this
.
opcodes
,
opcode
,
nextCode
;
var
out
=
[],
str
,
name
,
value
;
for
(
var
i
=
0
,
l
=
opcodes
.
length
;
i
<
l
;
i
++
)
{
opcode
=
opcodes
[
i
];
if
(
opcode
===
'
DECLARE
'
)
{
name
=
opcodes
[
++
i
];
value
=
opcodes
[
++
i
];
out
.
push
(
"
DECLARE
"
+
name
+
"
=
"
+
value
);
}
else
{
str
=
Compiler
.
DISASSEMBLE_MAP
[
opcode
];
var
extraParams
=
Compiler
.
multiParamSize
(
opcode
);
var
codes
=
[];
for
(
var
j
=
0
;
j
<
extraParams
;
j
++
)
{
nextCode
=
opcodes
[
++
i
];
if
(
typeof
nextCode
===
"
string
"
)
{
nextCode
=
"
\"
"
+
nextCode
.
replace
(
"
\n
"
,
"
\\
n
"
)
+
"
\"
"
;
}
codes
.
push
(
nextCode
);
}
str
=
str
+
"
"
+
codes
.
join
(
"
"
);
out
.
push
(
str
);
}
}
return
out
.
join
(
"
\n
"
);
},
guid
:
0
,
compile
:
function
(
program
,
options
)
{
this
.
children
=
[];
this
.
depths
=
{
list
:
[]};
this
.
options
=
options
;
// These changes will propagate to the other compiler components
var
knownHelpers
=
this
.
options
.
knownHelpers
;
this
.
options
.
knownHelpers
=
{
'
helperMissing
'
:
true
,
'
blockHelperMissing
'
:
true
,
'
each
'
:
true
,
'
if
'
:
true
,
'
unless
'
:
true
,
'
with
'
:
true
,
'
log
'
:
true
};
if
(
knownHelpers
)
{
for
(
var
name
in
knownHelpers
)
{
this
.
options
.
knownHelpers
[
name
]
=
knownHelpers
[
name
];
}
}
return
this
.
program
(
program
);
},
accept
:
function
(
node
)
{
return
this
[
node
.
type
](
node
);
},
program
:
function
(
program
)
{
var
statements
=
program
.
statements
,
statement
;
this
.
opcodes
=
[];
for
(
var
i
=
0
,
l
=
statements
.
length
;
i
<
l
;
i
++
)
{
statement
=
statements
[
i
];
this
[
statement
.
type
](
statement
);
}
this
.
isSimple
=
l
===
1
;
this
.
depths
.
list
=
this
.
depths
.
list
.
sort
(
function
(
a
,
b
)
{
return
a
-
b
;
});
return
this
;
},
compileProgram
:
function
(
program
)
{
var
result
=
new
this
.
compiler
().
compile
(
program
,
this
.
options
);
var
guid
=
this
.
guid
++
;
this
.
usePartial
=
this
.
usePartial
||
result
.
usePartial
;
this
.
children
[
guid
]
=
result
;
for
(
var
i
=
0
,
l
=
result
.
depths
.
list
.
length
;
i
<
l
;
i
++
)
{
depth
=
result
.
depths
.
list
[
i
];
if
(
depth
<
2
)
{
continue
;
}
else
{
this
.
addDepth
(
depth
-
1
);
}
}
return
guid
;
},
block
:
function
(
block
)
{
var
mustache
=
block
.
mustache
;
var
depth
,
child
,
inverse
,
inverseGuid
;
var
params
=
this
.
setupStackForMustache
(
mustache
);
var
programGuid
=
this
.
compileProgram
(
block
.
program
);
if
(
block
.
program
.
inverse
)
{
inverseGuid
=
this
.
compileProgram
(
block
.
program
.
inverse
);
this
.
declare
(
'
inverse
'
,
inverseGuid
);
}
this
.
opcode
(
'
invokeProgram
'
,
programGuid
,
params
.
length
,
!!
mustache
.
hash
);
this
.
declare
(
'
inverse
'
,
null
);
this
.
opcode
(
'
append
'
);
},
inverse
:
function
(
block
)
{
var
params
=
this
.
setupStackForMustache
(
block
.
mustache
);
var
programGuid
=
this
.
compileProgram
(
block
.
program
);
this
.
declare
(
'
inverse
'
,
programGuid
);
this
.
opcode
(
'
invokeProgram
'
,
null
,
params
.
length
,
!!
block
.
mustache
.
hash
);
this
.
declare
(
'
inverse
'
,
null
);
this
.
opcode
(
'
append
'
);
},
hash
:
function
(
hash
)
{
var
pairs
=
hash
.
pairs
,
pair
,
val
;
this
.
opcode
(
'
push
'
,
'
{}
'
);
for
(
var
i
=
0
,
l
=
pairs
.
length
;
i
<
l
;
i
++
)
{
pair
=
pairs
[
i
];
val
=
pair
[
1
];
this
.
accept
(
val
);
this
.
opcode
(
'
assignToHash
'
,
pair
[
0
]);
}
},
partial
:
function
(
partial
)
{
var
id
=
partial
.
id
;
this
.
usePartial
=
true
;
if
(
partial
.
context
)
{
this
.
ID
(
partial
.
context
);
}
else
{
this
.
opcode
(
'
push
'
,
'
depth0
'
);
}
this
.
opcode
(
'
invokePartial
'
,
id
.
original
);
this
.
opcode
(
'
append
'
);
},
content
:
function
(
content
)
{
this
.
opcode
(
'
appendContent
'
,
content
.
string
);
},
mustache
:
function
(
mustache
)
{
var
params
=
this
.
setupStackForMustache
(
mustache
);
this
.
opcode
(
'
invokeMustache
'
,
params
.
length
,
mustache
.
id
.
original
,
!!
mustache
.
hash
);
if
(
mustache
.
escaped
&&
!
this
.
options
.
noEscape
)
{
this
.
opcode
(
'
appendEscaped
'
);
}
else
{
this
.
opcode
(
'
append
'
);
}
},
ID
:
function
(
id
)
{
this
.
addDepth
(
id
.
depth
);
this
.
opcode
(
'
getContext
'
,
id
.
depth
);
this
.
opcode
(
'
lookupWithHelpers
'
,
id
.
parts
[
0
]
||
null
,
id
.
isScoped
||
false
);
for
(
var
i
=
1
,
l
=
id
.
parts
.
length
;
i
<
l
;
i
++
)
{
this
.
opcode
(
'
lookup
'
,
id
.
parts
[
i
]);
}
},
STRING
:
function
(
string
)
{
this
.
opcode
(
'
pushString
'
,
string
.
string
);
},
INTEGER
:
function
(
integer
)
{
this
.
opcode
(
'
push
'
,
integer
.
integer
);
},
BOOLEAN
:
function
(
bool
)
{
this
.
opcode
(
'
push
'
,
bool
.
bool
);
},
comment
:
function
()
{},
// HELPERS
pushParams
:
function
(
params
)
{
var
i
=
params
.
length
,
param
;
while
(
i
--
)
{
param
=
params
[
i
];
if
(
this
.
options
.
stringParams
)
{
if
(
param
.
depth
)
{
this
.
addDepth
(
param
.
depth
);
}
this
.
opcode
(
'
getContext
'
,
param
.
depth
||
0
);
this
.
opcode
(
'
pushStringParam
'
,
param
.
string
);
}
else
{
this
[
param
.
type
](
param
);
}
}
},
opcode
:
function
(
name
,
val1
,
val2
,
val3
)
{
this
.
opcodes
.
push
(
Compiler
.
OPCODE_MAP
[
name
]);
if
(
val1
!==
undefined
)
{
this
.
opcodes
.
push
(
val1
);
}
if
(
val2
!==
undefined
)
{
this
.
opcodes
.
push
(
val2
);
}
if
(
val3
!==
undefined
)
{
this
.
opcodes
.
push
(
val3
);
}
},
declare
:
function
(
name
,
value
)
{
this
.
opcodes
.
push
(
'
DECLARE
'
);
this
.
opcodes
.
push
(
name
);
this
.
opcodes
.
push
(
value
);
},
addDepth
:
function
(
depth
)
{
if
(
depth
===
0
)
{
return
;
}
if
(
!
this
.
depths
[
depth
])
{
this
.
depths
[
depth
]
=
true
;
this
.
depths
.
list
.
push
(
depth
);
}
},
setupStackForMustache
:
function
(
mustache
)
{
var
params
=
mustache
.
params
;
this
.
pushParams
(
params
);
if
(
mustache
.
hash
)
{
this
.
hash
(
mustache
.
hash
);
}
this
.
ID
(
mustache
.
id
);
return
params
;
}
};
JavaScriptCompiler
.
prototype
=
{
// PUBLIC API: You can override these methods in a subclass to provide
// alternative compiled forms for name lookup and buffering semantics
nameLookup
:
function
(
parent
,
name
,
type
)
{
if
(
/^
[
0-9
]
+$/
.
test
(
name
))
{
return
parent
+
"
[
"
+
name
+
"
]
"
;
}
else
if
(
JavaScriptCompiler
.
isValidJavaScriptVariableName
(
name
))
{
return
parent
+
"
.
"
+
name
;
}
else
{
return
parent
+
"
['
"
+
name
+
"
']
"
;
}
},
appendToBuffer
:
function
(
string
)
{
if
(
this
.
environment
.
isSimple
)
{
return
"
return
"
+
string
+
"
;
"
;
}
else
{
return
"
buffer +=
"
+
string
+
"
;
"
;
}
},
initializeBuffer
:
function
()
{
return
this
.
quotedString
(
""
);
},
namespace
:
"
Handlebars
"
,
// END PUBLIC API
compile
:
function
(
environment
,
options
,
context
,
asObject
)
{
this
.
environment
=
environment
;
this
.
options
=
options
||
{};
this
.
name
=
this
.
environment
.
name
;
this
.
isChild
=
!!
context
;
this
.
context
=
context
||
{
programs
:
[],
aliases
:
{
self
:
'
this
'
},
registers
:
{
list
:
[]}
};
this
.
preamble
();
this
.
stackSlot
=
0
;
this
.
stackVars
=
[];
this
.
compileChildren
(
environment
,
options
);
var
opcodes
=
environment
.
opcodes
,
opcode
;
this
.
i
=
0
;
for
(
l
=
opcodes
.
length
;
this
.
i
<
l
;
this
.
i
++
)
{
opcode
=
this
.
nextOpcode
(
0
);
if
(
opcode
[
0
]
===
'
DECLARE
'
)
{
this
.
i
=
this
.
i
+
2
;
this
[
opcode
[
1
]]
=
opcode
[
2
];
}
else
{
this
.
i
=
this
.
i
+
opcode
[
1
].
length
;
this
[
opcode
[
0
]].
apply
(
this
,
opcode
[
1
]);
}
}
return
this
.
createFunctionContext
(
asObject
);
},
nextOpcode
:
function
(
n
)
{
var
opcodes
=
this
.
environment
.
opcodes
,
opcode
=
opcodes
[
this
.
i
+
n
],
name
,
val
;
var
extraParams
,
codes
;
if
(
opcode
===
'
DECLARE
'
)
{
name
=
opcodes
[
this
.
i
+
1
];
val
=
opcodes
[
this
.
i
+
2
];
return
[
'
DECLARE
'
,
name
,
val
];
}
else
{
name
=
Compiler
.
DISASSEMBLE_MAP
[
opcode
];
extraParams
=
Compiler
.
multiParamSize
(
opcode
);
codes
=
[];
for
(
var
j
=
0
;
j
<
extraParams
;
j
++
)
{
codes
.
push
(
opcodes
[
this
.
i
+
j
+
1
+
n
]);
}
return
[
name
,
codes
];
}
},
eat
:
function
(
opcode
)
{
this
.
i
=
this
.
i
+
opcode
.
length
;
},
preamble
:
function
()
{
var
out
=
[];
// this register will disambiguate helper lookup from finding a function in
// a context. This is necessary for mustache compatibility, which requires
// that context functions in blocks are evaluated by blockHelperMissing, and
// then proceed as if the resulting value was provided to blockHelperMissing.
this
.
useRegister
(
'
foundHelper
'
);
if
(
!
this
.
isChild
)
{
var
namespace
=
this
.
namespace
;
var
copies
=
"
helpers = helpers ||
"
+
namespace
+
"
.helpers;
"
;
if
(
this
.
environment
.
usePartial
)
{
copies
=
copies
+
"
partials = partials ||
"
+
namespace
+
"
.partials;
"
;
}
out
.
push
(
copies
);
}
else
{
out
.
push
(
''
);
}
if
(
!
this
.
environment
.
isSimple
)
{
out
.
push
(
"
, buffer =
"
+
this
.
initializeBuffer
());
}
else
{
out
.
push
(
""
);
}
// track the last context pushed into place to allow skipping the
// getContext opcode when it would be a noop
this
.
lastContext
=
0
;
this
.
source
=
out
;
},
createFunctionContext
:
function
(
asObject
)
{
var
locals
=
this
.
stackVars
;
if
(
!
this
.
isChild
)
{
locals
=
locals
.
concat
(
this
.
context
.
registers
.
list
);
}
if
(
locals
.
length
>
0
)
{
this
.
source
[
1
]
=
this
.
source
[
1
]
+
"
,
"
+
locals
.
join
(
"
,
"
);
}
// Generate minimizer alias mappings
if
(
!
this
.
isChild
)
{
var
aliases
=
[]
for
(
var
alias
in
this
.
context
.
aliases
)
{
this
.
source
[
1
]
=
this
.
source
[
1
]
+
'
,
'
+
alias
+
'
=
'
+
this
.
context
.
aliases
[
alias
];
}
}
if
(
this
.
source
[
1
])
{
this
.
source
[
1
]
=
"
var
"
+
this
.
source
[
1
].
substring
(
2
)
+
"
;
"
;
}
// Merge children
if
(
!
this
.
isChild
)
{
this
.
source
[
1
]
+=
'
\n
'
+
this
.
context
.
programs
.
join
(
'
\n
'
)
+
'
\n
'
;
}
if
(
!
this
.
environment
.
isSimple
)
{
this
.
source
.
push
(
"
return buffer;
"
);
}
var
params
=
this
.
isChild
?
[
"
depth0
"
,
"
data
"
]
:
[
"
Handlebars
"
,
"
depth0
"
,
"
helpers
"
,
"
partials
"
,
"
data
"
];
for
(
var
i
=
0
,
l
=
this
.
environment
.
depths
.
list
.
length
;
i
<
l
;
i
++
)
{
params
.
push
(
"
depth
"
+
this
.
environment
.
depths
.
list
[
i
]);
}
if
(
asObject
)
{
params
.
push
(
this
.
source
.
join
(
"
\n
"
));
return
Function
.
apply
(
this
,
params
);
}
else
{
var
functionSource
=
'
function
'
+
(
this
.
name
||
''
)
+
'
(
'
+
params
.
join
(
'
,
'
)
+
'
) {
\n
'
+
this
.
source
.
join
(
"
\n
"
)
+
'
}
'
;
Handlebars
.
log
(
Handlebars
.
logger
.
DEBUG
,
functionSource
+
"
\n\n
"
);
return
functionSource
;
}
},
appendContent
:
function
(
content
)
{
this
.
source
.
push
(
this
.
appendToBuffer
(
this
.
quotedString
(
content
)));
},
append
:
function
()
{
var
local
=
this
.
popStack
();
this
.
source
.
push
(
"
if(
"
+
local
+
"
||
"
+
local
+
"
=== 0) {
"
+
this
.
appendToBuffer
(
local
)
+
"
}
"
);
if
(
this
.
environment
.
isSimple
)
{
this
.
source
.
push
(
"
else {
"
+
this
.
appendToBuffer
(
"
''
"
)
+
"
}
"
);
}
},
appendEscaped
:
function
()
{
var
opcode
=
this
.
nextOpcode
(
1
),
extra
=
""
;
this
.
context
.
aliases
.
escapeExpression
=
'
this.escapeExpression
'
;
if
(
opcode
[
0
]
===
'
appendContent
'
)
{
extra
=
"
+
"
+
this
.
quotedString
(
opcode
[
1
][
0
]);
this
.
eat
(
opcode
);
}
this
.
source
.
push
(
this
.
appendToBuffer
(
"
escapeExpression(
"
+
this
.
popStack
()
+
"
)
"
+
extra
));
},
getContext
:
function
(
depth
)
{
if
(
this
.
lastContext
!==
depth
)
{
this
.
lastContext
=
depth
;
}
},
lookupWithHelpers
:
function
(
name
,
isScoped
)
{
if
(
name
)
{
var
topStack
=
this
.
nextStack
();
this
.
usingKnownHelper
=
false
;
var
toPush
;
if
(
!
isScoped
&&
this
.
options
.
knownHelpers
[
name
])
{
toPush
=
topStack
+
"
=
"
+
this
.
nameLookup
(
'
helpers
'
,
name
,
'
helper
'
);
this
.
usingKnownHelper
=
true
;
}
else
if
(
isScoped
||
this
.
options
.
knownHelpersOnly
)
{
toPush
=
topStack
+
"
=
"
+
this
.
nameLookup
(
'
depth
'
+
this
.
lastContext
,
name
,
'
context
'
);
}
else
{
this
.
register
(
'
foundHelper
'
,
this
.
nameLookup
(
'
helpers
'
,
name
,
'
helper
'
));
toPush
=
topStack
+
"
= foundHelper ||
"
+
this
.
nameLookup
(
'
depth
'
+
this
.
lastContext
,
name
,
'
context
'
);
}
toPush
+=
'
;
'
;
this
.
source
.
push
(
toPush
);
}
else
{
this
.
pushStack
(
'
depth
'
+
this
.
lastContext
);
}
},
lookup
:
function
(
name
)
{
var
topStack
=
this
.
topStack
();
this
.
source
.
push
(
topStack
+
"
= (
"
+
topStack
+
"
=== null ||
"
+
topStack
+
"
=== undefined ||
"
+
topStack
+
"
=== false ?
"
+
topStack
+
"
:
"
+
this
.
nameLookup
(
topStack
,
name
,
'
context
'
)
+
"
);
"
);
},
pushStringParam
:
function
(
string
)
{
this
.
pushStack
(
'
depth
'
+
this
.
lastContext
);
this
.
pushString
(
string
);
},
pushString
:
function
(
string
)
{
this
.
pushStack
(
this
.
quotedString
(
string
));
},
push
:
function
(
name
)
{
this
.
pushStack
(
name
);
},
invokeMustache
:
function
(
paramSize
,
original
,
hasHash
)
{
this
.
populateParams
(
paramSize
,
this
.
quotedString
(
original
),
"
{}
"
,
null
,
hasHash
,
function
(
nextStack
,
helperMissingString
,
id
)
{
if
(
!
this
.
usingKnownHelper
)
{
this
.
context
.
aliases
.
helperMissing
=
'
helpers.helperMissing
'
;
this
.
context
.
aliases
.
undef
=
'
void 0
'
;
this
.
source
.
push
(
"
else if(
"
+
id
+
"
=== undef) {
"
+
nextStack
+
"
= helperMissing.call(
"
+
helperMissingString
+
"
); }
"
);
if
(
nextStack
!==
id
)
{
this
.
source
.
push
(
"
else {
"
+
nextStack
+
"
=
"
+
id
+
"
; }
"
);
}
}
});
},
invokeProgram
:
function
(
guid
,
paramSize
,
hasHash
)
{
var
inverse
=
this
.
programExpression
(
this
.
inverse
);
var
mainProgram
=
this
.
programExpression
(
guid
);
this
.
populateParams
(
paramSize
,
null
,
mainProgram
,
inverse
,
hasHash
,
function
(
nextStack
,
helperMissingString
,
id
)
{
if
(
!
this
.
usingKnownHelper
)
{
this
.
context
.
aliases
.
blockHelperMissing
=
'
helpers.blockHelperMissing
'
;
this
.
source
.
push
(
"
else {
"
+
nextStack
+
"
= blockHelperMissing.call(
"
+
helperMissingString
+
"
); }
"
);
}
});
},
populateParams
:
function
(
paramSize
,
helperId
,
program
,
inverse
,
hasHash
,
fn
)
{
var
needsRegister
=
hasHash
||
this
.
options
.
stringParams
||
inverse
||
this
.
options
.
data
;
var
id
=
this
.
popStack
(),
nextStack
;
var
params
=
[],
param
,
stringParam
,
stringOptions
;
if
(
needsRegister
)
{
this
.
register
(
'
tmp1
'
,
program
);
stringOptions
=
'
tmp1
'
;
}
else
{
stringOptions
=
'
{ hash: {} }
'
;
}
if
(
needsRegister
)
{
var
hash
=
(
hasHash
?
this
.
popStack
()
:
'
{}
'
);
this
.
source
.
push
(
'
tmp1.hash =
'
+
hash
+
'
;
'
);
}
if
(
this
.
options
.
stringParams
)
{
this
.
source
.
push
(
'
tmp1.contexts = [];
'
);
}
for
(
var
i
=
0
;
i
<
paramSize
;
i
++
)
{
param
=
this
.
popStack
();
params
.
push
(
param
);
if
(
this
.
options
.
stringParams
)
{
this
.
source
.
push
(
'
tmp1.contexts.push(
'
+
this
.
popStack
()
+
'
);
'
);
}
}
if
(
inverse
)
{
this
.
source
.
push
(
'
tmp1.fn = tmp1;
'
);
this
.
source
.
push
(
'
tmp1.inverse =
'
+
inverse
+
'
;
'
);
}
if
(
this
.
options
.
data
)
{
this
.
source
.
push
(
'
tmp1.data = data;
'
);
}
params
.
push
(
stringOptions
);
this
.
populateCall
(
params
,
id
,
helperId
||
id
,
fn
,
program
!==
'
{}
'
);
},
populateCall
:
function
(
params
,
id
,
helperId
,
fn
,
program
)
{
var
paramString
=
[
"
depth0
"
].
concat
(
params
).
join
(
"
,
"
);
var
helperMissingString
=
[
"
depth0
"
].
concat
(
helperId
).
concat
(
params
).
join
(
"
,
"
);
var
nextStack
=
this
.
nextStack
();
if
(
this
.
usingKnownHelper
)
{
this
.
source
.
push
(
nextStack
+
"
=
"
+
id
+
"
.call(
"
+
paramString
+
"
);
"
);
}
else
{
this
.
context
.
aliases
.
functionType
=
'
"function"
'
;
var
condition
=
program
?
"
foundHelper &&
"
:
""
this
.
source
.
push
(
"
if(
"
+
condition
+
"
typeof
"
+
id
+
"
=== functionType) {
"
+
nextStack
+
"
=
"
+
id
+
"
.call(
"
+
paramString
+
"
); }
"
);
}
fn
.
call
(
this
,
nextStack
,
helperMissingString
,
id
);
this
.
usingKnownHelper
=
false
;
},
invokePartial
:
function
(
context
)
{
params
=
[
this
.
nameLookup
(
'
partials
'
,
context
,
'
partial
'
),
"
'
"
+
context
+
"
'
"
,
this
.
popStack
(),
"
helpers
"
,
"
partials
"
];
if
(
this
.
options
.
data
)
{
params
.
push
(
"
data
"
);
}
this
.
pushStack
(
"
self.invokePartial(
"
+
params
.
join
(
"
,
"
)
+
"
);
"
);
},
assignToHash
:
function
(
key
)
{
var
value
=
this
.
popStack
();
var
hash
=
this
.
topStack
();
this
.
source
.
push
(
hash
+
"
['
"
+
key
+
"
'] =
"
+
value
+
"
;
"
);
},
// HELPERS
compiler
:
JavaScriptCompiler
,
compileChildren
:
function
(
environment
,
options
)
{
var
children
=
environment
.
children
,
child
,
compiler
;
for
(
var
i
=
0
,
l
=
children
.
length
;
i
<
l
;
i
++
)
{
child
=
children
[
i
];
compiler
=
new
this
.
compiler
();
this
.
context
.
programs
.
push
(
''
);
// Placeholder to prevent name conflicts for nested children
var
index
=
this
.
context
.
programs
.
length
;
child
.
index
=
index
;
child
.
name
=
'
program
'
+
index
;
this
.
context
.
programs
[
index
]
=
compiler
.
compile
(
child
,
options
,
this
.
context
);
}
},
programExpression
:
function
(
guid
)
{
if
(
guid
==
null
)
{
return
"
self.noop
"
;
}
var
child
=
this
.
environment
.
children
[
guid
],
depths
=
child
.
depths
.
list
;
var
programParams
=
[
child
.
index
,
child
.
name
,
"
data
"
];
for
(
var
i
=
0
,
l
=
depths
.
length
;
i
<
l
;
i
++
)
{
depth
=
depths
[
i
];
if
(
depth
===
1
)
{
programParams
.
push
(
"
depth0
"
);
}
else
{
programParams
.
push
(
"
depth
"
+
(
depth
-
1
));
}
}
if
(
depths
.
length
===
0
)
{
return
"
self.program(
"
+
programParams
.
join
(
"
,
"
)
+
"
)
"
;
}
else
{
programParams
.
shift
();
return
"
self.programWithDepth(
"
+
programParams
.
join
(
"
,
"
)
+
"
)
"
;
}
},
register
:
function
(
name
,
val
)
{
this
.
useRegister
(
name
);
this
.
source
.
push
(
name
+
"
=
"
+
val
+
"
;
"
);
},
useRegister
:
function
(
name
)
{
if
(
!
this
.
context
.
registers
[
name
])
{
this
.
context
.
registers
[
name
]
=
true
;
this
.
context
.
registers
.
list
.
push
(
name
);
}
},
pushStack
:
function
(
item
)
{
this
.
source
.
push
(
this
.
nextStack
()
+
"
=
"
+
item
+
"
;
"
);
return
"
stack
"
+
this
.
stackSlot
;
},
nextStack
:
function
()
{
this
.
stackSlot
++
;
if
(
this
.
stackSlot
>
this
.
stackVars
.
length
)
{
this
.
stackVars
.
push
(
"
stack
"
+
this
.
stackSlot
);
}
return
"
stack
"
+
this
.
stackSlot
;
},
popStack
:
function
()
{
return
"
stack
"
+
this
.
stackSlot
--
;
},
topStack
:
function
()
{
return
"
stack
"
+
this
.
stackSlot
;
},
quotedString
:
function
(
str
)
{
return
'
"
'
+
str
.
replace
(
/
\\
/g
,
'
\\\\
'
)
.
replace
(
/"/g
,
'
\\
"
'
)
.
replace
(
/
\n
/g
,
'
\\
n
'
)
.
replace
(
/
\r
/g
,
'
\\
r
'
)
+
'
"
'
;
}
};
var
reservedWords
=
(
"
break else new var
"
+
"
case finally return void
"
+
"
catch for switch while
"
+
"
continue function this with
"
+
"
default if throw
"
+
"
delete in try
"
+
"
do instanceof typeof
"
+
"
abstract enum int short
"
+
"
boolean export interface static
"
+
"
byte extends long super
"
+
"
char final native synchronized
"
+
"
class float package throws
"
+
"
const goto private transient
"
+
"
debugger implements protected volatile
"
+
"
double import public let yield
"
).
split
(
"
"
);
var
compilerWords
=
JavaScriptCompiler
.
RESERVED_WORDS
=
{};
for
(
var
i
=
0
,
l
=
reservedWords
.
length
;
i
<
l
;
i
++
)
{
compilerWords
[
reservedWords
[
i
]]
=
true
;
}
JavaScriptCompiler
.
isValidJavaScriptVariableName
=
function
(
name
)
{
if
(
!
JavaScriptCompiler
.
RESERVED_WORDS
[
name
]
&&
/^
[
a-zA-Z_$
][
0-9a-zA-Z_$
]
+$/
.
test
(
name
))
{
return
true
;
}
return
false
;
}
})(
Handlebars
.
Compiler
,
Handlebars
.
JavaScriptCompiler
);
Handlebars
.
precompile
=
function
(
string
,
options
)
{
options
=
options
||
{};
var
ast
=
Handlebars
.
parse
(
string
);
var
environment
=
new
Handlebars
.
Compiler
().
compile
(
ast
,
options
);
return
new
Handlebars
.
JavaScriptCompiler
().
compile
(
environment
,
options
);
};
Handlebars
.
compile
=
function
(
string
,
options
)
{
options
=
options
||
{};
var
compiled
;
function
compile
()
{
var
ast
=
Handlebars
.
parse
(
string
);
var
environment
=
new
Handlebars
.
Compiler
().
compile
(
ast
,
options
);
var
templateSpec
=
new
Handlebars
.
JavaScriptCompiler
().
compile
(
environment
,
options
,
undefined
,
true
);
return
Handlebars
.
template
(
templateSpec
);
}
// Template is only compiled on first use and cached after that point.
return
function
(
context
,
options
)
{
if
(
!
compiled
)
{
compiled
=
compile
();
}
return
compiled
.
call
(
this
,
context
,
options
);
};
};
;
// lib/handlebars/runtime.js
Handlebars
.
VM
=
{
template
:
function
(
templateSpec
)
{
// Just add water
var
container
=
{
escapeExpression
:
Handlebars
.
Utils
.
escapeExpression
,
invokePartial
:
Handlebars
.
VM
.
invokePartial
,
programs
:
[],
program
:
function
(
i
,
fn
,
data
)
{
var
programWrapper
=
this
.
programs
[
i
];
if
(
data
)
{
return
Handlebars
.
VM
.
program
(
fn
,
data
);
}
else
if
(
programWrapper
)
{
return
programWrapper
;
}
else
{
programWrapper
=
this
.
programs
[
i
]
=
Handlebars
.
VM
.
program
(
fn
);
return
programWrapper
;
}
},
programWithDepth
:
Handlebars
.
VM
.
programWithDepth
,
noop
:
Handlebars
.
VM
.
noop
};
return
function
(
context
,
options
)
{
options
=
options
||
{};
return
templateSpec
.
call
(
container
,
Handlebars
,
context
,
options
.
helpers
,
options
.
partials
,
options
.
data
);
};
},
programWithDepth
:
function
(
fn
,
data
,
$depth
)
{
var
args
=
Array
.
prototype
.
slice
.
call
(
arguments
,
2
);
return
function
(
context
,
options
)
{
options
=
options
||
{};
return
fn
.
apply
(
this
,
[
context
,
options
.
data
||
data
].
concat
(
args
));
};
},
program
:
function
(
fn
,
data
)
{
return
function
(
context
,
options
)
{
options
=
options
||
{};
return
fn
(
context
,
options
.
data
||
data
);
};
},
noop
:
function
()
{
return
""
;
},
invokePartial
:
function
(
partial
,
name
,
context
,
helpers
,
partials
,
data
)
{
options
=
{
helpers
:
helpers
,
partials
:
partials
,
data
:
data
};
if
(
partial
===
undefined
)
{
throw
new
Handlebars
.
Exception
(
"
The partial
"
+
name
+
"
could not be found
"
);
}
else
if
(
partial
instanceof
Function
)
{
return
partial
(
context
,
options
);
}
else
if
(
!
Handlebars
.
compile
)
{
throw
new
Handlebars
.
Exception
(
"
The partial
"
+
name
+
"
could not be compiled when running in runtime-only mode
"
);
}
else
{
partials
[
name
]
=
Handlebars
.
compile
(
partial
);
return
partials
[
name
](
context
,
options
);
}
}
};
Handlebars
.
template
=
Handlebars
.
VM
.
template
;
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment